diff --git a/lib/connection.js b/lib/connection.js index 05ff52461b0..48ea6bb2450 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -647,6 +647,30 @@ Connection.prototype.listCollections = async function listCollections() { return await cursor.toArray(); }; +/** + * Helper for MongoDB Node driver's `listDatabases()`. + * Returns an object with a `databases` property that contains an + * array of database objects. + * + * #### Example: + * const { databases } = await mongoose.connection.listDatabases(); + * databases; // [{ name: 'mongoose_test', sizeOnDisk: 0, empty: false }] + * + * @method listCollections + * @return {Promise<{ databases: Array<{ name: string }> }>} + * @api public + */ + +Connection.prototype.listDatabases = async function listDatabases() { + if ((this.readyState === STATES.connecting || this.readyState === STATES.disconnected) && this._shouldBufferCommands()) { + await new Promise(resolve => { + this._queue.push({ fn: resolve }); + }); + } + + return await this.db.admin().listDatabases(); +}; + /** * Helper for `dropDatabase()`. Deletes the given database, including all * collections, documents, and indexes. diff --git a/test/connection.test.js b/test/connection.test.js index 3d1170838cf..82df2ee4c3a 100644 --- a/test/connection.test.js +++ b/test/connection.test.js @@ -1580,6 +1580,17 @@ describe('connections:', function() { }); assert.ok(session); }); + it('listDatabases() should return a list of database objects with a name property (gh-9048)', async function() { + const connection = await mongoose.createConnection(start.uri).asPromise(); + // If this test is running in isolation, then the `start.uri` db might not + // exist yet, so create this collection (and the associated db) just in case + await connection.createCollection('tests').catch(() => {}); + + const { databases } = await connection.listDatabases(); + assert.ok(connection.name); + console.log(databases); + assert.ok(databases.map(database => database.name).includes(connection.name)); + }); describe('createCollections()', function() { it('should create collections for all models on the connection with the createCollections() function (gh-13300)', async function() { const m = new mongoose.Mongoose(); diff --git a/test/types/connection.test.ts b/test/types/connection.test.ts index 93c3fc6c0d8..c5979663a20 100644 --- a/test/types/connection.test.ts +++ b/test/types/connection.test.ts @@ -78,6 +78,10 @@ expectType>( conn.listCollections().then(collections => collections.map(coll => coll.name)) ); +expectType>( + conn.listDatabases().then(dbs => dbs.databases.map(db => db.name)) +); + export function autoTypedModelConnection() { const AutoTypedSchema = autoTypedSchema(); const AutoTypedModel = connection.model('AutoTypeModelConnection', AutoTypedSchema); diff --git a/types/connection.d.ts b/types/connection.d.ts index b2812d01cf6..2f47bdc84e5 100644 --- a/types/connection.d.ts +++ b/types/connection.d.ts @@ -132,6 +132,12 @@ declare module 'mongoose' { */ listCollections(): Promise[]>; + /** + * Helper for MongoDB Node driver's `listDatabases()`. + * Returns an array of database names. + */ + listDatabases(): Promise; + /** * A [POJO](https://masteringjs.io/tutorials/fundamentals/pojo) containing * a map from model names to models. Contains all models that have been