From 123344cc2b3593c814a2238b1714530ab2a49463 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 3 May 2021 14:31:53 +0200 Subject: [PATCH] fix(shell-api): allow legacy coll.runCommand overload MONGOSH-688 --- packages/shell-api/src/collection.spec.ts | 23 ++++++++++++++- packages/shell-api/src/collection.ts | 34 +++++++++++++---------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/packages/shell-api/src/collection.spec.ts b/packages/shell-api/src/collection.spec.ts index 28343bcece..28723196cc 100644 --- a/packages/shell-api/src/collection.spec.ts +++ b/packages/shell-api/src/collection.spec.ts @@ -1346,9 +1346,20 @@ describe('Collection', () => { ); }); + it('accepts an explicit options object as its first command for legacy compatibility', async() => { + await collection.runCommand({ someCommand: 'differenttestns' }); + + expect(serviceProvider.runCommandWithCheck).to.have.been.calledWith( + collection._database._name, + { + someCommand: 'differenttestns' + } + ); + }); + it('throws an error if commandName is not a string', async() => { const e = await collection.runCommand( - {} as any + 42 as any ).catch(e => e); expect(e).to.be.instanceOf(MongoshInvalidInputError); @@ -1356,6 +1367,16 @@ describe('Collection', () => { expect(e.code).to.equal(CommonErrors.InvalidArgument); }); + it('throws an error if both arguments are options objects', async() => { + const e = await collection.runCommand( + {}, {} + ).catch(e => e); + + expect(e).to.be.instanceOf(MongoshInvalidInputError); + expect(e.message).to.include('takes a command string as its first arugment'); + expect(e.code).to.equal(CommonErrors.InvalidArgument); + }); + it('throws an error if commandName is passed as option', async() => { const e = await collection.runCommand( 'commandName', { commandName: 1 } as any diff --git a/packages/shell-api/src/collection.ts b/packages/shell-api/src/collection.ts index b6b1a3d9cf..287f3be828 100644 --- a/packages/shell-api/src/collection.ts +++ b/packages/shell-api/src/collection.ts @@ -1312,27 +1312,33 @@ export default class Collection extends ShellApiClass { } @returnsPromise - async runCommand(commandName: string, options?: RunCommandOptions): Promise { - assertArgsDefinedType([commandName], ['string'], 'Collection.runCommand'); - - if (options && commandName in options) { - throw new MongoshInvalidInputError( - 'The "commandName" argument cannot be passed as an option to "runCommand".', - CommonErrors.InvalidArgument - ); + async runCommand(commandName: string | Document, options?: RunCommandOptions): Promise { + assertArgsDefinedType([commandName], [['string', 'object']], 'Collection.runCommand'); + if (options) { + if (typeof commandName !== 'string') { + throw new MongoshInvalidInputError( + 'Collection.runCommand takes a command string as its first arugment', + CommonErrors.InvalidArgument + ); + } else if (commandName in options) { + throw new MongoshInvalidInputError( + 'The "commandName" argument cannot be passed as an option to "runCommand".', + CommonErrors.InvalidArgument + ); + } } - const hiddenCommands = new RegExp(HIDDEN_COMMANDS); - if (!hiddenCommands.test(commandName)) { + if (typeof commandName === 'string' && !hiddenCommands.test(commandName)) { this._emitCollectionApiCall('runCommand', { commandName }); } + const cmd = typeof commandName === 'string' ? { + [commandName]: this._name, + ...options + } : commandName; return await this._mongo._serviceProvider.runCommandWithCheck( this._database._name, - { - [commandName]: this._name, - ...options - }, + cmd, this._database._baseOptions ); }