diff --git a/.gitignore b/.gitignore
index 33a4bcbb1..eeffeebcf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,8 +36,8 @@ node_modules
.node_repl_history
# Transpiled code
-lib
-packages/mongodb-memory-server-core/lib
+#lib
+#packages/mongodb-memory-server-core/lib
*.tsbuildinfo
coverage
diff --git a/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.d.ts b/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.d.ts
new file mode 100644
index 000000000..62ad616ec
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.d.ts
@@ -0,0 +1,239 @@
+///
+///
+import { EventEmitter } from 'events';
+import { MongoMemoryServer, AutomaticAuth, DisposeOptions } from './MongoMemoryServer';
+import { Cleanup, ManagerAdvanced } from './util/utils';
+import { MongoBinaryOpts } from './util/MongoBinary';
+import { MongoMemoryInstanceOpts, MongoMemoryInstanceOptsBase, StorageEngine } from './util/MongoInstance';
+import { SpawnOptions } from 'child_process';
+/**
+ * Replica set specific options.
+ */
+export interface ReplSetOpts {
+ /**
+ * Enable Authentication
+ * @default false
+ */
+ auth?: AutomaticAuth;
+ /**
+ * additional command line arguments passed to `mongod`
+ * @default []
+ */
+ args?: string[];
+ /**
+ * if this number is bigger than "instanceOpts.length", more "generic" servers get started
+ * if this number is lower than "instanceOpts.length", no more "generic" servers get started (server count will be "instanceOpts.length")
+ * @default 1
+ */
+ count?: number;
+ /**
+ * add an database into the uri (in mongodb its the auth database, in mongoose its the default database for models)
+ * @default ""
+ */
+ dbName?: string;
+ /**
+ * bind to all IP addresses specify `::,0.0.0.0`
+ * @default '127.0.0.1'
+ */
+ ip?: string;
+ /**
+ * replSet name
+ * @default 'testset'
+ */
+ name?: string;
+ /**
+ * Childprocess spawn options
+ * @default {}
+ */
+ spawn?: SpawnOptions;
+ /**
+ *`mongod` storage engine type
+ * @default 'ephemeralForTest' unless mongodb version is `7.0.0`, where its `wiredTiger`
+ */
+ storageEngine?: StorageEngine;
+ /**
+ * Options for "rsConfig"
+ * @default {}
+ */
+ configSettings?: MongoMemoryReplSetConfigSettings;
+ /**
+ * Options for automatic dispose for "Explicit Resource Management"
+ */
+ dispose?: DisposeOptions;
+}
+/**
+ * Options for "rsConfig"
+ */
+export interface MongoMemoryReplSetConfigSettings {
+ chainingAllowed?: boolean;
+ heartbeatTimeoutSecs?: number;
+ heartbeatIntervalMillis?: number;
+ electionTimeoutMillis?: number;
+ catchUpTimeoutMillis?: number;
+}
+/**
+ * Options for the replSet
+ */
+export interface MongoMemoryReplSetOpts {
+ /**
+ * Specific Options to use for some instances
+ */
+ instanceOpts: MongoMemoryInstanceOptsBase[];
+ /**
+ * Binary Options used for all instances
+ */
+ binary: MongoBinaryOpts;
+ /**
+ * Options used for all instances
+ * -> gets overwritten by specific "instanceOpts"
+ */
+ replSet: ReplSetOpts;
+}
+/**
+ * Enum for "_state" inside "MongoMemoryReplSet"
+ */
+export declare enum MongoMemoryReplSetStates {
+ init = "init",
+ running = "running",
+ stopped = "stopped"
+}
+/**
+ * All Events for "MongoMemoryReplSet"
+ */
+export declare enum MongoMemoryReplSetEvents {
+ stateChange = "stateChange"
+}
+export interface MongoMemoryReplSet extends EventEmitter {
+ emit(event: MongoMemoryReplSetEvents, ...args: any[]): boolean;
+ on(event: MongoMemoryReplSetEvents, listener: (...args: any[]) => void): this;
+ once(event: MongoMemoryReplSetEvents, listener: (...args: any[]) => void): this;
+}
+/**
+ * Class for managing an replSet
+ */
+export declare class MongoMemoryReplSet extends EventEmitter implements ManagerAdvanced {
+ /**
+ * All servers this ReplSet instance manages
+ */
+ servers: MongoMemoryServer[];
+ /** Options for individual instances */
+ protected _instanceOpts: MongoMemoryInstanceOptsBase[];
+ /** Options for the Binary across all instances */
+ protected _binaryOpts: MongoBinaryOpts;
+ /** Options for the Replset itself and defaults for instances */
+ protected _replSetOpts: Required;
+ /** TMPDIR for the keyfile, when auth is used */
+ protected _keyfiletmp?: string;
+ protected _state: MongoMemoryReplSetStates;
+ protected _ranCreateAuth: boolean;
+ constructor(opts?: Partial);
+ /**
+ * Change "this._state" to "newState" and emit "newState"
+ * @param newState The new State to set & emit
+ */
+ protected stateChange(newState: MongoMemoryReplSetStates, ...args: any[]): void;
+ /**
+ * Create an instance of "MongoMemoryReplSet" and call start
+ * @param opts Options for the ReplSet
+ */
+ static create(opts?: Partial): Promise;
+ /**
+ * Get Current state of this class
+ */
+ get state(): MongoMemoryReplSetStates;
+ /**
+ * Get & Set "instanceOpts"
+ * @throws if "state" is not "stopped"
+ */
+ get instanceOpts(): MongoMemoryInstanceOptsBase[];
+ set instanceOpts(val: MongoMemoryInstanceOptsBase[]);
+ /**
+ * Get & Set "binaryOpts"
+ * @throws if "state" is not "stopped"
+ */
+ get binaryOpts(): MongoBinaryOpts;
+ set binaryOpts(val: MongoBinaryOpts);
+ /**
+ * Get & Set "replSetOpts"
+ * (Applies defaults)
+ * @throws if "state" is not "stopped"
+ */
+ get replSetOpts(): ReplSetOpts;
+ set replSetOpts(val: ReplSetOpts);
+ /**
+ * Helper function to determine if "auth" should be enabled
+ * This function expectes to be run after the auth object has been transformed to a object
+ * @returns "true" when "auth" should be enabled
+ */
+ protected enableAuth(): boolean;
+ /**
+ * Returns instance options suitable for a MongoMemoryServer.
+ * @param baseOpts Options to merge with
+ * @param keyfileLocation The Keyfile location if "auth" is used
+ */
+ protected getInstanceOpts(baseOpts?: MongoMemoryInstanceOptsBase, keyfileLocation?: string): MongoMemoryInstanceOpts;
+ /**
+ * Returns an mongodb URI that is setup with all replSet servers
+ * @param otherDb add an database into the uri (in mongodb its the auth database, in mongoose its the default database for models)
+ * @param otherIp change the ip in the generated uri, default will otherwise always be "127.0.0.1"
+ * @throws if state is not "running"
+ * @throws if an server doesnt have "instanceInfo.port" defined
+ * @returns an valid mongo URI, by the definition of https://docs.mongodb.com/manual/reference/connection-string/
+ */
+ getUri(otherDb?: string, otherIp?: string): string;
+ /**
+ * Start underlying `mongod` instances.
+ * @throws if state is already "running"
+ */
+ start(): Promise;
+ /**
+ * Initialize & start all servers in the replSet
+ */
+ protected initAllServers(): Promise;
+ /**
+ * Ensure "_keyfiletmp" is defined
+ * @returns the ensured "_keyfiletmp" value
+ */
+ protected ensureKeyFile(): Promise;
+ /**
+ * Stop the underlying `mongod` instance(s).
+ * @param cleanupOptions Set how to run ".cleanup", by default only `{ doCleanup: true }` is used
+ */
+ stop(cleanupOptions?: Cleanup): Promise;
+ /**
+ * Remove the defined dbPath's
+ * @param options Set how to run a cleanup, by default `{ doCleanup: true }` is used
+ * @throws If "state" is not "stopped"
+ * @throws If "instanceInfo" is not defined
+ * @throws If an fs error occured
+ */
+ cleanup(options?: Cleanup): Promise;
+ /**
+ * Wait until all instances are running
+ * @throws if state is "stopped" (cannot wait on something that dosnt start)
+ */
+ waitUntilRunning(): Promise;
+ /**
+ * Connects to the first server from the list of servers and issues the `replSetInitiate`
+ * command passing in a new replica set configuration object.
+ * @throws if state is not "init"
+ * @throws if "servers.length" is not 1 or above
+ * @throws if package "mongodb" is not installed
+ */
+ protected _initReplSet(): Promise;
+ /**
+ * Create the one Instance (without starting them)
+ * @param instanceOpts Instance Options to use for this instance
+ */
+ protected _initServer(instanceOpts: MongoMemoryInstanceOpts): MongoMemoryServer;
+ /**
+ * Wait until the replSet has elected a Primary
+ * @param timeout Timeout to not run infinitly, default: 30s
+ * @param where Extra Parameter for logging to know where this function was called
+ * @throws if timeout is reached
+ */
+ protected _waitForPrimary(timeout?: number, where?: string): Promise;
+ [Symbol.asyncDispose](): Promise;
+}
+export default MongoMemoryReplSet;
+//# sourceMappingURL=MongoMemoryReplSet.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.d.ts.map b/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.d.ts.map
new file mode 100644
index 000000000..d94a4cc49
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoMemoryReplSet.d.ts","sourceRoot":"","sources":["../src/MongoMemoryReplSet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.js b/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.js
new file mode 100644
index 000000000..7580cee90
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.js
@@ -0,0 +1,555 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MongoMemoryReplSet = exports.MongoMemoryReplSetEvents = exports.MongoMemoryReplSetStates = void 0;
+const tslib_1 = require("tslib");
+const events_1 = require("events");
+const MongoMemoryServer_1 = require("./MongoMemoryServer");
+const utils_1 = require("./util/utils");
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const mongodb_1 = require("mongodb");
+const MongoInstance_1 = require("./util/MongoInstance");
+const errors_1 = require("./util/errors");
+const fs_1 = require("fs");
+const path_1 = require("path");
+const semver = tslib_1.__importStar(require("semver"));
+const DryMongoBinary_1 = require("./util/DryMongoBinary");
+const log = (0, debug_1.default)('MongoMS:MongoMemoryReplSet');
+/**
+ * Enum for "_state" inside "MongoMemoryReplSet"
+ */
+var MongoMemoryReplSetStates;
+(function (MongoMemoryReplSetStates) {
+ MongoMemoryReplSetStates["init"] = "init";
+ MongoMemoryReplSetStates["running"] = "running";
+ MongoMemoryReplSetStates["stopped"] = "stopped";
+})(MongoMemoryReplSetStates || (exports.MongoMemoryReplSetStates = MongoMemoryReplSetStates = {}));
+/**
+ * All Events for "MongoMemoryReplSet"
+ */
+var MongoMemoryReplSetEvents;
+(function (MongoMemoryReplSetEvents) {
+ MongoMemoryReplSetEvents["stateChange"] = "stateChange";
+})(MongoMemoryReplSetEvents || (exports.MongoMemoryReplSetEvents = MongoMemoryReplSetEvents = {}));
+/**
+ * Class for managing an replSet
+ */
+// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
+class MongoMemoryReplSet extends events_1.EventEmitter {
+ constructor(opts = {}) {
+ super();
+ /**
+ * All servers this ReplSet instance manages
+ */
+ this.servers = [];
+ this._state = MongoMemoryReplSetStates.stopped;
+ this._ranCreateAuth = false;
+ this.binaryOpts = { ...opts.binary };
+ this.instanceOpts = opts.instanceOpts ?? [];
+ this.replSetOpts = { ...opts.replSet };
+ }
+ /**
+ * Change "this._state" to "newState" and emit "newState"
+ * @param newState The new State to set & emit
+ */
+ stateChange(newState, ...args) {
+ this._state = newState;
+ this.emit(MongoMemoryReplSetEvents.stateChange, newState, ...args);
+ }
+ /**
+ * Create an instance of "MongoMemoryReplSet" and call start
+ * @param opts Options for the ReplSet
+ */
+ static async create(opts) {
+ log('create: Called .create() method');
+ const replSet = new this({ ...opts });
+ await replSet.start();
+ return replSet;
+ }
+ /**
+ * Get Current state of this class
+ */
+ get state() {
+ return this._state;
+ }
+ /**
+ * Get & Set "instanceOpts"
+ * @throws if "state" is not "stopped"
+ */
+ get instanceOpts() {
+ return this._instanceOpts;
+ }
+ set instanceOpts(val) {
+ assertionIsMMSRSState(MongoMemoryReplSetStates.stopped, this._state);
+ this._instanceOpts = val;
+ }
+ /**
+ * Get & Set "binaryOpts"
+ * @throws if "state" is not "stopped"
+ */
+ get binaryOpts() {
+ return this._binaryOpts;
+ }
+ set binaryOpts(val) {
+ assertionIsMMSRSState(MongoMemoryReplSetStates.stopped, this._state);
+ this._binaryOpts = val;
+ }
+ /**
+ * Get & Set "replSetOpts"
+ * (Applies defaults)
+ * @throws if "state" is not "stopped"
+ */
+ get replSetOpts() {
+ return this._replSetOpts;
+ }
+ set replSetOpts(val) {
+ assertionIsMMSRSState(MongoMemoryReplSetStates.stopped, this._state);
+ // the following needs to be done because we set the default "storageEngine" here
+ // which means the default is seen as set "explicitly" by the instance and would warn
+ // in binary versions >=7.0.0
+ const opts = DryMongoBinary_1.DryMongoBinary.getEnsuredOptions(this.binaryOpts);
+ // try to convert a string to a valid semver, like "v6.0-latest" (compiles to "6.0.0")
+ // use "0.0.0" as a fallback to have a valid semver for later checks, but warn on invalid
+ const coercedVersion = semver.coerce(opts.version) ?? new semver.SemVer('0.0.0');
+ const storageEngine = (0, utils_1.getStorageEngine)(val.storageEngine, coercedVersion);
+ const defaults = {
+ auth: { enable: false },
+ args: [],
+ name: 'testset',
+ count: 1,
+ dbName: (0, utils_1.generateDbName)(),
+ ip: '127.0.0.1',
+ spawn: {},
+ storageEngine,
+ configSettings: {},
+ dispose: {},
+ };
+ // force overwrite "storageEngine" because it is transformed already
+ this._replSetOpts = { ...defaults, ...val, storageEngine };
+ (0, utils_1.assertion)(this._replSetOpts.count > 0, new errors_1.ReplsetCountLowError(this._replSetOpts.count));
+ // only set default is enabled
+ if (this._replSetOpts.auth.enable) {
+ this._replSetOpts.auth = (0, utils_1.authDefault)(this._replSetOpts.auth);
+ }
+ }
+ /**
+ * Helper function to determine if "auth" should be enabled
+ * This function expectes to be run after the auth object has been transformed to a object
+ * @returns "true" when "auth" should be enabled
+ */
+ enableAuth() {
+ if ((0, utils_1.isNullOrUndefined)(this._replSetOpts.auth)) {
+ return false;
+ }
+ (0, utils_1.assertion)(typeof this._replSetOpts.auth === 'object', new errors_1.AuthNotObjectError());
+ return typeof this._replSetOpts.auth.enable === 'boolean' // if "this._replSetOpts.auth.enable" is defined, use that
+ ? this._replSetOpts.auth.enable
+ : false; // if "this._replSetOpts.auth.enable" is not defined, default to false
+ }
+ /**
+ * Returns instance options suitable for a MongoMemoryServer.
+ * @param baseOpts Options to merge with
+ * @param keyfileLocation The Keyfile location if "auth" is used
+ */
+ getInstanceOpts(baseOpts = {}, keyfileLocation) {
+ const enableAuth = this.enableAuth();
+ const opts = {
+ auth: enableAuth,
+ args: this._replSetOpts.args,
+ dbName: this._replSetOpts.dbName,
+ ip: this._replSetOpts.ip,
+ replSet: this._replSetOpts.name,
+ storageEngine: this._replSetOpts.storageEngine,
+ };
+ if (!(0, utils_1.isNullOrUndefined)(keyfileLocation)) {
+ opts.keyfileLocation = keyfileLocation;
+ }
+ if (baseOpts.args) {
+ opts.args = this._replSetOpts.args.concat(baseOpts.args);
+ }
+ if (baseOpts.port) {
+ opts.port = baseOpts.port;
+ }
+ if (baseOpts.dbPath) {
+ opts.dbPath = baseOpts.dbPath;
+ }
+ if (baseOpts.storageEngine) {
+ opts.storageEngine = baseOpts.storageEngine;
+ }
+ if (baseOpts.replicaMemberConfig) {
+ opts.replicaMemberConfig = baseOpts.replicaMemberConfig;
+ }
+ if (baseOpts.launchTimeout) {
+ opts.launchTimeout = baseOpts.launchTimeout;
+ }
+ log('getInstanceOpts: instance opts:', opts);
+ return opts;
+ }
+ /**
+ * Returns an mongodb URI that is setup with all replSet servers
+ * @param otherDb add an database into the uri (in mongodb its the auth database, in mongoose its the default database for models)
+ * @param otherIp change the ip in the generated uri, default will otherwise always be "127.0.0.1"
+ * @throws if state is not "running"
+ * @throws if an server doesnt have "instanceInfo.port" defined
+ * @returns an valid mongo URI, by the definition of https://docs.mongodb.com/manual/reference/connection-string/
+ */
+ getUri(otherDb, otherIp) {
+ log('getUri:', this.state);
+ switch (this.state) {
+ case MongoMemoryReplSetStates.running:
+ case MongoMemoryReplSetStates.init:
+ break;
+ case MongoMemoryReplSetStates.stopped:
+ default:
+ throw new errors_1.StateError([MongoMemoryReplSetStates.running, MongoMemoryReplSetStates.init], this.state);
+ }
+ const hosts = this.servers
+ .map((s) => {
+ const port = s.instanceInfo?.port;
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(port), new Error('Instance Port is undefined!'));
+ const ip = otherIp || '127.0.0.1';
+ return `${ip}:${port}`;
+ })
+ .join(',');
+ return (0, utils_1.uriTemplate)(hosts, undefined, (0, utils_1.generateDbName)(otherDb), [
+ `replicaSet=${this._replSetOpts.name}`,
+ ]);
+ }
+ /**
+ * Start underlying `mongod` instances.
+ * @throws if state is already "running"
+ */
+ async start() {
+ log('start:', this.state);
+ switch (this.state) {
+ case MongoMemoryReplSetStates.stopped:
+ break;
+ case MongoMemoryReplSetStates.running:
+ default:
+ throw new errors_1.StateError([MongoMemoryReplSetStates.stopped], this.state);
+ }
+ this.stateChange(MongoMemoryReplSetStates.init); // this needs to be executed before "setImmediate"
+ await (0, utils_1.ensureAsync)()
+ .then(() => this.initAllServers())
+ .then(() => this._initReplSet())
+ .catch(async (err) => {
+ if (!debug_1.default.enabled('MongoMS:MongoMemoryReplSet')) {
+ console.warn('Starting the MongoMemoryReplSet Instance failed, enable debug log for more information. Error:\n', err);
+ }
+ log('ensureAsync chain threw a Error: ', err);
+ await this.stop({ doCleanup: false, force: false }); // still try to close the instance that was spawned, without cleanup for investigation
+ this.stateChange(MongoMemoryReplSetStates.stopped);
+ throw err;
+ });
+ }
+ /**
+ * Initialize & start all servers in the replSet
+ */
+ async initAllServers() {
+ log('initAllServers');
+ this.stateChange(MongoMemoryReplSetStates.init);
+ if (this.servers.length > 0) {
+ log('initAllServers: lenght of "servers" is higher than 0, starting existing servers');
+ if (this._ranCreateAuth) {
+ log('initAllServers: "_ranCreateAuth" is true, re-using auth');
+ const keyfilepath = (0, path_1.resolve)(await this.ensureKeyFile(), 'keyfile');
+ for (const server of this.servers) {
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(server.instanceInfo), new errors_1.InstanceInfoError('MongoMemoryReplSet.initAllServers'));
+ (0, utils_1.assertion)(typeof this._replSetOpts.auth === 'object', new errors_1.AuthNotObjectError());
+ server.instanceInfo.instance.instanceOpts.auth = true;
+ server.instanceInfo.instance.instanceOpts.keyfileLocation = keyfilepath;
+ server.instanceInfo.instance.extraConnectionOptions = {
+ authSource: 'admin',
+ authMechanism: 'SCRAM-SHA-256',
+ auth: {
+ username: this._replSetOpts.auth.customRootName, // cast because these are existing
+ password: this._replSetOpts.auth.customRootPwd,
+ },
+ };
+ }
+ }
+ await Promise.all(this.servers.map((s) => s.start(true)));
+ log('initAllServers: finished starting existing instances again');
+ return;
+ }
+ let keyfilePath = undefined;
+ if (this.enableAuth()) {
+ keyfilePath = (0, path_1.resolve)(await this.ensureKeyFile(), 'keyfile');
+ }
+ // Any servers defined within `_instanceOpts` should be started first as
+ // the user could have specified a `dbPath` in which case we would want to perform
+ // the `replSetInitiate` command against that server.
+ this._instanceOpts.forEach((opts, index) => {
+ log(`initAllServers: starting special server "${index + 1}" of "${this._instanceOpts.length}" from instanceOpts (count: ${this.servers.length + 1}):`, opts);
+ this.servers.push(this._initServer(this.getInstanceOpts(opts, keyfilePath)));
+ });
+ while (this.servers.length < this._replSetOpts.count) {
+ log(`initAllServers: starting extra server "${this.servers.length + 1}" of "${this._replSetOpts.count}" (count: ${this.servers.length + 1})`);
+ this.servers.push(this._initServer(this.getInstanceOpts(undefined, keyfilePath)));
+ }
+ log('initAllServers: waiting for all servers to finish starting');
+ // ensures all servers are listening for connection
+ await Promise.all(this.servers.map((s) => s.start()));
+ log('initAllServers: finished starting all servers initially');
+ }
+ /**
+ * Ensure "_keyfiletmp" is defined
+ * @returns the ensured "_keyfiletmp" value
+ */
+ async ensureKeyFile() {
+ log('ensureKeyFile');
+ if ((0, utils_1.isNullOrUndefined)(this._keyfiletmp)) {
+ this._keyfiletmp = await (0, utils_1.createTmpDir)('mongo-mem-keyfile-');
+ }
+ const keyfilepath = (0, path_1.resolve)(this._keyfiletmp, 'keyfile');
+ // if path does not exist or have no access, create it (or fail)
+ if (!(await (0, utils_1.statPath)(keyfilepath))) {
+ log('ensureKeyFile: creating Keyfile');
+ (0, utils_1.assertion)(typeof this._replSetOpts.auth === 'object', new errors_1.AuthNotObjectError());
+ await fs_1.promises.writeFile((0, path_1.resolve)(this._keyfiletmp, 'keyfile'), this._replSetOpts.auth.keyfileContent ?? '0123456789', { mode: 0o700 } // this is because otherwise mongodb errors with "permissions are too open" on unix systems
+ );
+ }
+ return this._keyfiletmp;
+ }
+ /**
+ * Stop the underlying `mongod` instance(s).
+ * @param cleanupOptions Set how to run ".cleanup", by default only `{ doCleanup: true }` is used
+ */
+ async stop(cleanupOptions) {
+ log(`stop: called by ${(0, utils_1.isNullOrUndefined)(process.exitCode) ? 'manual' : 'process exit'}`);
+ /** Default to cleanup temporary, but not custom dbpaths */
+ let cleanup = { doCleanup: true, force: false };
+ // handle the new way of setting what and how to cleanup
+ if (typeof cleanupOptions === 'object') {
+ cleanup = cleanupOptions;
+ }
+ if (this._state === MongoMemoryReplSetStates.stopped) {
+ log('stop: state is "stopped", trying to stop / kill anyway');
+ }
+ const successfullyStopped = await Promise.all(this.servers.map((s) => s.stop({ doCleanup: false, force: false })))
+ .then(() => {
+ this.stateChange(MongoMemoryReplSetStates.stopped);
+ return true;
+ })
+ .catch((err) => {
+ log('stop:', err);
+ this.stateChange(MongoMemoryReplSetStates.stopped, err);
+ return false;
+ });
+ // return early if the instances failed to stop
+ if (!successfullyStopped) {
+ return false;
+ }
+ if (cleanup.doCleanup) {
+ await this.cleanup(cleanup);
+ }
+ return true;
+ }
+ /**
+ * Remove the defined dbPath's
+ * @param options Set how to run a cleanup, by default `{ doCleanup: true }` is used
+ * @throws If "state" is not "stopped"
+ * @throws If "instanceInfo" is not defined
+ * @throws If an fs error occured
+ */
+ async cleanup(options) {
+ assertionIsMMSRSState(MongoMemoryReplSetStates.stopped, this._state);
+ log(`cleanup for "${this.servers.length}" servers`);
+ /** Default to doing cleanup, but not forcing it */
+ let cleanup = { doCleanup: true, force: false };
+ // handle the new way of setting what and how to cleanup
+ if (typeof options === 'object') {
+ cleanup = options;
+ }
+ log(`cleanup:`, cleanup);
+ // dont do cleanup, if "doCleanup" is false
+ if (!cleanup.doCleanup) {
+ log('cleanup: "doCleanup" is set to false');
+ return;
+ }
+ await Promise.all(this.servers.map((s) => s.cleanup(cleanup)));
+ // cleanup the keyfile tmpdir
+ if (!(0, utils_1.isNullOrUndefined)(this._keyfiletmp)) {
+ await (0, utils_1.removeDir)(this._keyfiletmp);
+ this._keyfiletmp = undefined;
+ }
+ this.servers = [];
+ this._ranCreateAuth = false;
+ return;
+ }
+ /**
+ * Wait until all instances are running
+ * @throws if state is "stopped" (cannot wait on something that dosnt start)
+ */
+ async waitUntilRunning() {
+ await (0, utils_1.ensureAsync)();
+ log('waitUntilRunning:', this._state);
+ switch (this._state) {
+ case MongoMemoryReplSetStates.running:
+ // just return immediatly if the replSet is already running
+ return;
+ case MongoMemoryReplSetStates.init:
+ // wait for event "running"
+ await new Promise((res) => {
+ // the use of "this" here can be done because "on" either binds "this" or uses an arrow function
+ function waitRunning(state) {
+ // this is because other states can be emitted multiple times (like stopped & init for auth creation)
+ if (state === MongoMemoryReplSetStates.running) {
+ this.removeListener(MongoMemoryReplSetEvents.stateChange, waitRunning);
+ res();
+ }
+ }
+ this.on(MongoMemoryReplSetEvents.stateChange, waitRunning);
+ });
+ return;
+ case MongoMemoryReplSetStates.stopped:
+ default:
+ throw new errors_1.StateError([MongoMemoryReplSetStates.running, MongoMemoryReplSetStates.init], this.state);
+ }
+ }
+ /**
+ * Connects to the first server from the list of servers and issues the `replSetInitiate`
+ * command passing in a new replica set configuration object.
+ * @throws if state is not "init"
+ * @throws if "servers.length" is not 1 or above
+ * @throws if package "mongodb" is not installed
+ */
+ async _initReplSet() {
+ log('_initReplSet');
+ assertionIsMMSRSState(MongoMemoryReplSetStates.init, this._state);
+ (0, utils_1.assertion)(this.servers.length > 0, new Error('One or more servers are required.'));
+ const uris = this.servers.map((server) => server.getUri());
+ const isInMemory = this.servers[0].instanceInfo?.storageEngine === 'ephemeralForTest';
+ const extraOptions = this._ranCreateAuth
+ ? (this.servers[0].instanceInfo?.instance.extraConnectionOptions ?? {})
+ : {};
+ const con = await mongodb_1.MongoClient.connect(uris[0], {
+ // somehow since mongodb-nodejs 4.0, this option is needed when the server is set to be in a replset
+ directConnection: true,
+ ...extraOptions,
+ });
+ log('_initReplSet: connected');
+ // try-finally to close connection in any case
+ try {
+ const adminDb = con.db('admin');
+ const members = uris.map((uri, index) => ({
+ _id: index,
+ host: (0, utils_1.getHost)(uri),
+ ...(this.servers[index].opts.instance?.replicaMemberConfig || {}), // Overwrite replica member config
+ }));
+ const rsConfig = {
+ _id: this._replSetOpts.name,
+ members,
+ writeConcernMajorityJournalDefault: !isInMemory, // if storage engine is "ephemeralForTest" deactivate this option, otherwise enable it
+ settings: {
+ electionTimeoutMillis: 500,
+ ...this._replSetOpts.configSettings,
+ },
+ };
+ // try-catch because the first "command" can fail
+ try {
+ log('_initReplSet: trying "replSetInitiate"');
+ await adminDb.command({ replSetInitiate: rsConfig });
+ if (this.enableAuth()) {
+ log('_initReplSet: "enableAuth" returned "true"');
+ await this._waitForPrimary(undefined, '_initReplSet authIsObject');
+ // find the primary instance to run createAuth on
+ const primary = this.servers.find((server) => server.instanceInfo?.instance.isInstancePrimary);
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(primary), new Error('No Primary found'));
+ // this should be defined at this point, but is checked anyway (thanks to types)
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(primary.instanceInfo), new errors_1.InstanceInfoError('_initReplSet authIsObject primary'));
+ await con.close(); // just ensuring that no timeouts happen or conflicts happen
+ await primary.createAuth(primary.instanceInfo);
+ this._ranCreateAuth = true;
+ }
+ }
+ catch (err) {
+ if (err instanceof mongodb_1.MongoError && err.errmsg == 'already initialized') {
+ log(`_initReplSet: "${err.errmsg}": trying to set old config`);
+ const { config: oldConfig } = await adminDb.command({ replSetGetConfig: 1 });
+ log('_initReplSet: got old config:\n', oldConfig);
+ await adminDb.command({
+ replSetReconfig: oldConfig,
+ force: true,
+ });
+ }
+ else {
+ throw err;
+ }
+ }
+ log('_initReplSet: ReplSet-reconfig finished');
+ await this._waitForPrimary(undefined, '_initReplSet beforeRunning');
+ this.stateChange(MongoMemoryReplSetStates.running);
+ log('_initReplSet: running');
+ }
+ finally {
+ log('_initReplSet: finally closing connection');
+ await con.close();
+ }
+ }
+ /**
+ * Create the one Instance (without starting them)
+ * @param instanceOpts Instance Options to use for this instance
+ */
+ _initServer(instanceOpts) {
+ const serverOpts = {
+ binary: this._binaryOpts,
+ instance: instanceOpts,
+ spawn: this._replSetOpts.spawn,
+ auth: typeof this.replSetOpts.auth === 'object' ? this.replSetOpts.auth : undefined,
+ };
+ const server = new MongoMemoryServer_1.MongoMemoryServer(serverOpts);
+ return server;
+ }
+ /**
+ * Wait until the replSet has elected a Primary
+ * @param timeout Timeout to not run infinitly, default: 30s
+ * @param where Extra Parameter for logging to know where this function was called
+ * @throws if timeout is reached
+ */
+ async _waitForPrimary(timeout = 1000 * 30, where) {
+ log('_waitForPrimary: Waiting for a Primary');
+ let timeoutId;
+ // "race" because not all servers will be a primary
+ await Promise.race([
+ ...this.servers.map((server) => new Promise((res, rej) => {
+ const instanceInfo = server.instanceInfo;
+ // this should be defined at this point, but is checked anyway (thanks to types)
+ if ((0, utils_1.isNullOrUndefined)(instanceInfo)) {
+ return rej(new errors_1.InstanceInfoError('_waitForPrimary Primary race'));
+ }
+ instanceInfo.instance.once(MongoInstance_1.MongoInstanceEvents.instancePrimary, res);
+ if (instanceInfo.instance.isInstancePrimary) {
+ log('_waitForPrimary: found instance being already primary');
+ res();
+ }
+ })),
+ new Promise((_res, rej) => {
+ timeoutId = setTimeout(() => {
+ Promise.all([...this.servers.map((v) => v.stop())]); // this is not chained with "rej", this is here just so things like jest can exit at some point
+ rej(new errors_1.WaitForPrimaryTimeoutError(timeout, where));
+ }, timeout);
+ }),
+ ]);
+ if (!(0, utils_1.isNullOrUndefined)(timeoutId)) {
+ clearTimeout(timeoutId);
+ }
+ log('_waitForPrimary: detected one primary instance ');
+ }
+ // Symbol for "Explicit Resource Management"
+ async [Symbol.asyncDispose]() {
+ if (this.replSetOpts.dispose?.enabled ?? true) {
+ await this.stop(this.replSetOpts.dispose?.cleanup);
+ }
+ }
+}
+exports.MongoMemoryReplSet = MongoMemoryReplSet;
+exports.default = MongoMemoryReplSet;
+/**
+ * Helper function to de-duplicate state checking for "MongoMemoryReplSetStates"
+ * @param wantedState The State that is wanted
+ * @param currentState The current State ("this._state")
+ */
+function assertionIsMMSRSState(wantedState, currentState) {
+ (0, utils_1.assertion)(currentState === wantedState, new errors_1.StateError([wantedState], currentState));
+}
+//# sourceMappingURL=MongoMemoryReplSet.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.js.map b/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.js.map
new file mode 100644
index 000000000..423d3855f
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/MongoMemoryReplSet.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoMemoryReplSet.js","sourceRoot":"","sources":["../src/MongoMemoryReplSet.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/MongoMemoryServer.d.ts b/packages/mongodb-memory-server-core/lib/MongoMemoryServer.d.ts
new file mode 100644
index 000000000..5b876ff1d
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/MongoMemoryServer.d.ts
@@ -0,0 +1,324 @@
+///
+///
+import { SpawnOptions } from 'child_process';
+import { ManagerAdvanced, Cleanup } from './util/utils';
+import { MongoInstance, MongodOpts, MongoMemoryInstanceOpts } from './util/MongoInstance';
+import { MongoBinaryOpts } from './util/MongoBinary';
+import { EventEmitter } from 'events';
+/**
+ * Type with automatic options removed
+ * "auth" is automatically handled and set via {@link AutomaticAuth}
+ */
+export type MemoryServerInstanceOpts = Omit & ExtraInstanceOpts;
+/**
+ * Extra Instance options specifically for {@link MongoMemoryServer}
+ */
+export interface ExtraInstanceOpts {
+ /**
+ * Change if port generation is enabled or not.
+ *
+ * If enabled and a port is set, that port is tried, if locked a new one will be generated.
+ * If disabled and a port is set, only that port is tried, if locked a error will be thrown.
+ * If disabled and no port is set, will act as if enabled.
+ *
+ * This setting will get overwritten by `start`'s `forceSamePort` parameter if set
+ *
+ * @default true
+ */
+ portGeneration?: boolean;
+}
+/**
+ * MongoMemoryServer Stored Options
+ */
+export interface MongoMemoryServerOpts {
+ instance?: MemoryServerInstanceOpts;
+ binary?: MongoBinaryOpts;
+ spawn?: SpawnOptions;
+ /**
+ * Defining this enables automatic user creation
+ */
+ auth?: AutomaticAuth;
+ /**
+ * Options for automatic dispose for "Explicit Resource Management"
+ */
+ dispose?: DisposeOptions;
+}
+/**
+ * Options to configure `Symbol.asyncDispose` behavior
+ */
+export interface DisposeOptions {
+ /**
+ * Set whether to run the dispose hook or not.
+ * Note that this only applies when `Symbol.asyncDispose` is actually called
+ * @default true
+ */
+ enabled?: boolean;
+ /**
+ * Pass custom options for cleanup
+ * @default { doCleanup: true, force: false }
+ */
+ cleanup?: Cleanup;
+}
+export interface AutomaticAuth {
+ /**
+ * Enable Automatic User creation
+ * @default false
+ */
+ enable?: boolean;
+ /**
+ * Extra Users to create besides the root user
+ * @default []
+ */
+ extraUsers?: CreateUser[];
+ /**
+ * mongodb-memory-server automatically creates a root user (with "root" role)
+ * @default 'mongodb-memory-server-root'
+ */
+ customRootName?: string;
+ /**
+ * mongodb-memory-server automatically creates a root user with this password
+ * @default 'rootuser'
+ */
+ customRootPwd?: string;
+ /**
+ * Force to run "createAuth"
+ * @default false "createAuth" is normally only run when the given "dbPath" is empty (no files)
+ */
+ force?: boolean;
+ /**
+ * Custom Keyfile content to use (only has an effect in replset's)
+ * Note: This is not secure, this is for test environments only!
+ * @default "0123456789"
+ */
+ keyfileContent?: string;
+}
+/**
+ * Data used by _startUpInstance's "data" variable
+ */
+export interface StartupInstanceData {
+ port: NonNullable;
+ dbPath?: MongoMemoryInstanceOpts['dbPath'];
+ dbName: NonNullable;
+ ip: NonNullable;
+ storageEngine: NonNullable;
+ replSet?: NonNullable;
+ tmpDir?: string;
+ keyfileLocation?: NonNullable;
+ launchTimeout?: NonNullable;
+}
+/**
+ * Information about the currently running instance
+ */
+export interface MongoInstanceData extends StartupInstanceData {
+ dbPath: NonNullable;
+ instance: MongoInstance;
+}
+/**
+ * All Events for "MongoMemoryServer"
+ */
+export declare enum MongoMemoryServerEvents {
+ stateChange = "stateChange"
+}
+/**
+ * All States for "MongoMemoryServer._state"
+ */
+export declare enum MongoMemoryServerStates {
+ new = "new",
+ starting = "starting",
+ running = "running",
+ stopped = "stopped"
+}
+/**
+ * All MongoDB Built-in Roles
+ * @see https://docs.mongodb.com/manual/reference/built-in-roles/
+ */
+export type UserRoles = 'read' | 'readWrite' | 'dbAdmin' | 'dbOwner' | 'userAdmin' | 'clusterAdmin' | 'clusterManager' | 'clusterMonitor' | 'hostManager' | 'backup' | 'restore' | 'readAnyDatabase' | 'readWriteAnyDatabase' | 'userAdminAnyDatabase' | 'dbAdminAnyDatabase' | 'root' | string;
+export interface RoleSpecification {
+ /**
+ * A role grants privileges to perform sets of actions on defined resources.
+ * A given role applies to the database on which it is defined and can grant access down to a collection level of granularity.
+ */
+ role: string;
+ /** The database this user's role should effect. */
+ db: string;
+}
+/**
+ * Interface options for "db.createUser" (used for this package)
+ * This interface is WITHOUT the custom options from this package
+ * (Some text copied from https://docs.mongodb.com/manual/reference/method/db.createUser/#definition)
+ * This interface only exists, because mongodb dosnt provide such an interface for "createUser" (or as just very basic types) as of 6.7.0
+ */
+export interface CreateUserMongoDB {
+ /**
+ * Username
+ */
+ createUser: string;
+ /**
+ * Password
+ */
+ pwd: string;
+ /**
+ * Any arbitrary information.
+ * This field can be used to store any data an admin wishes to associate with this particular user.
+ * @example this could be the user’s full name or employee id.
+ */
+ customData?: {
+ [key: string]: any;
+ };
+ /**
+ * The Roles for the user, can be an empty array
+ */
+ roles: string | string[] | RoleSpecification | RoleSpecification[];
+ /**
+ * Specify the specific SCRAM mechanism or mechanisms for creating SCRAM user credentials.
+ */
+ mechanisms?: ('SCRAM-SHA-1' | 'SCRAM-SHA-256')[];
+ /**
+ * The authentication restrictions the server enforces on the created user.
+ * Specifies a list of IP addresses and CIDR ranges from which the user is allowed to connect to the server or from which the server can accept users.
+ */
+ authenticationRestrictions?: {
+ clientSource?: string;
+ serverAddress?: string;
+ }[];
+ /**
+ * Indicates whether the server or the client digests the password.
+ * "true" - The Server digests the Password
+ * "false" - The Client digests the Password
+ */
+ digestPassword?: boolean;
+}
+/**
+ * Interface options for "db.createUser" (used for this package)
+ * This interface is WITH the custom options from this package
+ * (Some text copied from https://docs.mongodb.com/manual/reference/method/db.createUser/#definition)
+ */
+export interface CreateUser extends CreateUserMongoDB {
+ /**
+ * In which Database to create this user in
+ * @default 'admin' by default the "admin" database is used
+ */
+ database?: string;
+}
+export interface MongoMemoryServerGetStartOptions {
+ /** Defines wheter should {@link MongoMemoryServer.createAuth} be run */
+ createAuth: boolean;
+ data: StartupInstanceData;
+ mongodOptions: Partial;
+}
+export interface MongoMemoryServer extends EventEmitter {
+ emit(event: MongoMemoryServerEvents, ...args: any[]): boolean;
+ on(event: MongoMemoryServerEvents, listener: (...args: any[]) => void): this;
+ once(event: MongoMemoryServerEvents, listener: (...args: any[]) => void): this;
+}
+export declare class MongoMemoryServer extends EventEmitter implements ManagerAdvanced {
+ /**
+ * Information about the started instance
+ */
+ protected _instanceInfo?: MongoInstanceData;
+ /**
+ * General Options for this Instance
+ */
+ opts: MongoMemoryServerOpts;
+ /**
+ * The Current State of this instance
+ */
+ protected _state: MongoMemoryServerStates;
+ /**
+ * Original Auth Configuration (this.opts can be changed if stopped, but auth cannot be changed here)
+ */
+ readonly auth?: Required;
+ /**
+ * Create a Mongo-Memory-Sever Instance
+ * @param opts Mongo-Memory-Sever Options
+ */
+ constructor(opts?: MongoMemoryServerOpts);
+ /**
+ * Create a Mongo-Memory-Sever Instance that can be awaited
+ * @param opts Mongo-Memory-Sever Options
+ */
+ static create(opts?: MongoMemoryServerOpts): Promise;
+ /**
+ * Start the Mongod Instance
+ * @param forceSamePort Force to use the port defined in `options.instance` (disabled port generation)
+ * @throws if state is not "new" or "stopped"
+ */
+ start(forceSamePort?: boolean): Promise;
+ /**
+ * Change "this._state" to "newState" and emit "stateChange" with "newState"
+ * @param newState The new State to set & emit
+ */
+ protected stateChange(newState: MongoMemoryServerStates): void;
+ /**
+ * Debug-log with template applied
+ * @param msg The Message to log
+ */
+ protected debug(msg: string, ...extra: unknown[]): void;
+ /**
+ * Find a new unlocked port
+ * @param port A User defined default port
+ */
+ protected getNewPort(port?: number): Promise;
+ /**
+ * Construct Instance Starting Options
+ * @param forceSamePort Force to use the port defined in `options.instance` (disabled port generation)
+ */
+ protected getStartOptions(forceSamePort?: boolean): Promise;
+ /**
+ * Internal Function to start an instance
+ * @param forceSamePort Force to use the port defined in `options.instance` (disabled port generation)
+ * @private
+ */
+ _startUpInstance(forceSamePort?: boolean): Promise;
+ /**
+ * Stop the current In-Memory Instance
+ * @param cleanupOptions Set how to run ".cleanup", by default only `{ doCleanup: true }` is used
+ */
+ stop(cleanupOptions?: Cleanup): Promise;
+ /**
+ * Remove the defined dbPath
+ * @param options Set how to run a cleanup, by default `{ doCleanup: true }` is used
+ * @throws If "state" is not "stopped"
+ * @throws If "instanceInfo" is not defined
+ * @throws If an fs error occured
+ */
+ cleanup(options?: Cleanup): Promise;
+ /**
+ * Get Information about the currently running instance, if it is not running it returns "undefined"
+ */
+ get instanceInfo(): MongoInstanceData | undefined;
+ /**
+ * Get Current state of this class
+ */
+ get state(): MongoMemoryServerStates;
+ /**
+ * Ensure that the instance is running
+ * -> throws if instance cannot be started
+ */
+ ensureInstance(): Promise;
+ /**
+ * Generate the Connection string used by mongodb
+ * @param otherDb add a database into the uri (in mongodb its the auth database, in mongoose its the default database for models)
+ * @param otherIp change the ip in the generated uri, default will otherwise always be "127.0.0.1"
+ * @throws if state is not "running" (or "starting")
+ * @throws if a server doesnt have "instanceInfo.port" defined
+ * @returns a valid mongo URI, by the definition of https://docs.mongodb.com/manual/reference/connection-string/
+ */
+ getUri(otherDb?: string, otherIp?: string): string;
+ /**
+ * Create the Root user and additional users using the [localhost exception](https://www.mongodb.com/docs/manual/core/localhost-exception/#std-label-localhost-exception)
+ * This Function assumes "this.opts.auth" is already processed into "this.auth"
+ * @param data Used to get "ip" and "port"
+ * @internal
+ */
+ createAuth(data: StartupInstanceData): Promise;
+ /**
+ * Helper function to determine if the "auth" object is set and not to be disabled
+ * This function expectes to be run after the auth object has been transformed to a object
+ * @returns "true" when "auth" should be enabled
+ */
+ protected authObjectEnable(): boolean;
+ [Symbol.asyncDispose](): Promise;
+}
+export default MongoMemoryServer;
+//# sourceMappingURL=MongoMemoryServer.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/MongoMemoryServer.d.ts.map b/packages/mongodb-memory-server-core/lib/MongoMemoryServer.d.ts.map
new file mode 100644
index 000000000..84b0bc472
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/MongoMemoryServer.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoMemoryServer.d.ts","sourceRoot":"","sources":["../src/MongoMemoryServer.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/MongoMemoryServer.js b/packages/mongodb-memory-server-core/lib/MongoMemoryServer.js
new file mode 100644
index 000000000..d8ab8fdaa
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/MongoMemoryServer.js
@@ -0,0 +1,512 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MongoMemoryServer = exports.MongoMemoryServerStates = exports.MongoMemoryServerEvents = void 0;
+const tslib_1 = require("tslib");
+const getport_1 = require("./util/getport");
+const utils_1 = require("./util/utils");
+const MongoInstance_1 = require("./util/MongoInstance");
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const events_1 = require("events");
+const fs_1 = require("fs");
+const mongodb_1 = require("mongodb");
+const errors_1 = require("./util/errors");
+const os = tslib_1.__importStar(require("os"));
+const DryMongoBinary_1 = require("./util/DryMongoBinary");
+const semver = tslib_1.__importStar(require("semver"));
+const log = (0, debug_1.default)('MongoMS:MongoMemoryServer');
+/**
+ * All Events for "MongoMemoryServer"
+ */
+var MongoMemoryServerEvents;
+(function (MongoMemoryServerEvents) {
+ MongoMemoryServerEvents["stateChange"] = "stateChange";
+})(MongoMemoryServerEvents || (exports.MongoMemoryServerEvents = MongoMemoryServerEvents = {}));
+/**
+ * All States for "MongoMemoryServer._state"
+ */
+var MongoMemoryServerStates;
+(function (MongoMemoryServerStates) {
+ MongoMemoryServerStates["new"] = "new";
+ MongoMemoryServerStates["starting"] = "starting";
+ MongoMemoryServerStates["running"] = "running";
+ MongoMemoryServerStates["stopped"] = "stopped";
+})(MongoMemoryServerStates || (exports.MongoMemoryServerStates = MongoMemoryServerStates = {}));
+// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
+class MongoMemoryServer extends events_1.EventEmitter {
+ /**
+ * Create a Mongo-Memory-Sever Instance
+ * @param opts Mongo-Memory-Sever Options
+ */
+ constructor(opts) {
+ super();
+ /**
+ * The Current State of this instance
+ */
+ this._state = MongoMemoryServerStates.new;
+ this.opts = { ...opts };
+ // instance option "auth" will be automatically set and handled via AutomaticAuth
+ if ('auth' in (this.opts.instance ?? {})) {
+ log('opts.instance.auth was defined, but will be set automatically, ignoring');
+ delete this.opts.instance?.auth;
+ }
+ if (this.opts.auth?.enable === true) {
+ // assign defaults
+ this.auth = (0, utils_1.authDefault)(this.opts.auth);
+ }
+ }
+ /**
+ * Create a Mongo-Memory-Sever Instance that can be awaited
+ * @param opts Mongo-Memory-Sever Options
+ */
+ static async create(opts) {
+ log('create: Called .create() method');
+ const instance = new MongoMemoryServer({ ...opts });
+ await instance.start();
+ return instance;
+ }
+ /**
+ * Start the Mongod Instance
+ * @param forceSamePort Force to use the port defined in `options.instance` (disabled port generation)
+ * @throws if state is not "new" or "stopped"
+ */
+ async start(forceSamePort) {
+ this.debug('start: Called .start() method');
+ switch (this._state) {
+ case MongoMemoryServerStates.new:
+ case MongoMemoryServerStates.stopped:
+ break;
+ case MongoMemoryServerStates.running:
+ case MongoMemoryServerStates.starting:
+ default:
+ throw new errors_1.StateError([MongoMemoryServerStates.new, MongoMemoryServerStates.stopped], this.state);
+ }
+ (0, utils_1.assertion)((0, utils_1.isNullOrUndefined)(this._instanceInfo?.instance.mongodProcess), new Error('Cannot start because "instance.mongodProcess" is already defined!'));
+ this.stateChange(MongoMemoryServerStates.starting);
+ await this._startUpInstance(forceSamePort).catch(async (err) => {
+ // add error information on macos-arm because "spawn Unknown system error -86" does not say much
+ if (err instanceof Error && err.message?.includes('spawn Unknown system error -86')) {
+ if (os.platform() === 'darwin' && os.arch() === 'arm64') {
+ err.message += err.message += ', Is Rosetta Installed and Setup correctly?';
+ }
+ }
+ if (!debug_1.default.enabled('MongoMS:MongoMemoryServer')) {
+ console.warn('Starting the MongoMemoryServer Instance failed, enable debug log for more information. Error:\n', err);
+ }
+ this.debug('_startUpInstance threw a Error: ', err);
+ await this.stop({ doCleanup: false, force: false }); // still try to close the instance that was spawned, without cleanup for investigation
+ this.stateChange(MongoMemoryServerStates.stopped);
+ throw err;
+ });
+ this.stateChange(MongoMemoryServerStates.running);
+ this.debug('start: Instance fully Started');
+ }
+ /**
+ * Change "this._state" to "newState" and emit "stateChange" with "newState"
+ * @param newState The new State to set & emit
+ */
+ stateChange(newState) {
+ this._state = newState;
+ this.emit(MongoMemoryServerEvents.stateChange, newState);
+ }
+ /**
+ * Debug-log with template applied
+ * @param msg The Message to log
+ */
+ debug(msg, ...extra) {
+ const port = this._instanceInfo?.port ?? 'unknown';
+ log(`Mongo[${port}]: ${msg}`, ...extra);
+ }
+ /**
+ * Find a new unlocked port
+ * @param port A User defined default port
+ */
+ async getNewPort(port) {
+ const newPort = await (0, getport_1.getFreePort)(port);
+ // only log this message if a custom port was provided
+ if (port != newPort && typeof port === 'number') {
+ this.debug(`getNewPort: starting with port "${newPort}", since "${port}" was locked`);
+ }
+ return newPort;
+ }
+ /**
+ * Construct Instance Starting Options
+ * @param forceSamePort Force to use the port defined in `options.instance` (disabled port generation)
+ */
+ async getStartOptions(forceSamePort = false) {
+ this.debug(`getStartOptions: forceSamePort: ${forceSamePort}`);
+ /** Shortcut to this.opts.instance */
+ const instOpts = this.opts.instance ?? {};
+ /**
+ * This variable is used for determining if "createAuth" should be run
+ */
+ let isNew = true;
+ const opts = await DryMongoBinary_1.DryMongoBinary.generateOptions(this.opts.binary);
+ let storageEngine = instOpts.storageEngine;
+ // try to convert a string to a valid semver, like "v6.0-latest" (compiles to "6.0.0")
+ // use "0.0.0" as a fallback to have a valid semver for later checks, but warn on invalid
+ const coercedVersion = semver.coerce(opts.version) ?? new semver.SemVer('0.0.0');
+ // warn on invalid version here, a invalid version will be thrown in MongoBinaryDownloadUrl if downloading
+ if (semver.eq(coercedVersion, '0.0.0')) {
+ console.warn(new errors_1.UnknownVersionError(opts.version));
+ }
+ storageEngine = (0, utils_1.getStorageEngine)(storageEngine, coercedVersion);
+ // use pre-defined port if available, otherwise generate a new port
+ let port = typeof instOpts.port === 'number' ? instOpts.port : undefined;
+ // if "forceSamePort" is not true, and get a available port
+ if (!forceSamePort || (0, utils_1.isNullOrUndefined)(port)) {
+ port = await this.getNewPort(port);
+ }
+ // consider directly using "this.opts.instance", to pass through all options, even if not defined in "StartupInstanceData"
+ const data = {
+ port: port,
+ dbName: (0, utils_1.generateDbName)(instOpts.dbName),
+ ip: instOpts.ip ?? '127.0.0.1',
+ storageEngine: storageEngine,
+ replSet: instOpts.replSet,
+ dbPath: instOpts.dbPath,
+ tmpDir: undefined,
+ keyfileLocation: instOpts.keyfileLocation,
+ launchTimeout: instOpts.launchTimeout,
+ };
+ if ((0, utils_1.isNullOrUndefined)(this._instanceInfo)) {
+ // create a tmpDir instance if no "dbPath" is given
+ if (!data.dbPath) {
+ data.tmpDir = await (0, utils_1.createTmpDir)('mongo-mem-');
+ data.dbPath = data.tmpDir;
+ isNew = true; // just to ensure "isNew" is "true" because a new temporary directory got created
+ }
+ else {
+ this.debug(`getStartOptions: Checking if "${data.dbPath}}" (no new tmpDir) already has data`);
+ const files = await fs_1.promises.readdir(data.dbPath);
+ isNew = files.length === 0; // if there are no files in the directory, assume that the database is new
+ }
+ }
+ else {
+ isNew = false;
+ }
+ const enableAuth = this.authObjectEnable();
+ const createAuth = enableAuth && // re-use all the checks from "enableAuth"
+ !(0, utils_1.isNullOrUndefined)(this.auth) && // needs to be re-checked because typescript complains
+ (this.auth.force || isNew) && // check that either "isNew" or "this.auth.force" is "true"
+ !instOpts.replSet; // dont run "createAuth" when its a replset, it will be run by the replset controller
+ return {
+ data: data,
+ createAuth: createAuth,
+ mongodOptions: {
+ instance: {
+ ...data,
+ args: instOpts.args,
+ auth: enableAuth,
+ },
+ binary: this.opts.binary,
+ spawn: this.opts.spawn,
+ },
+ };
+ }
+ /**
+ * Internal Function to start an instance
+ * @param forceSamePort Force to use the port defined in `options.instance` (disabled port generation)
+ * @private
+ */
+ async _startUpInstance(forceSamePort) {
+ this.debug('_startUpInstance: Called MongoMemoryServer._startUpInstance() method');
+ const useSamePort = forceSamePort ?? !(this.opts.instance?.portGeneration ?? true);
+ if (!(0, utils_1.isNullOrUndefined)(this._instanceInfo)) {
+ this.debug('_startUpInstance: "instanceInfo" already defined, reusing instance');
+ if (!useSamePort) {
+ const newPort = await this.getNewPort(this._instanceInfo.port);
+ this._instanceInfo.instance.instanceOpts.port = newPort;
+ this._instanceInfo.port = newPort;
+ }
+ await this._instanceInfo.instance.start();
+ return;
+ }
+ const { mongodOptions, createAuth, data } = await this.getStartOptions(useSamePort);
+ this.debug(`_startUpInstance: Creating new MongoDB instance with options:`, mongodOptions);
+ const instance = await MongoInstance_1.MongoInstance.create(mongodOptions);
+ this._instanceInfo = {
+ ...data,
+ dbPath: data.dbPath, // because otherwise the types would be incompatible
+ instance,
+ };
+ // log after "_instanceInfo" is set so that the port shows up in the message
+ this.debug(`_startUpInstance: Instance Started, createAuth: "${createAuth}"`);
+ // always set the "extraConnectionOptions" when "auth" is enabled, regardless of if "createAuth" gets run
+ if (this.authObjectEnable() &&
+ mongodOptions.instance?.auth === true &&
+ !(0, utils_1.isNullOrUndefined)(this.auth) // extra check again for typescript, because it cant reuse checks from "enableAuth" yet
+ ) {
+ instance.extraConnectionOptions = {
+ authSource: 'admin',
+ authMechanism: 'SCRAM-SHA-256',
+ auth: {
+ username: this.auth.customRootName,
+ password: this.auth.customRootPwd,
+ },
+ };
+ }
+ // "isNullOrUndefined" because otherwise typescript complains about "this.auth" possibly being not defined
+ if (!(0, utils_1.isNullOrUndefined)(this.auth) && createAuth) {
+ this.debug(`_startUpInstance: Running "createAuth" (force: "${this.auth.force}")`);
+ await this.createAuth(data);
+ }
+ }
+ /**
+ * Stop the current In-Memory Instance
+ * @param cleanupOptions Set how to run ".cleanup", by default only `{ doCleanup: true }` is used
+ */
+ async stop(cleanupOptions) {
+ this.debug('stop: Called .stop() method');
+ /** Default to cleanup temporary, but not custom dbpaths */
+ let cleanup = { doCleanup: true, force: false };
+ // handle the new way of setting what and how to cleanup
+ if (typeof cleanupOptions === 'object') {
+ cleanup = cleanupOptions;
+ }
+ // just return "true" if there was never an instance
+ if ((0, utils_1.isNullOrUndefined)(this._instanceInfo)) {
+ this.debug('stop: "instanceInfo" is not defined (never ran?)');
+ return false;
+ }
+ if (this._state === MongoMemoryServerStates.stopped) {
+ this.debug('stop: state is "stopped", trying to stop / kill anyway');
+ }
+ this.debug(`stop: Stopping MongoDB server on port ${this._instanceInfo.port} with pid ${this._instanceInfo.instance?.mongodProcess?.pid}` // "undefined" would say more than ""
+ );
+ await this._instanceInfo.instance.stop();
+ this.stateChange(MongoMemoryServerStates.stopped);
+ if (cleanup.doCleanup) {
+ await this.cleanup(cleanup);
+ }
+ return true;
+ }
+ /**
+ * Remove the defined dbPath
+ * @param options Set how to run a cleanup, by default `{ doCleanup: true }` is used
+ * @throws If "state" is not "stopped"
+ * @throws If "instanceInfo" is not defined
+ * @throws If an fs error occured
+ */
+ async cleanup(options) {
+ assertionIsMMSState(MongoMemoryServerStates.stopped, this.state);
+ /** Default to doing cleanup, but not forcing it */
+ let cleanup = { doCleanup: true, force: false };
+ // handle the new way of setting what and how to cleanup
+ if (typeof options === 'object') {
+ cleanup = options;
+ }
+ this.debug(`cleanup:`, cleanup);
+ // dont do cleanup, if "doCleanup" is false
+ if (!cleanup.doCleanup) {
+ this.debug('cleanup: "doCleanup" is set to false');
+ return;
+ }
+ if ((0, utils_1.isNullOrUndefined)(this._instanceInfo)) {
+ this.debug('cleanup: "instanceInfo" is undefined');
+ return;
+ }
+ (0, utils_1.assertion)((0, utils_1.isNullOrUndefined)(this._instanceInfo.instance.mongodProcess), new Error('Cannot cleanup because "instance.mongodProcess" is still defined'));
+ const tmpDir = this._instanceInfo.tmpDir;
+ if (!(0, utils_1.isNullOrUndefined)(tmpDir)) {
+ this.debug(`cleanup: removing tmpDir at ${tmpDir}`);
+ await (0, utils_1.removeDir)(tmpDir);
+ }
+ if (cleanup.force) {
+ const dbPath = this._instanceInfo.dbPath;
+ const res = await (0, utils_1.statPath)(dbPath);
+ if ((0, utils_1.isNullOrUndefined)(res)) {
+ this.debug(`cleanup: force is true, but path "${dbPath}" dosnt exist anymore`);
+ }
+ else {
+ (0, utils_1.assertion)(res.isDirectory(), new Error('Defined dbPath is not a directory'));
+ await (0, utils_1.removeDir)(dbPath);
+ }
+ }
+ this.stateChange(MongoMemoryServerStates.new); // reset "state" to new, because the dbPath got removed
+ this._instanceInfo = undefined;
+ }
+ /**
+ * Get Information about the currently running instance, if it is not running it returns "undefined"
+ */
+ get instanceInfo() {
+ return this._instanceInfo;
+ }
+ /**
+ * Get Current state of this class
+ */
+ get state() {
+ return this._state;
+ }
+ /**
+ * Ensure that the instance is running
+ * -> throws if instance cannot be started
+ */
+ async ensureInstance() {
+ this.debug('ensureInstance: Called .ensureInstance() method');
+ switch (this._state) {
+ case MongoMemoryServerStates.running:
+ if (this._instanceInfo) {
+ return this._instanceInfo;
+ }
+ throw new errors_1.InstanceInfoError('MongoMemoryServer.ensureInstance (state: running)');
+ case MongoMemoryServerStates.new:
+ case MongoMemoryServerStates.stopped:
+ break;
+ case MongoMemoryServerStates.starting:
+ return new Promise((res, rej) => this.once(MongoMemoryServerEvents.stateChange, (state) => {
+ if (state != MongoMemoryServerStates.running) {
+ rej(new Error(`"ensureInstance" waited for "running" but got a different state: "${state}"`));
+ return;
+ }
+ // this assertion is mainly for types (typescript otherwise would complain that "_instanceInfo" might be "undefined")
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(this._instanceInfo), new Error('InstanceInfo is undefined!'));
+ res(this._instanceInfo);
+ }));
+ default:
+ throw new errors_1.StateError([
+ MongoMemoryServerStates.running,
+ MongoMemoryServerStates.new,
+ MongoMemoryServerStates.stopped,
+ MongoMemoryServerStates.starting,
+ ], this.state);
+ }
+ this.debug('ensureInstance: no running instance, calling "start()" command');
+ await this.start();
+ this.debug('ensureInstance: "start()" command was succesfully resolved');
+ // check again for 1. Typescript-type reasons and 2. if .start failed to throw an error
+ (0, utils_1.assertion)(!!this._instanceInfo, new errors_1.InstanceInfoError('MongoMemoryServer.ensureInstance (after starting)'));
+ return this._instanceInfo;
+ }
+ /**
+ * Generate the Connection string used by mongodb
+ * @param otherDb add a database into the uri (in mongodb its the auth database, in mongoose its the default database for models)
+ * @param otherIp change the ip in the generated uri, default will otherwise always be "127.0.0.1"
+ * @throws if state is not "running" (or "starting")
+ * @throws if a server doesnt have "instanceInfo.port" defined
+ * @returns a valid mongo URI, by the definition of https://docs.mongodb.com/manual/reference/connection-string/
+ */
+ getUri(otherDb, otherIp) {
+ this.debug('getUri:', this.state, otherDb, otherIp);
+ switch (this.state) {
+ case MongoMemoryServerStates.running:
+ case MongoMemoryServerStates.starting:
+ break;
+ case MongoMemoryServerStates.stopped:
+ default:
+ throw new errors_1.StateError([MongoMemoryServerStates.running, MongoMemoryServerStates.starting], this.state);
+ }
+ assertionInstanceInfo(this._instanceInfo);
+ return (0, utils_1.uriTemplate)(otherIp || '127.0.0.1', this._instanceInfo.port, (0, utils_1.generateDbName)(otherDb));
+ }
+ /**
+ * Create the Root user and additional users using the [localhost exception](https://www.mongodb.com/docs/manual/core/localhost-exception/#std-label-localhost-exception)
+ * This Function assumes "this.opts.auth" is already processed into "this.auth"
+ * @param data Used to get "ip" and "port"
+ * @internal
+ */
+ async createAuth(data) {
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(this.auth), new Error('"createAuth" got called, but "this.auth" is undefined!'));
+ assertionInstanceInfo(this._instanceInfo);
+ this.debug('createAuth: options:', this.auth);
+ let con = await mongodb_1.MongoClient.connect((0, utils_1.uriTemplate)(data.ip, data.port, 'admin'));
+ try {
+ let db = con.db('admin'); // just to ensure it is actually the "admin" database AND to have the "Db" data
+ // Create the root user
+ this.debug(`createAuth: Creating Root user, name: "${this.auth.customRootName}"`);
+ await db.command({
+ createUser: this.auth.customRootName,
+ pwd: this.auth.customRootPwd,
+ mechanisms: ['SCRAM-SHA-256'],
+ customData: {
+ createdBy: 'mongodb-memory-server',
+ as: 'ROOTUSER',
+ },
+ roles: ['root'],
+ // "writeConcern" is needced, otherwise replset servers might fail with "auth failed: such user does not exist"
+ writeConcern: {
+ w: 'majority',
+ },
+ });
+ if (this.auth.extraUsers.length > 0) {
+ this.debug(`createAuth: Creating "${this.auth.extraUsers.length}" Custom Users`);
+ this.auth.extraUsers.sort((a, b) => {
+ if (a.database === 'admin') {
+ return -1; // try to make all "admin" at the start of the array
+ }
+ return a.database === b.database ? 0 : 1; // "0" to sort all databases that are the same after each other, and "1" to for pushing it back
+ });
+ // reconnecting the database because the root user now exists and the "localhost exception" only allows the first user
+ await con.close();
+ con = await mongodb_1.MongoClient.connect(this.getUri('admin'), this._instanceInfo.instance.extraConnectionOptions ?? {});
+ db = con.db('admin');
+ for (const user of this.auth.extraUsers) {
+ user.database = (0, utils_1.isNullOrUndefined)(user.database) ? 'admin' : user.database;
+ // just to have not to call "con.db" everytime in the loop if its the same
+ if (user.database !== db.databaseName) {
+ db = con.db(user.database);
+ }
+ this.debug('createAuth: Creating User: ', user);
+ await db.command({
+ createUser: user.createUser,
+ pwd: user.pwd,
+ customData: {
+ ...user.customData,
+ createdBy: 'mongodb-memory-server',
+ as: 'EXTRAUSER',
+ },
+ roles: user.roles,
+ authenticationRestrictions: user.authenticationRestrictions ?? [],
+ mechanisms: user.mechanisms ?? ['SCRAM-SHA-256'],
+ digestPassword: user.digestPassword ?? true,
+ // "writeConcern" is needced, otherwise replset servers might fail with "auth failed: such user does not exist"
+ writeConcern: {
+ w: 'majority',
+ },
+ });
+ }
+ }
+ }
+ finally {
+ // close connection in any case (even if throwing a error or being successfull)
+ await con.close();
+ }
+ }
+ /**
+ * Helper function to determine if the "auth" object is set and not to be disabled
+ * This function expectes to be run after the auth object has been transformed to a object
+ * @returns "true" when "auth" should be enabled
+ */
+ authObjectEnable() {
+ if ((0, utils_1.isNullOrUndefined)(this.auth)) {
+ return false;
+ }
+ return typeof this.auth.enable === 'boolean' // if "this._replSetOpts.auth.enable" is defined, use that
+ ? this.auth.enable
+ : false; // if "this._replSetOpts.auth.enable" is not defined, default to false
+ }
+ // Symbol for "Explicit Resource Management"
+ async [Symbol.asyncDispose]() {
+ if (this.opts.dispose?.enabled ?? true) {
+ await this.stop(this.opts.dispose?.cleanup);
+ }
+ }
+}
+exports.MongoMemoryServer = MongoMemoryServer;
+exports.default = MongoMemoryServer;
+/**
+ * This function is to de-duplicate code
+ * -> this couldnt be included in the class, because "asserts this.instanceInfo" is not allowed
+ * @param val this.instanceInfo
+ */
+function assertionInstanceInfo(val) {
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(val), new Error('"instanceInfo" is undefined'));
+}
+/**
+ * Helper function to de-duplicate state checking for "MongoMemoryServerStates"
+ * @param wantedState The State that is wanted
+ * @param currentState The current State ("this._state")
+ */
+function assertionIsMMSState(wantedState, currentState) {
+ (0, utils_1.assertion)(currentState === wantedState, new errors_1.StateError([wantedState], currentState));
+}
+//# sourceMappingURL=MongoMemoryServer.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/MongoMemoryServer.js.map b/packages/mongodb-memory-server-core/lib/MongoMemoryServer.js.map
new file mode 100644
index 000000000..bf17f04c3
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/MongoMemoryServer.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoMemoryServer.js","sourceRoot":"","sources":["../src/MongoMemoryServer.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/index.d.ts b/packages/mongodb-memory-server-core/lib/index.d.ts
new file mode 100644
index 000000000..2520bc98c
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/index.d.ts
@@ -0,0 +1,10 @@
+import './util/resolveConfig';
+import { MongoMemoryServer } from './MongoMemoryServer';
+export { DryMongoBinary } from './util/DryMongoBinary';
+export { MongoBinary } from './util/MongoBinary';
+export { MongoInstance } from './util/MongoInstance';
+export { MongoMemoryReplSet } from './MongoMemoryReplSet';
+export * as errors from './util/errors';
+export { MongoMemoryServer };
+export default MongoMemoryServer;
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/index.d.ts.map b/packages/mongodb-memory-server-core/lib/index.d.ts.map
new file mode 100644
index 000000000..a54ac0a18
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/index.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAC7B,eAAe,iBAAiB,CAAC"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/index.js b/packages/mongodb-memory-server-core/lib/index.js
new file mode 100644
index 000000000..165d86142
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/index.js
@@ -0,0 +1,18 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MongoMemoryServer = exports.errors = exports.MongoMemoryReplSet = exports.MongoInstance = exports.MongoBinary = exports.DryMongoBinary = void 0;
+const tslib_1 = require("tslib");
+require("./util/resolveConfig"); // import it for the side-effects (globals)
+const MongoMemoryServer_1 = require("./MongoMemoryServer");
+Object.defineProperty(exports, "MongoMemoryServer", { enumerable: true, get: function () { return MongoMemoryServer_1.MongoMemoryServer; } });
+var DryMongoBinary_1 = require("./util/DryMongoBinary");
+Object.defineProperty(exports, "DryMongoBinary", { enumerable: true, get: function () { return DryMongoBinary_1.DryMongoBinary; } });
+var MongoBinary_1 = require("./util/MongoBinary");
+Object.defineProperty(exports, "MongoBinary", { enumerable: true, get: function () { return MongoBinary_1.MongoBinary; } });
+var MongoInstance_1 = require("./util/MongoInstance");
+Object.defineProperty(exports, "MongoInstance", { enumerable: true, get: function () { return MongoInstance_1.MongoInstance; } });
+var MongoMemoryReplSet_1 = require("./MongoMemoryReplSet");
+Object.defineProperty(exports, "MongoMemoryReplSet", { enumerable: true, get: function () { return MongoMemoryReplSet_1.MongoMemoryReplSet; } });
+exports.errors = tslib_1.__importStar(require("./util/errors"));
+exports.default = MongoMemoryServer_1.MongoMemoryServer;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/index.js.map b/packages/mongodb-memory-server-core/lib/index.js.map
new file mode 100644
index 000000000..f5c6c2bd1
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,gCAA8B,CAAC,2CAA2C;AAC1E,2DAAwD;AAQ/C,kGARA,qCAAiB,OAQA;AAN1B,wDAAuD;AAA9C,gHAAA,cAAc,OAAA;AACvB,kDAAiD;AAAxC,0GAAA,WAAW,OAAA;AACpB,sDAAqD;AAA5C,8GAAA,aAAa,OAAA;AACtB,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA;AAC3B,gEAAwC;AAGxC,kBAAe,qCAAiB,CAAC"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.d.ts b/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.d.ts
new file mode 100644
index 000000000..112c575a6
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.d.ts
@@ -0,0 +1,105 @@
+import { AnyOS } from './getos';
+/** Interface for general options required to pass-around (all optional) */
+export interface BaseDryMongoBinaryOptions {
+ version?: string;
+ downloadDir?: string;
+ os?: AnyOS;
+ arch?: string;
+ platform?: string;
+ systemBinary?: string;
+}
+/** Interface for general options required to pass-aroung (version not optional) */
+export interface DryMongoBinaryOptions extends BaseDryMongoBinaryOptions {
+ version: NonNullable;
+}
+/** Interface for the options arguments in function "DryMongoBinary.getBinaryName" */
+export interface DryMongoBinaryNameOptions {
+ version: NonNullable;
+ arch: NonNullable;
+ platform: NonNullable;
+ os: NonNullable;
+}
+/** Interface to store all generated Paths that would be possible a binary would be in */
+export interface DryMongoBinaryPaths {
+ /** Path from `DOWNLOAD_DIR` config option */
+ resolveConfig: string;
+ /** Path for "~/.config/" (user home) */
+ homeCache: string;
+ /** Path for "PROJECT/node_modules/.cache/" (project local cache) */
+ modulesCache: string;
+ /** Path for relative to CWD "CWD/" (relative CWD path) */
+ relative: string;
+}
+/**
+ * Interface for "DryMongoBinary.parseArchiveNameRegex"'s regex groups
+ */
+export interface DryMongoBinaryArchiveRegexGroups {
+ platform?: string;
+ arch?: string;
+ dist?: string;
+ version?: string;
+}
+/**
+ * Locate an Binary, without downloading / locking
+ */
+export declare class DryMongoBinary {
+ /**
+ * Binaries already found, values are: [Version, Path]
+ */
+ static binaryCache: Map;
+ /**
+ * Try to locate an existing binary
+ * @returns The Path to an Binary Found, or undefined
+ */
+ static locateBinary(opts: DryMongoBinaryOptions): Promise;
+ /**
+ * Ensure the given options fulfill {@link DryMongoBinaryOptions} by defaulting them
+ * @param opts The options to ensure
+ * @returns The ensured options
+ */
+ static getEnsuredOptions(opts?: BaseDryMongoBinaryOptions): DryMongoBinaryOptions;
+ /**
+ * Generate All required options for the binary name / path generation
+ */
+ static generateOptions(opts?: BaseDryMongoBinaryOptions): Promise>;
+ /**
+ * Parse "input" into DryMongoBinaryOptions
+ * @param input The Input to be parsed with the regex
+ * @param opts The Options which will be augmented with "input"
+ * @returns The Augmented options
+ */
+ static parseArchiveNameRegex(input: string, opts: Required): Required;
+ /**
+ * Get the full path with filename
+ * @returns Absoulte Path with FileName
+ */
+ static getBinaryName(opts: DryMongoBinaryNameOptions): Promise;
+ /**
+ * Combine basePath with binaryName
+ */
+ static combineBinaryName(basePath: string, binaryName: string): string;
+ /**
+ * Probe if the provided "systemBinary" is an existing path
+ * @param systemBinary The Path to probe for an System-Binary
+ * @returns System Binary path or undefined
+ */
+ static getSystemPath(systemBinary: string): Promise;
+ /**
+ * Generate an "MongoBinaryPaths" object
+ *
+ * This Function should not hit the FileSystem
+ * @returns an finished "MongoBinaryPaths" object
+ */
+ static generatePaths(opts: DryMongoBinaryOptions & DryMongoBinaryNameOptions): Promise;
+ /**
+ * Generate the Path where an Binary will be located
+ * @returns "boolean" indicating if the binary exists at the provided path, and "string" the path to use for the binary
+ */
+ static generateDownloadPath(opts: DryMongoBinaryOptions & DryMongoBinaryNameOptions): Promise<[boolean, string]>;
+ /**
+ * This function is used, because jest just dosnt want "os.homedir" to be mocked
+ * if someone can find an way to actually mock this in an test, please change it
+ */
+ private static homedir;
+}
+//# sourceMappingURL=DryMongoBinary.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.d.ts.map b/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.d.ts.map
new file mode 100644
index 000000000..127757ffc
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"DryMongoBinary.d.ts","sourceRoot":"","sources":["../../src/util/DryMongoBinary.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAS,KAAK,EAAsB,MAAM,SAAS,CAAC;AAM3D,2EAA2E;AAC3E,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,KAAK,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,mFAAmF;AACnF,MAAM,WAAW,qBAAsB,SAAQ,yBAAyB;IACtE,OAAO,EAAE,WAAW,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC,CAAC;CAC5D;AAED,qFAAqF;AACrF,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,WAAW,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC;IACvD,IAAI,EAAE,WAAW,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,QAAQ,EAAE,WAAW,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,CAAC;IACxD,EAAE,EAAE,WAAW,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;CAC9C;AAED,yFAAyF;AACzF,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB;;OAEG;IACH,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAa;IAEpD;;;OAGG;WACU,YAAY,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAkDnF;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,yBAAyB,GAAG,qBAAqB;IAQjF;;OAEG;WACU,eAAe,CAC1B,IAAI,CAAC,EAAE,yBAAyB,GAC/B,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IAqC3C;;;;;OAKG;IACH,MAAM,CAAC,qBAAqB,CAC1B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GACpC,QAAQ,CAAC,qBAAqB,CAAC;IAgDlC;;;OAGG;WACU,aAAa,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkB5E;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAMtE;;;;OAIG;WACU,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAmB7E;;;;;OAKG;WACU,aAAa,CACxB,IAAI,EAAE,qBAAqB,GAAG,yBAAyB,GACtD,OAAO,CAAC,mBAAmB,CAAC;IAyD/B;;;OAGG;WACU,oBAAoB,CAC/B,IAAI,EAAE,qBAAqB,GAAG,yBAAyB,GACtD,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAiE7B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,OAAO;CAGvB"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.js b/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.js
new file mode 100644
index 000000000..79e4d22f7
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.js
@@ -0,0 +1,281 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.DryMongoBinary = void 0;
+const tslib_1 = require("tslib");
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const resolveConfig_1 = require("./resolveConfig");
+const utils_1 = require("./utils");
+const path = tslib_1.__importStar(require("path"));
+const os_1 = require("os");
+const find_cache_dir_1 = tslib_1.__importDefault(require("find-cache-dir"));
+const getos_1 = require("./getos");
+const errors_1 = require("./errors");
+const MongoBinaryDownloadUrl_1 = require("./MongoBinaryDownloadUrl");
+const log = (0, debug_1.default)('MongoMS:DryMongoBinary');
+/**
+ * Locate an Binary, without downloading / locking
+ */
+class DryMongoBinary {
+ /**
+ * Try to locate an existing binary
+ * @returns The Path to an Binary Found, or undefined
+ */
+ static async locateBinary(opts) {
+ log(`locateBinary: Trying to locate Binary for version "${opts.version}"`);
+ const useOpts = await this.generateOptions(opts);
+ if (!!useOpts.systemBinary) {
+ log(`locateBinary: env "SYSTEM_BINARY" was provided with value: "${useOpts.systemBinary}"`);
+ const systemReturn = await this.getSystemPath(path.resolve(useOpts.systemBinary));
+ if ((0, utils_1.isNullOrUndefined)(systemReturn)) {
+ throw new errors_1.BinaryNotFoundError(useOpts.systemBinary, ' (systemBinary)');
+ }
+ return systemReturn;
+ }
+ if (this.binaryCache.has(opts.version)) {
+ const binary = this.binaryCache.get(opts.version);
+ log(`locateBinary: Requested Version found in cache: "[${opts.version}, ${binary}]"`);
+ return binary;
+ }
+ log('locateBinary: running generateDownloadPath');
+ const returnValue = await this.generateDownloadPath(useOpts);
+ if (!returnValue[0]) {
+ log('locateBinary: could not find a existing binary');
+ return undefined;
+ }
+ // check for the race-condition of "extraction started, but not finished"
+ // or said differently, the file "exists" but is not fully extracted yet
+ // see https://github.com/typegoose/mongodb-memory-server/issues/872
+ if (returnValue[0] &&
+ (await (0, utils_1.pathExists)((0, utils_1.lockfilePath)(path.dirname(returnValue[1]), useOpts.version)))) {
+ log('locateBinary: binary found, but also a download-lock, trying to resolve lock');
+ return undefined;
+ }
+ log(`locateBinary: found binary at "${returnValue[1]}"`);
+ this.binaryCache.set(opts.version, returnValue[1]);
+ return returnValue[1];
+ }
+ /**
+ * Ensure the given options fulfill {@link DryMongoBinaryOptions} by defaulting them
+ * @param opts The options to ensure
+ * @returns The ensured options
+ */
+ static getEnsuredOptions(opts) {
+ const defaultVersion = (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.VERSION) ?? resolveConfig_1.DEFAULT_VERSION;
+ return (0, utils_1.isNullOrUndefined)(opts)
+ ? { version: defaultVersion }
+ : { ...opts, version: opts.version || defaultVersion };
+ }
+ /**
+ * Generate All required options for the binary name / path generation
+ */
+ static async generateOptions(opts) {
+ log('generateOptions');
+ const ensuredOpts = DryMongoBinary.getEnsuredOptions(opts);
+ const final = {
+ version: ensuredOpts.version,
+ downloadDir: (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_DIR) || ensuredOpts.downloadDir || '',
+ os: ensuredOpts.os ?? (await (0, getos_1.getOS)()),
+ platform: ensuredOpts.platform || (0, os_1.platform)(),
+ arch: ensuredOpts.arch || (0, os_1.arch)(),
+ systemBinary: (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.SYSTEM_BINARY) || ensuredOpts.systemBinary || '',
+ };
+ final.downloadDir = path.dirname((await this.generateDownloadPath(final))[1]);
+ // if truthy
+ if ((0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.ARCHIVE_NAME) ||
+ (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_URL)) {
+ // "DOWNLOAD_URL" will be used over "ARCHIVE_NAME"
+ // the "as string" cast is there because it is already checked that one of the 2 exists, and "resolveConfig" ensures it only returns strings
+ const input = ((0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_URL) ||
+ (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.ARCHIVE_NAME));
+ log(`generateOptions: ARCHIVE_NAME or DOWNLOAD_URL defined, generating options based on that (input: "${input}")`);
+ return this.parseArchiveNameRegex(input, final);
+ }
+ return final;
+ }
+ /**
+ * Parse "input" into DryMongoBinaryOptions
+ * @param input The Input to be parsed with the regex
+ * @param opts The Options which will be augmented with "input"
+ * @returns The Augmented options
+ */
+ static parseArchiveNameRegex(input, opts) {
+ log(`parseArchiveNameRegex (input: "${input}")`);
+ const archiveMatches = /mongodb-(?linux|win32|osx|macos)(?:-ssl-|-)(?\w{4,})(?:-(?\w+)|)(?:-ssl-|-)(?:v|)(?[\d.]+(?:-latest|))\./gim.exec(input);
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(archiveMatches), new errors_1.NoRegexMatchError('input'));
+ // this error is kinda impossible to test, because the regex we use either has matches that are groups or no matches
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(archiveMatches.groups), new errors_1.NoRegexMatchError('input', 'groups'));
+ const groups = archiveMatches.groups;
+ (0, utils_1.assertion)(typeof groups.version === 'string' && groups.version.length > 1, new errors_1.ParseArchiveRegexError('version'));
+ // the following 2 assertions are hard to test, because the regex has restrictions that are more strict than the assertions
+ (0, utils_1.assertion)(typeof groups.platform === 'string' && groups.platform.length > 1, new errors_1.ParseArchiveRegexError('platform'));
+ (0, utils_1.assertion)(typeof groups.arch === 'string' && groups.arch.length >= 4, new errors_1.ParseArchiveRegexError('arch'));
+ opts.version = groups.version;
+ opts.arch = groups.arch;
+ if (groups.platform === 'linux') {
+ const distMatches = !!groups.dist ? /([a-z]+)(\d*)/gim.exec(groups.dist) : null;
+ opts.os = {
+ os: 'linux',
+ dist: typeof distMatches?.[1] === 'string' ? distMatches[1] : 'unknown',
+ // "release" should be able to be discarded in this case
+ release: '',
+ };
+ }
+ else {
+ opts.os = { os: groups.platform };
+ }
+ return opts;
+ }
+ /**
+ * Get the full path with filename
+ * @returns Absoulte Path with FileName
+ */
+ static async getBinaryName(opts) {
+ log('getBinaryName');
+ let binaryName;
+ if ((0, resolveConfig_1.envToBool)((0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.USE_ARCHIVE_NAME_FOR_BINARY_NAME))) {
+ const archiveName = await new MongoBinaryDownloadUrl_1.MongoBinaryDownloadUrl(opts).getArchiveName();
+ binaryName = path.parse(archiveName).name;
+ }
+ else {
+ const addExe = opts.platform === 'win32' ? '.exe' : '';
+ const dist = (0, getos_1.isLinuxOS)(opts.os) ? opts.os.dist : opts.os.os;
+ binaryName = `mongod-${opts.arch}-${dist}-${opts.version}${addExe}`;
+ }
+ return binaryName;
+ }
+ /**
+ * Combine basePath with binaryName
+ */
+ static combineBinaryName(basePath, binaryName) {
+ log('combineBinaryName');
+ return path.resolve(basePath, binaryName);
+ }
+ /**
+ * Probe if the provided "systemBinary" is an existing path
+ * @param systemBinary The Path to probe for an System-Binary
+ * @returns System Binary path or undefined
+ */
+ static async getSystemPath(systemBinary) {
+ log('getSystempath');
+ try {
+ await (0, utils_1.checkBinaryPermissions)(systemBinary);
+ log(`getSystemPath: found system binary path at "${systemBinary}"`);
+ return systemBinary; // returns if "access" is successful
+ }
+ catch (err) {
+ log(`getSystemPath: can't find system binary at "${systemBinary}".\n${err instanceof Error ? err.message : err}`);
+ }
+ return undefined;
+ }
+ /**
+ * Generate an "MongoBinaryPaths" object
+ *
+ * This Function should not hit the FileSystem
+ * @returns an finished "MongoBinaryPaths" object
+ */
+ static async generatePaths(opts) {
+ log('generatePaths', opts);
+ const final = {
+ homeCache: '',
+ modulesCache: '',
+ relative: '',
+ resolveConfig: '',
+ };
+ const binaryName = await this.getBinaryName(opts);
+ // Assign "node_modules/.cache" to modulesCache
+ // if we're in postinstall script, npm will set the cwd too deep
+ // when in postinstall, npm will provide an "INIT_CWD" env variable
+ let nodeModulesDLDir = process.env['INIT_CWD'] || process.cwd();
+ // as long as "node_modules/mongodb-memory-server*" is included in the path, go the paths up
+ while (nodeModulesDLDir.includes(`node_modules${path.sep}mongodb-memory-server`)) {
+ nodeModulesDLDir = path.resolve(nodeModulesDLDir, '..', '..');
+ }
+ const configPackagePath = (0, resolveConfig_1.packageJsonPath)();
+ // use the same "node_modules/.cache" as the package.json that was found for config options, if available
+ if (configPackagePath && (await (0, utils_1.pathExists)(path.resolve(configPackagePath, 'node_modules')))) {
+ nodeModulesDLDir = configPackagePath;
+ }
+ const tmpModulesCache = (0, find_cache_dir_1.default)({
+ name: 'mongodb-memory-server',
+ cwd: nodeModulesDLDir,
+ });
+ if (!(0, utils_1.isNullOrUndefined)(tmpModulesCache)) {
+ final.modulesCache = this.combineBinaryName(path.resolve(tmpModulesCache), binaryName);
+ }
+ const homeCache = path.resolve(this.homedir(), '.cache/mongodb-binaries');
+ final.homeCache = this.combineBinaryName(homeCache, binaryName);
+ // Resolve the config value "DOWNLOAD_DIR" if provided, otherwise remove from list
+ const resolveConfigValue = opts.downloadDir || (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_DIR);
+ if (!(0, utils_1.isNullOrUndefined)(resolveConfigValue) && resolveConfigValue.length > 0) {
+ log(`generatePaths: resolveConfigValue is not empty`);
+ final.resolveConfig = this.combineBinaryName(resolveConfigValue, binaryName);
+ }
+ // Resolve relative to cwd if no other has been found
+ final.relative = this.combineBinaryName(path.resolve(process.cwd(), 'mongodb-binaries'), binaryName);
+ return final;
+ }
+ /**
+ * Generate the Path where an Binary will be located
+ * @returns "boolean" indicating if the binary exists at the provided path, and "string" the path to use for the binary
+ */
+ static async generateDownloadPath(opts) {
+ const preferGlobal = (0, resolveConfig_1.envToBool)((0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.PREFER_GLOBAL_PATH));
+ log(`generateDownloadPath: Generating Download Path, preferGlobal: "${preferGlobal}"`);
+ const paths = await this.generatePaths(opts);
+ log('generateDownloadPath: Paths:', paths, opts.systemBinary);
+ // SystemBinary will only be returned if defined and paths exists
+ if (!!opts.systemBinary && (await (0, utils_1.pathExists)(opts.systemBinary))) {
+ const sysPath = await this.getSystemPath(opts.systemBinary);
+ if (!(0, utils_1.isNullOrUndefined)(sysPath)) {
+ return [true, sysPath];
+ }
+ }
+ // Section where paths are probed for an existing binary
+ if (await (0, utils_1.pathExists)(paths.resolveConfig)) {
+ log(`generateDownloadPath: Found binary in resolveConfig (DOWNLOAD_DIR): "${paths.resolveConfig}"`);
+ return [true, paths.resolveConfig];
+ }
+ if (await (0, utils_1.pathExists)(paths.homeCache)) {
+ log(`generateDownloadPath: Found binary in homeCache: "${paths.homeCache}"`);
+ return [true, paths.homeCache];
+ }
+ if (await (0, utils_1.pathExists)(paths.modulesCache)) {
+ log(`generateDownloadPath: Found binary in modulesCache: "${paths.modulesCache}"`);
+ return [true, paths.modulesCache];
+ }
+ if (await (0, utils_1.pathExists)(paths.relative)) {
+ log(`generateDownloadPath: Found binary in relative: "${paths.relative}"`);
+ return [true, paths.relative];
+ }
+ // Section where binary path gets generated when no binary was found
+ log(`generateDownloadPath: no existing binary for version "${opts.version}" was found`);
+ if (paths.resolveConfig.length > 0) {
+ log(`generateDownloadPath: using resolveConfig (DOWNLOAD_DIR) "${paths.resolveConfig}"`);
+ return [false, paths.resolveConfig];
+ }
+ if (preferGlobal && !!paths.homeCache) {
+ log(`generateDownloadPath: using global (preferGlobal) "${paths.homeCache}"`);
+ return [false, paths.homeCache];
+ }
+ // this case may not happen, if somehow the cwd gets changed outside of "node_modules" reach
+ if (paths.modulesCache.length > 0) {
+ log(`generateDownloadPath: using modulesCache "${paths.modulesCache}"`);
+ return [false, paths.modulesCache];
+ }
+ log(`generateDownloadPath: using relative "${paths.relative}"`);
+ return [false, paths.relative];
+ }
+ /**
+ * This function is used, because jest just dosnt want "os.homedir" to be mocked
+ * if someone can find an way to actually mock this in an test, please change it
+ */
+ static homedir() {
+ return (0, os_1.homedir)();
+ }
+}
+exports.DryMongoBinary = DryMongoBinary;
+/**
+ * Binaries already found, values are: [Version, Path]
+ */
+DryMongoBinary.binaryCache = new Map();
+//# sourceMappingURL=DryMongoBinary.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.js.map b/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.js.map
new file mode 100644
index 000000000..9a5d3eea9
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/DryMongoBinary.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"DryMongoBinary.js","sourceRoot":"","sources":["../../src/util/DryMongoBinary.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinary.d.ts b/packages/mongodb-memory-server-core/lib/util/MongoBinary.d.ts
new file mode 100644
index 000000000..06d3da96d
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinary.d.ts
@@ -0,0 +1,24 @@
+import { BaseDryMongoBinaryOptions } from './DryMongoBinary';
+export interface MongoBinaryOpts extends BaseDryMongoBinaryOptions {
+ checkMD5?: boolean;
+}
+/**
+ * Class used to combine "DryMongoBinary" & "MongoBinaryDownload"
+ */
+export declare class MongoBinary {
+ /**
+ * Probe download path and download the binary
+ * @param options Options Configuring which binary to download and to which path
+ * @returns The BinaryPath the binary has been downloaded to
+ */
+ static download(options: Required): Promise;
+ /**
+ * Probe all supported paths for an binary and return the binary path
+ * @param opts Options configuring which binary to search for
+ * @throws {Error} if no valid BinaryPath has been found
+ * @returns The first found BinaryPath
+ */
+ static getPath(opts?: MongoBinaryOpts): Promise;
+}
+export default MongoBinary;
+//# sourceMappingURL=MongoBinary.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinary.d.ts.map b/packages/mongodb-memory-server-core/lib/util/MongoBinary.d.ts.map
new file mode 100644
index 000000000..057c80945
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinary.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoBinary.d.ts","sourceRoot":"","sources":["../../src/util/MongoBinary.ts"],"names":[],"mappings":"AAQA,OAAO,EAAkB,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAI7E,MAAM,WAAW,eAAgB,SAAQ,yBAAyB;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB;;;;OAIG;WACU,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAwC1E;;;;;OAKG;WACU,OAAO,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,MAAM,CAAC;CA6ElE;AAED,eAAe,WAAW,CAAC"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinary.js b/packages/mongodb-memory-server-core/lib/util/MongoBinary.js
new file mode 100644
index 000000000..307443b69
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinary.js
@@ -0,0 +1,121 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MongoBinary = void 0;
+const tslib_1 = require("tslib");
+const os_1 = tslib_1.__importDefault(require("os"));
+const MongoBinaryDownload_1 = tslib_1.__importDefault(require("./MongoBinaryDownload"));
+const resolveConfig_1 = tslib_1.__importStar(require("./resolveConfig"));
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const semver = tslib_1.__importStar(require("semver"));
+const utils_1 = require("./utils");
+const child_process_1 = require("child_process");
+const lockfile_1 = require("./lockfile");
+const DryMongoBinary_1 = require("./DryMongoBinary");
+const log = (0, debug_1.default)('MongoMS:MongoBinary');
+/**
+ * Class used to combine "DryMongoBinary" & "MongoBinaryDownload"
+ */
+class MongoBinary {
+ /**
+ * Probe download path and download the binary
+ * @param options Options Configuring which binary to download and to which path
+ * @returns The BinaryPath the binary has been downloaded to
+ */
+ static async download(options) {
+ log('download');
+ const { downloadDir, version } = options;
+ // create downloadDir
+ await (0, utils_1.mkdir)(downloadDir);
+ /** Lockfile path */
+ const lockfile = (0, utils_1.lockfilePath)(downloadDir, version);
+ log(`download: Waiting to acquire Download lock for file "${lockfile}"`);
+ // wait to get a lock
+ // downloading of binaries may be quite long procedure
+ // that's why we are using so big wait/stale periods
+ const lock = await lockfile_1.LockFile.lock(lockfile);
+ log('download: Download lock acquired');
+ // this is to ensure that the lockfile gets removed in case of an error
+ try {
+ // check cache if it got already added to the cache
+ if (!DryMongoBinary_1.DryMongoBinary.binaryCache.has(version)) {
+ log(`download: Adding version ${version} to cache`);
+ const downloader = new MongoBinaryDownload_1.default(options);
+ DryMongoBinary_1.DryMongoBinary.binaryCache.set(version, await downloader.getMongodPath());
+ }
+ }
+ finally {
+ log('download: Removing Download lock');
+ // remove lock
+ await lock.unlock();
+ log('download: Download lock removed');
+ }
+ const cachePath = DryMongoBinary_1.DryMongoBinary.binaryCache.get(version);
+ // ensure that "path" exists, so the return type does not change
+ (0, utils_1.assertion)(typeof cachePath === 'string', new Error(`No Cache Path for version "${version}" found (and download failed silently?)`));
+ return cachePath;
+ }
+ /**
+ * Probe all supported paths for an binary and return the binary path
+ * @param opts Options configuring which binary to search for
+ * @throws {Error} if no valid BinaryPath has been found
+ * @returns The first found BinaryPath
+ */
+ static async getPath(opts = {}) {
+ log('getPath');
+ // "||" is still used here, because it should default if the value is false-y (like an empty string)
+ const options = {
+ ...(await DryMongoBinary_1.DryMongoBinary.generateOptions(opts)),
+ platform: opts.platform || (0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.PLATFORM) || os_1.default.platform(),
+ checkMD5: opts.checkMD5 || (0, resolveConfig_1.envToBool)((0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.MD5_CHECK)),
+ };
+ log(`getPath: MongoBinary options:`, JSON.stringify(options, null, 2));
+ let binaryPath = await DryMongoBinary_1.DryMongoBinary.locateBinary(options);
+ // check if the system binary has the same version as requested
+ if (!!options.systemBinary) {
+ // this case should actually never be false, because if "SYSTEM_BINARY" is set, "locateBinary" will run "getSystemPath" which tests the path for permissions
+ if (!(0, utils_1.isNullOrUndefined)(binaryPath)) {
+ // dont warn if the versions dont match if "SYSTEM_BINARY_VERSION_CHECK" is false, but still test the binary if it is available to be executed
+ if ((0, resolveConfig_1.envToBool)((0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.SYSTEM_BINARY_VERSION_CHECK))) {
+ log(`getPath: Spawning binaryPath "${binaryPath}" to get version`);
+ const spawnOutput = (0, child_process_1.spawnSync)(binaryPath, ['--version'])
+ // NOTE: "stdout" seemingly can be "undefined", see https://github.com/typegoose/mongodb-memory-server/issues/742#issuecomment-2528284865
+ .stdout?.toString()
+ // this regex is to match the first line of the "mongod --version" output "db version v4.0.25" OR "db version v4.2.19-11-ge2f2736"
+ .match(/^\s*db\s+version\s+v?(\d+\.\d+\.\d+)(-\d*)?(-[a-zA-Z0-9].*)?\s*$/im);
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(spawnOutput), new Error('Couldnt find an version from system binary output!'));
+ log('getPath: Checking & Warning about version conflicts');
+ const binaryVersion = spawnOutput[1];
+ if (semver.neq(options.version, binaryVersion)) {
+ // we will log the version number of the system binary and the version requested so the user can see the difference
+ console.warn('getPath: MongoMemoryServer: Possible version conflict\n' +
+ ` SystemBinary version: "${binaryVersion}"\n` +
+ ` Requested version: "${options.version}"\n\n` +
+ ' Using SystemBinary!');
+ }
+ }
+ }
+ else {
+ throw new Error('Option "SYSTEM_BINARY" was set, but binaryPath was empty! (system binary could not be found?) [This Error should normally not be thrown, please report this]');
+ }
+ }
+ (0, utils_1.assertion)(typeof options.version === 'string', new Error('"MongoBinary.options.version" is not an string!'));
+ if (!binaryPath) {
+ if ((0, resolveConfig_1.envToBool)((0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.RUNTIME_DOWNLOAD))) {
+ log('getPath: "RUNTIME_DOWNLOAD" is "true", trying to download');
+ binaryPath = await this.download(options);
+ }
+ else {
+ log('getPath: "RUNTIME_DOWNLOAD" is "false", not downloading');
+ }
+ }
+ if (!binaryPath) {
+ const runtimeDownload = (0, resolveConfig_1.envToBool)((0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.RUNTIME_DOWNLOAD));
+ throw new Error(`MongoBinary.getPath: could not find an valid binary path! (Got: "${binaryPath}", RUNTIME_DOWNLOAD: "${runtimeDownload}")`);
+ }
+ log(`getPath: Mongod binary path: "${binaryPath}"`);
+ return binaryPath;
+ }
+}
+exports.MongoBinary = MongoBinary;
+exports.default = MongoBinary;
+//# sourceMappingURL=MongoBinary.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinary.js.map b/packages/mongodb-memory-server-core/lib/util/MongoBinary.js.map
new file mode 100644
index 000000000..2b2155dbf
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinary.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoBinary.js","sourceRoot":"","sources":["../../src/util/MongoBinary.ts"],"names":[],"mappings":";;;;AAAA,oDAAoB;AACpB,wFAAwD;AACxD,yEAAmF;AACnF,0DAA0B;AAC1B,uDAAiC;AACjC,mCAA4E;AAC5E,iDAA0C;AAC1C,yCAAsC;AACtC,qDAA6E;AAE7E,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,qBAAqB,CAAC,CAAC;AAMzC;;GAEG;AACH,MAAa,WAAW;IACtB;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAkC;QACtD,GAAG,CAAC,UAAU,CAAC,CAAC;QAChB,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QACzC,qBAAqB;QACrB,MAAM,IAAA,aAAK,EAAC,WAAW,CAAC,CAAC;QAEzB,oBAAoB;QACpB,MAAM,QAAQ,GAAG,IAAA,oBAAY,EAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACpD,GAAG,CAAC,wDAAwD,QAAQ,GAAG,CAAC,CAAC;QACzE,qBAAqB;QACrB,sDAAsD;QACtD,oDAAoD;QACpD,MAAM,IAAI,GAAG,MAAM,mBAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAExC,uEAAuE;QACvE,IAAI,CAAC;YACH,mDAAmD;YACnD,IAAI,CAAC,+BAAc,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7C,GAAG,CAAC,4BAA4B,OAAO,WAAW,CAAC,CAAC;gBACpD,MAAM,UAAU,GAAG,IAAI,6BAAmB,CAAC,OAAO,CAAC,CAAC;gBACpD,+BAAc,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,GAAG,CAAC,kCAAkC,CAAC,CAAC;YACxC,cAAc;YACd,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,GAAG,CAAC,iCAAiC,CAAC,CAAC;QACzC,CAAC;QAED,MAAM,SAAS,GAAG,+BAAc,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1D,gEAAgE;QAChE,IAAA,iBAAS,EACP,OAAO,SAAS,KAAK,QAAQ,EAC7B,IAAI,KAAK,CAAC,8BAA8B,OAAO,yCAAyC,CAAC,CAC1F,CAAC;QAEF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAwB,EAAE;QAC7C,GAAG,CAAC,SAAS,CAAC,CAAC;QAEf,oGAAoG;QACpG,MAAM,OAAO,GAA8B;YACzC,GAAG,CAAC,MAAM,+BAAc,CAAC,eAAe,CAAC,IAAiC,CAAC,CAAC;YAC5E,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAA,uBAAa,EAAC,sCAAsB,CAAC,QAAQ,CAAC,IAAI,YAAE,CAAC,QAAQ,EAAE;YAC1F,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAA,yBAAS,EAAC,IAAA,uBAAa,EAAC,sCAAsB,CAAC,SAAS,CAAC,CAAC;SACtF,CAAC;QAEF,GAAG,CAAC,+BAA+B,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEvE,IAAI,UAAU,GAAuB,MAAM,+BAAc,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAEhF,+DAA+D;QAC/D,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC3B,4JAA4J;YAC5J,IAAI,CAAC,IAAA,yBAAiB,EAAC,UAAU,CAAC,EAAE,CAAC;gBACnC,8IAA8I;gBAC9I,IAAI,IAAA,yBAAS,EAAC,IAAA,uBAAa,EAAC,sCAAsB,CAAC,2BAA2B,CAAC,CAAC,EAAE,CAAC;oBACjF,GAAG,CAAC,iCAAiC,UAAU,kBAAkB,CAAC,CAAC;oBACnE,MAAM,WAAW,GAAG,IAAA,yBAAS,EAAC,UAAU,EAAE,CAAC,WAAW,CAAC,CAAC;wBACtD,yIAAyI;yBACxI,MAAM,EAAE,QAAQ,EAAE;wBACnB,kIAAkI;yBACjI,KAAK,CAAC,oEAAoE,CAAC,CAAC;oBAE/E,IAAA,iBAAS,EACP,CAAC,IAAA,yBAAiB,EAAC,WAAW,CAAC,EAC/B,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAChE,CAAC;oBAEF,GAAG,CAAC,qDAAqD,CAAC,CAAC;oBAC3D,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;oBAErC,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC;wBAC/C,mHAAmH;wBACnH,OAAO,CAAC,IAAI,CACV,yDAAyD;4BACvD,4BAA4B,aAAa,KAAK;4BAC9C,4BAA4B,OAAO,CAAC,OAAO,OAAO;4BAClD,uBAAuB,CAC1B,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CACb,8JAA8J,CAC/J,CAAC;YACJ,CAAC;QACH,CAAC;QAED,IAAA,iBAAS,EACP,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EACnC,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAC7D,CAAC;QAEF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,IAAA,yBAAS,EAAC,IAAA,uBAAa,EAAC,sCAAsB,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;gBACtE,GAAG,CAAC,2DAA2D,CAAC,CAAC;gBACjE,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,yDAAyD,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QAED,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,eAAe,GAAG,IAAA,yBAAS,EAAC,IAAA,uBAAa,EAAC,sCAAsB,CAAC,gBAAgB,CAAC,CAAC,CAAC;YAC1F,MAAM,IAAI,KAAK,CACb,oEAAoE,UAAU,yBAAyB,eAAe,IAAI,CAC3H,CAAC;QACJ,CAAC;QAED,GAAG,CAAC,iCAAiC,UAAU,GAAG,CAAC,CAAC;QAEpD,OAAO,UAAU,CAAC;IACpB,CAAC;CACF;AAjID,kCAiIC;AAED,kBAAe,WAAW,CAAC"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.d.ts b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.d.ts
new file mode 100644
index 000000000..cc7849682
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.d.ts
@@ -0,0 +1,96 @@
+///
+///
+import { URL } from 'url';
+import { MongoBinaryOpts } from './MongoBinary';
+import { RequestOptions } from 'https';
+export interface MongoBinaryDownloadProgress {
+ current: number;
+ length: number;
+ totalMb: number;
+ lastPrintedAt: number;
+}
+/**
+ * Download and extract the "mongod" binary
+ */
+export declare class MongoBinaryDownload {
+ dlProgress: MongoBinaryDownloadProgress;
+ protected _downloadingUrl?: string;
+ /** These options are kind of raw, they are not run through DryMongoBinary.generateOptions */
+ binaryOpts: Required;
+ constructor(opts: MongoBinaryOpts);
+ /**
+ * Get the full path with filename
+ * @returns Absoulte Path with FileName
+ */
+ protected getPath(): Promise;
+ /**
+ * Get the path of the already downloaded "mongod" file
+ * otherwise download it and then return the path
+ */
+ getMongodPath(): Promise;
+ /**
+ * Download the MongoDB Archive and check it against an MD5
+ * @returns The MongoDB Archive location
+ */
+ startDownload(): Promise;
+ /**
+ * Download MD5 file and check it against the MongoDB Archive
+ * @param urlForReferenceMD5 URL to download the MD5
+ * @param mongoDBArchive The MongoDB Archive file location
+ *
+ * @returns {undefined} if "checkMD5" is falsey
+ * @returns {true} if the md5 check was successful
+ * @throws if the md5 check failed
+ */
+ makeMD5check(urlForReferenceMD5: string, mongoDBArchive: string): Promise;
+ /**
+ * Download file from downloadUrl
+ * @param downloadUrl URL to download a File
+ * @returns The Path to the downloaded archive file
+ */
+ download(downloadUrl: string): Promise;
+ /**
+ * Extract given Archive
+ * @param mongoDBArchive Archive location
+ * @returns extracted directory location
+ */
+ extract(mongoDBArchive: string): Promise;
+ /**
+ * Extract a .tar.gz archive
+ * @param mongoDBArchive Archive location
+ * @param extractPath Directory to extract to
+ * @param filter Method to determine which files to extract
+ */
+ extractTarGz(mongoDBArchive: string, extractPath: string, filter: (file: string) => boolean): Promise;
+ /**
+ * Extract a .zip archive
+ * @param mongoDBArchive Archive location
+ * @param extractPath Directory to extract to
+ * @param filter Method to determine which files to extract
+ */
+ extractZip(mongoDBArchive: string, extractPath: string, filter: (file: string) => boolean): Promise;
+ /**
+ * Download given httpOptions to tempDownloadLocation, then move it to downloadLocation
+ * @param url The URL to download the file from
+ * @param httpOptions The httpOptions directly passed to https.get
+ * @param downloadLocation The location the File should be after the download
+ * @param tempDownloadLocation The location the File should be while downloading
+ * @param maxRetries Maximum number of retries on download failure
+ * @param baseDelay Base delay in milliseconds for retrying the download
+ */
+ httpDownload(url: URL, httpOptions: RequestOptions, downloadLocation: string, tempDownloadLocation: string, maxRetries?: number, baseDelay?: number): Promise;
+ private attemptDownload;
+ /**
+ * Print the Download Progress to STDOUT
+ * @param chunk A chunk to get the length
+ */
+ printDownloadProgress(chunk: {
+ length: number;
+ }, forcePrint?: boolean): void;
+ /**
+ * Helper function to de-duplicate assigning "_downloadingUrl"
+ */
+ assignDownloadingURL(url: URL): string;
+}
+export default MongoBinaryDownload;
+//# sourceMappingURL=MongoBinaryDownload.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.d.ts.map b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.d.ts.map
new file mode 100644
index 000000000..fa70d09cf
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoBinaryDownload.d.ts","sourceRoot":"","sources":["../../src/util/MongoBinaryDownload.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAa1B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAOvC,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,UAAU,EAAE,2BAA2B,CAAC;IACxC,SAAS,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAEnC,6FAA6F;IAC7F,UAAU,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;gBAE1B,IAAI,EAAE,eAAe;IA2BjC;;;OAGG;cACa,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAS1C;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAqBtC;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAyBtC;;;;;;;;OAQG;IACG,YAAY,CAChB,kBAAkB,EAAE,MAAM,EAC1B,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAyB/B;;;;OAIG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuDpD;;;;OAIG;IACG,OAAO,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCtD;;;;;OAKG;IACG,YAAY,CAChB,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAChC,OAAO,CAAC,IAAI,CAAC;IAiChB;;;;;OAKG;IACG,UAAU,CACd,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAChC,OAAO,CAAC,IAAI,CAAC;IAmChB;;;;;;;;OAQG;IACG,YAAY,CAChB,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,cAAc,EAC3B,gBAAgB,EAAE,MAAM,EACxB,oBAAoB,EAAE,MAAM,EAC5B,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,GAAE,MAAa,GACvB,OAAO,CAAC,MAAM,CAAC;YAoDJ,eAAe;IAsH7B;;;OAGG;IACH,qBAAqB,CAAC,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,UAAU,GAAE,OAAe,GAAG,IAAI;IA2BnF;;OAEG;IACH,oBAAoB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM;CAKvC;AAED,eAAe,mBAAmB,CAAC"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.js b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.js
new file mode 100644
index 000000000..1c24d921f
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.js
@@ -0,0 +1,401 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MongoBinaryDownload = void 0;
+const tslib_1 = require("tslib");
+const os_1 = tslib_1.__importDefault(require("os"));
+const url_1 = require("url");
+const path_1 = tslib_1.__importDefault(require("path"));
+const fs_1 = require("fs");
+const follow_redirects_1 = require("follow-redirects");
+const zlib_1 = require("zlib");
+const tar_stream_1 = tslib_1.__importDefault(require("tar-stream"));
+const yauzl_1 = tslib_1.__importDefault(require("yauzl"));
+const MongoBinaryDownloadUrl_1 = tslib_1.__importDefault(require("./MongoBinaryDownloadUrl"));
+const https_proxy_agent_1 = require("https-proxy-agent");
+const resolveConfig_1 = tslib_1.__importStar(require("./resolveConfig"));
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const utils_1 = require("./utils");
+const DryMongoBinary_1 = require("./DryMongoBinary");
+const readline_1 = require("readline");
+const errors_1 = require("./errors");
+const log = (0, debug_1.default)('MongoMS:MongoBinaryDownload');
+const retryableStatusCodes = [503, 500];
+const retryableErrorCodes = ['ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED'];
+/**
+ * Download and extract the "mongod" binary
+ */
+class MongoBinaryDownload {
+ constructor(opts) {
+ (0, utils_1.assertion)(typeof opts.downloadDir === 'string', new Error('An DownloadDir must be specified!'));
+ const version = opts.version ?? (0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.VERSION);
+ (0, utils_1.assertion)(typeof version === 'string', new Error('An MongoDB Binary version must be specified!'));
+ // DryMongoBinary.generateOptions cannot be used here, because its async
+ this.binaryOpts = {
+ platform: opts.platform ?? os_1.default.platform(),
+ arch: opts.arch ?? os_1.default.arch(),
+ version: version,
+ downloadDir: opts.downloadDir,
+ checkMD5: opts.checkMD5 ?? (0, resolveConfig_1.envToBool)((0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.MD5_CHECK)),
+ systemBinary: opts.systemBinary ?? '',
+ os: opts.os ?? { os: 'unknown' },
+ };
+ this.dlProgress = {
+ current: 0,
+ length: 0,
+ totalMb: 0,
+ lastPrintedAt: 0,
+ };
+ }
+ /**
+ * Get the full path with filename
+ * @returns Absoulte Path with FileName
+ */
+ async getPath() {
+ const opts = await DryMongoBinary_1.DryMongoBinary.generateOptions(this.binaryOpts);
+ return DryMongoBinary_1.DryMongoBinary.combineBinaryName(this.binaryOpts.downloadDir, await DryMongoBinary_1.DryMongoBinary.getBinaryName(opts));
+ }
+ /**
+ * Get the path of the already downloaded "mongod" file
+ * otherwise download it and then return the path
+ */
+ async getMongodPath() {
+ log('getMongodPath');
+ const mongodPath = await this.getPath();
+ if (await (0, utils_1.pathExists)(mongodPath)) {
+ log(`getMongodPath: mongod path "${mongodPath}" already exists, using this`);
+ return mongodPath;
+ }
+ const mongoDBArchive = await this.startDownload();
+ await this.extract(mongoDBArchive);
+ await fs_1.promises.unlink(mongoDBArchive);
+ if (await (0, utils_1.pathExists)(mongodPath)) {
+ return mongodPath;
+ }
+ throw new Error(`Cannot find downloaded mongod binary by path "${mongodPath}"`);
+ }
+ /**
+ * Download the MongoDB Archive and check it against an MD5
+ * @returns The MongoDB Archive location
+ */
+ async startDownload() {
+ log('startDownload');
+ const mbdUrl = new MongoBinaryDownloadUrl_1.default(this.binaryOpts);
+ await (0, utils_1.mkdir)(this.binaryOpts.downloadDir);
+ try {
+ await fs_1.promises.access(this.binaryOpts.downloadDir, fs_1.constants.X_OK | fs_1.constants.W_OK); // check that this process has permissions to create files & modify file contents & read file contents
+ }
+ catch (err) {
+ console.error(`Download Directory at "${this.binaryOpts.downloadDir}" does not have sufficient permissions to be used by this process\n` +
+ 'Needed Permissions: Write & Execute (-wx)\n');
+ throw err;
+ }
+ const downloadUrl = await mbdUrl.getDownloadUrl();
+ const mongoDBArchive = await this.download(downloadUrl);
+ await this.makeMD5check(`${downloadUrl}.md5`, mongoDBArchive);
+ return mongoDBArchive;
+ }
+ /**
+ * Download MD5 file and check it against the MongoDB Archive
+ * @param urlForReferenceMD5 URL to download the MD5
+ * @param mongoDBArchive The MongoDB Archive file location
+ *
+ * @returns {undefined} if "checkMD5" is falsey
+ * @returns {true} if the md5 check was successful
+ * @throws if the md5 check failed
+ */
+ async makeMD5check(urlForReferenceMD5, mongoDBArchive) {
+ log('makeMD5check: Checking MD5 of downloaded binary...');
+ if (!this.binaryOpts.checkMD5) {
+ log('makeMD5check: checkMD5 is disabled');
+ return undefined;
+ }
+ const archiveMD5Path = await this.download(urlForReferenceMD5);
+ const signatureContent = (await fs_1.promises.readFile(archiveMD5Path)).toString('utf-8');
+ const regexMatch = signatureContent.match(/^\s*([\w\d]+)\s*/i);
+ const md5SigRemote = regexMatch ? regexMatch[1] : null;
+ const md5SigLocal = await (0, utils_1.md5FromFile)(mongoDBArchive);
+ log(`makeMD5check: Local MD5: ${md5SigLocal}, Remote MD5: ${md5SigRemote}`);
+ if (md5SigRemote !== md5SigLocal) {
+ throw new errors_1.Md5CheckFailedError(md5SigLocal, md5SigRemote || 'unknown');
+ }
+ await fs_1.promises.unlink(archiveMD5Path);
+ return true;
+ }
+ /**
+ * Download file from downloadUrl
+ * @param downloadUrl URL to download a File
+ * @returns The Path to the downloaded archive file
+ */
+ async download(downloadUrl) {
+ log('download');
+ const proxy = process.env['yarn_https-proxy'] ||
+ process.env.yarn_proxy ||
+ process.env['npm_config_https-proxy'] ||
+ process.env.npm_config_proxy ||
+ process.env.https_proxy ||
+ process.env.http_proxy ||
+ process.env.HTTPS_PROXY ||
+ process.env.HTTP_PROXY;
+ const strictSsl = process.env.npm_config_strict_ssl === 'true';
+ const urlObject = new url_1.URL(downloadUrl);
+ urlObject.port = urlObject.port || '443';
+ const requestOptions = {
+ method: 'GET',
+ rejectUnauthorized: strictSsl,
+ protocol: (0, resolveConfig_1.envToBool)((0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.USE_HTTP)) ? 'http:' : 'https:',
+ agent: proxy ? new https_proxy_agent_1.HttpsProxyAgent(proxy) : undefined,
+ };
+ const filename = urlObject.pathname.split('/').pop();
+ if (!filename) {
+ throw new Error(`MongoBinaryDownload: missing filename for url "${downloadUrl}"`);
+ }
+ const downloadLocation = path_1.default.resolve(this.binaryOpts.downloadDir, filename);
+ const tempDownloadLocation = path_1.default.resolve(this.binaryOpts.downloadDir, `${filename}.downloading`);
+ log(`download: Downloading${proxy ? ` via proxy "${proxy}"` : ''}: "${downloadUrl}"`);
+ if (await (0, utils_1.pathExists)(downloadLocation)) {
+ log('download: Already downloaded archive found, skipping download');
+ return downloadLocation;
+ }
+ this.assignDownloadingURL(urlObject);
+ const downloadedFile = await this.httpDownload(urlObject, requestOptions, downloadLocation, tempDownloadLocation);
+ return downloadedFile;
+ }
+ /**
+ * Extract given Archive
+ * @param mongoDBArchive Archive location
+ * @returns extracted directory location
+ */
+ async extract(mongoDBArchive) {
+ log('extract');
+ const mongodbFullPath = await this.getPath();
+ log(`extract: archive: "${mongoDBArchive}" final: "${mongodbFullPath}"`);
+ await (0, utils_1.mkdir)(path_1.default.dirname(mongodbFullPath));
+ const filter = (file) => /(?:bin\/(?:mongod(?:\.exe)?))$/i.test(file);
+ if (/(.tar.gz|.tgz)$/.test(mongoDBArchive)) {
+ await this.extractTarGz(mongoDBArchive, mongodbFullPath, filter);
+ }
+ else if (/.zip$/.test(mongoDBArchive)) {
+ await this.extractZip(mongoDBArchive, mongodbFullPath, filter);
+ }
+ else {
+ throw new Error(`MongoBinaryDownload: unsupported archive "${mongoDBArchive}" (downloaded from "${this._downloadingUrl ?? 'unknown'}"). Broken archive from MongoDB Provider?`);
+ }
+ if (!(await (0, utils_1.pathExists)(mongodbFullPath))) {
+ throw new Error(`MongoBinaryDownload: missing mongod binary in "${mongoDBArchive}" (downloaded from "${this._downloadingUrl ?? 'unknown'}"). Broken archive from MongoDB Provider?`);
+ }
+ return mongodbFullPath;
+ }
+ /**
+ * Extract a .tar.gz archive
+ * @param mongoDBArchive Archive location
+ * @param extractPath Directory to extract to
+ * @param filter Method to determine which files to extract
+ */
+ async extractTarGz(mongoDBArchive, extractPath, filter) {
+ log('extractTarGz');
+ const extract = tar_stream_1.default.extract();
+ extract.on('entry', (header, stream, next) => {
+ if (filter(header.name)) {
+ stream.pipe((0, fs_1.createWriteStream)(extractPath, {
+ mode: 0o775,
+ }));
+ }
+ stream.on('end', () => next());
+ stream.resume();
+ });
+ return new Promise((res, rej) => {
+ (0, fs_1.createReadStream)(mongoDBArchive)
+ .on('error', (err) => {
+ rej(new errors_1.GenericMMSError('Unable to open tarball ' + mongoDBArchive + ': ' + err));
+ })
+ .pipe((0, zlib_1.createUnzip)())
+ .on('error', (err) => {
+ rej(new errors_1.GenericMMSError('Error during unzip for ' + mongoDBArchive + ': ' + err));
+ })
+ .pipe(extract)
+ .on('error', (err) => {
+ rej(new errors_1.GenericMMSError('Error during untar for ' + mongoDBArchive + ': ' + err));
+ })
+ .on('finish', res);
+ });
+ }
+ /**
+ * Extract a .zip archive
+ * @param mongoDBArchive Archive location
+ * @param extractPath Directory to extract to
+ * @param filter Method to determine which files to extract
+ */
+ async extractZip(mongoDBArchive, extractPath, filter) {
+ log('extractZip');
+ return new Promise((resolve, reject) => {
+ yauzl_1.default.open(mongoDBArchive, { lazyEntries: true }, (err, zipfile) => {
+ if (err || !zipfile) {
+ return reject(err);
+ }
+ zipfile.readEntry();
+ zipfile.on('end', () => resolve());
+ zipfile.on('entry', (entry) => {
+ if (!filter(entry.fileName)) {
+ return zipfile.readEntry();
+ }
+ zipfile.openReadStream(entry, (err2, r) => {
+ if (err2 || !r) {
+ return reject(err2);
+ }
+ r.on('end', () => zipfile.readEntry());
+ r.pipe((0, fs_1.createWriteStream)(extractPath, {
+ mode: 0o775,
+ }));
+ });
+ });
+ });
+ });
+ }
+ /**
+ * Download given httpOptions to tempDownloadLocation, then move it to downloadLocation
+ * @param url The URL to download the file from
+ * @param httpOptions The httpOptions directly passed to https.get
+ * @param downloadLocation The location the File should be after the download
+ * @param tempDownloadLocation The location the File should be while downloading
+ * @param maxRetries Maximum number of retries on download failure
+ * @param baseDelay Base delay in milliseconds for retrying the download
+ */
+ async httpDownload(url, httpOptions, downloadLocation, tempDownloadLocation, maxRetries, baseDelay = 1000) {
+ log('httpDownload');
+ const downloadUrl = this.assignDownloadingURL(url);
+ const maxRedirects = parseInt((0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.MAX_REDIRECTS) ?? '');
+ const useHttpsOptions = {
+ maxRedirects: Number.isNaN(maxRedirects) ? 2 : maxRedirects,
+ ...httpOptions,
+ };
+ // Get maxRetries from config if not provided
+ const retriesFromConfig = parseInt((0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.MAX_RETRIES) ?? '');
+ const retries = typeof maxRetries === 'number'
+ ? maxRetries
+ : !Number.isNaN(retriesFromConfig)
+ ? retriesFromConfig
+ : 3;
+ for (let attempt = 0; attempt <= retries; attempt++) {
+ try {
+ return await this.attemptDownload(url, useHttpsOptions, downloadLocation, tempDownloadLocation, downloadUrl, httpOptions);
+ }
+ catch (error) {
+ const shouldRetry = (error instanceof errors_1.DownloadError &&
+ retryableStatusCodes.some((code) => error.message.includes(code.toString()))) ||
+ (error?.code && retryableErrorCodes.includes(error.code));
+ if (!shouldRetry || attempt === retries) {
+ throw error;
+ }
+ const base = baseDelay * Math.pow(2, attempt);
+ const jitter = Math.floor(Math.random() * 1000);
+ const delay = base + jitter;
+ log(`httpDownload: attempt ${attempt + 1} failed with ${error.message}, retrying in ${delay}ms...`);
+ await new Promise((resolve) => setTimeout(resolve, delay));
+ }
+ }
+ throw new Error('Max retries exceeded');
+ }
+ async attemptDownload(url, useHttpsOptions, downloadLocation, tempDownloadLocation, downloadUrl, httpOptions) {
+ return new Promise((resolve, reject) => {
+ log(`httpDownload: trying to download "${downloadUrl}"`);
+ const request = follow_redirects_1.https.get(url, useHttpsOptions, (response) => {
+ if (response.statusCode != 200) {
+ if (response.statusCode === 403) {
+ reject(new errors_1.DownloadError(downloadUrl, "Status Code is 403 (MongoDB's 404)\n" +
+ "This means that the requested version-platform combination doesn't exist\n" +
+ "Try to use different version 'new MongoMemoryServer({ binary: { version: 'X.Y.Z' } })'\n" +
+ 'List of available versions can be found here: ' +
+ 'https://www.mongodb.com/download-center/community/releases/archive'));
+ return;
+ }
+ reject(new errors_1.DownloadError(downloadUrl, `Status Code isn't 200! (it is ${response.statusCode})`));
+ return;
+ }
+ // content-length, otherwise 0
+ let contentLength;
+ if (typeof response.headers['content-length'] != 'string') {
+ log('Response header "content-length" is empty!');
+ contentLength = 0;
+ }
+ else {
+ contentLength = parseInt(response.headers['content-length'], 10);
+ if (Number.isNaN(contentLength)) {
+ log('Response header "content-length" resolved to NaN!');
+ contentLength = 0;
+ }
+ }
+ // error if the content-length header is missing or is 0 if config option "DOWNLOAD_IGNORE_MISSING_HEADER" is not set to "true"
+ if (!(0, resolveConfig_1.envToBool)((0, resolveConfig_1.default)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_IGNORE_MISSING_HEADER)) &&
+ contentLength <= 0) {
+ reject(new errors_1.DownloadError(downloadUrl, 'Response header "content-length" does not exist or resolved to NaN'));
+ return;
+ }
+ this.dlProgress.current = 0;
+ this.dlProgress.length = contentLength;
+ this.dlProgress.totalMb = Math.round((this.dlProgress.length / 1048576) * 10) / 10;
+ const fileStream = (0, fs_1.createWriteStream)(tempDownloadLocation);
+ response.pipe(fileStream);
+ fileStream.on('finish', async () => {
+ if (this.dlProgress.current < this.dlProgress.length &&
+ !httpOptions.path?.endsWith('.md5')) {
+ reject(new errors_1.DownloadError(downloadUrl, `Too small (${this.dlProgress.current} bytes) mongod binary downloaded.`));
+ return;
+ }
+ this.printDownloadProgress({ length: 0 }, true);
+ fileStream.close();
+ await fs_1.promises.rename(tempDownloadLocation, downloadLocation);
+ log(`httpDownload: moved "${tempDownloadLocation}" to "${downloadLocation}"`);
+ resolve(downloadLocation);
+ });
+ response.on('data', (chunk) => {
+ this.printDownloadProgress(chunk);
+ });
+ response.on('error', (err) => {
+ reject(new errors_1.DownloadError(downloadUrl, err.message));
+ });
+ });
+ request.on('error', (err) => {
+ console.error(`Could NOT download "${downloadUrl}"!`, err.message);
+ reject(new errors_1.DownloadError(downloadUrl, err.message));
+ });
+ request.setTimeout(60000, () => {
+ request.destroy();
+ reject(new errors_1.DownloadError(downloadUrl, 'Request timeout after 60 seconds'));
+ });
+ });
+ }
+ /**
+ * Print the Download Progress to STDOUT
+ * @param chunk A chunk to get the length
+ */
+ printDownloadProgress(chunk, forcePrint = false) {
+ this.dlProgress.current += chunk.length;
+ const now = Date.now();
+ if (now - this.dlProgress.lastPrintedAt < 2000 && !forcePrint) {
+ return;
+ }
+ this.dlProgress.lastPrintedAt = now;
+ const percentComplete = Math.round(((100.0 * this.dlProgress.current) / this.dlProgress.length) * 10) / 10;
+ const mbComplete = Math.round((this.dlProgress.current / 1048576) * 10) / 10;
+ const crReturn = this.binaryOpts.platform === 'win32' ? '\x1b[0G' : '\r';
+ const message = `Downloading MongoDB "${this.binaryOpts.version}": ${percentComplete}% (${mbComplete}mb / ${this.dlProgress.totalMb}mb)${crReturn}`;
+ if (process.stdout.isTTY) {
+ // if TTY overwrite last line over and over until finished and clear line to avoid residual characters
+ (0, readline_1.clearLine)(process.stdout, 0); // this is because "process.stdout.clearLine" does not exist anymore
+ process.stdout.write(message);
+ }
+ else {
+ console.log(message);
+ }
+ }
+ /**
+ * Helper function to de-duplicate assigning "_downloadingUrl"
+ */
+ assignDownloadingURL(url) {
+ this._downloadingUrl = url.href;
+ return this._downloadingUrl;
+ }
+}
+exports.MongoBinaryDownload = MongoBinaryDownload;
+exports.default = MongoBinaryDownload;
+//# sourceMappingURL=MongoBinaryDownload.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.js.map b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.js.map
new file mode 100644
index 000000000..f6abbdd12
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownload.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoBinaryDownload.js","sourceRoot":"","sources":["../../src/util/MongoBinaryDownload.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.d.ts b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.d.ts
new file mode 100644
index 000000000..58f23edd7
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.d.ts
@@ -0,0 +1,98 @@
+import { AnyOS, LinuxOS } from './getos';
+export interface MongoBinaryDownloadUrlOpts {
+ version: string;
+ platform: string;
+ arch: string;
+ os?: AnyOS;
+}
+/** Set the default ubuntu version number */
+export declare const DEFAULT_UBUNTU_YEAR = 22;
+/**
+ * Download URL generator
+ */
+export declare class MongoBinaryDownloadUrl implements MongoBinaryDownloadUrlOpts {
+ platform: string;
+ arch: string;
+ version: string;
+ os?: AnyOS;
+ constructor(opts: MongoBinaryDownloadUrlOpts);
+ /**
+ * Assemble the URL to download
+ * Calls all the necessary functions to determine the URL
+ */
+ getDownloadUrl(): Promise;
+ /**
+ * Get the archive
+ */
+ getArchiveName(): Promise;
+ /**
+ * Get the archive for Windows
+ * (from: https://www.mongodb.org/dl/win32)
+ */
+ getArchiveNameWin(): string;
+ /**
+ * Get the archive for OSX (Mac)
+ * (from: https://www.mongodb.org/dl/osx)
+ */
+ getArchiveNameOsx(): string;
+ /**
+ * Get the archive for Linux
+ * (from: https://www.mongodb.org/dl/linux)
+ */
+ getArchiveNameLinux(): Promise;
+ /**
+ * Parse and apply config option DISTRO
+ */
+ protected overwriteDistro(): void;
+ /**
+ * Get the version string (with distro)
+ * @param os LinuxOS Object
+ */
+ getLinuxOSVersionString(os: LinuxOS): string;
+ /**
+ * Get the version string for Debian
+ * @param os LinuxOS Object
+ */
+ getDebianVersionString(os: LinuxOS): string;
+ /**
+ * Get the version string for Fedora
+ * @param os LinuxOS Object
+ */
+ getFedoraVersionString(os: LinuxOS): string;
+ /**
+ * Get the version string for Red Hat Enterprise Linux
+ * @param os LinuxOS Object
+ */
+ getRhelVersionString(os: LinuxOS): string;
+ /**
+ * Get the version string for Amazon Distro
+ * @param os LinuxOS Object
+ */
+ getAmazonVersionString(os: LinuxOS): string;
+ /**
+ * Get the version string for Suse / OpenSuse
+ * @param os LinuxOS Object
+ */
+ getSuseVersionString(os: LinuxOS): string;
+ /**
+ * Get the version string for Ubuntu
+ * @param os LinuxOS Object
+ */
+ getUbuntuVersionString(os: LinuxOS): string;
+ /**
+ * Translate input platform to mongodb-archive useable platform
+ * @param platform The Platform to translate to a mongodb archive platform
+ * @example
+ * darwin -> osx
+ */
+ translatePlatform(platform: string): string;
+ /**
+ * Translate input arch to mongodb-archive useable arch
+ * @param arch The Architecture to translate to a mongodb archive architecture
+ * @example
+ * x64 -> x86_64
+ */
+ static translateArch(arch: string): string;
+}
+export default MongoBinaryDownloadUrl;
+//# sourceMappingURL=MongoBinaryDownloadUrl.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.d.ts.map b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.d.ts.map
new file mode 100644
index 000000000..04c1fd856
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoBinaryDownloadUrl.d.ts","sourceRoot":"","sources":["../../src/util/MongoBinaryDownloadUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAiBhD,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,KAAK,CAAC;CACZ;AAED,4CAA4C;AAC5C,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC;;GAEG;AACH,qBAAa,sBAAuB,YAAW,0BAA0B;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,KAAK,CAAC;gBAEC,IAAI,EAAE,0BAA0B;IAO5C;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IA+BvC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAqBvC;;;OAGG;IACH,iBAAiB,IAAI,MAAM;IAiB3B;;;OAGG;IACH,iBAAiB,IAAI,MAAM;IA+B3B;;;OAGG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAwB5C;;OAEG;IACH,SAAS,CAAC,eAAe;IA6BzB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM;IAiD5C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM;IA0D3C;;;OAGG;IACH,sBAAsB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM;IAyB3C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM;IAqFzC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM;IAY3C;;;OAGG;IAEH,oBAAoB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM;IAMzC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM;IAgJ3C;;;;;OAKG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAmB3C;;;;;OAKG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAY3C;AAED,eAAe,sBAAsB,CAAC"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.js b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.js
new file mode 100644
index 000000000..436001eca
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.js
@@ -0,0 +1,565 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MongoBinaryDownloadUrl = exports.DEFAULT_UBUNTU_YEAR = void 0;
+const tslib_1 = require("tslib");
+const getos_1 = require("./getos");
+const resolveConfig_1 = require("./resolveConfig");
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const semver = tslib_1.__importStar(require("semver"));
+const utils_1 = require("./utils");
+const url_1 = require("url");
+const errors_1 = require("./errors");
+const log = (0, debug_1.default)('MongoMS:MongoBinaryDownloadUrl');
+/** Set the default ubuntu version number */
+exports.DEFAULT_UBUNTU_YEAR = 22; // TODO: try to keep this up-to-date to the latest LTS
+/**
+ * Download URL generator
+ */
+class MongoBinaryDownloadUrl {
+ constructor(opts) {
+ this.version = opts.version;
+ this.platform = this.translatePlatform(opts.platform);
+ this.arch = MongoBinaryDownloadUrl.translateArch(opts.arch);
+ this.os = opts.os;
+ }
+ /**
+ * Assemble the URL to download
+ * Calls all the necessary functions to determine the URL
+ */
+ async getDownloadUrl() {
+ const downloadUrl = (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_URL);
+ if (downloadUrl) {
+ log(`Using "${downloadUrl}" as the Download-URL`);
+ const url = new url_1.URL(downloadUrl); // check if this is an valid url
+ return url.toString();
+ }
+ const archive = await this.getArchiveName();
+ log(`Using "${archive}" as the Archive String`);
+ const mirror = (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_MIRROR) ?? 'https://fastdl.mongodb.org';
+ log(`Using "${mirror}" as the mirror`);
+ const url = new url_1.URL(mirror);
+ // ensure that the "mirror" path ends with "/"
+ if (!url.pathname.endsWith('/')) {
+ url.pathname = url.pathname + '/';
+ }
+ // no extra "/" between "pathname" and "platfrom", because of the "if" statement above to ensure "url.pathname" to end with "/"
+ url.pathname = `${url.pathname}${this.platform}/${archive}`;
+ return url.toString();
+ }
+ /**
+ * Get the archive
+ */
+ async getArchiveName() {
+ const archive_name = (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.ARCHIVE_NAME);
+ // double-"!" to not include falsy values
+ if (!!archive_name) {
+ return archive_name;
+ }
+ switch (this.platform) {
+ case 'osx':
+ return this.getArchiveNameOsx();
+ case 'win32':
+ case 'windows':
+ return this.getArchiveNameWin();
+ case 'linux':
+ return this.getArchiveNameLinux();
+ default:
+ throw new errors_1.UnknownPlatformError(this.platform);
+ }
+ }
+ /**
+ * Get the archive for Windows
+ * (from: https://www.mongodb.org/dl/win32)
+ */
+ getArchiveNameWin() {
+ let name = `mongodb-${this.platform}-${this.arch}`;
+ const coercedVersion = semver.coerce(this.version);
+ if (!(0, utils_1.isNullOrUndefined)(coercedVersion)) {
+ if (semver.satisfies(coercedVersion, '4.2.x')) {
+ name += '-2012plus';
+ }
+ else if (semver.lt(coercedVersion, '4.1.0')) {
+ name += '-2008plus-ssl';
+ }
+ }
+ name += `-${this.version}.zip`;
+ return name;
+ }
+ /**
+ * Get the archive for OSX (Mac)
+ * (from: https://www.mongodb.org/dl/osx)
+ */
+ getArchiveNameOsx() {
+ let name = `mongodb-osx`;
+ const coercedVersion = semver.coerce(this.version);
+ if (!(0, utils_1.isNullOrUndefined)(coercedVersion) && semver.gte(coercedVersion, '3.2.0')) {
+ name += '-ssl';
+ }
+ if ((0, utils_1.isNullOrUndefined)(coercedVersion) || semver.gte(coercedVersion, '4.2.0')) {
+ name = `mongodb-macos`; // somehow these files are not listed in https://www.mongodb.org/dl/osx
+ }
+ // mongodb has native arm64
+ if (this.arch === 'aarch64') {
+ // force usage of "x86_64" binary for all versions below than 6.0.0
+ if (!(0, utils_1.isNullOrUndefined)(coercedVersion) && semver.lt(coercedVersion, '6.0.0')) {
+ log('getArchiveNameOsx: Arch is "aarch64" and version is below 6.0.0, using x64 binary');
+ this.arch = 'x86_64';
+ }
+ else {
+ log('getArchiveNameOsx: Arch is "aarch64" and version is above or equal to 6.0.0, using arm64 binary');
+ // naming for macos is still "arm64" instead of "aarch64"
+ this.arch = 'arm64';
+ }
+ }
+ name += `-${this.arch}-${this.version}.tgz`;
+ return name;
+ }
+ /**
+ * Get the archive for Linux
+ * (from: https://www.mongodb.org/dl/linux)
+ */
+ async getArchiveNameLinux() {
+ if (!this.os && (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DISTRO)) {
+ this.os = await (0, getos_1.getOS)();
+ }
+ if ((0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DISTRO)) {
+ this.overwriteDistro();
+ }
+ const osString = this.getLinuxOSVersionString(this.os);
+ // this is below, to allow overwriting the arch (like arm64 to aarch64)
+ let name = `mongodb-linux-${this.arch}`;
+ // guard against any falsy values
+ if (!!osString) {
+ name += `-${osString}`;
+ }
+ name += `-${this.version}.tgz`;
+ return name;
+ }
+ /**
+ * Parse and apply config option DISTRO
+ */
+ overwriteDistro() {
+ const env = (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DISTRO);
+ if ((0, utils_1.isNullOrUndefined)(env)) {
+ return;
+ }
+ const split = env.split('-');
+ const distro = split[0];
+ const release = split[1];
+ if ((0, utils_1.isNullOrUndefined)(distro)) {
+ throw new errors_1.GenericMMSError('Expected DISTRO option to have a distro like "ubuntu-18.04"');
+ }
+ if ((0, utils_1.isNullOrUndefined)(release)) {
+ throw new errors_1.GenericMMSError('Expected DISTRO option to have a release like "ubuntu-18.04" (delimited by "-")');
+ }
+ this.os = {
+ os: 'linux',
+ dist: distro,
+ release: release,
+ };
+ }
+ /**
+ * Get the version string (with distro)
+ * @param os LinuxOS Object
+ */
+ getLinuxOSVersionString(os) {
+ if (regexHelper(/ubuntu/i, os)) {
+ return this.getUbuntuVersionString(os);
+ }
+ else if (regexHelper(/amzn/i, os)) {
+ return this.getAmazonVersionString(os);
+ }
+ else if (regexHelper(/suse/i, os)) {
+ return this.getSuseVersionString(os);
+ // handle "oracle linux"(ol) as "rhel", because they define "id_like: fedora", but the versions themself match up with rhel
+ }
+ else if (regexHelper(/(rhel|centos|scientific|^ol$)/i, os)) {
+ return this.getRhelVersionString(os);
+ }
+ else if (regexHelper(/fedora/i, os)) {
+ return this.getFedoraVersionString(os);
+ }
+ else if (regexHelper(/debian/i, os)) {
+ return this.getDebianVersionString(os);
+ }
+ else if (regexHelper(/alpine/i, os)) {
+ console.warn('There is no official build of MongoDB for Alpine!');
+ // Match "arch", "archlinux", "manjaro", "manjarolinux", "arco", "arcolinux"
+ }
+ else if (regexHelper(/(arch|manjaro|arco)(?:linux)?$/i, os)) {
+ console.warn(`There is no official build of MongoDB for ArchLinux (${os.dist}). Falling back to Ubuntu 22.04 release.`);
+ return this.getUbuntuVersionString({
+ os: 'linux',
+ dist: 'Ubuntu Linux',
+ release: '22.04',
+ });
+ }
+ else if (regexHelper(/gentoo/i, os)) {
+ // it seems like debian binaries work for gentoo too (at least most), see https://github.com/typegoose/mongodb-memory-server/issues/639
+ console.warn(`There is no official build of MongoDB for Gentoo (${os.dist}). Falling back to Debian.`);
+ return this.getDebianVersionString({
+ os: 'linux',
+ dist: 'Debian',
+ release: '11',
+ });
+ }
+ else if (regexHelper(/unknown/i, os)) {
+ // "unknown" is likely to happen if no release file / command could be found
+ console.warn('Couldnt parse dist information, please report this to https://github.com/typegoose/mongodb-memory-server/issues');
+ }
+ // mongodb does not ship generic linux builds anymore
+ throw new errors_1.UnknownLinuxDistro(os.dist, os.id_like ?? []);
+ }
+ /**
+ * Get the version string for Debian
+ * @param os LinuxOS Object
+ */
+ getDebianVersionString(os) {
+ let name = 'debian';
+ const release = parseFloat(os.release);
+ const coercedVersion = semver.coerce(this.version);
+ if ((0, utils_1.isNullOrUndefined)(coercedVersion)) {
+ throw new errors_1.UnknownVersionError(this.version);
+ }
+ // without any "release"(empty string), fallback to testing
+ // see https://tracker.debian.org/news/1433360/accepted-base-files-13-source-into-unstable/
+ const isTesting = ['unstable', 'testing', ''].includes(os.release);
+ if (isTesting || release >= 12) {
+ name += '12';
+ }
+ else if (release >= 11) {
+ // Debian 11 is compatible with the binaries for debian 10
+ // but does not have binaries for before 5.0.8
+ // and only set to use "debian10" if the requested version is not a latest version
+ if (semver.lt(coercedVersion, '5.0.8') && !testVersionIsLatest(this.version)) {
+ log('debian11 detected, but version below 5.0.8 requested, using debian10');
+ name += '10';
+ }
+ else {
+ name += '11';
+ }
+ }
+ else if (release >= 10) {
+ name += '10';
+ }
+ else if (release >= 9) {
+ name += '92';
+ }
+ else if (release >= 8.1) {
+ name += '81';
+ }
+ else if (release >= 7.1) {
+ name += '71';
+ }
+ if (isTesting || release >= 12) {
+ if (semver.lt(coercedVersion, '7.0.3') && !testVersionIsLatest(this.version)) {
+ throw new errors_1.KnownVersionIncompatibilityError(`Debian ${release || os.release || os.codename}`, this.version, '>=7.0.3', 'Mongodb does not provide binaries for versions before 7.0.3 for Debian 12+ and also cannot be mapped to a previous Debian release');
+ }
+ }
+ else if (release >= 10) {
+ if (semver.lt(coercedVersion, '4.2.1') && !testVersionIsLatest(this.version)) {
+ throw new errors_1.KnownVersionIncompatibilityError(`Debian ${release || os.release || os.codename}`, this.version, '>=4.2.1', 'Mongodb does not provide binaries for versions before 4.2.1 for Debian 10+ and also cannot be mapped to a previous Debian release');
+ }
+ }
+ return name;
+ }
+ /**
+ * Get the version string for Fedora
+ * @param os LinuxOS Object
+ */
+ getFedoraVersionString(os) {
+ const fedoraVer = parseInt(os.release, 10);
+ const rhelOS = {
+ os: 'linux',
+ dist: 'rhel',
+ // fallback to 8.0
+ release: '8.0',
+ };
+ // 36 and onwards dont ship with libcrypto.so.1.1 anymore and need to be manually installed ("openssl1.1")
+ // 34 onward dosnt have "compat-openssl10" anymore, and only build from 4.0.24 are available for "rhel80"
+ if (fedoraVer >= 34) {
+ rhelOS.release = '8.0';
+ }
+ else if (fedoraVer >= 19) {
+ rhelOS.release = '7.0';
+ }
+ else if (fedoraVer >= 12) {
+ rhelOS.release = '6.2';
+ }
+ else if (fedoraVer >= 6) {
+ rhelOS.release = '5.5';
+ }
+ return this.getRhelVersionString(rhelOS);
+ }
+ /**
+ * Get the version string for Red Hat Enterprise Linux
+ * @param os LinuxOS Object
+ */
+ getRhelVersionString(os) {
+ let name = 'rhel';
+ const { release } = os;
+ const releaseAsSemver = semver.coerce(release); // coerce "8" to "8.0.0" and "8.2" to "8.2.0", makes comparing easier than "parseInt" or "parseFloat"
+ const coercedVersion = semver.coerce(this.version);
+ if ((0, utils_1.isNullOrUndefined)(coercedVersion)) {
+ throw new errors_1.UnknownVersionError(this.version);
+ }
+ if (releaseAsSemver) {
+ // extra checks for architecture aarch64 (arm64)
+ // should not assign "name" by itself
+ if (this.arch === 'aarch64') {
+ // there are no versions for aarch64 before rhel 8.2 (or currently after)
+ if (semver.lt(releaseAsSemver, '8.2.0')) {
+ throw new errors_1.KnownVersionIncompatibilityError(`Rhel ${release} arm64`, this.version, '>=4.4.2', 'ARM64(aarch64) support for rhel is only for rhel82 or higher');
+ }
+ // there are no versions for aarch64 before mongodb 4.4.2
+ // Note: version 4.4.2 and 4.4.3 are NOT listed at the list, but are existing; list: https://www.mongodb.com/download-center/community/releases/archive
+ if (semver.lt(coercedVersion, '4.4.2') && !testVersionIsLatest(this.version)) {
+ throw new errors_1.KnownVersionIncompatibilityError(`Rhel ${release} arm64`, this.version, '>=4.4.2');
+ }
+ // rhel 9 does not provide openssl 1.1 anymore, making it incompatible with previous versions
+ // lowest rhel9 arm64 is 6.0.7
+ if (semver.satisfies(releaseAsSemver, '>=9.0.0') && semver.lt(coercedVersion, '6.0.7')) {
+ throw new errors_1.KnownVersionIncompatibilityError(`Rhel ${release} arm64`, this.version, '>=6.0.7');
+ }
+ }
+ if (semver.satisfies(releaseAsSemver, '>=9.0.0')) {
+ // there are only binaries for rhel90 since 6.0.4
+ name += '90';
+ }
+ else if (semver.satisfies(releaseAsSemver, '8.2.0') && this.arch == 'aarch64') {
+ // Mongodb changed its naming for rhel8 only https://jira.mongodb.org/browse/SERVER-92375
+ // NOTE: as of 10.10.2024 `(rhel8|rhel80)-7.0.13` is not downloadable but `7.0.14` is
+ if (semver.satisfies(coercedVersion, '^5.0.29 || ^6.0.17 || ^7.0.13 || ^8.0.0')) {
+ name += '8';
+ }
+ else {
+ name += '82';
+ }
+ }
+ else if (semver.satisfies(releaseAsSemver, '^8.0.0')) {
+ // Mongodb changed its naming for rhel8 only https://jira.mongodb.org/browse/SERVER-92375
+ // NOTE: as of 10.10.2024 `(rhel8|rhel80)-7.0.13` is not downloadable but `7.0.14` is
+ if (semver.satisfies(coercedVersion, '^5.0.29 || ^6.0.17 || ^7.0.13 || ^8.0.0')) {
+ name += '8';
+ }
+ else {
+ name += '80';
+ }
+ }
+ else if (semver.satisfies(releaseAsSemver, '^7.0.0')) {
+ name += '70';
+ }
+ else if (semver.satisfies(releaseAsSemver, '^6.0.0')) {
+ name += '62';
+ }
+ else if (semver.satisfies(releaseAsSemver, '^5.0.0')) {
+ name += '55';
+ }
+ else {
+ console.warn(`Unhandled RHEL version: "${release}"("${this.arch}")`);
+ }
+ }
+ else {
+ console.warn(`Couldnt coerce RHEL version "${release}"`);
+ }
+ // fallback if name has not been modified yet
+ if (name === 'rhel') {
+ log('getRhelVersionString: falling back to "70"');
+ // fallback to "70", because that is what currently is supporting 3.6 to 5.0 and should work with many
+ name += '70';
+ }
+ return name;
+ }
+ /**
+ * Get the version string for Amazon Distro
+ * @param os LinuxOS Object
+ */
+ getAmazonVersionString(os) {
+ let name = 'amazon';
+ const release = parseInt(os.release, 10);
+ if (release >= 2) {
+ name += release.toString();
+ }
+ // dont add anthing as fallback, because for "amazon 1", mongodb just uses "amazon"
+ return name;
+ }
+ /**
+ * Get the version string for Suse / OpenSuse
+ * @param os LinuxOS Object
+ */
+ // TODO: add tests for getSuseVersionString
+ getSuseVersionString(os) {
+ const releaseMatch = os.release.match(/(^11|^12|^15)/);
+ return releaseMatch ? `suse${releaseMatch[0]}` : '';
+ }
+ /**
+ * Get the version string for Ubuntu
+ * @param os LinuxOS Object
+ */
+ getUbuntuVersionString(os) {
+ let ubuntuOS = undefined;
+ const coercedVersion = semver.coerce(this.version);
+ if ((0, utils_1.isNullOrUndefined)(coercedVersion)) {
+ throw new errors_1.UnknownVersionError(this.version);
+ }
+ // "id_like" processing (version conversion) [this is an block to be collapsible]
+ {
+ if (/^linux\s?mint\s*$/i.test(os.dist)) {
+ const mintToUbuntuRelease = {
+ 17: '14.04',
+ 18: '16.04',
+ 19: '18.04',
+ 20: '20.04',
+ 21: '22.04',
+ 22: '24.04',
+ };
+ ubuntuOS = {
+ os: 'linux',
+ dist: 'ubuntu',
+ release: mintToUbuntuRelease[parseInt(os.release.split('.')[0])] || mintToUbuntuRelease[21],
+ };
+ }
+ if (/^elementary(?:\s?os)?\s*$/i.test(os.dist)) {
+ const elementaryToUbuntuRelease = {
+ 3: '14.04',
+ 4: '16.04',
+ 5: '18.04',
+ 6: '20.04',
+ 7: '22.04',
+ };
+ // untangle elemenatary versioning from hell https://en.wikipedia.org/wiki/Elementary_OS#Development
+ const [elementaryMajor, elementaryMinor] = os.release.split('.').map((el) => parseInt(el));
+ // versions below 5.0 were named 0.X, and so use the minor version if major is 0
+ const realMajor = elementaryMajor || elementaryMinor;
+ ubuntuOS = {
+ os: 'linux',
+ dist: 'ubuntu',
+ release: elementaryToUbuntuRelease[realMajor] || elementaryToUbuntuRelease[7],
+ };
+ }
+ }
+ if ((0, utils_1.isNullOrUndefined)(ubuntuOS)) {
+ // Warn against distros that have a ID_LIKE set to "ubuntu", but no other upstream information and are not specially mapped (see above)
+ if (!/^ubuntu(?:| linux)\s*$/i.test(os.dist)) {
+ console.warn(`Unmapped distro "${os.dist}" with ID_LIKE "ubuntu", defaulting to highest ubuntu version!\n` +
+ 'This means that your distro does not have a internal mapping in MMS or does not have a upstream release file (like "/etc/upstream-release/lsb-release"), but has set a ID_LIKE');
+ ubuntuOS = {
+ os: 'linux',
+ dist: 'ubuntu',
+ release: `${exports.DEFAULT_UBUNTU_YEAR}.04`,
+ };
+ }
+ else {
+ ubuntuOS = os;
+ }
+ }
+ let ubuntuYear = parseInt(ubuntuOS.release.split('.')[0], 10);
+ if (Number.isNaN(ubuntuYear)) {
+ console.warn(`Could not parse ubuntu year from "${ubuntuOS.release}", using default`);
+ ubuntuYear = exports.DEFAULT_UBUNTU_YEAR;
+ }
+ if (this.arch === 'aarch64') {
+ // this is because, before version 4.1.10, everything for "arm64" / "aarch64" were just "arm64" and for "ubuntu1604"
+ if (semver.satisfies(coercedVersion, '<4.1.10')) {
+ this.arch = 'arm64';
+ return 'ubuntu1604';
+ }
+ // this is because versions below "4.4.0" did not provide an binary for anything above 1804
+ if (semver.satisfies(coercedVersion, '>=4.1.10 <4.4.0')) {
+ return 'ubuntu1804';
+ }
+ }
+ if (ubuntuOS.release === '14.10') {
+ return 'ubuntu1410-clang';
+ }
+ // there are no MongoDB 3.x binary distributions for ubuntu >= 18
+ // https://www.mongodb.org/dl/linux/x86_64-ubuntu1604
+ if (ubuntuYear >= 18 && semver.satisfies(coercedVersion, '3.x.x')) {
+ log(`getUbuntuVersionString: ubuntuYear is "${ubuntuYear}", which dosnt have an 3.x.x version, defaulting to "1604"`);
+ return 'ubuntu1604';
+ }
+ // there are no MongoDB <=4.3.x binary distributions for ubuntu > 18
+ // https://www.mongodb.org/dl/linux/x86_64-ubuntu1804
+ if (ubuntuYear > 18 && semver.satisfies(coercedVersion, '<=4.3.x')) {
+ log(`getUbuntuVersionString: ubuntuYear is "${ubuntuYear}", which dosnt have an "<=4.3.x" version, defaulting to "1804"`);
+ return 'ubuntu1804';
+ }
+ // there are only binaries for 2204 since 6.0.4 (and not binaries for ubuntu2104)
+ if (ubuntuYear >= 21 && semver.satisfies(coercedVersion, '<6.0.4')) {
+ return 'ubuntu2004';
+ }
+ // there are only binaries for 2404 since 8.0.0, not in 7.x
+ if (ubuntuYear >= 22 && semver.satisfies(coercedVersion, '<8.0.0')) {
+ return 'ubuntu2204';
+ }
+ // base case for higher than mongodb supported ubuntu versions
+ {
+ // TODO: try to keep this up-to-date to the latest mongodb supported ubuntu version
+ /**
+ * Highest ubuntu year supported by mongodb binaries
+ * @see https://www.mongodb.com/download-center/community/releases/archive
+ */
+ const highestUbuntuYear = 24; // 24 is the highest supported as of mongodb 8.0.1
+ if (ubuntuYear > highestUbuntuYear) {
+ log(`getUbuntuVersionString: ubuntuYear "${ubuntuYear}" is higher than the currently supported mongodb year of "${highestUbuntuYear}", using highest known`);
+ return 'ubuntu2404';
+ }
+ }
+ // the "04" version always exists for ubuntu, use that as default
+ return `ubuntu${ubuntuYear}04`;
+ }
+ /**
+ * Translate input platform to mongodb-archive useable platform
+ * @param platform The Platform to translate to a mongodb archive platform
+ * @example
+ * darwin -> osx
+ */
+ translatePlatform(platform) {
+ switch (platform) {
+ case 'darwin':
+ return 'osx';
+ case 'win32':
+ const version = semver.coerce(this.version);
+ if ((0, utils_1.isNullOrUndefined)(version)) {
+ return 'windows';
+ }
+ return semver.gte(version, '4.3.0') ? 'windows' : 'win32';
+ case 'linux':
+ return 'linux';
+ default:
+ throw new errors_1.UnknownPlatformError(platform);
+ }
+ }
+ /**
+ * Translate input arch to mongodb-archive useable arch
+ * @param arch The Architecture to translate to a mongodb archive architecture
+ * @example
+ * x64 -> x86_64
+ */
+ static translateArch(arch) {
+ switch (arch) {
+ case 'x86_64':
+ case 'x64':
+ return 'x86_64';
+ case 'arm64':
+ case 'aarch64':
+ return 'aarch64';
+ default:
+ throw new errors_1.UnknownArchitectureError(arch);
+ }
+ }
+}
+exports.MongoBinaryDownloadUrl = MongoBinaryDownloadUrl;
+exports.default = MongoBinaryDownloadUrl;
+/**
+ * Helper function to reduce code / regex duplication
+ */
+function regexHelper(regex, os) {
+ return (regex.test(os.dist) ||
+ (!(0, utils_1.isNullOrUndefined)(os.id_like) ? os.id_like.filter((v) => regex.test(v)).length >= 1 : false));
+}
+/** Helper to consistently test if a version is a "-latest" version, like "v5.0-latest" */
+function testVersionIsLatest(version) {
+ return /^v\d+\.\d+-latest$/.test(version);
+}
+//# sourceMappingURL=MongoBinaryDownloadUrl.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.js.map b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.js.map
new file mode 100644
index 000000000..8f9fba96b
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoBinaryDownloadUrl.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoBinaryDownloadUrl.js","sourceRoot":"","sources":["../../src/util/MongoBinaryDownloadUrl.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoInstance.d.ts b/packages/mongodb-memory-server-core/lib/util/MongoInstance.d.ts
new file mode 100644
index 000000000..9c46b1977
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoInstance.d.ts
@@ -0,0 +1,285 @@
+///
+///
+///
+import { ChildProcess, SpawnOptions } from 'child_process';
+import { MongoBinaryOpts } from './MongoBinary';
+import { ManagerBase } from './utils';
+import { EventEmitter } from 'events';
+import { MongoClientOptions } from 'mongodb';
+export type StorageEngine = 'ephemeralForTest' | 'wiredTiger';
+/**
+ * Overwrite replica member-specific configuration
+ *
+ * @see {@link https://docs.mongodb.com/manual/reference/replica-configuration/#replica-set-configuration-document-example}
+ *
+ * @example
+ * ```ts
+ * {
+ * priority: 2,
+ * buildIndexes: false,
+ * votes: 2,
+ * }
+ * ```
+ */
+export interface ReplicaMemberConfig {
+ /**
+ * A boolean that identifies an arbiter.
+ * @default false - A value of `true` indicates that the member is an arbiter.
+ */
+ arbiterOnly?: boolean;
+ /**
+ * A boolean that indicates whether the mongod builds indexes on this member.
+ * You can only set this value when adding a member to a replica set.
+ * @default true
+ */
+ buildIndexes?: boolean;
+ /**
+ * The replica set hides this instance and does not include the member in the output of `db.hello()` or `hello`.
+ * @default true
+ */
+ hidden?: boolean;
+ /**
+ * A number that indicates the relative eligibility of a member to become a primary.
+ * Specify higher values to make a member more eligible to become primary, and lower values to make the member less eligible.
+ * @default 1 for primary/secondary; 0 for arbiters.
+ */
+ priority?: number;
+ /**
+ * A tags document contains user-defined tag field and value pairs for the replica set member.
+ * @default null
+ * @example
+ * ```ts
+ * { "": "", "": "",... }
+ * ```
+ */
+ tags?: any;
+ /**
+ * Mongodb 4.x only - The number of seconds "behind" the primary that this replica set member should "lag".
+ * For mongodb 5.x, use `secondaryDelaySecs` instead.
+ * @see {@link https://docs.mongodb.com/v4.4/tutorial/configure-a-delayed-replica-set-member/}
+ * @default 0
+ */
+ slaveDelay?: number;
+ /**
+ * Mongodb 5.x only - The number of seconds "behind" the primary that this replica set member should "lag".
+ * @default 0
+ */
+ secondaryDelaySecs?: number;
+ /**
+ * The number of votes a server will cast in a replica set election.
+ * The number of votes each member has is either 1 or 0, and arbiters always have exactly 1 vote.
+ * @default 1
+ */
+ votes?: number;
+}
+export interface MongoMemoryInstanceOptsBase {
+ /**
+ * Extra Arguments to add
+ */
+ args?: string[];
+ /**
+ * Set which port to use
+ * Adds "--port"
+ * @default from get-port
+ */
+ port?: number;
+ /**
+ * Set which storage path to use
+ * Adds "--dbpath"
+ * @default TmpDir
+ */
+ dbPath?: string;
+ /**
+ * Set which Storage Engine to use
+ * Adds "--storageEngine"
+ * @default "ephemeralForTest"
+ */
+ storageEngine?: StorageEngine;
+ /**
+ * Set the Replica-Member-Config
+ * Only has a effect when started with "MongoMemoryReplSet"
+ */
+ replicaMemberConfig?: ReplicaMemberConfig;
+ /**
+ * Define a custom timeout for when out of some reason the binary cannot get started correctly
+ * Time in MS
+ * @default 10000 10 seconds
+ */
+ launchTimeout?: number;
+}
+export interface MongoMemoryInstanceOpts extends MongoMemoryInstanceOptsBase {
+ /**
+ * Set which parameter will be used
+ * true -> "--auth"
+ * false -> "--noauth"
+ * @default false
+ */
+ auth?: boolean;
+ /**
+ * Currently unused option
+ * @default undefined
+ */
+ dbName?: string;
+ /**
+ * for binding to all IP addresses set it to `::,0.0.0.0`, by default '127.0.0.1'
+ * Adds "--bind_ip"
+ * @default undefined
+ */
+ ip?: string;
+ /**
+ * Set that this instance is part of a replset
+ * Adds "--replSet"
+ * @default undefined
+ */
+ replSet?: string;
+ /**
+ * Location for the "--keyfile" argument
+ * Only has an effect when "auth" is enabled and is a replset
+ * Adds "--keyfile"
+ * @default undefined
+ */
+ keyfileLocation?: string;
+}
+export declare enum MongoInstanceEvents {
+ instanceReplState = "instanceReplState",
+ instancePrimary = "instancePrimary",
+ instanceReady = "instanceReady",
+ instanceSTDOUT = "instanceSTDOUT",
+ instanceSTDERR = "instanceSTDERR",
+ instanceClosed = "instanceClosed",
+ /** Only Raw Error (emitted by mongodProcess) */
+ instanceRawError = "instanceRawError",
+ /** Raw Errors and Custom Errors */
+ instanceError = "instanceError",
+ killerLaunched = "killerLaunched",
+ instanceLaunched = "instanceLaunched",
+ instanceStarted = "instanceStarted"
+}
+export interface MongodOpts {
+ /** instance options */
+ instance: MongoMemoryInstanceOpts;
+ /** mongo binary options */
+ binary: MongoBinaryOpts;
+ /** child process spawn options */
+ spawn: SpawnOptions;
+}
+export interface MongoInstance extends EventEmitter {
+ emit(event: MongoInstanceEvents, ...args: any[]): boolean;
+ on(event: MongoInstanceEvents, listener: (...args: any[]) => void): this;
+ once(event: MongoInstanceEvents, listener: (...args: any[]) => void): this;
+}
+/**
+ * MongoDB Instance Handler Class
+ * This Class starts & stops the "mongod" process directly and handles stdout, sterr and close events
+ */
+export declare class MongoInstance extends EventEmitter implements ManagerBase {
+ instanceOpts: MongoMemoryInstanceOpts;
+ readonly binaryOpts: Readonly;
+ readonly spawnOpts: Readonly;
+ /**
+ * Extra options to append to "mongoclient.connect"
+ * Mainly used for authentication
+ */
+ extraConnectionOptions?: MongoClientOptions;
+ /**
+ * The "mongod" Process reference
+ */
+ mongodProcess?: ChildProcess;
+ /**
+ * The "mongo_killer" Process reference
+ */
+ killerProcess?: ChildProcess;
+ /**
+ * This boolean is "true" if the instance is elected to be PRIMARY
+ */
+ isInstancePrimary: boolean;
+ /**
+ * This boolean is "true" if the instance is successfully started
+ */
+ isInstanceReady: boolean;
+ /**
+ * This boolean is "true" if the instance is part of an replset
+ */
+ isReplSet: boolean;
+ /**
+ * Extra promise to avoid multiple calls of `.stop` at the same time
+ *
+ * @see https://github.com/typegoose/mongodb-memory-server/issues/802
+ */
+ stopPromise?: Promise;
+ constructor(opts: Partial);
+ /**
+ * Debug-log with template applied
+ * @param msg The Message to log
+ */
+ protected debug(msg: string, ...extra: unknown[]): void;
+ /**
+ * Create an new instance an call method "start"
+ * @param opts Options passed to the new instance
+ */
+ static create(opts: Partial): Promise;
+ /**
+ * Create an array of arguments for the mongod instance
+ */
+ prepareCommandArgs(): string[];
+ /**
+ * Create the mongod process
+ * @fires MongoInstance#instanceStarted
+ */
+ start(): Promise;
+ /**
+ * Shutdown all related processes (Mongod Instance & Killer Process)
+ */
+ stop(): Promise;
+ /**
+ * Actually launch mongod
+ * @param mongoBin The binary to run
+ * @fires MongoInstance#instanceLaunched
+ */
+ _launchMongod(mongoBin: string): ChildProcess;
+ /**
+ * Spawn an seperate process to kill the parent and the mongod instance to ensure "mongod" gets stopped in any case
+ * @param parentPid Parent nodejs process
+ * @param childPid Mongod process to kill
+ * @fires MongoInstance#killerLaunched
+ */
+ _launchKiller(parentPid: number, childPid: number): ChildProcess;
+ /**
+ * Event "error" handler
+ * @param err The Error to handle
+ * @fires MongoInstance#instanceRawError
+ * @fires MongoInstance#instanceError
+ */
+ errorHandler(err: string): void;
+ /**
+ * Write the CLOSE event to the debug function
+ * @param code The Exit code to handle
+ * @param signal The Signal to handle
+ * @fires MongoInstance#instanceClosed
+ */
+ closeHandler(code: number | null, signal: string | null): void;
+ /**
+ * Write STDERR to debug function
+ * @param message The STDERR line to write
+ * @fires MongoInstance#instanceSTDERR
+ */
+ stderrHandler(message: string | Buffer): void;
+ /**
+ * Write STDOUT to debug function and process some special messages
+ * @param message The STDOUT line to write/parse
+ * @fires MongoInstance#instanceSTDOUT
+ * @fires MongoInstance#instanceReady
+ * @fires MongoInstance#instanceError
+ * @fires MongoInstance#instancePrimary
+ * @fires MongoInstance#instanceReplState
+ */
+ stdoutHandler(message: string | Buffer): void;
+ /**
+ * Run Checks on the line if the lines contain any thrown errors
+ * @param line The Line to check
+ */
+ protected checkErrorInLine(line: string): void;
+ [Symbol.asyncDispose](): Promise;
+}
+export default MongoInstance;
+//# sourceMappingURL=MongoInstance.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoInstance.d.ts.map b/packages/mongodb-memory-server-core/lib/util/MongoInstance.d.ts.map
new file mode 100644
index 000000000..301e55522
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoInstance.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoInstance.d.ts","sourceRoot":"","sources":["../../src/util/MongoInstance.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoInstance.js b/packages/mongodb-memory-server-core/lib/util/MongoInstance.js
new file mode 100644
index 000000000..28729976c
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoInstance.js
@@ -0,0 +1,408 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MongoInstance = exports.MongoInstanceEvents = void 0;
+const tslib_1 = require("tslib");
+const child_process_1 = require("child_process");
+const path = tslib_1.__importStar(require("path"));
+const MongoBinary_1 = require("./MongoBinary");
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const utils_1 = require("./utils");
+const semver_1 = require("semver");
+const events_1 = require("events");
+const mongodb_1 = require("mongodb");
+const errors_1 = require("./errors");
+// ignore the nodejs warning for coverage
+/* istanbul ignore next */
+if ((0, semver_1.lt)(process.version, '16.20.1')) {
+ console.warn('Using NodeJS below 16.20.1');
+}
+const log = (0, debug_1.default)('MongoMS:MongoInstance');
+var MongoInstanceEvents;
+(function (MongoInstanceEvents) {
+ MongoInstanceEvents["instanceReplState"] = "instanceReplState";
+ MongoInstanceEvents["instancePrimary"] = "instancePrimary";
+ MongoInstanceEvents["instanceReady"] = "instanceReady";
+ MongoInstanceEvents["instanceSTDOUT"] = "instanceSTDOUT";
+ MongoInstanceEvents["instanceSTDERR"] = "instanceSTDERR";
+ MongoInstanceEvents["instanceClosed"] = "instanceClosed";
+ /** Only Raw Error (emitted by mongodProcess) */
+ MongoInstanceEvents["instanceRawError"] = "instanceRawError";
+ /** Raw Errors and Custom Errors */
+ MongoInstanceEvents["instanceError"] = "instanceError";
+ MongoInstanceEvents["killerLaunched"] = "killerLaunched";
+ MongoInstanceEvents["instanceLaunched"] = "instanceLaunched";
+ MongoInstanceEvents["instanceStarted"] = "instanceStarted";
+})(MongoInstanceEvents || (exports.MongoInstanceEvents = MongoInstanceEvents = {}));
+/**
+ * MongoDB Instance Handler Class
+ * This Class starts & stops the "mongod" process directly and handles stdout, sterr and close events
+ */
+// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
+class MongoInstance extends events_1.EventEmitter {
+ constructor(opts) {
+ super();
+ /**
+ * This boolean is "true" if the instance is elected to be PRIMARY
+ */
+ this.isInstancePrimary = false;
+ /**
+ * This boolean is "true" if the instance is successfully started
+ */
+ this.isInstanceReady = false;
+ /**
+ * This boolean is "true" if the instance is part of an replset
+ */
+ this.isReplSet = false;
+ this.instanceOpts = { ...opts.instance };
+ this.binaryOpts = { ...opts.binary };
+ this.spawnOpts = { ...opts.spawn };
+ this.on(MongoInstanceEvents.instanceReady, () => {
+ this.isInstanceReady = true;
+ this.debug('constructor: Instance is ready!');
+ });
+ this.on(MongoInstanceEvents.instanceError, async (err) => {
+ this.debug(`constructor: Instance has thrown an Error: ${err.toString()}`);
+ this.isInstanceReady = false;
+ this.isInstancePrimary = false;
+ await this.stop();
+ });
+ }
+ /**
+ * Debug-log with template applied
+ * @param msg The Message to log
+ */
+ debug(msg, ...extra) {
+ const port = this.instanceOpts.port ?? 'unknown';
+ log(`Mongo[${port}]: ${msg}`, ...extra);
+ }
+ /**
+ * Create an new instance an call method "start"
+ * @param opts Options passed to the new instance
+ */
+ static async create(opts) {
+ log('create: Called .create() method');
+ const instance = new this(opts);
+ await instance.start();
+ return instance;
+ }
+ /**
+ * Create an array of arguments for the mongod instance
+ */
+ prepareCommandArgs() {
+ this.debug('prepareCommandArgs');
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(this.instanceOpts.port), new Error('"instanceOpts.port" is required to be set!'));
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(this.instanceOpts.dbPath), new Error('"instanceOpts.dbPath" is required to be set!'));
+ const result = [];
+ result.push('--port', this.instanceOpts.port.toString());
+ result.push('--dbpath', this.instanceOpts.dbPath);
+ // "!!" converts the value to an boolean (double-invert) so that no "falsy" values are added
+ if (!!this.instanceOpts.replSet) {
+ this.isReplSet = true;
+ result.push('--replSet', this.instanceOpts.replSet);
+ }
+ if (!!this.instanceOpts.storageEngine) {
+ result.push('--storageEngine', this.instanceOpts.storageEngine);
+ }
+ if (!!this.instanceOpts.ip) {
+ result.push('--bind_ip', this.instanceOpts.ip);
+ }
+ if (this.instanceOpts.auth) {
+ result.push('--auth');
+ if (this.isReplSet) {
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(this.instanceOpts.keyfileLocation), new errors_1.KeyFileMissingError());
+ result.push('--keyFile', this.instanceOpts.keyfileLocation);
+ }
+ }
+ else {
+ result.push('--noauth');
+ }
+ const final = result.concat(this.instanceOpts.args ?? []);
+ this.debug('prepareCommandArgs: final argument array:' + JSON.stringify(final));
+ return final;
+ }
+ /**
+ * Create the mongod process
+ * @fires MongoInstance#instanceStarted
+ */
+ async start() {
+ this.debug('start');
+ if (!(0, utils_1.isNullOrUndefined)(this.mongodProcess?.pid)) {
+ throw new errors_1.GenericMMSError(`Cannot run "MongoInstance.start" because "mongodProcess.pid" is still defined (pid: ${this.mongodProcess?.pid})`);
+ }
+ this.isInstancePrimary = false;
+ this.isInstanceReady = false;
+ this.isReplSet = false;
+ let timeout;
+ const mongoBin = await MongoBinary_1.MongoBinary.getPath(this.binaryOpts);
+ await (0, utils_1.checkBinaryPermissions)(mongoBin);
+ const launch = new Promise((res, rej) => {
+ this.once(MongoInstanceEvents.instanceReady, res);
+ this.once(MongoInstanceEvents.instanceError, rej);
+ this.once(MongoInstanceEvents.instanceClosed, function launchInstanceClosed() {
+ rej(new Error('Instance Exited before being ready and without throwing an error!'));
+ });
+ // extra conditions just to be sure that the custom defined timeout is valid
+ const timeoutTime = !!this.instanceOpts.launchTimeout && this.instanceOpts.launchTimeout >= 1000
+ ? this.instanceOpts.launchTimeout
+ : 1000 * 10; // default 10 seconds
+ timeout = setTimeout(() => {
+ const err = new errors_1.GenericMMSError(`Instance failed to start within ${timeoutTime}ms`);
+ this.emit(MongoInstanceEvents.instanceError, err);
+ rej(err);
+ }, timeoutTime);
+ }).finally(() => {
+ // always clear the timeout after the promise somehow resolves
+ clearTimeout(timeout);
+ });
+ this.debug('start: Starting Processes');
+ this.mongodProcess = this._launchMongod(mongoBin);
+ // This assertion is here because somewhere between nodejs 12 and 16 the types for "childprocess.pid" changed to include "| undefined"
+ // it is tested and a error is thrown in "this_launchMongod", but typescript somehow does not see this yet as of 4.3.5
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(this.mongodProcess.pid), new Error('MongoD Process failed to spawn'));
+ this.killerProcess = this._launchKiller(process.pid, this.mongodProcess.pid);
+ await launch;
+ this.emit(MongoInstanceEvents.instanceStarted);
+ this.debug('start: Processes Started');
+ }
+ /**
+ * Shutdown all related processes (Mongod Instance & Killer Process)
+ */
+ async stop() {
+ this.debug('stop');
+ if (!this.mongodProcess && !this.killerProcess) {
+ this.debug('stop: nothing to shutdown, returning');
+ return false;
+ }
+ if (!(0, utils_1.isNullOrUndefined)(this.stopPromise)) {
+ this.debug('stop: stopPromise is already set, using that');
+ return this.stopPromise;
+ }
+ // wrap the actual stop in a promise, so it can be awaited in multiple calls
+ // for example a instanceError while stop is already running would cause another stop
+ this.stopPromise = (async () => {
+ if (!(0, utils_1.isNullOrUndefined)(this.mongodProcess) && (0, utils_1.isAlive)(this.mongodProcess.pid)) {
+ // try to run "shutdown" before running "killProcess" (gracefull "SIGINT")
+ // using this, otherwise on windows nodejs will handle "SIGINT" & "SIGTERM" & "SIGKILL" the same (instant exit)
+ if (this.isReplSet) {
+ let con;
+ try {
+ this.debug('stop: trying shutdownServer');
+ const port = this.instanceOpts.port;
+ const ip = this.instanceOpts.ip;
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(port), new Error('Cannot shutdown replset gracefully, no "port" is provided'));
+ (0, utils_1.assertion)(!(0, utils_1.isNullOrUndefined)(ip), new Error('Cannot shutdown replset gracefully, no "ip" is provided'));
+ con = await mongodb_1.MongoClient.connect((0, utils_1.uriTemplate)(ip, port, 'admin'), {
+ // stopping a instance should not take long to connect to, default would be 30 seconds
+ serverSelectionTimeoutMS: 5000, // 5 seconds
+ ...this.extraConnectionOptions,
+ directConnection: true,
+ });
+ const admin = con.db('admin'); // just to ensure it is actually the "admin" database
+ // "timeoutSecs" is set to "1" otherwise it will take at least "10" seconds to stop (very long tests)
+ await admin.command({ shutdown: 1, force: true, timeoutSecs: 1 });
+ this.debug('stop: after admin shutdown command');
+ }
+ catch (err) {
+ // Quote from MongoDB Documentation (https://docs.mongodb.com/manual/reference/command/replSetStepDown/#client-connections):
+ // > Starting in MongoDB 4.2, replSetStepDown command no longer closes all client connections.
+ // > In MongoDB 4.0 and earlier, replSetStepDown command closes all client connections during the step down.
+ // so error "MongoNetworkError: connection 1 to 127.0.0.1:41485 closed" will get thrown below 4.2
+ if (!(err instanceof mongodb_1.MongoNetworkError &&
+ /^connection \d+ to [\d.]+:\d+ closed$/i.test(err.message))) {
+ console.warn(err);
+ }
+ }
+ finally {
+ if (!(0, utils_1.isNullOrUndefined)(con)) {
+ // even if it errors out, somehow the connection stays open
+ await con.close();
+ }
+ }
+ }
+ await (0, utils_1.killProcess)(this.mongodProcess, 'mongodProcess', this.instanceOpts.port);
+ this.mongodProcess = undefined; // reset reference to the childProcess for "mongod"
+ }
+ else {
+ this.debug('stop: mongodProcess: nothing to shutdown, skipping');
+ }
+ if (!(0, utils_1.isNullOrUndefined)(this.killerProcess)) {
+ await (0, utils_1.killProcess)(this.killerProcess, 'killerProcess', this.instanceOpts.port);
+ this.killerProcess = undefined; // reset reference to the childProcess for "mongo_killer"
+ }
+ else {
+ this.debug('stop: killerProcess: nothing to shutdown, skipping');
+ }
+ this.debug('stop: Instance Finished Shutdown');
+ return true;
+ })().finally(() => (this.stopPromise = undefined));
+ return this.stopPromise;
+ }
+ /**
+ * Actually launch mongod
+ * @param mongoBin The binary to run
+ * @fires MongoInstance#instanceLaunched
+ */
+ _launchMongod(mongoBin) {
+ this.debug('_launchMongod: Launching Mongod Process');
+ const childProcess = (0, child_process_1.spawn)(path.resolve(mongoBin), this.prepareCommandArgs(), {
+ ...this.spawnOpts,
+ stdio: 'pipe', // ensure that stdio is always an pipe, regardless of user input
+ });
+ childProcess.stderr?.on('data', this.stderrHandler.bind(this));
+ childProcess.stdout?.on('data', this.stdoutHandler.bind(this));
+ childProcess.on('close', this.closeHandler.bind(this));
+ childProcess.on('error', this.errorHandler.bind(this));
+ if ((0, utils_1.isNullOrUndefined)(childProcess.pid)) {
+ throw new errors_1.StartBinaryFailedError(path.resolve(mongoBin));
+ }
+ childProcess.unref();
+ this.emit(MongoInstanceEvents.instanceLaunched);
+ return childProcess;
+ }
+ /**
+ * Spawn an seperate process to kill the parent and the mongod instance to ensure "mongod" gets stopped in any case
+ * @param parentPid Parent nodejs process
+ * @param childPid Mongod process to kill
+ * @fires MongoInstance#killerLaunched
+ */
+ _launchKiller(parentPid, childPid) {
+ this.debug(`_launchKiller: Launching Killer Process (parent: ${parentPid}, child: ${childPid})`);
+ // spawn process which kills itself and mongo process if current process is dead
+ const killer = (0, child_process_1.fork)(path.resolve(__dirname, '../../scripts/mongo_killer.js'), [parentPid.toString(), childPid.toString()], {
+ execArgv: [],
+ detached: true,
+ stdio: 'ignore', // stdio cannot be done with an detached process cross-systems and without killing the fork on parent termination
+ });
+ killer.unref(); // dont force an exit on the fork when parent is exiting
+ this.emit(MongoInstanceEvents.killerLaunched);
+ return killer;
+ }
+ /**
+ * Event "error" handler
+ * @param err The Error to handle
+ * @fires MongoInstance#instanceRawError
+ * @fires MongoInstance#instanceError
+ */
+ errorHandler(err) {
+ this.emit(MongoInstanceEvents.instanceRawError, err);
+ this.emit(MongoInstanceEvents.instanceError, err);
+ }
+ /**
+ * Write the CLOSE event to the debug function
+ * @param code The Exit code to handle
+ * @param signal The Signal to handle
+ * @fires MongoInstance#instanceClosed
+ */
+ closeHandler(code, signal) {
+ // check if the platform is windows, if yes check if the code is not "12" or "0" otherwise just check code is not "0"
+ // because for mongodb any event on windows (like SIGINT / SIGTERM) will result in an code 12
+ // https://docs.mongodb.com/manual/reference/exit-codes/#12
+ if ((process.platform === 'win32' && code != 12 && code != 0) ||
+ (process.platform !== 'win32' && code != 0)) {
+ this.debug('closeHandler: Mongod instance closed with an non-0 (or non 12 on windows) code!');
+ // Note: this also emits when a signal is present, which is expected because signals are not expected here
+ this.emit(MongoInstanceEvents.instanceError, new errors_1.UnexpectedCloseError(code, signal));
+ }
+ this.debug(`closeHandler: code: "${code}", signal: "${signal}"`);
+ this.emit(MongoInstanceEvents.instanceClosed, code, signal);
+ }
+ /**
+ * Write STDERR to debug function
+ * @param message The STDERR line to write
+ * @fires MongoInstance#instanceSTDERR
+ */
+ stderrHandler(message) {
+ const line = message.toString().trim();
+ this.debug(`stderrHandler: ""${line}""`); // denoting the STDERR string with double quotes, because the stdout might also use quotes
+ this.emit(MongoInstanceEvents.instanceSTDERR, line);
+ this.checkErrorInLine(line);
+ }
+ /**
+ * Write STDOUT to debug function and process some special messages
+ * @param message The STDOUT line to write/parse
+ * @fires MongoInstance#instanceSTDOUT
+ * @fires MongoInstance#instanceReady
+ * @fires MongoInstance#instanceError
+ * @fires MongoInstance#instancePrimary
+ * @fires MongoInstance#instanceReplState
+ */
+ stdoutHandler(message) {
+ const line = message.toString().trim(); // trimming to remove extra new lines and spaces around the message
+ this.debug(`stdoutHandler: ""${line}""`); // denoting the STDOUT string with double quotes, because the stdout might also use quotes
+ this.emit(MongoInstanceEvents.instanceSTDOUT, line);
+ // dont use "else if", because input can be multiple lines and match multiple things
+ if (/waiting for connections/i.test(line)) {
+ this.emit(MongoInstanceEvents.instanceReady);
+ }
+ this.checkErrorInLine(line);
+ // this case needs to be infront of "transition to primary complete", otherwise it might reset "isInstancePrimary" to "false"
+ if (/transition to \w+ from \w+/i.test(line)) {
+ const state = /transition to (\w+) from \w+/i.exec(line)?.[1] ?? 'UNKNOWN';
+ this.emit(MongoInstanceEvents.instanceReplState, state);
+ if (state !== 'PRIMARY') {
+ this.isInstancePrimary = false;
+ }
+ }
+ if (/transition to primary complete; database writes are now permitted/i.test(line)) {
+ this.isInstancePrimary = true;
+ this.debug('stdoutHandler: emitting "instancePrimary"');
+ this.emit(MongoInstanceEvents.instancePrimary);
+ }
+ }
+ /**
+ * Run Checks on the line if the lines contain any thrown errors
+ * @param line The Line to check
+ */
+ checkErrorInLine(line) {
+ if (/address already in use/i.test(line)) {
+ this.emit(MongoInstanceEvents.instanceError, new errors_1.StdoutInstanceError(`Port "${this.instanceOpts.port}" already in use`));
+ }
+ {
+ const execptionMatch = /\bexception in initAndListen: (\w+): /i.exec(line);
+ if (!(0, utils_1.isNullOrUndefined)(execptionMatch)) {
+ // in pre-4.0 mongodb this exception may have been "permission denied" and "Data directory /path not found"
+ this.emit(MongoInstanceEvents.instanceError, new errors_1.StdoutInstanceError(`Instance Failed to start with "${execptionMatch[1] ?? 'unknown'}". Original Error:\n` +
+ line.substring(execptionMatch.index + execptionMatch[0].length)));
+ }
+ // special handling for when mongodb outputs this error as json
+ const execptionMatchJson = /\bDBException in initAndListen,/i.test(line);
+ if (execptionMatchJson) {
+ const loadedJSON = JSON.parse(line) ?? {};
+ this.emit(MongoInstanceEvents.instanceError, new errors_1.StdoutInstanceError(`Instance Failed to start with "DBException in initAndListen". Original Error:\n` +
+ loadedJSON?.attr?.error ?? line // try to use the parsed json, but as fallback use the entire line
+ ));
+ }
+ }
+ if (/CURL_OPENSSL_3['\s]+not found/i.test(line)) {
+ this.emit(MongoInstanceEvents.instanceError, new errors_1.StdoutInstanceError('libcurl3 is not available on your system. Mongod requires it and cannot be started without it.\n' +
+ 'You should manually install libcurl3 or try to use an newer version of MongoDB'));
+ }
+ if (/CURL_OPENSSL_4['\s]+not found/i.test(line)) {
+ this.emit(MongoInstanceEvents.instanceError, new errors_1.StdoutInstanceError('libcurl4 is not available on your system. Mongod requires it and cannot be started without it.\n' +
+ 'You need to manually install libcurl4'));
+ }
+ {
+ /*
+ The following regex matches something like "libsomething.so.1: cannot open shared object"
+ and is optimized to only start matching at a word boundary ("\b") and using atomic-group replacement "(?=inner)\1"
+ */
+ const liberrormatch = line.match(/\b(?=(lib[^:]+))\1: cannot open shared object/i);
+ if (!(0, utils_1.isNullOrUndefined)(liberrormatch)) {
+ const lib = liberrormatch[1].toLocaleLowerCase() ?? 'unknown';
+ this.emit(MongoInstanceEvents.instanceError, new errors_1.StdoutInstanceError(`Instance failed to start because a library is missing or cannot be opened: "${lib}"`));
+ }
+ }
+ if (/\*\*\*aborting after/i.test(line)) {
+ const match = line.match(/\*\*\*aborting after ([^\n]+)/i);
+ const extra = match?.[1] ? ` (${match[1]})` : '';
+ this.emit(MongoInstanceEvents.instanceError, new errors_1.StdoutInstanceError('Mongod internal error' + extra));
+ }
+ }
+ /// Symbol for "Explicit Resource Management"
+ async [Symbol.asyncDispose]() {
+ await this.stop();
+ }
+}
+exports.MongoInstance = MongoInstance;
+exports.default = MongoInstance;
+//# sourceMappingURL=MongoInstance.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/MongoInstance.js.map b/packages/mongodb-memory-server-core/lib/util/MongoInstance.js.map
new file mode 100644
index 000000000..fcb0cdc74
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/MongoInstance.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"MongoInstance.js","sourceRoot":"","sources":["../../src/util/MongoInstance.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/errors.d.ts b/packages/mongodb-memory-server-core/lib/util/errors.d.ts
new file mode 100644
index 000000000..c2480df74
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/errors.d.ts
@@ -0,0 +1,120 @@
+export declare class StateError extends Error {
+ wantedStates: string[];
+ gotState: string;
+ constructor(wantedStates: string[], gotState: string);
+}
+export declare class UnknownLockfileStatusError extends Error {
+ status: number;
+ constructor(status: number);
+}
+export declare class UnableToUnlockLockfileError extends Error {
+ thisInstance: boolean;
+ file: string;
+ constructor(thisInstance: boolean, file: string);
+}
+export declare class UnknownPlatformError extends Error {
+ platform: string;
+ constructor(platform: string);
+}
+export declare class UnknownArchitectureError extends Error {
+ arch: string;
+ platform?: string | undefined;
+ constructor(arch: string, platform?: string | undefined);
+}
+export declare class WaitForPrimaryTimeoutError extends Error {
+ timeout: number;
+ where?: string | undefined;
+ constructor(timeout: number, where?: string | undefined);
+}
+export declare class Md5CheckFailedError extends Error {
+ binarymd5: string;
+ checkfilemd5: string;
+ constructor(binarymd5: string, checkfilemd5: string);
+}
+export declare class StartBinaryFailedError extends Error {
+ binary: string;
+ constructor(binary: string);
+}
+export declare class InstanceInfoError extends Error {
+ where: string;
+ constructor(where: string);
+}
+export declare class KeyFileMissingError extends Error {
+ constructor();
+}
+export declare class AuthNotObjectError extends Error {
+ constructor();
+}
+export declare class InsufficientPermissionsError extends Error {
+ path: string;
+ constructor(path: string);
+}
+export declare class BinaryNotFoundError extends Error {
+ path: string;
+ extra: string;
+ constructor(path: string, extra?: string);
+}
+/**
+ * Custom Fallback Error for "utils.assertion", it is a named/custom Error to confuse less in the stacktrace
+ */
+export declare class AssertionFallbackError extends Error {
+ constructor();
+}
+export declare class ReplsetCountLowError extends Error {
+ count: number;
+ constructor(count: number);
+}
+export declare class ParseArchiveRegexError extends Error {
+ key: string;
+ constructor(key: string);
+}
+export declare class NoRegexMatchError extends Error {
+ name: string;
+ extra?: string | undefined;
+ constructor(name: string, extra?: string | undefined);
+}
+export declare class KnownVersionIncompatibilityError extends Error {
+ dist: string;
+ requested_version: string;
+ available_versions: string;
+ extra?: string | undefined;
+ constructor(dist: string, requested_version: string, available_versions: string, extra?: string | undefined);
+}
+/**
+ * Basic Error wrapper for "instanceError" events from "stdoutHandler"
+ */
+export declare class StdoutInstanceError extends Error {
+ constructor(msg: string);
+}
+/**
+ * Error for when the instance closes with non-0 (or non-12) codes or signals
+ */
+export declare class UnexpectedCloseError extends Error {
+ constructor(code: number | null, signal: string | null);
+}
+/**
+ * Error for when VERSION fails to coerce to a semver version but is required
+ */
+export declare class UnknownVersionError extends Error {
+ version: string;
+ constructor(version: string);
+}
+/**
+ * Error for when downloading fails
+ */
+export declare class DownloadError extends Error {
+ url: string;
+ msg: string;
+ constructor(url: string, msg: string);
+}
+/**
+ * Error for when the linux distro is unknown
+ */
+export declare class UnknownLinuxDistro extends Error {
+ distro: string;
+ id_like: string[];
+ constructor(distro: string, id_like: string[]);
+}
+export declare class GenericMMSError extends Error {
+}
+//# sourceMappingURL=errors.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/errors.d.ts.map b/packages/mongodb-memory-server-core/lib/util/errors.d.ts.map
new file mode 100644
index 000000000..978a9ee67
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/errors.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/util/errors.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/errors.js b/packages/mongodb-memory-server-core/lib/util/errors.js
new file mode 100644
index 000000000..040a9bcd5
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/errors.js
@@ -0,0 +1,217 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.GenericMMSError = exports.UnknownLinuxDistro = exports.DownloadError = exports.UnknownVersionError = exports.UnexpectedCloseError = exports.StdoutInstanceError = exports.KnownVersionIncompatibilityError = exports.NoRegexMatchError = exports.ParseArchiveRegexError = exports.ReplsetCountLowError = exports.AssertionFallbackError = exports.BinaryNotFoundError = exports.InsufficientPermissionsError = exports.AuthNotObjectError = exports.KeyFileMissingError = exports.InstanceInfoError = exports.StartBinaryFailedError = exports.Md5CheckFailedError = exports.WaitForPrimaryTimeoutError = exports.UnknownArchitectureError = exports.UnknownPlatformError = exports.UnableToUnlockLockfileError = exports.UnknownLockfileStatusError = exports.StateError = void 0;
+const utils_1 = require("./utils");
+class StateError extends Error {
+ constructor(wantedStates, gotState) {
+ super(`Incorrect State for operation: "${gotState}", allowed States: "[${wantedStates.join(',')}]"\n` +
+ 'This may be because of using a v6.x way of calling functions, look at the following guide if anything applies:\n' +
+ 'https://typegoose.github.io/mongodb-memory-server/docs/guides/migration/migrate7#no-function-other-than-start-create-ensureinstance-will-be-starting-anything');
+ this.wantedStates = wantedStates;
+ this.gotState = gotState;
+ }
+}
+exports.StateError = StateError;
+class UnknownLockfileStatusError extends Error {
+ constructor(status) {
+ super(`Unknown LockFile Status: "${status}"`);
+ this.status = status;
+ }
+}
+exports.UnknownLockfileStatusError = UnknownLockfileStatusError;
+class UnableToUnlockLockfileError extends Error {
+ constructor(thisInstance, file) {
+ super(`Cannot unlock file "${file}", because it is not locked by this ${thisInstance ? 'instance' : 'process'}`);
+ this.thisInstance = thisInstance;
+ this.file = file;
+ }
+}
+exports.UnableToUnlockLockfileError = UnableToUnlockLockfileError;
+class UnknownPlatformError extends Error {
+ constructor(platform) {
+ super(`Unknown Platform: "${platform}"`);
+ this.platform = platform;
+ }
+}
+exports.UnknownPlatformError = UnknownPlatformError;
+class UnknownArchitectureError extends Error {
+ constructor(arch, platform) {
+ super();
+ this.arch = arch;
+ this.platform = platform;
+ if (!(0, utils_1.isNullOrUndefined)(platform)) {
+ this.message = `Unsupported Architecture-Platform combination: arch: "${arch}", platform: "${platform}"`;
+ }
+ else {
+ this.message = `Unsupported Architecture: "${arch}"`;
+ }
+ }
+}
+exports.UnknownArchitectureError = UnknownArchitectureError;
+class WaitForPrimaryTimeoutError extends Error {
+ constructor(timeout, where) {
+ super(`Timed out after ${timeout}ms while waiting for a Primary (where: "${where}")`);
+ this.timeout = timeout;
+ this.where = where;
+ }
+}
+exports.WaitForPrimaryTimeoutError = WaitForPrimaryTimeoutError;
+class Md5CheckFailedError extends Error {
+ constructor(binarymd5, checkfilemd5) {
+ super(`MD5 check failed! Binary MD5 is "${binarymd5}", Checkfile MD5 is "${checkfilemd5}"`);
+ this.binarymd5 = binarymd5;
+ this.checkfilemd5 = checkfilemd5;
+ }
+}
+exports.Md5CheckFailedError = Md5CheckFailedError;
+class StartBinaryFailedError extends Error {
+ constructor(binary) {
+ super(`Starting the Binary Failed (PID is undefined)! Binary: "${binary}"`);
+ this.binary = binary;
+ }
+}
+exports.StartBinaryFailedError = StartBinaryFailedError;
+class InstanceInfoError extends Error {
+ constructor(where) {
+ super(`"instanceInfo" was undefined when expected to be defined! (where: "${where}")`);
+ this.where = where;
+ }
+}
+exports.InstanceInfoError = InstanceInfoError;
+class KeyFileMissingError extends Error {
+ constructor() {
+ super(`"keyfileLocation" was undefined when expected!`);
+ }
+}
+exports.KeyFileMissingError = KeyFileMissingError;
+class AuthNotObjectError extends Error {
+ constructor() {
+ super('"auth" was not a object when it was expected!');
+ }
+}
+exports.AuthNotObjectError = AuthNotObjectError;
+class InsufficientPermissionsError extends Error {
+ constructor(path) {
+ super(`File "${path}" does not have the required Permissions, required Permissions: "--x"`);
+ this.path = path;
+ }
+}
+exports.InsufficientPermissionsError = InsufficientPermissionsError;
+class BinaryNotFoundError extends Error {
+ constructor(path, extra = '') {
+ super(`No Binary at path "${path}" was found! (ENOENT)${extra}`);
+ this.path = path;
+ this.extra = extra;
+ }
+}
+exports.BinaryNotFoundError = BinaryNotFoundError;
+/**
+ * Custom Fallback Error for "utils.assertion", it is a named/custom Error to confuse less in the stacktrace
+ */
+class AssertionFallbackError extends Error {
+ constructor() {
+ super('Assert failed - no custom error');
+ }
+}
+exports.AssertionFallbackError = AssertionFallbackError;
+class ReplsetCountLowError extends Error {
+ constructor(count) {
+ super(`ReplSet Count needs to be 1 or higher! (specified count: "${count}")`);
+ this.count = count;
+ }
+}
+exports.ReplsetCountLowError = ReplsetCountLowError;
+class ParseArchiveRegexError extends Error {
+ constructor(key) {
+ super(`Expected "${key}" to be found in regex groups`);
+ this.key = key;
+ }
+}
+exports.ParseArchiveRegexError = ParseArchiveRegexError;
+class NoRegexMatchError extends Error {
+ constructor(name, extra) {
+ super();
+ this.name = name;
+ this.extra = extra;
+ const addExtra = !!extra ? `(${extra})` : '';
+ this.message = `Expected "${name}" to have Regex Matches${addExtra}`;
+ }
+}
+exports.NoRegexMatchError = NoRegexMatchError;
+class KnownVersionIncompatibilityError extends Error {
+ constructor(dist, requested_version, available_versions, extra) {
+ super();
+ this.dist = dist;
+ this.requested_version = requested_version;
+ this.available_versions = available_versions;
+ this.extra = extra;
+ const addExtra = !!extra ? `\n${extra}` : '';
+ this.message = `Requested Version "${requested_version}" is not available for "${dist}"! Available Versions: "${available_versions}"${addExtra}`;
+ }
+}
+exports.KnownVersionIncompatibilityError = KnownVersionIncompatibilityError;
+/**
+ * Basic Error wrapper for "instanceError" events from "stdoutHandler"
+ */
+class StdoutInstanceError extends Error {
+ // not using "public variable: type", because it is a basic wrapper for "Error"
+ constructor(msg) {
+ super(msg);
+ }
+}
+exports.StdoutInstanceError = StdoutInstanceError;
+/**
+ * Error for when the instance closes with non-0 (or non-12) codes or signals
+ */
+class UnexpectedCloseError extends Error {
+ constructor(code, signal) {
+ super();
+ this.message = `Instance closed unexpectedly with code "${code}" and signal "${signal}"`;
+ if (signal == 'SIGILL') {
+ this.message +=
+ '\nThe Process Exited with SIGILL, which mean illegal instruction, which is commonly thrown in mongodb 5.0+ when not having AVX available on the CPU';
+ }
+ if (process.platform === 'win32' && (code ?? 0) > 1000000000) {
+ this.message +=
+ '\nExit Code is large, commonly meaning that vc_redist is not installed, the latest vc_redist can be found at https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170';
+ }
+ }
+}
+exports.UnexpectedCloseError = UnexpectedCloseError;
+/**
+ * Error for when VERSION fails to coerce to a semver version but is required
+ */
+class UnknownVersionError extends Error {
+ constructor(version) {
+ super(`Could not coerce VERSION to a semver version (version: "${version}")`);
+ this.version = version;
+ }
+}
+exports.UnknownVersionError = UnknownVersionError;
+/**
+ * Error for when downloading fails
+ */
+class DownloadError extends Error {
+ constructor(url, msg) {
+ super(`Download failed for url \"${url}\", Details:\n${msg}`);
+ this.url = url;
+ this.msg = msg;
+ }
+}
+exports.DownloadError = DownloadError;
+/**
+ * Error for when the linux distro is unknown
+ */
+class UnknownLinuxDistro extends Error {
+ constructor(distro, id_like) {
+ super(`Unknown/unsupported linux "${distro}" id_like's: [${id_like?.join(', ')}]`);
+ this.distro = distro;
+ this.id_like = id_like;
+ }
+}
+exports.UnknownLinuxDistro = UnknownLinuxDistro;
+/* Custom Generic Error class for MMS */
+class GenericMMSError extends Error {
+}
+exports.GenericMMSError = GenericMMSError;
+//# sourceMappingURL=errors.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/errors.js.map b/packages/mongodb-memory-server-core/lib/util/errors.js.map
new file mode 100644
index 000000000..1be5e6730
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/errors.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/util/errors.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/getos/index.d.ts b/packages/mongodb-memory-server-core/lib/util/getos/index.d.ts
new file mode 100644
index 000000000..f5d2f5aab
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/getos/index.d.ts
@@ -0,0 +1,35 @@
+/** Helper Static so that a consistent UNKNOWN value is used */
+export declare const UNKNOWN = "unknown";
+export interface OtherOS {
+ os: 'aix' | 'android' | 'darwin' | 'freebsd' | 'openbsd' | 'sunos' | 'win32' | 'cygwin' | string;
+}
+export interface LinuxOS extends OtherOS {
+ os: 'linux';
+ dist: string;
+ release: string;
+ codename?: string;
+ id_like?: string[];
+}
+export type AnyOS = OtherOS | LinuxOS;
+/**
+ * Check if the OS is a LinuxOS Typeguard
+ * @param os The OS object to check for
+ */
+export declare function isLinuxOS(os: AnyOS): os is LinuxOS;
+/** Get an OS object */
+export declare function getOS(): Promise;
+/**
+ * Helper function to check if the input os is valid
+ * @param os The OS information to check
+ * @returns `true` if not undefined AND not UNKNOWN
+ */
+export declare function isValidOs(os: LinuxOS | undefined): os is LinuxOS;
+/**
+ * Parse LSB-like output (either command or file)
+ */
+export declare function parseLSB(input: string): LinuxOS;
+/**
+ * Parse OSRelease-like output
+ */
+export declare function parseOS(input: string): LinuxOS;
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/getos/index.d.ts.map b/packages/mongodb-memory-server-core/lib/util/getos/index.d.ts.map
new file mode 100644
index 000000000..24dafa46d
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/getos/index.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/util/getos/index.ts"],"names":[],"mappings":"AAsBA,+DAA+D;AAC/D,eAAO,MAAM,OAAO,YAAY,CAAC;AAEjC,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CAClG;AAED,MAAM,WAAW,OAAQ,SAAQ,OAAO;IACtC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,OAAO,CAAC;AAEtC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,KAAK,GAAG,EAAE,IAAI,OAAO,CAElD;AAOD,uBAAuB;AACvB,wBAAsB,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAc5C;AAoDD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,SAAS,GAAG,EAAE,IAAI,OAAO,CAOhE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAO/C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAQ9C"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/getos/index.js b/packages/mongodb-memory-server-core/lib/util/getos/index.js
new file mode 100644
index 000000000..bc0e6757f
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/getos/index.js
@@ -0,0 +1,126 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.parseOS = exports.parseLSB = exports.isValidOs = exports.getOS = exports.isLinuxOS = exports.UNKNOWN = void 0;
+const tslib_1 = require("tslib");
+const os_1 = require("os");
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const utils_1 = require("../utils");
+const log = (0, debug_1.default)('MongoMS:getos');
+/** Collection of Regexes for "lsb_release -a" parsing */
+const LSBRegex = {
+ // regex format is "lsb_release" (command output) and then "lsb-release" (file output)
+ name: /^(?:distributor id:|DISTRIB_ID=)\s*(.*)$/im,
+ codename: /^(?:codename:|DISTRIB_CODENAME=)\s*(.*)$/im,
+ release: /^(?:release:|DISTRIB_RELEASE=)\s*(.*)$/im,
+};
+/** Collection of Regexes for "/etc/os-release" parsing */
+const OSRegex = {
+ name: /^id\s*=\s*"?(\w*)"?$/im,
+ codename: /^version_codename\s*=\s*(.*)$/im,
+ release: /^version_id\s*=\s*"?(\d*(?:\.\d*)?)"?$/im,
+ id_like: /^id_like\s*=\s*"?([\w\s]*)"?$/im,
+};
+/** Helper Static so that a consistent UNKNOWN value is used */
+exports.UNKNOWN = 'unknown';
+/**
+ * Check if the OS is a LinuxOS Typeguard
+ * @param os The OS object to check for
+ */
+function isLinuxOS(os) {
+ return os.os === 'linux';
+}
+exports.isLinuxOS = isLinuxOS;
+/**
+ * Cache the "getOS" call, so that not much has to be re-executed over and over
+ */
+let cachedOs;
+/** Get an OS object */
+async function getOS() {
+ if (!cachedOs) {
+ /** Node builtin function for first determinations */
+ const osName = (0, os_1.platform)();
+ // Linux is a special case.
+ if (osName === 'linux') {
+ cachedOs = await getLinuxInformation();
+ }
+ else {
+ cachedOs = { os: osName };
+ }
+ }
+ return cachedOs;
+}
+exports.getOS = getOS;
+/** Function to outsource Linux Information Parsing */
+async function getLinuxInformation() {
+ // Structure of this function:
+ // 1. get upstream release, if possible
+ // 2. get os release (etc) because it has an "id_like"
+ // 3. get os release (usr) because it has an "id_like"
+ // 4. get lsb-release (etc) as fallback
+ const upstreamLSB = await (0, utils_1.tryReleaseFile)('/etc/upstream-release/lsb-release', parseLSB);
+ if (isValidOs(upstreamLSB)) {
+ log('getLinuxInformation: Using UpstreamLSB');
+ return upstreamLSB;
+ }
+ const etcOsRelease = await (0, utils_1.tryReleaseFile)('/etc/os-release', parseOS);
+ if (isValidOs(etcOsRelease)) {
+ log('getLinuxInformation: Using etcOsRelease');
+ return etcOsRelease;
+ }
+ const usrOsRelease = await (0, utils_1.tryReleaseFile)('/usr/lib/os-release', parseOS);
+ if (isValidOs(usrOsRelease)) {
+ log('getLinuxInformation: Using usrOsRelease');
+ return usrOsRelease;
+ }
+ const etcLSBRelease = await (0, utils_1.tryReleaseFile)('/etc/lsb-release', parseLSB);
+ if (isValidOs(etcLSBRelease)) {
+ log('getLinuxInformation: Using etcLSBRelease');
+ return etcLSBRelease;
+ }
+ console.warn('Could not find any valid Release File, using fallback information');
+ // if none has worked, return unknown
+ return {
+ os: 'linux',
+ dist: exports.UNKNOWN,
+ release: '',
+ };
+}
+/**
+ * Helper function to check if the input os is valid
+ * @param os The OS information to check
+ * @returns `true` if not undefined AND not UNKNOWN
+ */
+function isValidOs(os) {
+ // helper for debugging
+ if (os && os.dist === exports.UNKNOWN) {
+ log('isValidOS: found defined os, but was unknown:', os);
+ }
+ return !(0, utils_1.isNullOrUndefined)(os) && os.dist !== exports.UNKNOWN;
+}
+exports.isValidOs = isValidOs;
+/**
+ * Parse LSB-like output (either command or file)
+ */
+function parseLSB(input) {
+ return {
+ os: 'linux',
+ dist: input.match(LSBRegex.name)?.[1].toLocaleLowerCase() ?? exports.UNKNOWN,
+ codename: input.match(LSBRegex.codename)?.[1].toLocaleLowerCase(),
+ release: input.match(LSBRegex.release)?.[1].toLocaleLowerCase() ?? '',
+ };
+}
+exports.parseLSB = parseLSB;
+/**
+ * Parse OSRelease-like output
+ */
+function parseOS(input) {
+ return {
+ os: 'linux',
+ dist: input.match(OSRegex.name)?.[1].toLocaleLowerCase() ?? exports.UNKNOWN,
+ codename: input.match(OSRegex.codename)?.[1].toLocaleLowerCase(),
+ release: input.match(OSRegex.release)?.[1].toLocaleLowerCase() ?? '',
+ id_like: input.match(OSRegex.id_like)?.[1].toLocaleLowerCase().split(' '),
+ };
+}
+exports.parseOS = parseOS;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/getos/index.js.map b/packages/mongodb-memory-server-core/lib/util/getos/index.js.map
new file mode 100644
index 000000000..c0fee33a4
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/getos/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/util/getos/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/getport/index.d.ts b/packages/mongodb-memory-server-core/lib/util/getport/index.d.ts
new file mode 100644
index 000000000..e8981ab40
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/getport/index.d.ts
@@ -0,0 +1,34 @@
+/** Linux min port that does not require root permissions */
+export declare const MIN_PORT = 1024;
+/** u16 max number */
+export declare const MAX_PORT = 65535;
+/**
+ * Try to get a free port.
+ * @param firstPort The first port to try or empty for a random port
+ * @param max_tries maximum amount of tries to get a port, default to {@link MAX_DEFAULT_TRIES}
+ * @returns A valid free port
+ * @throws if "max_tries" is exceeded
+ */
+export declare function getFreePort(firstPort?: number, max_tries?: number): Promise;
+export default getFreePort;
+/**
+ * Ensure that input number is within range of {@link MIN_PORT} and {@link MAX_PORT}.
+ * If more than {@link MAX_PORT}, wrap around, if less than {@link MIN_PORT} use {@link MIN_PORT}.
+ * @param port The Number to check
+ * @returns A Valid number in port range
+ */
+export declare function validPort(port: number): number;
+/**
+ * Try a given port.
+ * @param port The port to try
+ * @returns the port if successful, "-1" in case of `EADDRINUSE`, all other errors reject
+ * @throws The error given if the code is not "EADDRINUSE"
+ */
+export declare function tryPort(port: number): Promise;
+/**
+ * Reset the {@link PORTS_CACHE} to its initial state.
+ *
+ * This function is meant for debugging and testing purposes only.
+ */
+export declare function resetPortsCache(): void;
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/getport/index.d.ts.map b/packages/mongodb-memory-server-core/lib/util/getport/index.d.ts.map
new file mode 100644
index 000000000..c50a2a25c
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/getport/index.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/util/getport/index.ts"],"names":[],"mappings":"AAKA,4DAA4D;AAC5D,eAAO,MAAM,QAAQ,OAAO,CAAC;AAC7B,qBAAqB;AACrB,eAAO,MAAM,QAAQ,QAAQ,CAAC;AA2B9B;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,GAAE,MAA0B,GACpC,OAAO,CAAC,MAAM,CAAC,CAqDjB;AAED,eAAe,WAAW,CAAC;AAE3B;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI9C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBrD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,SAG9B"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/getport/index.js b/packages/mongodb-memory-server-core/lib/util/getport/index.js
new file mode 100644
index 000000000..432e58216
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/getport/index.js
@@ -0,0 +1,125 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.resetPortsCache = exports.tryPort = exports.validPort = exports.getFreePort = exports.MAX_PORT = exports.MIN_PORT = void 0;
+const tslib_1 = require("tslib");
+const net = tslib_1.__importStar(require("node:net"));
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const log = (0, debug_1.default)('MongoMS:GetPort');
+/** Linux min port that does not require root permissions */
+exports.MIN_PORT = 1024;
+/** u16 max number */
+exports.MAX_PORT = 65535;
+/**
+ * Time before {@link PORTS_CACHE} gets cleared
+ * 10 seconds
+ */
+const PORTS_CACHE_CLEAN_TIME = 1000 * 10;
+/**
+ * Ports cache, so that locked ports are quickly ignored and hoping for less port stealing
+ */
+const PORTS_CACHE = {
+ timeSet: undefined,
+ ports: new Set(),
+};
+/** Max default tries before giving up */
+const MAX_DEFAULT_TRIES = 10;
+/**
+ * Try to get a free port.
+ * @param firstPort The first port to try or empty for a random port
+ * @param max_tries maximum amount of tries to get a port, default to {@link MAX_DEFAULT_TRIES}
+ * @returns A valid free port
+ * @throws if "max_tries" is exceeded
+ */
+async function getFreePort(firstPort, max_tries = MAX_DEFAULT_TRIES) {
+ // use "0" as a fallback to use net0listen, which generates a random free port
+ firstPort = firstPort || 0;
+ // clear ports cache after some time, but not on an interval
+ if (PORTS_CACHE.timeSet && Date.now() - PORTS_CACHE.timeSet > PORTS_CACHE_CLEAN_TIME) {
+ PORTS_CACHE.ports.clear();
+ PORTS_CACHE.timeSet = Date.now();
+ }
+ else if (!PORTS_CACHE.timeSet) {
+ PORTS_CACHE.timeSet = Date.now();
+ }
+ let tries = 0;
+ while (tries <= max_tries) {
+ tries += 1;
+ // "0" means to use have ".listen" use a random port
+ const nextPort = tries === 1 ? firstPort : 0;
+ // try next port, because it is already in the cache
+ // unless port is "0" which will use "net.listen(0)"
+ if (PORTS_CACHE.ports.has(nextPort) && nextPort !== 0) {
+ continue;
+ }
+ PORTS_CACHE.ports.add(nextPort);
+ const triedPort = await tryPort(nextPort);
+ if (triedPort > 0) {
+ // check if triedPort is already in the cache (ie the vm executed another instance's getport before binary startup)
+ // and that the triedPort is not a custom port
+ const inCacheAndNotSame = PORTS_CACHE.ports.has(triedPort) && nextPort !== triedPort;
+ log(`getFreePort: found free port ${triedPort}, in cache and not custom: ${inCacheAndNotSame}`);
+ // returned port can be different than the "nextPort" (if net0listen)
+ PORTS_CACHE.ports.add(nextPort);
+ // ensure that no other instance can get the same port if the vm decides to run the other instance's getport before starting the last one
+ if (inCacheAndNotSame) {
+ continue;
+ }
+ // reset the cache time as we now have just added new ports
+ PORTS_CACHE.timeSet = Date.now();
+ return triedPort;
+ }
+ }
+ throw new Error('Max port tries exceeded');
+}
+exports.getFreePort = getFreePort;
+exports.default = getFreePort;
+/**
+ * Ensure that input number is within range of {@link MIN_PORT} and {@link MAX_PORT}.
+ * If more than {@link MAX_PORT}, wrap around, if less than {@link MIN_PORT} use {@link MIN_PORT}.
+ * @param port The Number to check
+ * @returns A Valid number in port range
+ */
+function validPort(port) {
+ const mod = port % exports.MAX_PORT;
+ return mod < exports.MIN_PORT ? exports.MIN_PORT : mod;
+}
+exports.validPort = validPort;
+/**
+ * Try a given port.
+ * @param port The port to try
+ * @returns the port if successful, "-1" in case of `EADDRINUSE`, all other errors reject
+ * @throws The error given if the code is not "EADDRINUSE"
+ */
+function tryPort(port) {
+ return new Promise((res, rej) => {
+ const server = net.createServer();
+ // some engines dont support ".unref"(net / tcp.unref), like "deno" in the past and now "bun"
+ if (typeof server.unref === 'function') {
+ server.unref(); // dont keep this server from exiting the application
+ }
+ server.on('error', (err) => {
+ if (err?.code !== 'EADDRINUSE') {
+ rej(err);
+ }
+ res(-1);
+ });
+ server.listen(port, () => {
+ const address = server.address();
+ const port = address.port;
+ server.close();
+ res(port);
+ });
+ });
+}
+exports.tryPort = tryPort;
+/**
+ * Reset the {@link PORTS_CACHE} to its initial state.
+ *
+ * This function is meant for debugging and testing purposes only.
+ */
+function resetPortsCache() {
+ PORTS_CACHE.timeSet = undefined;
+ PORTS_CACHE.ports.clear();
+}
+exports.resetPortsCache = resetPortsCache;
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/getport/index.js.map b/packages/mongodb-memory-server-core/lib/util/getport/index.js.map
new file mode 100644
index 000000000..c77c39603
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/getport/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/util/getport/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/lockfile.d.ts b/packages/mongodb-memory-server-core/lib/util/lockfile.d.ts
new file mode 100644
index 000000000..495585c9e
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/lockfile.d.ts
@@ -0,0 +1,81 @@
+///
+import { EventEmitter } from 'events';
+import { Mutex } from 'async-mutex';
+export declare enum LockFileStatus {
+ /**
+ * Status is "available" to be grabbed (lockfile not existing or being invalid)
+ */
+ available = 0,
+ /**
+ * Status is "available for asking instance" (instance that asked has the lock)
+ */
+ availableInstance = 1,
+ /**
+ * Status is "locked by another instance in this process"
+ */
+ lockedSelf = 2,
+ /**
+ * Status is "locked by another process"
+ */
+ lockedDifferent = 3
+}
+export declare enum LockFileEvents {
+ lock = "lock",
+ unlock = "unlock"
+}
+interface LockFileEventsClass extends EventEmitter {
+ emit(event: LockFileEvents, ...args: any[]): boolean;
+ on(event: LockFileEvents, listener: (...args: any[]) => void): this;
+ once(event: LockFileEvents, listener: (...args: any[]) => void): this;
+}
+/** Dummy class for types */
+declare class LockFileEventsClass extends EventEmitter {
+}
+export declare class LockFile {
+ /** All Files that are handled by this process */
+ static files: Set;
+ /** Listen for events from this process */
+ static events: LockFileEventsClass;
+ /** Mutex to stop same-process race conditions */
+ static mutex: Mutex;
+ /**
+ * Acquire an lockfile
+ * @param file The file to use as the LockFile
+ */
+ static lock(file: string): Promise;
+ /**
+ * Check the status of the lockfile
+ * @param file The file to use as the LockFile
+ */
+ protected static checkLock(file: string, uuid?: string): Promise;
+ /**
+ * Wait for the Lock file to become available
+ * @param file The file to use as the LockFile
+ */
+ protected static waitForLock(file: string): Promise;
+ /**
+ * Function create the path and lock file
+ * @param file The file to use as the LockFile
+ */
+ protected static createLock(file: string): Promise;
+ /**
+ * File locked by this instance
+ */
+ file?: string;
+ /**
+ * UUID Unique to this lock instance
+ */
+ uuid?: string;
+ constructor(file: string, uuid: string);
+ /**
+ * Unlock the File that is locked by this instance
+ */
+ unlock(): Promise;
+ /**
+ * Helper function for the unlock-cleanup
+ * @param fileio Unlink the file?
+ */
+ protected unlockCleanup(fileio?: boolean): Promise;
+}
+export {};
+//# sourceMappingURL=lockfile.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/lockfile.d.ts.map b/packages/mongodb-memory-server-core/lib/util/lockfile.d.ts.map
new file mode 100644
index 000000000..df4f5e20e
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/lockfile.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../../src/util/lockfile.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAcpC,oBAAY,cAAc;IACxB;;OAEG;IACH,SAAS,IAAA;IACT;;OAEG;IACH,iBAAiB,IAAA;IACjB;;OAEG;IACH,UAAU,IAAA;IACV;;OAEG;IACH,eAAe,IAAA;CAChB;AAED,oBAAY,cAAc;IACxB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAGD,UAAU,mBAAoB,SAAQ,YAAY;IAEhD,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IACrD,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACpE,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CACvE;AAED,4BAA4B;AAE5B,cAAM,mBAAoB,SAAQ,YAAY;CAAG;AAEjD,qBAAa,QAAQ;IACnB,iDAAiD;IACjD,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAa;IACtC,0CAA0C;IAC1C,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAA6B;IAC/D,iDAAiD;IACjD,MAAM,CAAC,KAAK,EAAE,KAAK,CAAe;IAElC;;;OAGG;WACU,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAqBlD;;;OAGG;qBACoB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA+CtF;;;OAGG;qBACoB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAkDnE;;;OAGG;qBACoB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAmClE;;OAEG;IACI,IAAI,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACI,IAAI,CAAC,EAAE,MAAM,CAAC;gBAET,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAKtC;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B7B;;;OAGG;cACa,aAAa,CAAC,MAAM,GAAE,OAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAsBrE"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/lockfile.js b/packages/mongodb-memory-server-core/lib/util/lockfile.js
new file mode 100644
index 000000000..cf9eb3384
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/lockfile.js
@@ -0,0 +1,247 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.LockFile = exports.LockFileEvents = exports.LockFileStatus = void 0;
+const tslib_1 = require("tslib");
+const events_1 = require("events");
+const utils = tslib_1.__importStar(require("./utils"));
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const path = tslib_1.__importStar(require("path"));
+const fs_1 = require("fs");
+const async_mutex_1 = require("async-mutex");
+const errors_1 = require("./errors");
+const log = (0, debug_1.default)('MongoMS:LockFile');
+/**
+ * Error used to cause an promise to stop and re-wait for an lockfile
+ */
+class RepeatError extends Error {
+ constructor(repeat) {
+ super();
+ this.repeat = repeat;
+ }
+}
+var LockFileStatus;
+(function (LockFileStatus) {
+ /**
+ * Status is "available" to be grabbed (lockfile not existing or being invalid)
+ */
+ LockFileStatus[LockFileStatus["available"] = 0] = "available";
+ /**
+ * Status is "available for asking instance" (instance that asked has the lock)
+ */
+ LockFileStatus[LockFileStatus["availableInstance"] = 1] = "availableInstance";
+ /**
+ * Status is "locked by another instance in this process"
+ */
+ LockFileStatus[LockFileStatus["lockedSelf"] = 2] = "lockedSelf";
+ /**
+ * Status is "locked by another process"
+ */
+ LockFileStatus[LockFileStatus["lockedDifferent"] = 3] = "lockedDifferent";
+})(LockFileStatus || (exports.LockFileStatus = LockFileStatus = {}));
+var LockFileEvents;
+(function (LockFileEvents) {
+ LockFileEvents["lock"] = "lock";
+ LockFileEvents["unlock"] = "unlock";
+})(LockFileEvents || (exports.LockFileEvents = LockFileEvents = {}));
+/** Dummy class for types */
+// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
+class LockFileEventsClass extends events_1.EventEmitter {
+}
+class LockFile {
+ /**
+ * Acquire an lockfile
+ * @param file The file to use as the LockFile
+ */
+ static async lock(file) {
+ await utils.ensureAsync();
+ log(`lock: Locking file "${file}"`);
+ const useFile = path.resolve(file.trim());
+ // just to make sure "path" could resolve it to something
+ utils.assertion(useFile.length > 0, new Error('Provided Path for lock file is length of 0'));
+ const status = await this.checkLock(useFile);
+ switch (status) {
+ case LockFileStatus.lockedDifferent:
+ case LockFileStatus.lockedSelf:
+ return this.waitForLock(useFile);
+ case LockFileStatus.available:
+ return this.createLock(useFile);
+ default:
+ throw new errors_1.UnknownLockfileStatusError(status);
+ }
+ }
+ /**
+ * Check the status of the lockfile
+ * @param file The file to use as the LockFile
+ */
+ static async checkLock(file, uuid) {
+ log(`checkLock: for file "${file}" with uuid: "${uuid}"`);
+ // if file / path does not exist, directly acquire lock
+ if (!(await utils.pathExists(file))) {
+ return LockFileStatus.available;
+ }
+ try {
+ const fileData = (await fs_1.promises.readFile(file)).toString().trim().split(' ');
+ const readout = parseInt(fileData[0]);
+ if (readout === process.pid) {
+ log(`checkLock: Lock File Already exists, and is for *this* process, with uuid: "${fileData[1]}"`);
+ // early return if "file"(input) dosnt exists within the files Map anymore
+ if (!this.files.has(file)) {
+ return LockFileStatus.available;
+ }
+ // check if "uuid"(input) matches the filereadout, if yes say "available" (for unlock check)
+ if (!utils.isNullOrUndefined(uuid)) {
+ return uuid === fileData[1]
+ ? LockFileStatus.availableInstance
+ : LockFileStatus.lockedSelf;
+ }
+ // as fallback say "lockedSelf"
+ return LockFileStatus.lockedSelf;
+ }
+ log(`checkLock: Lock File Aready exists, for a different process: "${readout}"`);
+ return utils.isAlive(readout) ? LockFileStatus.lockedDifferent : LockFileStatus.available;
+ }
+ catch (err) {
+ if (utils.errorWithCode(err) && err.code === 'ENOENT') {
+ log('checkLock: reading file failed with ENOENT');
+ return LockFileStatus.available;
+ }
+ throw err;
+ }
+ }
+ /**
+ * Wait for the Lock file to become available
+ * @param file The file to use as the LockFile
+ */
+ static async waitForLock(file) {
+ log(`waitForLock: Starting to wait for file "${file}"`);
+ /** Store the interval id to be cleared later */
+ let interval = undefined;
+ /** Store the function in an value to be cleared later, without having to use an class-external or class function */
+ let eventCB = undefined;
+ await new Promise((res) => {
+ eventCB = (unlockedFile) => {
+ if (unlockedFile === file) {
+ res();
+ }
+ };
+ interval = setInterval(async () => {
+ const lockStatus = await this.checkLock(file);
+ log(`waitForLock: Interval for file "${file}" with status "${lockStatus}"`);
+ if (lockStatus === LockFileStatus.available) {
+ res();
+ }
+ }, 1000 * 3); // every 3 seconds
+ this.events.on(LockFileEvents.unlock, eventCB);
+ });
+ if (interval) {
+ clearInterval(interval);
+ }
+ if (eventCB) {
+ this.events.removeListener(LockFileEvents.unlock, eventCB);
+ }
+ log(`waitForLock: File became available "${file}"`);
+ // i hope the following prevents race-conditions
+ await utils.ensureAsync(); // to make sure all event listeners got executed
+ const lockStatus = await this.checkLock(file);
+ log(`waitForLock: Lock File Status reassessment for file "${file}": ${lockStatus}`);
+ switch (lockStatus) {
+ case LockFileStatus.lockedDifferent:
+ case LockFileStatus.lockedSelf:
+ return this.waitForLock(file);
+ case LockFileStatus.available:
+ return this.createLock(file);
+ default:
+ throw new errors_1.UnknownLockfileStatusError(lockStatus);
+ }
+ }
+ /**
+ * Function create the path and lock file
+ * @param file The file to use as the LockFile
+ */
+ static async createLock(file) {
+ // this function only gets called by processed "file" input, so no re-checking
+ log(`createLock: trying to create a lock file for "${file}"`);
+ const uuid = utils.uuidv4();
+ // This is not an ".catch" because in an callback running "return" dosnt "return" the parent function
+ try {
+ await this.mutex.runExclusive(async () => {
+ // this may cause "Stack Size" errors, because of an infinite loop if too many times this gets called
+ if (this.files.has(file)) {
+ log(`createLock: Map already has file "${file}"`);
+ throw new RepeatError(true);
+ }
+ await utils.mkdir(path.dirname(file));
+ await fs_1.promises.writeFile(file, `${process.pid.toString()} ${uuid}`);
+ this.files.add(file);
+ this.events.emit(LockFileEvents.lock, file);
+ });
+ }
+ catch (err) {
+ if (err instanceof RepeatError && err.repeat) {
+ return this.waitForLock(file);
+ }
+ }
+ log(`createLock: Lock File Created for file "${file}"`);
+ return new this(file, uuid);
+ }
+ constructor(file, uuid) {
+ this.file = file;
+ this.uuid = uuid;
+ }
+ /**
+ * Unlock the File that is locked by this instance
+ */
+ async unlock() {
+ await utils.ensureAsync();
+ log(`unlock: Unlocking file "${this.file}"`);
+ if (utils.isNullOrUndefined(this.file) || this.file?.length <= 0) {
+ log('unlock: invalid file, returning');
+ return;
+ }
+ // No "case-fallthrough" because this is more clear (and no linter will complain)
+ switch (await LockFile.checkLock(this.file, this.uuid)) {
+ case LockFileStatus.available:
+ log(`unlock: Lock Status was already "available" for file "${this.file}"`);
+ await this.unlockCleanup(false);
+ return;
+ case LockFileStatus.availableInstance:
+ log(`unlock: Lock Status was "availableInstance" for file "${this.file}"`);
+ await this.unlockCleanup(true);
+ return;
+ case LockFileStatus.lockedSelf:
+ throw new errors_1.UnableToUnlockLockfileError(true, this.file);
+ default:
+ throw new errors_1.UnableToUnlockLockfileError(false, this.file);
+ }
+ }
+ /**
+ * Helper function for the unlock-cleanup
+ * @param fileio Unlink the file?
+ */
+ async unlockCleanup(fileio = true) {
+ return await LockFile.mutex.runExclusive(async () => {
+ log(`unlockCleanup: for file "${this.file}"`);
+ if (utils.isNullOrUndefined(this.file)) {
+ return;
+ }
+ if (fileio) {
+ await fs_1.promises.unlink(this.file).catch((reason) => {
+ log(`unlockCleanup: lock file unlink failed: "${reason}"`);
+ });
+ }
+ LockFile.files.delete(this.file);
+ LockFile.events.emit(LockFileEvents.unlock, this.file);
+ // make this LockFile instance unusable (to prevent double unlock calling)
+ this.file = undefined;
+ this.uuid = undefined;
+ });
+ }
+}
+exports.LockFile = LockFile;
+/** All Files that are handled by this process */
+LockFile.files = new Set();
+/** Listen for events from this process */
+LockFile.events = new LockFileEventsClass();
+/** Mutex to stop same-process race conditions */
+LockFile.mutex = new async_mutex_1.Mutex();
+//# sourceMappingURL=lockfile.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/lockfile.js.map b/packages/mongodb-memory-server-core/lib/util/lockfile.js.map
new file mode 100644
index 000000000..97c5da60c
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/lockfile.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../src/util/lockfile.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/postinstallHelper.d.ts b/packages/mongodb-memory-server-core/lib/util/postinstallHelper.d.ts
new file mode 100644
index 000000000..4e8a69f74
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/postinstallHelper.d.ts
@@ -0,0 +1,2 @@
+export declare function postInstallEnsureBinary(version?: string, local?: boolean): Promise;
+//# sourceMappingURL=postinstallHelper.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/postinstallHelper.d.ts.map b/packages/mongodb-memory-server-core/lib/util/postinstallHelper.d.ts.map
new file mode 100644
index 000000000..738018758
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/postinstallHelper.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"postinstallHelper.d.ts","sourceRoot":"","sources":["../../src/util/postinstallHelper.ts"],"names":[],"mappings":"AA8BA,wBAAsB,uBAAuB,CAC3C,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,OAAO,GACd,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAyBvB"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/postinstallHelper.js b/packages/mongodb-memory-server-core/lib/util/postinstallHelper.js
new file mode 100644
index 000000000..6ce22629c
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/postinstallHelper.js
@@ -0,0 +1,41 @@
+"use strict";
+// this file is used by 'mongodb-memory-server' and 'mongodb-memory-server-global' (and '-global-x.x') as an shared install script
+// in this file the types for variables are set *explicitly* to prevent issues on type changes
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.postInstallEnsureBinary = void 0;
+const os_1 = require("os");
+const path_1 = require("path");
+const MongoBinary_1 = require("./MongoBinary");
+const resolveConfig_1 = require("./resolveConfig");
+(0, resolveConfig_1.findPackageJson)(process.env.INIT_CWD);
+if (!!(0, resolveConfig_1.envToBool)((0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.DISABLE_POSTINSTALL))) {
+ console.log('Mongodb-Memory-Server* postinstall skipped because "DISABLE_POSTINSTALL" was set to an truthy value');
+ process.exit(0);
+}
+// value is ensured to be either an string (with more than 0 length) or being undefined
+if (typeof (0, resolveConfig_1.resolveConfig)(resolveConfig_1.ResolveConfigVariables.SYSTEM_BINARY) === 'string') {
+ console.log('Mongodb-Memory-Server* postinstall skipped because "SYSTEM_BINARY" was provided');
+ process.exit(0);
+}
+async function postInstallEnsureBinary(version, local) {
+ console.log('Mongodb-Memory-Server* checking MongoDB binaries');
+ if (!local) {
+ // set "DOWNLOAD_DIR" to ~/.cache
+ (0, resolveConfig_1.setDefaultValue)(resolveConfig_1.ResolveConfigVariables.DOWNLOAD_DIR, (0, path_1.resolve)((0, os_1.homedir)(), '.cache', 'mongodb-binaries'));
+ }
+ else {
+ (0, resolveConfig_1.setDefaultValue)(resolveConfig_1.ResolveConfigVariables.PREFER_GLOBAL_PATH, 'false');
+ }
+ if (version) {
+ // if "version" is defined, apply it
+ (0, resolveConfig_1.setDefaultValue)(resolveConfig_1.ResolveConfigVariables.VERSION, version);
+ }
+ process.env[(0, resolveConfig_1.envName)(resolveConfig_1.ResolveConfigVariables.RUNTIME_DOWNLOAD)] = 'true'; // To make sure to actually download in an postinstall
+ const binPath = await MongoBinary_1.MongoBinary.getPath().catch((err) => {
+ console.warn('Mongodb-Memory-Server* failed to find an binary:\n', err.message);
+ process.exit(0); // Exiting with "0" to not fail the install (because it is an problem that can be solved otherwise)
+ });
+ console.log(`Mongodb-Memory-Server* found binary: "${binPath}"`);
+}
+exports.postInstallEnsureBinary = postInstallEnsureBinary;
+//# sourceMappingURL=postinstallHelper.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/postinstallHelper.js.map b/packages/mongodb-memory-server-core/lib/util/postinstallHelper.js.map
new file mode 100644
index 000000000..a4169ca0c
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/postinstallHelper.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"postinstallHelper.js","sourceRoot":"","sources":["../../src/util/postinstallHelper.ts"],"names":[],"mappings":";AAAA,kIAAkI;AAClI,8FAA8F;;;AAE9F,2BAA6B;AAC7B,+BAA+B;AAC/B,+CAA4C;AAC5C,mDAOyB;AAEzB,IAAA,+BAAe,EAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAEtC,IAAI,CAAC,CAAC,IAAA,yBAAS,EAAC,IAAA,6BAAa,EAAC,sCAAsB,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC;IAC3E,OAAO,CAAC,GAAG,CACT,qGAAqG,CACtG,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,uFAAuF;AACvF,IAAI,OAAO,IAAA,6BAAa,EAAC,sCAAsB,CAAC,aAAa,CAAC,KAAK,QAAQ,EAAE,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;IAC/F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAEM,KAAK,UAAU,uBAAuB,CAC3C,OAAgB,EAChB,KAAe;IAEf,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;IAEhE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,iCAAiC;QACjC,IAAA,+BAAe,EACb,sCAAsB,CAAC,YAAY,EACnC,IAAA,cAAO,EAAC,IAAA,YAAO,GAAE,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CACjD,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,IAAA,+BAAe,EAAC,sCAAsB,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,oCAAoC;QACpC,IAAA,+BAAe,EAAC,sCAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAA,uBAAO,EAAC,sCAAsB,CAAC,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,sDAAsD;IAE9H,MAAM,OAAO,GAAG,MAAM,yBAAW,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACxD,OAAO,CAAC,IAAI,CAAC,oDAAoD,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,mGAAmG;IACtH,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,yCAAyC,OAAO,GAAG,CAAC,CAAC;AACnE,CAAC;AA5BD,0DA4BC"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/resolveConfig.d.ts b/packages/mongodb-memory-server-core/lib/util/resolveConfig.d.ts
new file mode 100644
index 000000000..254388799
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/resolveConfig.d.ts
@@ -0,0 +1,77 @@
+/** Enum of all possible config options */
+export declare enum ResolveConfigVariables {
+ DOWNLOAD_DIR = "DOWNLOAD_DIR",
+ PLATFORM = "PLATFORM",
+ ARCH = "ARCH",
+ VERSION = "VERSION",
+ DEBUG = "DEBUG",
+ DOWNLOAD_MIRROR = "DOWNLOAD_MIRROR",
+ DOWNLOAD_URL = "DOWNLOAD_URL",
+ DOWNLOAD_IGNORE_MISSING_HEADER = "DOWNLOAD_IGNORE_MISSING_HEADER",
+ PREFER_GLOBAL_PATH = "PREFER_GLOBAL_PATH",
+ DISABLE_POSTINSTALL = "DISABLE_POSTINSTALL",
+ SYSTEM_BINARY = "SYSTEM_BINARY",
+ MD5_CHECK = "MD5_CHECK",
+ ARCHIVE_NAME = "ARCHIVE_NAME",
+ RUNTIME_DOWNLOAD = "RUNTIME_DOWNLOAD",
+ USE_HTTP = "USE_HTTP",
+ SYSTEM_BINARY_VERSION_CHECK = "SYSTEM_BINARY_VERSION_CHECK",
+ USE_ARCHIVE_NAME_FOR_BINARY_NAME = "USE_ARCHIVE_NAME_FOR_BINARY_NAME",
+ MAX_REDIRECTS = "MAX_REDIRECTS",
+ MAX_RETRIES = "MAX_RETRIES",// Added for download retry configuration
+ DISTRO = "DISTRO"
+}
+/** The Prefix for Environmental values */
+export declare const ENV_CONFIG_PREFIX = "MONGOMS_";
+/** This Value exists here, because "defaultValues" can be changed with "setDefaultValue", but this property is constant */
+export declare const DEFAULT_VERSION = "7.0.14";
+/** Default values for some config options that require explicit setting, it is constant so that the default values cannot be interfered with */
+export declare const defaultValues: Map;
+/** Interface for storing information about the found package.json from `findPackageJson` */
+interface PackageJSON {
+ /** The Path where the package.json was found (directory, not the file) */
+ filePath: string;
+ /** The Options that were parsed from the package.json */
+ config: Record;
+}
+/**
+ * Set an Default value for an specific key
+ * Mostly only used internally (for the "global-x.x" packages)
+ * @param key The Key the default value should be assigned to
+ * @param value The Value what the default should be
+ */
+export declare function setDefaultValue(key: ResolveConfigVariables, value: string): void;
+/**
+ * Find the nearest package.json (that has an non-empty config field) for the provided directory
+ * @param directory Set an custom directory to search the config in (default: process.cwd())
+ * @returns what "packagejson" variable is
+ */
+export declare function findPackageJson(directory?: string): PackageJSON | undefined;
+/**
+ * Apply Proccessing to input options (like resolving paths)
+ * @param input The input to process
+ * @param filepath The FilePath for the input to resolve relative paths to (needs to be a dirname and absolute)
+ * @returns always returns a object
+ */
+export declare function processConfigOption(input: unknown, filepath: string): Record;
+/**
+ * Resolve "variableName" value (process.env | packagejson | default | undefined)
+ * @param variableName The variable to search an value for
+ */
+export declare function resolveConfig(variableName: ResolveConfigVariables): string | undefined;
+/**
+ * Get the directory path of the `package.json` with config options, if available
+ * @returns The directory of the `package.json`, otherwise `undefined`
+ */
+export declare function packageJsonPath(): string | undefined;
+export default resolveConfig;
+/**
+ * Helper Function to add the prefix for "process.env[]"
+ */
+export declare function envName(variableName: ResolveConfigVariables): string;
+/**
+ * Convert "1, on, yes, true" to true (otherwise false)
+ * @param env The String / Environment Variable to check
+ */
+export declare function envToBool(env?: string): boolean;
+//# sourceMappingURL=resolveConfig.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/resolveConfig.d.ts.map b/packages/mongodb-memory-server-core/lib/util/resolveConfig.d.ts.map
new file mode 100644
index 000000000..fe0aa6a0e
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/resolveConfig.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"resolveConfig.d.ts","sourceRoot":"","sources":["../../src/util/resolveConfig.ts"],"names":[],"mappings":"AAeA,0CAA0C;AAC1C,oBAAY,sBAAsB;IAChC,YAAY,iBAAiB;IAC7B,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,KAAK,UAAU;IACf,eAAe,oBAAoB;IACnC,YAAY,iBAAiB;IAC7B,8BAA8B,mCAAmC;IACjE,kBAAkB,uBAAuB;IACzC,mBAAmB,wBAAwB;IAC3C,aAAa,kBAAkB;IAC/B,SAAS,cAAc;IACvB,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,QAAQ,aAAa;IACrB,2BAA2B,gCAAgC;IAC3D,gCAAgC,qCAAqC;IACrE,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB,CAAE,yCAAyC;IACtE,MAAM,WAAW;CAClB;AAED,0CAA0C;AAC1C,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAC5C,2HAA2H;AAC3H,eAAO,MAAM,eAAe,WAAW,CAAC;AACxC,gJAAgJ;AAChJ,eAAO,MAAM,aAAa,qCAWxB,CAAC;AAEH,4FAA4F;AAC5F,UAAU,WAAW;IACnB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEhF;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAsB3E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA0B5F;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,sBAAsB,GAAG,MAAM,GAAG,SAAS,CAMtF;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAEpD;AAED,eAAe,aAAa,CAAC;AAE7B;;GAEG;AACH,wBAAgB,OAAO,CAAC,YAAY,EAAE,sBAAsB,GAAG,MAAM,CAEpE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,GAAE,MAAW,GAAG,OAAO,CAQnD"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/resolveConfig.js b/packages/mongodb-memory-server-core/lib/util/resolveConfig.js
new file mode 100644
index 000000000..54110e2d4
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/resolveConfig.js
@@ -0,0 +1,178 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.envToBool = exports.envName = exports.packageJsonPath = exports.resolveConfig = exports.processConfigOption = exports.findPackageJson = exports.setDefaultValue = exports.defaultValues = exports.DEFAULT_VERSION = exports.ENV_CONFIG_PREFIX = exports.ResolveConfigVariables = void 0;
+const tslib_1 = require("tslib");
+const camelcase_1 = tslib_1.__importDefault(require("camelcase"));
+const new_find_package_json_1 = require("new-find-package-json");
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const path = tslib_1.__importStar(require("path"));
+const fs_1 = require("fs");
+const utils_1 = require("./utils");
+// polyfills
+// @ts-expect-error they are marked "read-only", but are set-able if not implemented by the runtime
+Symbol.dispose ??= Symbol('Symbol.dispose');
+// @ts-expect-error they are marked "read-only", but are set-able if not implemented by the runtime
+Symbol.asyncDispose ??= Symbol('Symbol.asyncDispose');
+const log = (0, debug_1.default)('MongoMS:ResolveConfig');
+/** Enum of all possible config options */
+var ResolveConfigVariables;
+(function (ResolveConfigVariables) {
+ ResolveConfigVariables["DOWNLOAD_DIR"] = "DOWNLOAD_DIR";
+ ResolveConfigVariables["PLATFORM"] = "PLATFORM";
+ ResolveConfigVariables["ARCH"] = "ARCH";
+ ResolveConfigVariables["VERSION"] = "VERSION";
+ ResolveConfigVariables["DEBUG"] = "DEBUG";
+ ResolveConfigVariables["DOWNLOAD_MIRROR"] = "DOWNLOAD_MIRROR";
+ ResolveConfigVariables["DOWNLOAD_URL"] = "DOWNLOAD_URL";
+ ResolveConfigVariables["DOWNLOAD_IGNORE_MISSING_HEADER"] = "DOWNLOAD_IGNORE_MISSING_HEADER";
+ ResolveConfigVariables["PREFER_GLOBAL_PATH"] = "PREFER_GLOBAL_PATH";
+ ResolveConfigVariables["DISABLE_POSTINSTALL"] = "DISABLE_POSTINSTALL";
+ ResolveConfigVariables["SYSTEM_BINARY"] = "SYSTEM_BINARY";
+ ResolveConfigVariables["MD5_CHECK"] = "MD5_CHECK";
+ ResolveConfigVariables["ARCHIVE_NAME"] = "ARCHIVE_NAME";
+ ResolveConfigVariables["RUNTIME_DOWNLOAD"] = "RUNTIME_DOWNLOAD";
+ ResolveConfigVariables["USE_HTTP"] = "USE_HTTP";
+ ResolveConfigVariables["SYSTEM_BINARY_VERSION_CHECK"] = "SYSTEM_BINARY_VERSION_CHECK";
+ ResolveConfigVariables["USE_ARCHIVE_NAME_FOR_BINARY_NAME"] = "USE_ARCHIVE_NAME_FOR_BINARY_NAME";
+ ResolveConfigVariables["MAX_REDIRECTS"] = "MAX_REDIRECTS";
+ ResolveConfigVariables["MAX_RETRIES"] = "MAX_RETRIES";
+ ResolveConfigVariables["DISTRO"] = "DISTRO";
+})(ResolveConfigVariables || (exports.ResolveConfigVariables = ResolveConfigVariables = {}));
+/** The Prefix for Environmental values */
+exports.ENV_CONFIG_PREFIX = 'MONGOMS_';
+/** This Value exists here, because "defaultValues" can be changed with "setDefaultValue", but this property is constant */
+exports.DEFAULT_VERSION = '7.0.14';
+/** Default values for some config options that require explicit setting, it is constant so that the default values cannot be interfered with */
+exports.defaultValues = new Map([
+ // apply app-default values here
+ [ResolveConfigVariables.VERSION, exports.DEFAULT_VERSION],
+ [ResolveConfigVariables.PREFER_GLOBAL_PATH, 'true'],
+ [ResolveConfigVariables.RUNTIME_DOWNLOAD, 'true'],
+ [ResolveConfigVariables.USE_HTTP, 'false'],
+ [ResolveConfigVariables.SYSTEM_BINARY_VERSION_CHECK, 'true'],
+ [ResolveConfigVariables.USE_ARCHIVE_NAME_FOR_BINARY_NAME, 'false'],
+ [ResolveConfigVariables.MD5_CHECK, 'true'],
+ [ResolveConfigVariables.MAX_REDIRECTS, '2'],
+ [ResolveConfigVariables.MAX_RETRIES, '3'], // Default maxRetries for downloads
+]);
+/**
+ * Set an Default value for an specific key
+ * Mostly only used internally (for the "global-x.x" packages)
+ * @param key The Key the default value should be assigned to
+ * @param value The Value what the default should be
+ */
+function setDefaultValue(key, value) {
+ exports.defaultValues.set(key, value);
+}
+exports.setDefaultValue = setDefaultValue;
+/** Cache the found package.json file */
+let packagejson = undefined;
+/**
+ * Find the nearest package.json (that has an non-empty config field) for the provided directory
+ * @param directory Set an custom directory to search the config in (default: process.cwd())
+ * @returns what "packagejson" variable is
+ */
+function findPackageJson(directory) {
+ for (const filename of (0, new_find_package_json_1.findSync)(directory || process.cwd())) {
+ log(`findPackageJson: Found package.json at "${filename}"`);
+ const readout = JSON.parse((0, fs_1.readFileSync)(filename).toString());
+ /** Shorthand for the long path */
+ const config = readout?.config?.mongodbMemoryServer;
+ if (!(0, utils_1.isNullOrUndefined)(config) && Object.keys(config ?? {}).length > 0) {
+ log(`findPackageJson: Found package with non-empty config field at "${filename}"`);
+ const filepath = path.dirname(filename);
+ packagejson = {
+ filePath: filepath,
+ config: processConfigOption(config, filepath),
+ };
+ break;
+ }
+ }
+ return packagejson;
+}
+exports.findPackageJson = findPackageJson;
+/**
+ * Apply Proccessing to input options (like resolving paths)
+ * @param input The input to process
+ * @param filepath The FilePath for the input to resolve relative paths to (needs to be a dirname and absolute)
+ * @returns always returns a object
+ */
+function processConfigOption(input, filepath) {
+ log('processConfigOption', input, filepath);
+ if (typeof input !== 'object') {
+ log('processConfigOptions: input was not a object');
+ return {};
+ }
+ // cast because it was tested before that "input" is a object and the key can only be a string in a package.json
+ const returnobj = input;
+ // These are so that "camelCase" doesnt get executed much & de-duplicate code
+ // "cc*" means "camelcase"
+ const ccDownloadDir = (0, camelcase_1.default)(ResolveConfigVariables.DOWNLOAD_DIR);
+ const ccSystemBinary = (0, camelcase_1.default)(ResolveConfigVariables.SYSTEM_BINARY);
+ if (ccDownloadDir in returnobj) {
+ returnobj[ccDownloadDir] = path.resolve(filepath, returnobj[ccDownloadDir]);
+ }
+ if (ccSystemBinary in returnobj) {
+ returnobj[ccSystemBinary] = path.resolve(filepath, returnobj[ccSystemBinary]);
+ }
+ return returnobj;
+}
+exports.processConfigOption = processConfigOption;
+/**
+ * Resolve "variableName" value (process.env | packagejson | default | undefined)
+ * @param variableName The variable to search an value for
+ */
+function resolveConfig(variableName) {
+ return (process.env[envName(variableName)] ??
+ packagejson?.config[(0, camelcase_1.default)(variableName)] ??
+ exports.defaultValues.get(variableName))?.toString();
+}
+exports.resolveConfig = resolveConfig;
+/**
+ * Get the directory path of the `package.json` with config options, if available
+ * @returns The directory of the `package.json`, otherwise `undefined`
+ */
+function packageJsonPath() {
+ return packagejson?.filePath;
+}
+exports.packageJsonPath = packageJsonPath;
+exports.default = resolveConfig;
+/**
+ * Helper Function to add the prefix for "process.env[]"
+ */
+function envName(variableName) {
+ return `${exports.ENV_CONFIG_PREFIX}${variableName}`;
+}
+exports.envName = envName;
+/**
+ * Convert "1, on, yes, true" to true (otherwise false)
+ * @param env The String / Environment Variable to check
+ */
+function envToBool(env = '') {
+ if (typeof env !== 'string') {
+ log('envToBool: input was not a string!');
+ return false;
+ }
+ return ['1', 'on', 'yes', 'true'].indexOf(env.toLowerCase()) !== -1;
+}
+exports.envToBool = envToBool;
+/**
+ * This exists because "debug.enabled('MongoMS:*')" will always return "true"
+ * This is used to not double-enable / double-print the enablement message
+ */
+let debug_enabled = false;
+// enable debug if "MONGOMS_DEBUG" is true
+if (envToBool(resolveConfig(ResolveConfigVariables.DEBUG))) {
+ debug_1.default.enable('MongoMS:*');
+ log('Debug Mode Enabled, through Environment Variable');
+ debug_enabled = true;
+}
+// run this after env debug enable to be able to debug this function too
+findPackageJson();
+// enable debug if "config.mongodbMemoryServer.debug" is true
+if (envToBool(resolveConfig(ResolveConfigVariables.DEBUG)) && !debug_enabled) {
+ debug_1.default.enable('MongoMS:*');
+ log('Debug Mode Enabled, through package.json');
+ debug_enabled = true;
+}
+//# sourceMappingURL=resolveConfig.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/resolveConfig.js.map b/packages/mongodb-memory-server-core/lib/util/resolveConfig.js.map
new file mode 100644
index 000000000..5d08a9e78
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/resolveConfig.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"resolveConfig.js","sourceRoot":"","sources":["../../src/util/resolveConfig.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/utils.d.ts b/packages/mongodb-memory-server-core/lib/util/utils.d.ts
new file mode 100644
index 000000000..72749d030
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/utils.d.ts
@@ -0,0 +1,182 @@
+///
+///
+///
+import { ChildProcess } from 'child_process';
+import { AutomaticAuth } from '../MongoMemoryServer';
+import { Stats } from 'fs';
+import { LinuxOS } from './getos';
+import { BinaryLike } from 'crypto';
+import { StorageEngine } from './MongoInstance';
+import * as semver from 'semver';
+/**
+ * This is here, because NodeJS does not have a FSError type
+ */
+interface ErrorWithCode extends Error {
+ code: string;
+}
+/**
+ * This is here, because NodeJS does not have a FSError type
+ * @param err Value to check agains
+ * @returns `true` if it is a error with code, `false` if not
+ */
+export declare function errorWithCode(err: unknown): err is ErrorWithCode;
+/**
+ * Return input or default database
+ * @param {string} dbName
+ */
+export declare function generateDbName(dbName?: string): string;
+/**
+ * Extracts the host and port information from a mongodb URI string.
+ * @param {string} uri mongodb URI
+ */
+export declare function getHost(uri: string): string;
+/**
+ * Basic MongoDB Connection string
+ * @param host the host ip or an list of hosts
+ * @param port the host port or undefined if "host" is an list of hosts
+ * @param dbName the database to add to the uri (in mongodb its the auth database, in mongoose its the default database for models)
+ * @param query extra uri-query options (joined with "&")
+ */
+export declare function uriTemplate(host: string, port: number | undefined, dbName: string, query?: string[]): string;
+/**
+ * Because since node 4.0.0 the internal util.is* functions got deprecated
+ * @param val Any value to test if null or undefined
+ */
+export declare function isNullOrUndefined(val: unknown): val is null | undefined;
+/**
+ * Assert an condition, if "false" throw error
+ * Note: it is not named "assert" to differentiate between node and jest types
+ * @param cond The Condition to throw
+ * @param error An Custom Error to throw
+ */
+export declare function assertion(cond: unknown, error?: Error): asserts cond;
+/**
+ * Kill an ChildProcess
+ * @param childprocess The Process to kill
+ * @param name the name used in the logs
+ * @param mongodPort the port for the mongod process (for easier logging)
+ */
+export declare function killProcess(childprocess: ChildProcess, name: string, mongodPort?: number): Promise;
+/**
+ * Check if the given Process is still alive
+ * @param {number} pid The Process PID
+ */
+export declare function isAlive(pid?: number): boolean;
+/**
+ * Call "process.nextTick" to ensure an function is exectued directly after all code surrounding it
+ * look at the following link to get to know on why this needed: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#process-nexttick (read full documentation)
+ */
+export declare function ensureAsync(): Promise;
+/**
+ * Convert Partitial input into full-defaulted output
+ * @param opts Partitial input options
+ */
+export declare function authDefault(opts: AutomaticAuth): Required;
+/**
+ * Run "fs.promises.stat", but return "undefined" if error is "ENOENT" or "EACCES"
+ * follows symlinks
+ * @param path The Path to Stat
+ * @throws if the error is not "ENOENT" or "EACCES"
+ */
+export declare function statPath(path: string): Promise;
+/**
+ * Like "fs.existsSync" but async
+ * uses "utils.statPath"
+ * follows symlinks
+ * @param path The Path to check for
+ */
+export declare function pathExists(path: string): Promise;
+/**
+ * Try to read an release file path and apply an parser to the output
+ * @param path The Path to read for an release file
+ * @param parser An function to parse the output of the file
+ */
+export declare function tryReleaseFile(path: string, parser: (output: string) => LinuxOS | undefined): Promise;
+/**
+ * Cleanup interface to provide easy to understand arguments for clean-up
+ */
+export interface Cleanup {
+ /**
+ * Setting this to `true` will activate cleanup
+ * @default true
+ */
+ doCleanup?: boolean;
+ /**
+ * Setting this to `true` will cleanup the directory even if it is *not* a temporary directory
+ * @default false
+ */
+ force?: boolean;
+}
+/**
+ * This Class is used to have unified types for base-manager functions
+ */
+export declare abstract class ManagerBase {
+ abstract start(forceSamePort: boolean): Promise;
+ abstract start(): Promise;
+ abstract stop(cleanup: Cleanup): Promise;
+ abstract [Symbol.asyncDispose](): Promise;
+}
+/**
+ * This Class is used to have unified types for advanced-manager functions
+ */
+export declare abstract class ManagerAdvanced extends ManagerBase {
+ abstract getUri(otherDB?: string | boolean): string;
+ abstract cleanup(cleanup: Cleanup): Promise;
+}
+/**
+ * Check that the Binary has sufficient Permissions to be executed
+ * @param path The Path to check
+ */
+export declare function checkBinaryPermissions(path: string): Promise;
+/**
+ * Make Directory, wrapper for native mkdir with recursive true
+ * @param path The Path to create
+ * @returns Nothing
+ */
+export declare function mkdir(path: string): Promise;
+/**
+ * Create a Temporary directory with prefix, and optionally at "atPath"
+ * @param prefix The prefix to use to create the tmpdir
+ * @param atPath Optionally set a custom path other than "os.tmpdir"
+ * @returns The created Path
+ */
+export declare function createTmpDir(prefix: string, atPath?: string): Promise;
+/**
+ * Removes the given "path", if it is a directory, and does not throw a error if not existing
+ * @param dirPath The Directory Path to delete
+ * @returns "true" if deleted, otherwise "false"
+ */
+export declare function removeDir(dirPath: string): Promise;
+/**
+ * Helper function to have uuidv4 generation and definition in one place
+ * @returns a uuid-v4
+ */
+export declare function uuidv4(): string;
+/**
+ * Helper function to have md5 generation and definition in one place
+ * @param content the content to checksum
+ * @returns a md5 of the input
+ */
+export declare function md5(content: BinaryLike): string;
+/**
+ * Helper function to have md5 generation and definition in one place for a file
+ * @param file the location of a file to read for a hash
+ * @returns a md5 of the input file
+ */
+export declare function md5FromFile(file: string): Promise;
+/**
+ * Helper function to get the lockfile for the provided `version` in `downloadDir`
+ * @param downloadDir The Download directory of the binary
+ * @param version The version to be downlaoded
+ * @returns The lockfile path
+ */
+export declare function lockfilePath(downloadDir: string, version: string): string;
+/**
+ * Get the storage engine for the given given binary version, and issue a warning if it needs to be changed
+ * @param storageEngine The engine that is configured
+ * @param coercedVersion The binary version as semver
+ * @returns The engine that actually will run in the given binary version
+ */
+export declare function getStorageEngine(storageEngine: StorageEngine | undefined, coercedVersion: semver.SemVer): StorageEngine;
+export {};
+//# sourceMappingURL=utils.d.ts.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/utils.d.ts.map b/packages/mongodb-memory-server-core/lib/util/utils.d.ts.map
new file mode 100644
index 000000000..a94e89261
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/utils.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/util/utils.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/utils.js b/packages/mongodb-memory-server-core/lib/util/utils.js
new file mode 100644
index 000000000..873a452b9
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/utils.js
@@ -0,0 +1,334 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getStorageEngine = exports.lockfilePath = exports.md5FromFile = exports.md5 = exports.uuidv4 = exports.removeDir = exports.createTmpDir = exports.mkdir = exports.checkBinaryPermissions = exports.ManagerAdvanced = exports.ManagerBase = exports.tryReleaseFile = exports.pathExists = exports.statPath = exports.authDefault = exports.ensureAsync = exports.isAlive = exports.killProcess = exports.assertion = exports.isNullOrUndefined = exports.uriTemplate = exports.getHost = exports.generateDbName = exports.errorWithCode = void 0;
+const tslib_1 = require("tslib");
+const debug_1 = tslib_1.__importDefault(require("debug"));
+const fs_1 = require("fs");
+const errors_1 = require("./errors");
+const os_1 = require("os");
+const path = tslib_1.__importStar(require("path"));
+const crypto_1 = require("crypto");
+const semver = tslib_1.__importStar(require("semver"));
+const log = (0, debug_1.default)('MongoMS:utils');
+/**
+ * This is here, because NodeJS does not have a FSError type
+ * @param err Value to check agains
+ * @returns `true` if it is a error with code, `false` if not
+ */
+function errorWithCode(err) {
+ return err instanceof Error && 'code' in err;
+}
+exports.errorWithCode = errorWithCode;
+/**
+ * Return input or default database
+ * @param {string} dbName
+ */
+function generateDbName(dbName) {
+ // this is ""(empty) to make it compatible with mongodb's uri format and mongoose's uri format
+ // (in mongodb its the auth database, in mongoose its the default database for models)
+ return dbName || '';
+}
+exports.generateDbName = generateDbName;
+/**
+ * Extracts the host and port information from a mongodb URI string.
+ * @param {string} uri mongodb URI
+ */
+function getHost(uri) {
+ // this will turn "mongodb://user:pass@localhost:port/authdb?queryoptions=1" to "localhost:port"
+ return uri.replace(/(?:^mongodb:\/{2})|(?:\/.*$)|(?:.*@)/gim, '');
+}
+exports.getHost = getHost;
+/**
+ * Basic MongoDB Connection string
+ * @param host the host ip or an list of hosts
+ * @param port the host port or undefined if "host" is an list of hosts
+ * @param dbName the database to add to the uri (in mongodb its the auth database, in mongoose its the default database for models)
+ * @param query extra uri-query options (joined with "&")
+ */
+function uriTemplate(host, port, dbName, query) {
+ const hosts = !isNullOrUndefined(port) ? `${host}:${port}` : host;
+ return `mongodb://${hosts}/${dbName}` + (!isNullOrUndefined(query) ? `?${query.join('&')}` : '');
+}
+exports.uriTemplate = uriTemplate;
+/**
+ * Because since node 4.0.0 the internal util.is* functions got deprecated
+ * @param val Any value to test if null or undefined
+ */
+function isNullOrUndefined(val) {
+ return val === null || val === undefined;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+/**
+ * Assert an condition, if "false" throw error
+ * Note: it is not named "assert" to differentiate between node and jest types
+ * @param cond The Condition to throw
+ * @param error An Custom Error to throw
+ */
+function assertion(cond, error) {
+ if (!cond) {
+ throw error ?? new errors_1.AssertionFallbackError();
+ }
+}
+exports.assertion = assertion;
+/**
+ * Kill an ChildProcess
+ * @param childprocess The Process to kill
+ * @param name the name used in the logs
+ * @param mongodPort the port for the mongod process (for easier logging)
+ */
+async function killProcess(childprocess, name, mongodPort) {
+ function ilog(msg) {
+ log(`Mongo[${mongodPort || 'unknown'}] killProcess: ${msg}`);
+ }
+ // this case can somehow happen, see https://github.com/typegoose/mongodb-memory-server/issues/666
+ if (isNullOrUndefined(childprocess)) {
+ ilog('childprocess was somehow undefined');
+ return;
+ }
+ // check if the childProcess (via PID) is still alive (found thanks to https://github.com/typegoose/mongodb-memory-server/issues/411)
+ if (!isAlive(childprocess.pid)) {
+ ilog("given childProcess's PID was not alive anymore");
+ return;
+ }
+ /**
+ * Timeout before using SIGKILL
+ */
+ const timeoutTime = 1000 * 10;
+ await new Promise((res, rej) => {
+ let timeout = setTimeout(() => {
+ ilog('timeout triggered, trying SIGKILL');
+ if (!debug_1.default.enabled('MongoMS:utils')) {
+ console.warn('An Process didnt exit with signal "SIGINT" within 10 seconds, using "SIGKILL"!\n' +
+ 'Enable debug logs for more information');
+ }
+ childprocess.kill('SIGKILL');
+ timeout = setTimeout(() => {
+ ilog('timeout triggered again, rejecting');
+ rej(new Error(`Process "${name}" didnt exit, enable debug for more information.`));
+ }, timeoutTime);
+ }, timeoutTime);
+ childprocess.once(`exit`, (code, signal) => {
+ ilog(`${name}: got exit signal, Code: ${code}, Signal: ${signal}`);
+ clearTimeout(timeout);
+ res();
+ });
+ ilog(`${name}: sending "SIGINT"`);
+ childprocess.kill('SIGINT');
+ });
+}
+exports.killProcess = killProcess;
+/**
+ * Check if the given Process is still alive
+ * @param {number} pid The Process PID
+ */
+function isAlive(pid) {
+ // This test (and allow to be undefined) is here because somewhere between nodejs 12 and 16 the types for "childprocess.pid" changed to include "| undefined"
+ if (isNullOrUndefined(pid)) {
+ return false;
+ }
+ try {
+ process.kill(pid, 0); // code "0" dosnt actually kill anything (on all supported systems)
+ return true;
+ }
+ catch (err) {
+ return false;
+ }
+}
+exports.isAlive = isAlive;
+/**
+ * Call "process.nextTick" to ensure an function is exectued directly after all code surrounding it
+ * look at the following link to get to know on why this needed: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#process-nexttick (read full documentation)
+ */
+async function ensureAsync() {
+ return new Promise((res) => process.nextTick(res));
+}
+exports.ensureAsync = ensureAsync;
+/**
+ * Convert Partitial input into full-defaulted output
+ * @param opts Partitial input options
+ */
+function authDefault(opts) {
+ return {
+ force: false,
+ enable: true,
+ customRootName: 'mongodb-memory-server-root',
+ customRootPwd: 'rootuser',
+ extraUsers: [],
+ keyfileContent: '0123456789',
+ ...opts,
+ };
+}
+exports.authDefault = authDefault;
+/**
+ * Run "fs.promises.stat", but return "undefined" if error is "ENOENT" or "EACCES"
+ * follows symlinks
+ * @param path The Path to Stat
+ * @throws if the error is not "ENOENT" or "EACCES"
+ */
+async function statPath(path) {
+ return fs_1.promises.stat(path).catch((err) => {
+ // catch the error if the directory doesn't exist or permission is denied, without throwing an error
+ if (['ENOENT', 'EACCES'].includes(err.code)) {
+ return undefined;
+ }
+ throw err;
+ });
+}
+exports.statPath = statPath;
+/**
+ * Like "fs.existsSync" but async
+ * uses "utils.statPath"
+ * follows symlinks
+ * @param path The Path to check for
+ */
+async function pathExists(path) {
+ return !isNullOrUndefined(await statPath(path));
+}
+exports.pathExists = pathExists;
+/**
+ * Try to read an release file path and apply an parser to the output
+ * @param path The Path to read for an release file
+ * @param parser An function to parse the output of the file
+ */
+async function tryReleaseFile(path, parser) {
+ try {
+ const output = await fs_1.promises.readFile(path);
+ return parser(output.toString());
+ }
+ catch (err) {
+ if (errorWithCode(err) && !['ENOENT', 'EACCES'].includes(err.code)) {
+ throw err;
+ }
+ log(`tryReleaseFile: "${path}" does not exist`);
+ return undefined;
+ }
+}
+exports.tryReleaseFile = tryReleaseFile;
+/**
+ * This Class is used to have unified types for base-manager functions
+ */
+class ManagerBase {
+}
+exports.ManagerBase = ManagerBase;
+/**
+ * This Class is used to have unified types for advanced-manager functions
+ */
+class ManagerAdvanced extends ManagerBase {
+}
+exports.ManagerAdvanced = ManagerAdvanced;
+/**
+ * Check that the Binary has sufficient Permissions to be executed
+ * @param path The Path to check
+ */
+async function checkBinaryPermissions(path) {
+ try {
+ await fs_1.promises.access(path, fs_1.constants.X_OK); // check if the provided path exists and has the execute bit for current user
+ }
+ catch (err) {
+ if (errorWithCode(err)) {
+ if (err.code === 'EACCES') {
+ throw new errors_1.InsufficientPermissionsError(path);
+ }
+ if (err.code === 'ENOENT') {
+ throw new errors_1.BinaryNotFoundError(path);
+ }
+ }
+ throw err;
+ }
+}
+exports.checkBinaryPermissions = checkBinaryPermissions;
+/**
+ * Make Directory, wrapper for native mkdir with recursive true
+ * @param path The Path to create
+ * @returns Nothing
+ */
+async function mkdir(path) {
+ await fs_1.promises.mkdir(path, { recursive: true });
+}
+exports.mkdir = mkdir;
+/**
+ * Create a Temporary directory with prefix, and optionally at "atPath"
+ * @param prefix The prefix to use to create the tmpdir
+ * @param atPath Optionally set a custom path other than "os.tmpdir"
+ * @returns The created Path
+ */
+async function createTmpDir(prefix, atPath) {
+ const tmpPath = atPath ?? (0, os_1.tmpdir)();
+ return fs_1.promises.mkdtemp(path.join(tmpPath, prefix));
+}
+exports.createTmpDir = createTmpDir;
+/**
+ * Removes the given "path", if it is a directory, and does not throw a error if not existing
+ * @param dirPath The Directory Path to delete
+ * @returns "true" if deleted, otherwise "false"
+ */
+async function removeDir(dirPath) {
+ const stat = await statPath(dirPath);
+ if (isNullOrUndefined(stat)) {
+ return;
+ }
+ if (!stat.isDirectory()) {
+ throw new Error(`Given Path is not a directory! (Path: "${dirPath}")`);
+ }
+ await fs_1.promises.rm(dirPath, { force: true, recursive: true });
+}
+exports.removeDir = removeDir;
+/**
+ * Helper function to have uuidv4 generation and definition in one place
+ * @returns a uuid-v4
+ */
+function uuidv4() {
+ return (0, crypto_1.randomUUID)();
+}
+exports.uuidv4 = uuidv4;
+/**
+ * Helper function to have md5 generation and definition in one place
+ * @param content the content to checksum
+ * @returns a md5 of the input
+ */
+function md5(content) {
+ return (0, crypto_1.createHash)('md5').update(content).digest('hex');
+}
+exports.md5 = md5;
+/**
+ * Helper function to have md5 generation and definition in one place for a file
+ * @param file the location of a file to read for a hash
+ * @returns a md5 of the input file
+ */
+async function md5FromFile(file) {
+ return md5(await fs_1.promises.readFile(file));
+}
+exports.md5FromFile = md5FromFile;
+/**
+ * Helper function to get the lockfile for the provided `version` in `downloadDir`
+ * @param downloadDir The Download directory of the binary
+ * @param version The version to be downlaoded
+ * @returns The lockfile path
+ */
+function lockfilePath(downloadDir, version) {
+ return path.resolve(downloadDir, `${version}.lock`);
+}
+exports.lockfilePath = lockfilePath;
+/**
+ * Get the storage engine for the given given binary version, and issue a warning if it needs to be changed
+ * @param storageEngine The engine that is configured
+ * @param coercedVersion The binary version as semver
+ * @returns The engine that actually will run in the given binary version
+ */
+function getStorageEngine(storageEngine, coercedVersion) {
+ // warn when storage engine "ephemeralForTest" is explicitly used and switch to "wiredTiger"
+ if (storageEngine === 'ephemeralForTest' && semver.gte(coercedVersion, '7.0.0')) {
+ console.warn('Storage Engine "ephemeralForTest" is removed since mongodb 7.0.0, automatically using "wiredTiger"!\n' +
+ 'This warning is because the mentioned storage engine is explicitly used and mongodb version is 7.0.0 or higher');
+ return 'wiredTiger';
+ }
+ if (isNullOrUndefined(storageEngine)) {
+ if (semver.gte(coercedVersion, '7.0.0')) {
+ return 'wiredTiger';
+ }
+ return 'ephemeralForTest';
+ }
+ return storageEngine;
+}
+exports.getStorageEngine = getStorageEngine;
+//# sourceMappingURL=utils.js.map
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/lib/util/utils.js.map b/packages/mongodb-memory-server-core/lib/util/utils.js.map
new file mode 100644
index 000000000..107a4cce3
--- /dev/null
+++ b/packages/mongodb-memory-server-core/lib/util/utils.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/util/utils.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/mongodb-memory-server-core/package.json b/packages/mongodb-memory-server-core/package.json
index d2e436abe..83b1ee456 100644
--- a/packages/mongodb-memory-server-core/package.json
+++ b/packages/mongodb-memory-server-core/package.json
@@ -1,6 +1,6 @@
{
- "name": "mongodb-memory-server-core",
- "version": "10.1.4",
+ "name": "@firefoxnx/mongodb-memory-server-core",
+ "version": "10.1.5",
"description": "MongoDB Server for testing (core package, without autodownload). The server will allow you to connect your favourite ODM or client library to the MongoDB Server and run parallel integration tests isolated from each other.",
"main": "lib/index",
"types": "lib/index.d.ts",
diff --git a/packages/mongodb-memory-server-core/src/util/MongoBinaryDownload.ts b/packages/mongodb-memory-server-core/src/util/MongoBinaryDownload.ts
index f7213a302..0822ab88c 100644
--- a/packages/mongodb-memory-server-core/src/util/MongoBinaryDownload.ts
+++ b/packages/mongodb-memory-server-core/src/util/MongoBinaryDownload.ts
@@ -19,6 +19,9 @@ import { RequestOptions } from 'https';
const log = debug('MongoMS:MongoBinaryDownload');
+const retryableStatusCodes = [503, 500];
+const retryableErrorCodes = ['ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED'];
+
export interface MongoBinaryDownloadProgress {
current: number;
length: number;
@@ -353,126 +356,199 @@ export class MongoBinaryDownload {
}
/**
- * Downlaod given httpOptions to tempDownloadLocation, then move it to downloadLocation
+ * Download given httpOptions to tempDownloadLocation, then move it to downloadLocation
+ * @param url The URL to download the file from
* @param httpOptions The httpOptions directly passed to https.get
* @param downloadLocation The location the File should be after the download
* @param tempDownloadLocation The location the File should be while downloading
+ * @param maxRetries Maximum number of retries on download failure
+ * @param baseDelay Base delay in milliseconds for retrying the download
*/
async httpDownload(
url: URL,
httpOptions: RequestOptions,
downloadLocation: string,
- tempDownloadLocation: string
+ tempDownloadLocation: string,
+ maxRetries?: number,
+ baseDelay: number = 1000
): Promise {
log('httpDownload');
const downloadUrl = this.assignDownloadingURL(url);
- const maxRedirects = parseInt(resolveConfig(ResolveConfigVariables.MAX_REDIRECTS) || '');
+ const maxRedirects = parseInt(resolveConfig(ResolveConfigVariables.MAX_REDIRECTS) ?? '');
const useHttpsOptions: Parameters[1] = {
maxRedirects: Number.isNaN(maxRedirects) ? 2 : maxRedirects,
...httpOptions,
};
+ // Get maxRetries from config if not provided
+ const retriesFromConfig = parseInt(resolveConfig(ResolveConfigVariables.MAX_RETRIES) ?? '');
+ const retries =
+ typeof maxRetries === 'number'
+ ? maxRetries
+ : !Number.isNaN(retriesFromConfig)
+ ? retriesFromConfig
+ : 3;
+
+ for (let attempt = 0; attempt <= retries; attempt++) {
+ try {
+ return await this.attemptDownload(
+ url,
+ useHttpsOptions,
+ downloadLocation,
+ tempDownloadLocation,
+ downloadUrl,
+ httpOptions
+ );
+ } catch (error: any) {
+ const shouldRetry =
+ (error instanceof DownloadError &&
+ retryableStatusCodes.some((code) => error.message.includes(code.toString()))) ||
+ (error?.code && retryableErrorCodes.includes(error.code));
+
+ if (!shouldRetry || attempt === retries) {
+ throw error;
+ }
+
+ const base = baseDelay * Math.pow(2, attempt);
+ const jitter = Math.floor(Math.random() * 1000);
+ const delay = base + jitter;
+ log(
+ `httpDownload: attempt ${attempt + 1} failed with ${error.message}, retrying in ${delay}ms...`
+ );
+ await new Promise((resolve) => setTimeout(resolve, delay));
+ }
+ }
+
+ throw new Error('Max retries exceeded');
+ }
+
+ /**
+ * Attempt to download the file from the given URL
+ * This function is used internally by `httpDownload`
+ * @param url
+ * @param useHttpsOptions
+ * @param downloadLocation
+ * @param tempDownloadLocation
+ * @param downloadUrl
+ * @param httpOptions
+ * @private
+ */
+ private async attemptDownload(
+ url: URL,
+ useHttpsOptions: Parameters[1],
+ downloadLocation: string,
+ tempDownloadLocation: string,
+ downloadUrl: string,
+ httpOptions: RequestOptions
+ ): Promise {
return new Promise((resolve, reject) => {
log(`httpDownload: trying to download "${downloadUrl}"`);
- https
- .get(url, useHttpsOptions, (response) => {
- if (response.statusCode != 200) {
- if (response.statusCode === 403) {
- reject(
- new DownloadError(
- downloadUrl,
- "Status Code is 403 (MongoDB's 404)\n" +
- "This means that the requested version-platform combination doesn't exist\n" +
- "Try to use different version 'new MongoMemoryServer({ binary: { version: 'X.Y.Z' } })'\n" +
- 'List of available versions can be found here: ' +
- 'https://www.mongodb.com/download-center/community/releases/archive'
- )
- );
-
- return;
- }
+ const request = https.get(url, useHttpsOptions, (response) => {
+ if (response.statusCode != 200) {
+ if (response.statusCode === 403) {
reject(
- new DownloadError(downloadUrl, `Status Code isnt 200! (it is ${response.statusCode})`)
+ new DownloadError(
+ downloadUrl,
+ "Status Code is 403 (MongoDB's 404)\n" +
+ "This means that the requested version-platform combination doesn't exist\n" +
+ "Try to use different version 'new MongoMemoryServer({ binary: { version: 'X.Y.Z' } })'\n" +
+ 'List of available versions can be found here: ' +
+ 'https://www.mongodb.com/download-center/community/releases/archive'
+ )
);
return;
}
- // content-length, otherwise 0
- let contentLength: number;
+ reject(
+ new DownloadError(downloadUrl, `Status Code isn't 200! (it is ${response.statusCode})`)
+ );
- if (typeof response.headers['content-length'] != 'string') {
- log('Response header "content-lenght" is empty!');
+ return;
+ }
- contentLength = 0;
- } else {
- contentLength = parseInt(response.headers['content-length'], 10);
+ // content-length, otherwise 0
+ let contentLength: number;
- if (Number.isNaN(contentLength)) {
- log('Response header "content-lenght" resolved to NaN!');
+ if (typeof response.headers['content-length'] != 'string') {
+ log('Response header "content-length" is empty!');
+ contentLength = 0;
+ } else {
+ contentLength = parseInt(response.headers['content-length'], 10);
- contentLength = 0;
- }
+ if (Number.isNaN(contentLength)) {
+ log('Response header "content-length" resolved to NaN!');
+ contentLength = 0;
}
+ }
+
+ // error if the content-length header is missing or is 0 if config option "DOWNLOAD_IGNORE_MISSING_HEADER" is not set to "true"
+ if (
+ !envToBool(resolveConfig(ResolveConfigVariables.DOWNLOAD_IGNORE_MISSING_HEADER)) &&
+ contentLength <= 0
+ ) {
+ reject(
+ new DownloadError(
+ downloadUrl,
+ 'Response header "content-length" does not exist or resolved to NaN'
+ )
+ );
+
+ return;
+ }
+
+ this.dlProgress.current = 0;
+ this.dlProgress.length = contentLength;
+ this.dlProgress.totalMb = Math.round((this.dlProgress.length / 1048576) * 10) / 10;
+
+ const fileStream = createWriteStream(tempDownloadLocation);
- // error if the content-length header is missing or is 0 if config option "DOWNLOAD_IGNORE_MISSING_HEADER" is not set to "true"
+ response.pipe(fileStream);
+
+ fileStream.on('finish', async () => {
if (
- !envToBool(resolveConfig(ResolveConfigVariables.DOWNLOAD_IGNORE_MISSING_HEADER)) &&
- contentLength <= 0
+ this.dlProgress.current < this.dlProgress.length &&
+ !httpOptions.path?.endsWith('.md5')
) {
reject(
new DownloadError(
downloadUrl,
- 'Response header "content-length" does not exist or resolved to NaN'
+ `Too small (${this.dlProgress.current} bytes) mongod binary downloaded.`
)
);
return;
}
- this.dlProgress.current = 0;
- this.dlProgress.length = contentLength;
- this.dlProgress.totalMb = Math.round((this.dlProgress.length / 1048576) * 10) / 10;
-
- const fileStream = createWriteStream(tempDownloadLocation);
-
- response.pipe(fileStream);
-
- fileStream.on('finish', async () => {
- if (
- this.dlProgress.current < this.dlProgress.length &&
- !httpOptions.path?.endsWith('.md5')
- ) {
- reject(
- new DownloadError(
- downloadUrl,
- `Too small (${this.dlProgress.current} bytes) mongod binary downloaded.`
- )
- );
-
- return;
- }
+ this.printDownloadProgress({ length: 0 }, true);
- this.printDownloadProgress({ length: 0 }, true);
+ fileStream.close();
+ await fspromises.rename(tempDownloadLocation, downloadLocation);
+ log(`httpDownload: moved "${tempDownloadLocation}" to "${downloadLocation}"`);
- fileStream.close();
- await fspromises.rename(tempDownloadLocation, downloadLocation);
- log(`httpDownload: moved "${tempDownloadLocation}" to "${downloadLocation}"`);
+ resolve(downloadLocation);
+ });
- resolve(downloadLocation);
- });
+ response.on('data', (chunk: any) => {
+ this.printDownloadProgress(chunk);
+ });
- response.on('data', (chunk: any) => {
- this.printDownloadProgress(chunk);
- });
- })
- .on('error', (err: Error) => {
- // log it without having debug enabled
- console.error(`Couldnt download "${downloadUrl}"!`, err.message);
+ response.on('error', (err: Error) => {
reject(new DownloadError(downloadUrl, err.message));
});
+ });
+
+ request.on('error', (err: Error) => {
+ console.error(`Could NOT download "${downloadUrl}"!`, err.message);
+ reject(new DownloadError(downloadUrl, err.message));
+ });
+
+ request.setTimeout(60000, () => {
+ request.destroy();
+ reject(new DownloadError(downloadUrl, 'Request timeout after 60 seconds'));
+ });
});
}
diff --git a/packages/mongodb-memory-server-core/src/util/resolveConfig.ts b/packages/mongodb-memory-server-core/src/util/resolveConfig.ts
index c8fa9e636..5deae79cd 100644
--- a/packages/mongodb-memory-server-core/src/util/resolveConfig.ts
+++ b/packages/mongodb-memory-server-core/src/util/resolveConfig.ts
@@ -33,6 +33,7 @@ export enum ResolveConfigVariables {
SYSTEM_BINARY_VERSION_CHECK = 'SYSTEM_BINARY_VERSION_CHECK',
USE_ARCHIVE_NAME_FOR_BINARY_NAME = 'USE_ARCHIVE_NAME_FOR_BINARY_NAME',
MAX_REDIRECTS = 'MAX_REDIRECTS',
+ MAX_RETRIES = 'MAX_RETRIES', // Added for download retry configuration
DISTRO = 'DISTRO',
}
@@ -51,6 +52,7 @@ export const defaultValues = new Map([
[ResolveConfigVariables.USE_ARCHIVE_NAME_FOR_BINARY_NAME, 'false'],
[ResolveConfigVariables.MD5_CHECK, 'true'],
[ResolveConfigVariables.MAX_REDIRECTS, '2'],
+ [ResolveConfigVariables.MAX_RETRIES, '3'], // Default maxRetries for downloads
]);
/** Interface for storing information about the found package.json from `findPackageJson` */
diff --git a/packages/mongodb-memory-server/index.js b/packages/mongodb-memory-server/index.js
index 700f10c54..b9ae69720 100644
--- a/packages/mongodb-memory-server/index.js
+++ b/packages/mongodb-memory-server/index.js
@@ -2,4 +2,4 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const tslib = require('tslib');
-tslib.__exportStar(require('mongodb-memory-server-core'), exports);
+tslib.__exportStar(require('@firefoxnx/mongodb-memory-server-core'), exports);
diff --git a/packages/mongodb-memory-server/package.json b/packages/mongodb-memory-server/package.json
index fed2ec2a1..8c4dec139 100644
--- a/packages/mongodb-memory-server/package.json
+++ b/packages/mongodb-memory-server/package.json
@@ -1,6 +1,6 @@
{
- "name": "mongodb-memory-server",
- "version": "10.1.4",
+ "name": "@firefoxnx/mongodb-memory-server",
+ "version": "10.1.6",
"description": "MongoDB Server for testing (auto-download latest version). The server will allow you to connect your favourite ODM or client library to the MongoDB Server and run parallel integration tests isolated from each other.",
"main": "index.js",
"types": "index.d.ts",
@@ -24,7 +24,7 @@
"mongomem"
],
"dependencies": {
- "mongodb-memory-server-core": "10.1.4",
+ "@firefoxnx/mongodb-memory-server-core": "10.1.4",
"tslib": "^2.7.0"
},
"scripts": {