"use strict";
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
    var useValue = arguments.length > 2;
    for (var i = 0; i < initializers.length; i++) {
        value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
    }
    return useValue ? value : void 0;
};
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
    function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
    var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
    var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
    var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
    var _, done = false;
    for (var i = decorators.length - 1; i >= 0; i--) {
        var context = {};
        for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
        for (var p in contextIn.access) context.access[p] = contextIn.access[p];
        context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
        var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
        if (kind === "accessor") {
            if (result === void 0) continue;
            if (result === null || typeof result !== "object") throw new TypeError("Object expected");
            if (_ = accept(result.get)) descriptor.get = _;
            if (_ = accept(result.set)) descriptor.set = _;
            if (_ = accept(result.init)) initializers.unshift(_);
        }
        else if (_ = accept(result)) {
            if (kind === "field") initializers.unshift(_);
            else descriptor[key] = _;
        }
    }
    if (target) Object.defineProperty(target, contextIn.name, descriptor);
    done = true;
};
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
    if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
    return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Database = void 0;
const collection_1 = require("./collection");
const decorators_1 = require("./decorators");
const enums_1 = require("./enums");
const helpers_1 = require("./helpers");
const index_1 = require("./index");
const errors_1 = require("@mongosh/errors");
const mongodb_redact_1 = require("mongodb-redact");
const change_stream_cursor_1 = __importDefault(require("./change-stream-cursor"));
const error_codes_1 = require("./error-codes");
let Database = (() => {
    let _classDecorators = [decorators_1.shellApiClassDefault];
    let _classDescriptor;
    let _classExtraInitializers = [];
    let _classThis;
    let _classSuper = decorators_1.ShellApiWithMongoClass;
    let _instanceExtraInitializers = [];
    let _getMongo_decorators;
    let _getCollectionNames_decorators;
    let _getCollectionInfos_decorators;
    let _runCommand_decorators;
    let _adminCommand_decorators;
    let _aggregate_decorators;
    let _getSiblingDB_decorators;
    let _getCollection_decorators;
    let _dropDatabase_decorators;
    let _createUser_decorators;
    let _updateUser_decorators;
    let _changeUserPassword_decorators;
    let _logout_decorators;
    let _dropUser_decorators;
    let _dropAllUsers_decorators;
    let _auth_decorators;
    let _grantRolesToUser_decorators;
    let _revokeRolesFromUser_decorators;
    let _getUser_decorators;
    let _getUsers_decorators;
    let _createCollection_decorators;
    let _createEncryptedCollection_decorators;
    let _createView_decorators;
    let _createRole_decorators;
    let _updateRole_decorators;
    let _dropRole_decorators;
    let _dropAllRoles_decorators;
    let _grantRolesToRole_decorators;
    let _revokeRolesFromRole_decorators;
    let _grantPrivilegesToRole_decorators;
    let _revokePrivilegesFromRole_decorators;
    let _getRole_decorators;
    let _getRoles_decorators;
    let _currentOp_decorators;
    let _killOp_decorators;
    let _shutdownServer_decorators;
    let _fsyncLock_decorators;
    let _fsyncUnlock_decorators;
    let _version_decorators;
    let _serverBits_decorators;
    let _isMaster_decorators;
    let _hello_decorators;
    let _serverBuildInfo_decorators;
    let _serverStatus_decorators;
    let _stats_decorators;
    let _hostInfo_decorators;
    let _serverCmdLineOpts_decorators;
    let _rotateCertificates_decorators;
    let _printCollectionStats_decorators;
    let _getProfilingStatus_decorators;
    let _setProfilingLevel_decorators;
    let _setLogLevel_decorators;
    let _getLogComponents_decorators;
    let _cloneDatabase_decorators;
    let _cloneCollection_decorators;
    let _copyDatabase_decorators;
    let _commandHelp_decorators;
    let _listCommands_decorators;
    let _getLastErrorObj_decorators;
    let _getLastError_decorators;
    let _printShardingStatus_decorators;
    let _printSecondaryReplicationInfo_decorators;
    let _getReplicationInfo_decorators;
    let _printReplicationInfo_decorators;
    let _printSlaveReplicationInfo_decorators;
    let _setSecondaryOk_decorators;
    let _watch_decorators;
    let _sql_decorators;
    let _checkMetadataConsistency_decorators;
    var Database = _classThis = class extends _classSuper {
        constructor(mongo, name, session) {
            super();
            this._mongo = __runInitializers(this, _instanceExtraInitializers);
            this._cachedCollectionNames = [];
            this._cachedHello = null;
            this._mongo = mongo;
            this._name = name;
            const collections = Object.create(null);
            this._collections = collections;
            this._session = session;
            const proxy = new Proxy(this, {
                get: (target, prop) => {
                    if (prop in target) {
                        return target[prop];
                    }
                    if (typeof prop !== 'string' ||
                        prop.startsWith('_') ||
                        !(0, helpers_1.isValidCollectionName)(prop)) {
                        return;
                    }
                    if (!collections[prop]) {
                        collections[prop] = new collection_1.Collection(mongo, proxy, prop);
                    }
                    return collections[prop];
                },
            });
            return proxy;
        }
        async _baseOptions() {
            const options = {};
            if (this._session) {
                options.session = this._session._session;
            }
            const maxTimeMS = await this._instanceState.shellApi.config.get('maxTimeMS');
            if (typeof maxTimeMS === 'number') {
                options.maxTimeMS = maxTimeMS;
            }
            return options;
        }
        async _maybeCachedHello() {
            return this._cachedHello ?? (await this.hello());
        }
        [enums_1.asPrintable]() {
            return this._name;
        }
        _emitDatabaseApiCall(methodName, methodArguments = {}) {
            this._mongo._instanceState.emitApiCallWithArgs({
                method: methodName,
                class: 'Database',
                db: this._name,
                arguments: methodArguments,
            });
        }
        async _runCommand(cmd, options = {}) {
            return this._mongo._serviceProvider.runCommandWithCheck(this._name, (0, helpers_1.adjustRunCommand)(cmd, this._instanceState.shellBson), {
                ...(await this._baseOptions()),
                ...options,
            });
        }
        async _runReadCommand(cmd, options = {}) {
            return this._mongo._serviceProvider.runCommandWithCheck(this._name, (0, helpers_1.adjustRunCommand)(cmd, this._instanceState.shellBson), {
                ...this._mongo._getExplicitlyRequestedReadPref(),
                ...(await this._baseOptions()),
                ...options,
            });
        }
        async _runAdminCommand(cmd, options = {}) {
            return this.getSiblingDB('admin')._runCommand(cmd, options);
        }
        async _runAdminReadCommand(cmd, options = {}) {
            return this.getSiblingDB('admin')._runReadCommand(cmd, options);
        }
        async _runCursorCommand(cmd, options = {}) {
            const runCursorCommandOptions = {
                ...this._mongo._getExplicitlyRequestedReadPref(),
                ...(await this._baseOptions()),
                ...options,
            };
            const constructionOptions = {
                method: 'runCursorCommand',
                args: [
                    this._name,
                    (0, helpers_1.adjustRunCommand)(cmd, this._instanceState.shellBson),
                    runCursorCommandOptions,
                ],
                cursorType: 'RunCommandCursor',
            };
            const providerCursor = this._mongo._serviceProvider[constructionOptions.method](...constructionOptions.args);
            const constructionOptionsWithChains = runCursorCommandOptions.session
                ? undefined
                : {
                    options: constructionOptions,
                };
            const cursor = new index_1.RunCommandCursor(this._mongo, providerCursor, constructionOptionsWithChains);
            this._mongo._instanceState.currentCursor = cursor;
            return cursor;
        }
        async _runAdminCursorCommand(cmd, options = {}) {
            return this.getSiblingDB('admin')._runCursorCommand(cmd, options);
        }
        async _listCollections(filter, options) {
            return ((await this._mongo._serviceProvider.listCollections(this._name, filter, {
                ...this._mongo._getExplicitlyRequestedReadPref(),
                ...(await this._baseOptions()),
                ...options,
            })) || []);
        }
        async _getCollectionNames(options) {
            const infos = await this._listCollections({}, { ...options, nameOnly: true });
            this._cachedCollectionNames = infos.map((collection) => collection.name);
            return this._cachedCollectionNames;
        }
        async _getCollectionNamesWithTypes(options) {
            let collections = await this._listCollections({}, { ...options, nameOnly: true });
            collections = collections.sort((c1, c2) => c1.name.localeCompare(c2.name));
            this._cachedCollectionNames = collections.map((collection) => collection.name);
            return collections.map((collection, index) => ({
                name: collection.name,
                badge: (0, helpers_1.getBadge)(collections, index),
            }));
        }
        async _getCollectionNamesForCompletion() {
            return await Promise.race([
                (async () => {
                    const result = await this._getCollectionNames({
                        readPreference: 'primaryPreferred',
                    });
                    this._mongo._instanceState.messageBus.emit('mongosh:load-collections-complete');
                    return result;
                })(),
                (async () => {
                    await new Promise((resolve) => setTimeout(resolve, 200)?.unref?.());
                    return this._cachedCollectionNames;
                })(),
            ]);
        }
        async _getLastErrorObj(w, wTimeout, j) {
            const cmd = { getlasterror: 1 };
            if (w) {
                cmd.w = w;
            }
            if (wTimeout) {
                cmd.wtimeout = wTimeout;
            }
            if (j !== undefined) {
                cmd.j = j;
            }
            try {
                return await this._mongo._serviceProvider.runCommand(this._name, cmd, await this._baseOptions());
            }
            catch (e) {
                return e;
            }
        }
        getMongo() {
            return this._mongo;
        }
        getName() {
            return this._name;
        }
        async getCollectionNames() {
            this._emitDatabaseApiCall('getCollectionNames');
            return (await this._getCollectionNames());
        }
        async getCollectionInfos(filter = {}, options = {}) {
            this._emitDatabaseApiCall('getCollectionInfos', { filter, options });
            return await this._listCollections(filter, options);
        }
        async runCommand(cmd, options) {
            (0, helpers_1.assertArgsDefinedType)([cmd], [['string', 'object']], 'Database.runCommand');
            if (typeof cmd === 'string') {
                cmd = { [cmd]: 1 };
            }
            try {
                if (!Object.keys(cmd).some((k) => (0, mongodb_redact_1.shouldRedactCommand)(k))) {
                    this._emitDatabaseApiCall('runCommand', { cmd, options });
                }
                return await this._runCommand(cmd, options);
            }
            catch (error) {
                if (error.codeName === 'NotPrimaryNoSecondaryOk') {
                    const message = `not primary - consider passing the readPreference option e.g. db.runCommand({ command }, { readPreference: "secondaryPreferred" })`;
                    error.message = message;
                }
                throw error;
            }
        }
        async adminCommand(cmd) {
            (0, helpers_1.assertArgsDefinedType)([cmd], [['string', 'object']], 'Database.adminCommand');
            if (typeof cmd === 'string') {
                cmd = { [cmd]: 1 };
            }
            if (!Object.keys(cmd).some((k) => (0, mongodb_redact_1.shouldRedactCommand)(k))) {
                this._emitDatabaseApiCall('adminCommand', { cmd });
            }
            return await this._runAdminCommand(cmd, {});
        }
        async aggregate(...args) {
            let options;
            let pipeline;
            if (args.length === 0 || Array.isArray(args[0])) {
                options = args[1] || {};
                pipeline = args[0] || [];
            }
            else {
                options = {};
                pipeline = args || [];
            }
            if ('background' in options) {
                await this._instanceState.printWarning(helpers_1.aggregateBackgroundOptionNotSupportedHelp);
            }
            (0, helpers_1.assertArgsDefinedType)([pipeline], [true], 'Database.aggregate');
            this._emitDatabaseApiCall('aggregate', { options, pipeline });
            const { aggOptions, explain, dbOptions } = (0, helpers_1.adaptAggregateOptions)(options, !!this._mongo._serviceProvider.hasUnifiedAggregateOptions?.());
            const aggregateOptions = { ...(await this._baseOptions()), ...aggOptions };
            const constructionOptions = {
                method: 'aggregateDb',
                args: [this._name, pipeline, aggregateOptions, dbOptions],
                cursorType: 'AggregationCursor',
            };
            const providerCursor = this._mongo._serviceProvider[constructionOptions.method](...constructionOptions.args);
            const constructionOptionsWithChains = aggregateOptions.session
                ? undefined
                : {
                    options: constructionOptions,
                };
            const cursor = new index_1.AggregationCursor(this._mongo, providerCursor, constructionOptionsWithChains);
            if (explain) {
                return await cursor.explain(explain);
            }
            else if ((0, helpers_1.shouldRunAggregationImmediately)(pipeline)) {
                await cursor.hasNext();
            }
            this._mongo._instanceState.currentCursor = cursor;
            return cursor;
        }
        getSiblingDB(db) {
            (0, helpers_1.assertArgsDefinedType)([db], ['string'], 'Database.getSiblingDB');
            this._emitDatabaseApiCall('getSiblingDB', { db });
            if (this._session) {
                return this._session.getDatabase(db);
            }
            return this._mongo._getDb(db);
        }
        getCollection(coll) {
            (0, helpers_1.assertArgsDefinedType)([coll], ['string'], 'Database.getColl');
            this._emitDatabaseApiCall('getCollection', { coll });
            if (!(0, helpers_1.isValidCollectionName)(coll)) {
                throw new errors_1.MongoshInvalidInputError(`Invalid collection name: ${coll}`, errors_1.CommonErrors.InvalidArgument);
            }
            const collections = this
                ._collections;
            if (!collections[coll]) {
                collections[coll] = new collection_1.Collection(this._mongo, this, coll);
            }
            return collections[coll];
        }
        async dropDatabase(writeConcern) {
            return await this._mongo._serviceProvider.dropDatabase(this._name, {
                ...(await this._baseOptions()),
                writeConcern,
            });
        }
        async createUser(user, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([user], ['object'], 'Database.createUser');
            (0, helpers_1.assertKeysDefined)(user, ['user', 'roles']);
            if (this._name === '$external') {
                if ('pwd' in user) {
                    throw new errors_1.MongoshInvalidInputError('Cannot set password for users on the $external database', errors_1.CommonErrors.InvalidArgument);
                }
            }
            else {
                (0, helpers_1.assertKeysDefined)(user, ['pwd']);
            }
            this._emitDatabaseApiCall('createUser', {});
            if (user.createUser) {
                throw new errors_1.MongoshInvalidInputError('Cannot set createUser field in helper method', errors_1.CommonErrors.InvalidArgument);
            }
            const command = (0, helpers_1.adaptOptions)({ user: 'createUser', passwordDigestor: null }, {}, user);
            if (writeConcern) {
                command.writeConcern = writeConcern;
            }
            const digestPwd = await (0, helpers_1.processDigestPassword)(user.user, user.passwordDigestor, command, this._instanceState.currentServiceProvider);
            const orderedCmd = {
                createUser: command.createUser,
                ...command,
                ...digestPwd,
            };
            return await this._runCommand(orderedCmd);
        }
        async updateUser(username, userDoc, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([username, userDoc], ['string', 'object'], 'Database.updateUser');
            this._emitDatabaseApiCall('updateUser', {});
            if (userDoc.passwordDigestor &&
                userDoc.passwordDigestor !== 'server' &&
                userDoc.passwordDigestor !== 'client') {
                throw new errors_1.MongoshInvalidInputError(`Invalid field: passwordDigestor must be 'client' or 'server', got ${userDoc.passwordDigestor}`, errors_1.CommonErrors.InvalidArgument);
            }
            const command = (0, helpers_1.adaptOptions)({ passwordDigestor: null }, {
                updateUser: username,
            }, userDoc);
            if (writeConcern) {
                command.writeConcern = writeConcern;
            }
            const digestPwd = await (0, helpers_1.processDigestPassword)(username, userDoc.passwordDigestor, command, this._instanceState.currentServiceProvider);
            const orderedCmd = {
                updateUser: command.updateUser,
                ...command,
                ...digestPwd,
            };
            return await this._runCommand(orderedCmd);
        }
        async changeUserPassword(username, password, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([username, password], ['string', 'string'], 'Database.changeUserPassword');
            this._emitDatabaseApiCall('changeUserPassword', {});
            const command = (0, helpers_1.adaptOptions)({}, {
                updateUser: username,
                pwd: password,
            }, {});
            if (writeConcern) {
                command.writeConcern = writeConcern;
            }
            const orderedCmd = { updateUser: command.updateUser, ...command };
            return await this._runCommand(orderedCmd);
        }
        async logout() {
            this._emitDatabaseApiCall('logout', {});
            this._mongo._instanceState.currentCursor = null;
            return await this._runCommand({ logout: 1 });
        }
        async dropUser(username, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([username], ['string'], 'Database.dropUser');
            this._emitDatabaseApiCall('dropUser', {});
            const cmd = { dropUser: username };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async dropAllUsers(writeConcern) {
            this._emitDatabaseApiCall('dropAllUsers', {});
            const cmd = { dropAllUsersFromDatabase: 1 };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async auth(...args) {
            this._emitDatabaseApiCall('auth', {});
            let authDoc;
            if (args.length === 1) {
                const { evaluationListener } = this._mongo._instanceState;
                if (typeof args[0] === 'string' && evaluationListener.onPrompt) {
                    authDoc = {
                        user: args[0],
                        pwd: await evaluationListener.onPrompt('Enter password', 'password'),
                    };
                }
                else {
                    authDoc = args[0];
                }
            }
            else if (args.length === 2) {
                authDoc = {
                    user: args[0],
                    pwd: args[1],
                };
            }
            else {
                throw new errors_1.MongoshInvalidInputError('auth expects (username), (username, password), or ({ user: username, pwd: password })', errors_1.CommonErrors.InvalidArgument);
            }
            if ((!authDoc.user || !authDoc.pwd) && !authDoc.mechanism) {
                throw new errors_1.MongoshInvalidInputError("auth expects user document with at least 'user' and 'pwd' or 'mechanism' fields", errors_1.CommonErrors.InvalidArgument);
            }
            if ('digestPassword' in authDoc) {
                throw new errors_1.MongoshUnimplementedError('digestPassword is not supported for authentication.', errors_1.CommonErrors.NotImplemented);
            }
            authDoc.authDb = this._name;
            this._mongo._instanceState.currentCursor = null;
            return await this._mongo._serviceProvider.authenticate(authDoc);
        }
        async grantRolesToUser(username, roles, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([username, roles], ['string', true], 'Database.grantRolesToUser');
            this._emitDatabaseApiCall('grantRolesToUser', {});
            const cmd = { grantRolesToUser: username, roles: roles };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async revokeRolesFromUser(username, roles, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([username, roles], ['string', true], 'Database.revokeRolesFromUser');
            this._emitDatabaseApiCall('revokeRolesFromUser', {});
            const cmd = { revokeRolesFromUser: username, roles: roles };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async getUser(username, options = {}) {
            (0, helpers_1.assertArgsDefinedType)([username], ['string'], 'Database.getUser');
            this._emitDatabaseApiCall('getUser', { username: username });
            const command = (0, helpers_1.adaptOptions)({}, { usersInfo: { user: username, db: this._name } }, options);
            const result = await this._runReadCommand(command);
            if (result.users === undefined) {
                throw new errors_1.MongoshInternalError('No users were returned from the userInfo command');
            }
            for (let i = 0; i < result.users.length; i++) {
                if (result.users[i].user === username) {
                    return result.users[i];
                }
            }
            return null;
        }
        async getUsers(options = {}) {
            this._emitDatabaseApiCall('getUsers', { options: options });
            const command = (0, helpers_1.adaptOptions)({}, { usersInfo: 1 }, options);
            return await this._runReadCommand(command);
        }
        async createCollection(name, options = {}) {
            (0, helpers_1.assertArgsDefinedType)([name], ['string'], 'Database.createCollection');
            this._emitDatabaseApiCall('createCollection', {
                name: name,
                options: options,
            });
            return await this._mongo._serviceProvider.createCollection(this._name, name, { ...(await this._baseOptions()), ...options });
        }
        async createEncryptedCollection(name, options) {
            this._emitDatabaseApiCall('createEncryptedCollection', {
                name: name,
                options: options,
            });
            return this._mongo
                .getClientEncryption()
                .createEncryptedCollection(this._name, name, options);
        }
        async createView(name, source, pipeline, options = {}) {
            (0, helpers_1.assertArgsDefinedType)([name, source, pipeline], ['string', 'string', true], 'Database.createView');
            this._emitDatabaseApiCall('createView', {
                name,
                source,
                pipeline,
                options,
            });
            const ccOpts = {
                ...(await this._baseOptions()),
                viewOn: source,
                pipeline: pipeline,
            };
            if (options.collation) {
                ccOpts.collation = options.collation;
            }
            return await this._mongo._serviceProvider.createCollection(this._name, name, ccOpts);
        }
        async createRole(role, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([role], ['object'], 'Database.createRole');
            (0, helpers_1.assertKeysDefined)(role, ['role', 'privileges', 'roles']);
            this._emitDatabaseApiCall('createRole', {});
            if (role.createRole) {
                throw new errors_1.MongoshInvalidInputError('Cannot set createRole field in helper method', errors_1.CommonErrors.InvalidArgument);
            }
            const command = (0, helpers_1.adaptOptions)({ role: 'createRole' }, {}, role);
            if (writeConcern) {
                command.writeConcern = writeConcern;
            }
            const orderedCmd = { createRole: command.createRole, ...command };
            return await this._runCommand(orderedCmd);
        }
        async updateRole(rolename, roleDoc, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([rolename, roleDoc], ['string', 'object'], 'Database.updateRole');
            this._emitDatabaseApiCall('updateRole', {});
            const command = (0, helpers_1.adaptOptions)({}, {
                updateRole: rolename,
            }, roleDoc);
            if (writeConcern) {
                command.writeConcern = writeConcern;
            }
            const orderedCmd = { updateRole: command.updateRole, ...command };
            return await this._runCommand(orderedCmd);
        }
        async dropRole(rolename, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([rolename], ['string'], 'Database.dropRole');
            this._emitDatabaseApiCall('dropRole', {});
            const cmd = { dropRole: rolename };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async dropAllRoles(writeConcern) {
            this._emitDatabaseApiCall('dropAllRoles', {});
            const cmd = { dropAllRolesFromDatabase: 1 };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async grantRolesToRole(rolename, roles, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([rolename, roles], ['string', true], 'Database.grantRolesToRole');
            this._emitDatabaseApiCall('grantRolesToRole', {});
            const cmd = { grantRolesToRole: rolename, roles: roles };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async revokeRolesFromRole(rolename, roles, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([rolename, roles], ['string', true], 'Database.revokeRolesFromRole');
            this._emitDatabaseApiCall('revokeRolesFromRole', {});
            const cmd = { revokeRolesFromRole: rolename, roles: roles };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async grantPrivilegesToRole(rolename, privileges, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([rolename, privileges], ['string', true], 'Database.grantPrivilegesToRole');
            this._emitDatabaseApiCall('grantPrivilegesToRole', {});
            const cmd = {
                grantPrivilegesToRole: rolename,
                privileges: privileges,
            };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async revokePrivilegesFromRole(rolename, privileges, writeConcern) {
            (0, helpers_1.assertArgsDefinedType)([rolename, privileges], ['string', true], 'Database.revokePrivilegesFromRole');
            this._emitDatabaseApiCall('revokePrivilegesFromRole', {});
            const cmd = {
                revokePrivilegesFromRole: rolename,
                privileges: privileges,
            };
            if (writeConcern) {
                cmd.writeConcern = writeConcern;
            }
            return await this._runCommand(cmd);
        }
        async getRole(rolename, options = {}) {
            (0, helpers_1.assertArgsDefinedType)([rolename], ['string'], 'Database.getRole');
            this._emitDatabaseApiCall('getRole', { rolename: rolename });
            const command = (0, helpers_1.adaptOptions)({}, { rolesInfo: { role: rolename, db: this._name } }, options);
            const result = await this._runReadCommand(command);
            if (result.roles === undefined) {
                throw new errors_1.MongoshInternalError('No roles returned from rolesInfo command');
            }
            for (let i = 0; i < result.roles.length; i++) {
                if (result.roles[i].role === rolename) {
                    return result.roles[i];
                }
            }
            return null;
        }
        async getRoles(options = {}) {
            this._emitDatabaseApiCall('getRoles', { options: options });
            const command = (0, helpers_1.adaptOptions)({}, { rolesInfo: 1 }, options);
            return await this._runReadCommand(command);
        }
        async _getCurrentOperations(opts) {
            const legacyCurrentOpOptions = typeof opts === 'boolean'
                ? { $all: opts, $ownOps: false }
                : { $all: !!opts.$all, $ownOps: !!opts.$ownOps };
            const pipeline = [
                {
                    $currentOp: {
                        allUsers: !legacyCurrentOpOptions.$ownOps,
                        idleConnections: legacyCurrentOpOptions.$all,
                        truncateOps: false,
                    },
                },
            ];
            if (typeof opts === 'object') {
                const matchingFilters = {};
                for (const filtername of Object.keys(opts)) {
                    if (filtername !== '$ownOps' &&
                        filtername !== '$all' &&
                        filtername !== '$truncateOps') {
                        matchingFilters[filtername] = opts[filtername];
                    }
                }
                pipeline.push({ $match: matchingFilters });
            }
            const adminDb = this.getSiblingDB('admin');
            const aggregateOptions = {
                $readPreference: { mode: 'primaryPreferred' },
                bsonRegExp: true,
            };
            try {
                const cursor = await adminDb.aggregate(pipeline, aggregateOptions);
                return await cursor.toArray();
            }
            catch (error) {
                if (error?.codeName === 'FailedToParse') {
                    delete pipeline[0].$currentOp.truncateOps;
                    const cursor = await adminDb.aggregate(pipeline, aggregateOptions);
                    return await cursor.toArray();
                }
                throw error;
            }
        }
        async currentOp(opts = {}) {
            this._emitDatabaseApiCall('currentOp', { opts: opts });
            const currentOps = await this._getCurrentOperations(opts);
            return {
                inprog: currentOps,
                ok: 1,
            };
        }
        async killOp(opId) {
            this._emitDatabaseApiCall('killOp', { opId });
            return await this._runAdminCommand({
                killOp: 1,
                op: opId,
            });
        }
        async shutdownServer(opts = {}) {
            this._emitDatabaseApiCall('shutdownServer', { opts: opts });
            return await this._runAdminCommand({
                shutdown: 1,
                ...opts,
            });
        }
        async fsyncLock() {
            this._emitDatabaseApiCall('fsyncLock', {});
            return await this._runAdminCommand({
                fsync: 1,
                lock: true,
            });
        }
        async fsyncUnlock() {
            this._emitDatabaseApiCall('fsyncUnlock', {});
            return await this._runAdminCommand({
                fsyncUnlock: 1,
            });
        }
        async version() {
            this._emitDatabaseApiCall('version', {});
            const info = await this._runAdminReadCommand({
                buildInfo: 1,
            });
            if (!info || info.version === undefined) {
                throw new errors_1.MongoshRuntimeError(`Error running command serverBuildInfo ${info ? info.errmsg || '' : ''}`, errors_1.CommonErrors.CommandFailed);
            }
            return info.version;
        }
        async serverBits() {
            this._emitDatabaseApiCall('serverBits', {});
            const info = await this._runAdminReadCommand({
                buildInfo: 1,
            });
            if (!info || info.bits === undefined) {
                throw new errors_1.MongoshRuntimeError(`Error running command serverBuildInfo ${info ? info.errmsg || '' : ''}`, errors_1.CommonErrors.CommandFailed);
            }
            return info.bits;
        }
        async isMaster() {
            this._emitDatabaseApiCall('isMaster', {});
            const result = await this._runReadCommand({
                isMaster: 1,
            });
            result.isWritablePrimary = result.ismaster;
            return result;
        }
        async hello() {
            this._emitDatabaseApiCall('hello', {});
            try {
                this._cachedHello = await this._runReadCommand({
                    hello: 1,
                });
                return this._cachedHello;
            }
            catch (err) {
                if (err?.codeName === 'CommandNotFound') {
                    const result = await this.isMaster();
                    delete result.ismaster;
                    this._cachedHello = result;
                    return this._cachedHello;
                }
                throw err;
            }
        }
        async serverBuildInfo() {
            this._emitDatabaseApiCall('serverBuildInfo', {});
            return await this._runAdminReadCommand({
                buildInfo: 1,
            });
        }
        async serverStatus(opts = {}) {
            this._emitDatabaseApiCall('serverStatus', { options: opts });
            return await this._runAdminReadCommand({
                serverStatus: 1,
                ...opts,
            });
        }
        async stats(scaleOrOptions = 1) {
            (0, helpers_1.assertArgsDefinedType)([scaleOrOptions], [['number', 'object']], 'Database.stats');
            if (typeof scaleOrOptions === 'number') {
                scaleOrOptions = { scale: scaleOrOptions };
            }
            this._emitDatabaseApiCall('stats', { scale: scaleOrOptions.scale });
            return await this._runReadCommand({
                dbStats: 1,
                scale: 1,
                ...scaleOrOptions,
            });
        }
        async hostInfo() {
            this._emitDatabaseApiCall('hostInfo', {});
            return await this._runAdminReadCommand({
                hostInfo: 1,
            });
        }
        async serverCmdLineOpts() {
            this._emitDatabaseApiCall('serverCmdLineOpts', {});
            return await this._runAdminReadCommand({
                getCmdLineOpts: 1,
            });
        }
        async rotateCertificates(message) {
            this._emitDatabaseApiCall('rotateCertificates', { message });
            return await this._runAdminCommand({
                rotateCertificates: 1,
                message,
            });
        }
        async printCollectionStats(scale = 1) {
            if (typeof scale !== 'number' || scale < 1) {
                throw new errors_1.MongoshInvalidInputError(`scale has to be a number >=1, got ${scale}`, errors_1.CommonErrors.InvalidArgument);
            }
            this._emitDatabaseApiCall('printCollectionStats', { scale: scale });
            const colls = await this.getCollectionNames();
            const result = {};
            for (const c of colls) {
                try {
                    result[c] = await this.getCollection(c).stats({ scale });
                }
                catch (error) {
                    result[c] = { ok: 0, errmsg: error?.message };
                }
            }
            return new index_1.CommandResult('StatsResult', result);
        }
        async getProfilingStatus() {
            this._emitDatabaseApiCall('getProfilingStatus', {});
            return await this._runReadCommand({
                profile: -1,
            });
        }
        async setProfilingLevel(level, opts = {}) {
            (0, helpers_1.assertArgsDefinedType)([level], ['number'], 'Database.setProfilingLevel');
            if (level < 0 || level > 2) {
                throw new errors_1.MongoshInvalidInputError(`Input level ${level} is out of range [0..2]`, errors_1.CommonErrors.InvalidArgument);
            }
            if (typeof opts === 'number') {
                opts = { slowms: opts };
            }
            this._emitDatabaseApiCall('setProfilingLevel', { opts: opts });
            return await this._runCommand({
                profile: level,
                ...opts,
            });
        }
        async setLogLevel(logLevel, component) {
            (0, helpers_1.assertArgsDefinedType)([logLevel], ['number'], 'Database.setLogLevel');
            this._emitDatabaseApiCall('setLogLevel', {
                logLevel: logLevel,
                component: component,
            });
            let componentNames = [];
            if (typeof component === 'string') {
                componentNames = component.split('.');
            }
            else if (component !== undefined) {
                throw new errors_1.MongoshInvalidInputError(`setLogLevel component must be a string: got ${typeof component}`, errors_1.CommonErrors.InvalidArgument);
            }
            let vDoc = { verbosity: logLevel };
            while (componentNames.length > 0) {
                const key = componentNames.pop();
                vDoc = { [key]: vDoc };
            }
            const cmdObj = { setParameter: 1, logComponentVerbosity: vDoc };
            return await this._runAdminCommand(cmdObj);
        }
        async getLogComponents() {
            this._emitDatabaseApiCall('getLogComponents', {});
            const cmdObj = { getParameter: 1, logComponentVerbosity: 1 };
            const result = await this._runAdminReadCommand(cmdObj);
            if (!result || result.logComponentVerbosity === undefined) {
                throw new errors_1.MongoshRuntimeError(`Error running command  ${result ? result.errmsg || '' : ''}`, errors_1.CommonErrors.CommandFailed);
            }
            return result.logComponentVerbosity;
        }
        cloneDatabase() {
            throw new errors_1.MongoshDeprecatedError('`cloneDatabase()` was removed because it was deprecated in MongoDB 4.0');
        }
        cloneCollection() {
            throw new errors_1.MongoshDeprecatedError('`cloneCollection()` was removed because it was deprecated in MongoDB 4.0');
        }
        copyDatabase() {
            throw new errors_1.MongoshDeprecatedError('`copyDatabase()` was removed because it was deprecated in MongoDB 4.0');
        }
        async commandHelp(name) {
            (0, helpers_1.assertArgsDefinedType)([name], ['string'], 'Database.commandHelp');
            this._emitDatabaseApiCall('commandHelp', { name: name });
            const command = {};
            command[name] = 1;
            command.help = true;
            const result = await this._runCommand(command);
            if (!result || result.help === undefined) {
                throw new errors_1.MongoshRuntimeError(`Error running command commandHelp ${result ? result.errmsg || '' : ''}`, errors_1.CommonErrors.CommandFailed);
            }
            return result.help;
        }
        async listCommands() {
            this._emitDatabaseApiCall('listCommands', {});
            const result = await this._runReadCommand({
                listCommands: 1,
            });
            if (!result || result.commands === undefined) {
                throw new errors_1.MongoshRuntimeError(`Error running command listCommands ${result ? result.errmsg || '' : ''}`, errors_1.CommonErrors.CommandFailed);
            }
            for (const cmdDescription of Object.values(result.commands)) {
                if ('slaveOk' in cmdDescription) {
                    cmdDescription.secondaryOk = cmdDescription.slaveOk;
                    delete cmdDescription.slaveOk;
                }
                if ('slaveOverrideOk' in cmdDescription) {
                    cmdDescription.secondaryOverrideOk = cmdDescription.slaveOverrideOk;
                    delete cmdDescription.slaveOverrideOk;
                }
            }
            return new index_1.CommandResult('ListCommandsResult', result.commands);
        }
        async getLastErrorObj(w, wTimeout, j) {
            await this._instanceState.printDeprecationWarning('Database.getLastErrorObj() is deprecated and will be removed in the future.');
            this._emitDatabaseApiCall('getLastErrorObj', {
                w: w,
                wTimeout: wTimeout,
                j: j,
            });
            return await this._getLastErrorObj(w, wTimeout, j);
        }
        async getLastError(w, wTimeout) {
            await this._instanceState.printDeprecationWarning('Database.getLastError() is deprecated and will be removed in the future.');
            this._emitDatabaseApiCall('getLastError', { w: w, wTimeout: wTimeout });
            const result = await this._getLastErrorObj(w, wTimeout);
            return result.err || null;
        }
        async printShardingStatus(verbose = false) {
            this._emitDatabaseApiCall('printShardingStatus', { verbose });
            const result = await (0, helpers_1.getPrintableShardStatus)(await (0, helpers_1.getConfigDB)(this), verbose);
            return new index_1.CommandResult('StatsResult', result);
        }
        async printSecondaryReplicationInfo() {
            let startOptimeDate = null;
            const local = this.getSiblingDB('local');
            if ((await local.getCollection('system.replset').countDocuments({})) !== 0) {
                const status = await this._runAdminReadCommand({ replSetGetStatus: 1 });
                let primary = null;
                for (const member of status.members) {
                    if (member.state === 1) {
                        primary = member;
                        break;
                    }
                }
                if (primary) {
                    startOptimeDate = primary.optimeDate;
                }
                else {
                    startOptimeDate = new Date(0, 0);
                    for (const member of status.members) {
                        if (member.optimeDate > startOptimeDate) {
                            startOptimeDate = member.optimeDate;
                        }
                    }
                }
                const result = {};
                for (const node of status.members) {
                    const nodeResult = {};
                    if (node === null || node === undefined) {
                        throw new errors_1.MongoshRuntimeError('Member returned from command replSetGetStatus is null', errors_1.CommonErrors.CommandFailed);
                    }
                    if (node.state === 1 || node.state === 7) {
                        continue;
                    }
                    if (node.optime && node.health !== 0) {
                        if (startOptimeDate === null || startOptimeDate === undefined) {
                            throw new errors_1.MongoshRuntimeError('getReplLag startOptimeDate is null', errors_1.CommonErrors.CommandFailed);
                        }
                        if (startOptimeDate) {
                            nodeResult.syncedTo = node.optimeDate.toString();
                        }
                        const ago = (startOptimeDate - node.optimeDate) / 1000;
                        const hrs = Math.round(ago / 36) / 100;
                        let suffix = '';
                        if (primary) {
                            suffix = 'primary ';
                        }
                        else {
                            suffix = 'freshest member (no primary available at the moment)';
                        }
                        nodeResult.replLag = `${Math.round(ago)} secs (${hrs} hrs) behind the ${suffix}`;
                    }
                    else {
                        nodeResult['no replication info, yet.  State'] = node.stateStr;
                    }
                    result[`source: ${node.name}`] = nodeResult;
                }
                return new index_1.CommandResult('StatsResult', result);
            }
            throw new errors_1.MongoshInvalidInputError('local.system.replset is empty. Are you connected to a replica set?', error_codes_1.ShellApiErrors.NotConnectedToReplicaSet);
        }
        async getReplicationInfo() {
            const localdb = this.getSiblingDB('local');
            const result = {};
            const oplog = 'oplog.rs';
            const localCollections = await localdb.getCollectionNames();
            if (!localCollections.includes(oplog)) {
                throw new errors_1.MongoshInvalidInputError('Replication not detected. Are you connected to a replset?', error_codes_1.ShellApiErrors.NotConnectedToReplicaSet);
            }
            const ol = localdb.getCollection(oplog);
            const [olStats, first, last] = await Promise.all([
                ol.stats(),
                (async () => (await ol.find()).sort({ $natural: 1 }).limit(1).tryNext())(),
                (async () => (await ol.find()).sort({ $natural: -1 }).limit(1).tryNext())(),
            ]);
            if (!olStats?.maxSize) {
                throw new errors_1.MongoshRuntimeError(`Could not get stats for local.${oplog} collection. collstats returned ${JSON.stringify(olStats)}`, errors_1.CommonErrors.CommandFailed);
            }
            result.configuredLogSizeMB = olStats.maxSize / (1024 * 1024);
            result.logSizeMB = Math.max(olStats.maxSize, olStats.size) / (1024 * 1024);
            result.usedMB = olStats.size / (1024 * 1024);
            result.usedMB = Math.ceil(result.usedMB * 100) / 100;
            if (first === null || last === null) {
                throw new errors_1.MongoshRuntimeError('objects not found in local.oplog.$main -- is this a new and empty db instance?', errors_1.CommonErrors.CommandFailed);
            }
            let tfirst = first.ts;
            let tlast = last.ts;
            if (tfirst && tlast) {
                tfirst = (0, helpers_1.tsToSeconds)(tfirst);
                tlast = (0, helpers_1.tsToSeconds)(tlast);
                result.timeDiff = tlast - tfirst;
                result.timeDiffHours = Math.round(result.timeDiff / 36) / 100;
                result.tFirst = new Date(tfirst * 1000).toString();
                result.tLast = new Date(tlast * 1000).toString();
                result.now = Date();
            }
            else {
                result.errmsg = 'ts element not found in oplog objects';
            }
            return result;
        }
        async printReplicationInfo() {
            const result = {};
            let replInfo;
            try {
                replInfo = await this.getReplicationInfo();
            }
            catch (error) {
                const helloResult = await this.hello();
                if (helloResult.arbiterOnly) {
                    return new index_1.CommandResult('StatsResult', {
                        message: 'cannot provide replication status from an arbiter',
                    });
                }
                else if (!helloResult.isWritablePrimary) {
                    const secondaryInfo = await this.printSecondaryReplicationInfo();
                    return new index_1.CommandResult('StatsResult', {
                        message: 'this is a secondary, printing secondary replication info.',
                        ...secondaryInfo.value,
                    });
                }
                throw error;
            }
            result['actual oplog size'] = `${replInfo.logSizeMB} MB`;
            result['configured oplog size'] = `${replInfo.configuredLogSizeMB} MB`;
            result['log length start to end'] = `${replInfo.timeDiff} secs (${replInfo.timeDiffHours} hrs)`;
            result['oplog first event time'] = replInfo.tFirst;
            result['oplog last event time'] = replInfo.tLast;
            result.now = replInfo.now;
            return new index_1.CommandResult('StatsResult', result);
        }
        printSlaveReplicationInfo() {
            throw new errors_1.MongoshDeprecatedError('Method deprecated, use db.printSecondaryReplicationInfo instead');
        }
        async setSecondaryOk() {
            await this._mongo.setSecondaryOk();
        }
        async watch(pipeline = [], options = {}) {
            if (!Array.isArray(pipeline)) {
                options = pipeline;
                pipeline = [];
            }
            this._emitDatabaseApiCall('watch', { pipeline, options });
            const cursor = new change_stream_cursor_1.default(this._mongo._serviceProvider.watch(pipeline, {
                ...(await this._baseOptions()),
                ...options,
            }, {}, this._name), this._name, this._mongo);
            if (!options.resumeAfter &&
                !options.startAfter &&
                !options.startAtOperationTime) {
                await cursor.tryNext();
            }
            this._mongo._instanceState.currentCursor = cursor;
            return cursor;
        }
        async sql(sqlString, options) {
            this._emitDatabaseApiCall('sql', { sqlString: sqlString, options });
            await this._instanceState.shellApi.print('Note: this is an experimental feature that may be subject to change in future releases.');
            const cursor = await this.aggregate([
                {
                    $sql: {
                        statement: sqlString,
                        format: 'jdbc',
                        dialect: 'mongosql',
                        formatVersion: 1,
                    },
                },
            ], options);
            try {
                await cursor.hasNext();
            }
            catch (err) {
                if (err.code?.valueOf() === 40324) {
                    throw new errors_1.MongoshRuntimeError('db.sql currently only works when connected to a Data Lake', errors_1.CommonErrors.CommandFailed);
                }
                throw err;
            }
            return cursor;
        }
        async checkMetadataConsistency(options = {}) {
            this._emitDatabaseApiCall('checkMetadataConsistency', { options });
            return this._runCursorCommand({
                checkMetadataConsistency: 1,
                ...options,
            });
        }
    };
    __setFunctionName(_classThis, "Database");
    (() => {
        const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
        _getMongo_decorators = [(0, decorators_1.returnType)('Mongo')];
        _getCollectionNames_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([1])];
        _getCollectionInfos_decorators = [decorators_1.returnsPromise, (0, decorators_1.serverVersions)(['3.0.0', enums_1.ServerVersions.latest]), (0, decorators_1.apiVersions)([1])];
        _runCommand_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([1])];
        _adminCommand_decorators = [decorators_1.returnsPromise, (0, decorators_1.serverVersions)(['3.4.0', enums_1.ServerVersions.latest]), (0, decorators_1.apiVersions)([1])];
        _aggregate_decorators = [decorators_1.returnsPromise, (0, decorators_1.returnType)('AggregationCursor'), (0, decorators_1.apiVersions)([1])];
        _getSiblingDB_decorators = [(0, decorators_1.returnType)('Database')];
        _getCollection_decorators = [(0, decorators_1.returnType)('Collection')];
        _dropDatabase_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([1])];
        _createUser_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _updateUser_decorators = [decorators_1.returnsPromise];
        _changeUserPassword_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _logout_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _dropUser_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _dropAllUsers_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _auth_decorators = [decorators_1.returnsPromise];
        _grantRolesToUser_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _revokeRolesFromUser_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _getUser_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _getUsers_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _createCollection_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([1])];
        _createEncryptedCollection_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([1])];
        _createView_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([1])];
        _createRole_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _updateRole_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _dropRole_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _dropAllRoles_decorators = [decorators_1.returnsPromise];
        _grantRolesToRole_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _revokeRolesFromRole_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _grantPrivilegesToRole_decorators = [decorators_1.returnsPromise];
        _revokePrivilegesFromRole_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _getRole_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _getRoles_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _currentOp_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _killOp_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _shutdownServer_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _fsyncLock_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _fsyncUnlock_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _version_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _serverBits_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _isMaster_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _hello_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([1]), (0, decorators_1.serverVersions)(['5.0.0', enums_1.ServerVersions.latest])];
        _serverBuildInfo_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _serverStatus_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _stats_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _hostInfo_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _serverCmdLineOpts_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _rotateCertificates_decorators = [decorators_1.returnsPromise, (0, decorators_1.serverVersions)(['5.0.0', enums_1.ServerVersions.latest]), (0, decorators_1.apiVersions)([])];
        _printCollectionStats_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _getProfilingStatus_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _setProfilingLevel_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _setLogLevel_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _getLogComponents_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _cloneDatabase_decorators = [decorators_1.deprecated];
        _cloneCollection_decorators = [decorators_1.deprecated];
        _copyDatabase_decorators = [decorators_1.deprecated];
        _commandHelp_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([1])];
        _listCommands_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _getLastErrorObj_decorators = [(0, decorators_1.serverVersions)([enums_1.ServerVersions.earliest, '5.1.0']), decorators_1.deprecated, decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _getLastError_decorators = [decorators_1.deprecated, decorators_1.returnsPromise, (0, decorators_1.apiVersions)([])];
        _printShardingStatus_decorators = [decorators_1.returnsPromise, (0, decorators_1.topologies)(['Sharded']), (0, decorators_1.apiVersions)([1])];
        _printSecondaryReplicationInfo_decorators = [decorators_1.returnsPromise, (0, decorators_1.topologies)(['ReplSet']), (0, decorators_1.apiVersions)([])];
        _getReplicationInfo_decorators = [decorators_1.returnsPromise, (0, decorators_1.topologies)(['ReplSet']), (0, decorators_1.apiVersions)([])];
        _printReplicationInfo_decorators = [decorators_1.returnsPromise, (0, decorators_1.apiVersions)([]), (0, decorators_1.topologies)(['ReplSet'])];
        _printSlaveReplicationInfo_decorators = [decorators_1.deprecated];
        _setSecondaryOk_decorators = [decorators_1.deprecated, decorators_1.returnsPromise];
        _watch_decorators = [(0, decorators_1.serverVersions)(['3.1.0', enums_1.ServerVersions.latest]), (0, decorators_1.topologies)(['ReplSet', 'Sharded']), (0, decorators_1.apiVersions)([1]), decorators_1.returnsPromise];
        _sql_decorators = [(0, decorators_1.serverVersions)(['4.4.0', enums_1.ServerVersions.latest]), decorators_1.returnsPromise, (0, decorators_1.returnType)('AggregationCursor')];
        _checkMetadataConsistency_decorators = [(0, decorators_1.serverVersions)(['7.0.0', enums_1.ServerVersions.latest]), (0, decorators_1.topologies)(['Sharded']), decorators_1.returnsPromise];
        __esDecorate(_classThis, null, _getMongo_decorators, { kind: "method", name: "getMongo", static: false, private: false, access: { has: obj => "getMongo" in obj, get: obj => obj.getMongo }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getCollectionNames_decorators, { kind: "method", name: "getCollectionNames", static: false, private: false, access: { has: obj => "getCollectionNames" in obj, get: obj => obj.getCollectionNames }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getCollectionInfos_decorators, { kind: "method", name: "getCollectionInfos", static: false, private: false, access: { has: obj => "getCollectionInfos" in obj, get: obj => obj.getCollectionInfos }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _runCommand_decorators, { kind: "method", name: "runCommand", static: false, private: false, access: { has: obj => "runCommand" in obj, get: obj => obj.runCommand }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _adminCommand_decorators, { kind: "method", name: "adminCommand", static: false, private: false, access: { has: obj => "adminCommand" in obj, get: obj => obj.adminCommand }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _aggregate_decorators, { kind: "method", name: "aggregate", static: false, private: false, access: { has: obj => "aggregate" in obj, get: obj => obj.aggregate }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getSiblingDB_decorators, { kind: "method", name: "getSiblingDB", static: false, private: false, access: { has: obj => "getSiblingDB" in obj, get: obj => obj.getSiblingDB }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getCollection_decorators, { kind: "method", name: "getCollection", static: false, private: false, access: { has: obj => "getCollection" in obj, get: obj => obj.getCollection }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _dropDatabase_decorators, { kind: "method", name: "dropDatabase", static: false, private: false, access: { has: obj => "dropDatabase" in obj, get: obj => obj.dropDatabase }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _createUser_decorators, { kind: "method", name: "createUser", static: false, private: false, access: { has: obj => "createUser" in obj, get: obj => obj.createUser }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _updateUser_decorators, { kind: "method", name: "updateUser", static: false, private: false, access: { has: obj => "updateUser" in obj, get: obj => obj.updateUser }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _changeUserPassword_decorators, { kind: "method", name: "changeUserPassword", static: false, private: false, access: { has: obj => "changeUserPassword" in obj, get: obj => obj.changeUserPassword }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _logout_decorators, { kind: "method", name: "logout", static: false, private: false, access: { has: obj => "logout" in obj, get: obj => obj.logout }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _dropUser_decorators, { kind: "method", name: "dropUser", static: false, private: false, access: { has: obj => "dropUser" in obj, get: obj => obj.dropUser }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _dropAllUsers_decorators, { kind: "method", name: "dropAllUsers", static: false, private: false, access: { has: obj => "dropAllUsers" in obj, get: obj => obj.dropAllUsers }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _auth_decorators, { kind: "method", name: "auth", static: false, private: false, access: { has: obj => "auth" in obj, get: obj => obj.auth }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _grantRolesToUser_decorators, { kind: "method", name: "grantRolesToUser", static: false, private: false, access: { has: obj => "grantRolesToUser" in obj, get: obj => obj.grantRolesToUser }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _revokeRolesFromUser_decorators, { kind: "method", name: "revokeRolesFromUser", static: false, private: false, access: { has: obj => "revokeRolesFromUser" in obj, get: obj => obj.revokeRolesFromUser }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getUser_decorators, { kind: "method", name: "getUser", static: false, private: false, access: { has: obj => "getUser" in obj, get: obj => obj.getUser }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getUsers_decorators, { kind: "method", name: "getUsers", static: false, private: false, access: { has: obj => "getUsers" in obj, get: obj => obj.getUsers }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _createCollection_decorators, { kind: "method", name: "createCollection", static: false, private: false, access: { has: obj => "createCollection" in obj, get: obj => obj.createCollection }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _createEncryptedCollection_decorators, { kind: "method", name: "createEncryptedCollection", static: false, private: false, access: { has: obj => "createEncryptedCollection" in obj, get: obj => obj.createEncryptedCollection }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _createView_decorators, { kind: "method", name: "createView", static: false, private: false, access: { has: obj => "createView" in obj, get: obj => obj.createView }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _createRole_decorators, { kind: "method", name: "createRole", static: false, private: false, access: { has: obj => "createRole" in obj, get: obj => obj.createRole }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _updateRole_decorators, { kind: "method", name: "updateRole", static: false, private: false, access: { has: obj => "updateRole" in obj, get: obj => obj.updateRole }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _dropRole_decorators, { kind: "method", name: "dropRole", static: false, private: false, access: { has: obj => "dropRole" in obj, get: obj => obj.dropRole }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _dropAllRoles_decorators, { kind: "method", name: "dropAllRoles", static: false, private: false, access: { has: obj => "dropAllRoles" in obj, get: obj => obj.dropAllRoles }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _grantRolesToRole_decorators, { kind: "method", name: "grantRolesToRole", static: false, private: false, access: { has: obj => "grantRolesToRole" in obj, get: obj => obj.grantRolesToRole }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _revokeRolesFromRole_decorators, { kind: "method", name: "revokeRolesFromRole", static: false, private: false, access: { has: obj => "revokeRolesFromRole" in obj, get: obj => obj.revokeRolesFromRole }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _grantPrivilegesToRole_decorators, { kind: "method", name: "grantPrivilegesToRole", static: false, private: false, access: { has: obj => "grantPrivilegesToRole" in obj, get: obj => obj.grantPrivilegesToRole }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _revokePrivilegesFromRole_decorators, { kind: "method", name: "revokePrivilegesFromRole", static: false, private: false, access: { has: obj => "revokePrivilegesFromRole" in obj, get: obj => obj.revokePrivilegesFromRole }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getRole_decorators, { kind: "method", name: "getRole", static: false, private: false, access: { has: obj => "getRole" in obj, get: obj => obj.getRole }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getRoles_decorators, { kind: "method", name: "getRoles", static: false, private: false, access: { has: obj => "getRoles" in obj, get: obj => obj.getRoles }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _currentOp_decorators, { kind: "method", name: "currentOp", static: false, private: false, access: { has: obj => "currentOp" in obj, get: obj => obj.currentOp }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _killOp_decorators, { kind: "method", name: "killOp", static: false, private: false, access: { has: obj => "killOp" in obj, get: obj => obj.killOp }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _shutdownServer_decorators, { kind: "method", name: "shutdownServer", static: false, private: false, access: { has: obj => "shutdownServer" in obj, get: obj => obj.shutdownServer }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _fsyncLock_decorators, { kind: "method", name: "fsyncLock", static: false, private: false, access: { has: obj => "fsyncLock" in obj, get: obj => obj.fsyncLock }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _fsyncUnlock_decorators, { kind: "method", name: "fsyncUnlock", static: false, private: false, access: { has: obj => "fsyncUnlock" in obj, get: obj => obj.fsyncUnlock }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _version_decorators, { kind: "method", name: "version", static: false, private: false, access: { has: obj => "version" in obj, get: obj => obj.version }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _serverBits_decorators, { kind: "method", name: "serverBits", static: false, private: false, access: { has: obj => "serverBits" in obj, get: obj => obj.serverBits }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _isMaster_decorators, { kind: "method", name: "isMaster", static: false, private: false, access: { has: obj => "isMaster" in obj, get: obj => obj.isMaster }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _hello_decorators, { kind: "method", name: "hello", static: false, private: false, access: { has: obj => "hello" in obj, get: obj => obj.hello }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _serverBuildInfo_decorators, { kind: "method", name: "serverBuildInfo", static: false, private: false, access: { has: obj => "serverBuildInfo" in obj, get: obj => obj.serverBuildInfo }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _serverStatus_decorators, { kind: "method", name: "serverStatus", static: false, private: false, access: { has: obj => "serverStatus" in obj, get: obj => obj.serverStatus }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _stats_decorators, { kind: "method", name: "stats", static: false, private: false, access: { has: obj => "stats" in obj, get: obj => obj.stats }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _hostInfo_decorators, { kind: "method", name: "hostInfo", static: false, private: false, access: { has: obj => "hostInfo" in obj, get: obj => obj.hostInfo }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _serverCmdLineOpts_decorators, { kind: "method", name: "serverCmdLineOpts", static: false, private: false, access: { has: obj => "serverCmdLineOpts" in obj, get: obj => obj.serverCmdLineOpts }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _rotateCertificates_decorators, { kind: "method", name: "rotateCertificates", static: false, private: false, access: { has: obj => "rotateCertificates" in obj, get: obj => obj.rotateCertificates }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _printCollectionStats_decorators, { kind: "method", name: "printCollectionStats", static: false, private: false, access: { has: obj => "printCollectionStats" in obj, get: obj => obj.printCollectionStats }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getProfilingStatus_decorators, { kind: "method", name: "getProfilingStatus", static: false, private: false, access: { has: obj => "getProfilingStatus" in obj, get: obj => obj.getProfilingStatus }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _setProfilingLevel_decorators, { kind: "method", name: "setProfilingLevel", static: false, private: false, access: { has: obj => "setProfilingLevel" in obj, get: obj => obj.setProfilingLevel }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _setLogLevel_decorators, { kind: "method", name: "setLogLevel", static: false, private: false, access: { has: obj => "setLogLevel" in obj, get: obj => obj.setLogLevel }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getLogComponents_decorators, { kind: "method", name: "getLogComponents", static: false, private: false, access: { has: obj => "getLogComponents" in obj, get: obj => obj.getLogComponents }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _cloneDatabase_decorators, { kind: "method", name: "cloneDatabase", static: false, private: false, access: { has: obj => "cloneDatabase" in obj, get: obj => obj.cloneDatabase }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _cloneCollection_decorators, { kind: "method", name: "cloneCollection", static: false, private: false, access: { has: obj => "cloneCollection" in obj, get: obj => obj.cloneCollection }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _copyDatabase_decorators, { kind: "method", name: "copyDatabase", static: false, private: false, access: { has: obj => "copyDatabase" in obj, get: obj => obj.copyDatabase }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _commandHelp_decorators, { kind: "method", name: "commandHelp", static: false, private: false, access: { has: obj => "commandHelp" in obj, get: obj => obj.commandHelp }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _listCommands_decorators, { kind: "method", name: "listCommands", static: false, private: false, access: { has: obj => "listCommands" in obj, get: obj => obj.listCommands }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getLastErrorObj_decorators, { kind: "method", name: "getLastErrorObj", static: false, private: false, access: { has: obj => "getLastErrorObj" in obj, get: obj => obj.getLastErrorObj }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getLastError_decorators, { kind: "method", name: "getLastError", static: false, private: false, access: { has: obj => "getLastError" in obj, get: obj => obj.getLastError }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _printShardingStatus_decorators, { kind: "method", name: "printShardingStatus", static: false, private: false, access: { has: obj => "printShardingStatus" in obj, get: obj => obj.printShardingStatus }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _printSecondaryReplicationInfo_decorators, { kind: "method", name: "printSecondaryReplicationInfo", static: false, private: false, access: { has: obj => "printSecondaryReplicationInfo" in obj, get: obj => obj.printSecondaryReplicationInfo }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _getReplicationInfo_decorators, { kind: "method", name: "getReplicationInfo", static: false, private: false, access: { has: obj => "getReplicationInfo" in obj, get: obj => obj.getReplicationInfo }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _printReplicationInfo_decorators, { kind: "method", name: "printReplicationInfo", static: false, private: false, access: { has: obj => "printReplicationInfo" in obj, get: obj => obj.printReplicationInfo }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _printSlaveReplicationInfo_decorators, { kind: "method", name: "printSlaveReplicationInfo", static: false, private: false, access: { has: obj => "printSlaveReplicationInfo" in obj, get: obj => obj.printSlaveReplicationInfo }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _setSecondaryOk_decorators, { kind: "method", name: "setSecondaryOk", static: false, private: false, access: { has: obj => "setSecondaryOk" in obj, get: obj => obj.setSecondaryOk }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _watch_decorators, { kind: "method", name: "watch", static: false, private: false, access: { has: obj => "watch" in obj, get: obj => obj.watch }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _sql_decorators, { kind: "method", name: "sql", static: false, private: false, access: { has: obj => "sql" in obj, get: obj => obj.sql }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(_classThis, null, _checkMetadataConsistency_decorators, { kind: "method", name: "checkMetadataConsistency", static: false, private: false, access: { has: obj => "checkMetadataConsistency" in obj, get: obj => obj.checkMetadataConsistency }, metadata: _metadata }, null, _instanceExtraInitializers);
        __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
        Database = _classThis = _classDescriptor.value;
        if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        __runInitializers(_classThis, _classExtraInitializers);
    })();
    return Database = _classThis;
})();
exports.Database = Database;
//# sourceMappingURL=database.js.map