[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto\n*.js text eol=lf\n"
  },
  {
    "path": ".gitignore",
    "content": ".idea/\ncoverage/\nnode_modules/\nlib/\ntemp\nyarn.lock\n*.log\n.DS_Store\nglobalConfig.json\n!.husky/_/husky.sh\n"
  },
  {
    "path": ".husky/_/husky.sh",
    "content": "#!/bin/sh\nif [ -z \"$husky_skip_init\" ]; then\n  debug () {\n    if [ \"$HUSKY_DEBUG\" = \"1\" ]; then\n      echo \"husky (debug) - $1\"\n    fi\n  }\n\n  readonly hook_name=\"$(basename \"$0\")\"\n  debug \"starting $hook_name...\"\n\n  if [ \"$HUSKY\" = \"0\" ]; then\n    debug \"HUSKY env variable is set to 0, skipping hook\"\n    exit 0\n  fi\n\n  if [ -f ~/.huskyrc ]; then\n    debug \"sourcing ~/.huskyrc\"\n    . ~/.huskyrc\n  fi\n\n  export readonly husky_skip_init=1\n  sh -e \"$0\" \"$@\"\n  exitCode=\"$?\"\n\n  if [ $exitCode != 0 ]; then\n    echo \"husky - $hook_name hook exited with code $exitCode (error)\"\n  fi\n\n  exit $exitCode\nfi\n"
  },
  {
    "path": ".husky/post-commit",
    "content": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\ngit update-index --again\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\npnpm exec lint-staged\n"
  },
  {
    "path": ".npmrc",
    "content": "package-lock=false\nnode-linker=hoisted\n"
  },
  {
    "path": ".nvmrc",
    "content": "22.15.1\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## 5.2.1\n\n- Updated dependencies:\n  - debug to v4.4.1\n  - mongodb-memory-server to v10\n- Updated Node.js to v22.15.1\n- Refactored isMongoMemoryReplSetOptions to helpers.ts\n\n# Breaking Changes\n\n## 5.0.0\n\n- Switched `node` version `18`->`22`\n"
  },
  {
    "path": "eslint.config.mjs",
    "content": "import rules from '@shelf/eslint-config/typescript.js';\n\nexport default [\n  ...rules,\n  {\n    rules: {\n      '@typescript-eslint/no-var-requires': 'off',\n    },\n  },\n  {files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx', '**/*.json']},\n  {\n    ignores: [\n      '.idea/',\n      '.pnpm-store/',\n      'coverage/',\n      'draft.js',\n      'lib/',\n      'dist/',\n      'node_modules/',\n      'packages/**/tsconfig.types.json',\n      'packages/**/node_modules/**',\n      'packages/**/lib/**',\n      'renovate.json',\n    ],\n  },\n];\n"
  },
  {
    "path": "jest-mongodb-config-repl.js",
    "content": "/** @type {import('./src/types').Config} */\nmodule.exports = {\n  mongodbMemoryServerOptions: {\n    binary: {\n      skipMD5: true,\n    },\n    autoStart: false,\n    instance: {},\n    replSet: {\n      count: 4,\n      storageEngine: 'wiredTiger',\n    },\n  },\n  mongoURLEnvName: 'MONGO_URL',\n};\n"
  },
  {
    "path": "jest-mongodb-config.js",
    "content": "/** @type {import('./src/types').Config} */\nmodule.exports = {\n  mongodbMemoryServerOptions: {\n    binary: {\n      skipMD5: true,\n    },\n    autoStart: false,\n    instance: {},\n  },\n  mongoURLEnvName: 'MONGO_URL',\n};\n"
  },
  {
    "path": "jest-preset.js",
    "content": "// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst preset = require('./lib').default;\n\nmodule.exports = preset;\n"
  },
  {
    "path": "license",
    "content": "MIT License\n\nCopyright (c) Gemshelf Inc. (shelf.io)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"@shelf/jest-mongodb\",\n  \"version\": \"6.0.2\",\n  \"description\": \"Run your tests using Jest & MongoDB in Memory server\",\n  \"keywords\": [\n    \"jest\",\n    \"jest environment\",\n    \"jest preset\",\n    \"mongodb\",\n    \"mongodb local\"\n  ],\n  \"repository\": \"shelfio/jest-mongodb\",\n  \"license\": \"MIT\",\n  \"author\": {\n    \"name\": \"Vlad Holubiev\",\n    \"email\": \"vlad@shelf.io\",\n    \"url\": \"shelf.io\"\n  },\n  \"files\": [\n    \"jest-preset.js\",\n    \"lib/\"\n  ],\n  \"scripts\": {\n    \"build\": \"rm -rf lib/ && tsc\",\n    \"lint\": \"pnpm run lint:ci --fix\",\n    \"lint:ci\": \"eslint . --quiet\",\n    \"prepack\": \"pnpm run build\",\n    \"test\": \"jest\",\n    \"test:repl\": \"MONGO_MEMORY_SERVER_FILE=jest-mongodb-config-repl.js jest\",\n    \"type-check\": \"tsc --noEmit\",\n    \"type-check:watch\": \"pnpm run type-check --watch\"\n  },\n  \"prettier\": \"@shelf/prettier-config\",\n  \"jest\": {\n    \"preset\": \"./jest-preset.js\"\n  },\n  \"dependencies\": {\n    \"@swc/jest\": \"0.2.39\",\n    \"debug\": \"4.4.1\",\n    \"mongodb-memory-server\": \"10.3.0\"\n  },\n  \"devDependencies\": {\n    \"@jest/environment\": \"30.2.0\",\n    \"@shelf/eslint-config\": \"5.4.0\",\n    \"@shelf/prettier-config\": \"1.0.0\",\n    \"@shelf/tsconfig\": \"0.1.0\",\n    \"@types/jest\": \"29.5.14\",\n    \"@types/node\": \"22\",\n    \"eslint\": \"9.39.1\",\n    \"husky\": \"9.1.7\",\n    \"jest\": \"29.7.0\",\n    \"jest-environment-node\": \"30.2.0\",\n    \"lint-staged\": \"16.2.7\",\n    \"mongodb\": \"7.0.0\",\n    \"prettier\": \"3.6.2\",\n    \"typescript\": \"5.9.3\"\n  },\n  \"peerDependencies\": {\n    \"jest-environment-node\": \"28.x || 29.x || 30.x\",\n    \"mongodb\": \"3.x.x || 4.x || 5.x || 6.x || 7.x\"\n  },\n  \"engines\": {\n    \"node\": \">=22\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"lint-staged\": {\n    \"*.{html,md,yml}\": [\n      \"prettier --write\"\n    ],\n    \"*.{ts,js,json}\": [\n      \"eslint --fix\"\n    ]\n  }\n}\n"
  },
  {
    "path": "readme.md",
    "content": "# jest-mongodb [![CircleCI](https://circleci.com/gh/shelfio/jest-mongodb/tree/master.svg?style=svg)](https://circleci.com/gh/shelfio/jest-mongodb/tree/master) ![](https://img.shields.io/badge/code_style-prettier-ff69b4.svg) [![npm (scoped)](https://img.shields.io/npm/v/@shelf/jest-mongodb.svg)](https://www.npmjs.com/package/@shelf/jest-mongodb)\n\n> Jest preset to run MongoDB memory server\n\n## Usage\n\n### 0. Install\n\n```\n$ yarn add @shelf/jest-mongodb --dev\n```\n\nMake sure `mongodb` is installed in the project as well, as it's required as a peer dependency.\n\n### 1. Create `jest.config.js`\n\n```js\nmodule.exports = {\n  preset: '@shelf/jest-mongodb',\n};\n```\n\nIf you have a custom `jest.config.js` make sure you remove `testEnvironment` property, otherwise it will conflict with the preset.\n\n### 2. Create `jest-mongodb-config.js`\n\nSee [mongodb-memory-server](https://github.com/nodkz/mongodb-memory-server#available-options)\n\n```js\nmodule.exports = {\n  mongodbMemoryServerOptions: {\n    binary: {\n      version: '4.0.3',\n      skipMD5: true,\n    },\n    autoStart: false,\n    instance: {},\n  },\n};\n```\n\nTo use the same database for all tests pass the config like this:\n\n```js\nmodule.exports = {\n  mongodbMemoryServerOptions: {\n    binary: {\n      version: '4.0.3',\n      skipMD5: true,\n    },\n    instance: {\n      dbName: 'jest',\n    },\n    autoStart: false,\n  },\n};\n```\n\nTo use separate database for each jest worker pass the `useSharedDBForAllJestWorkers: false` (doesn't create `process.env` variable when using this option):\n\n```js\nmodule.exports = {\n  mongodbMemoryServerOptions: {\n    binary: {\n      skipMD5: true,\n    },\n    autoStart: false,\n    instance: {},\n  },\n\n  useSharedDBForAllJestWorkers: false,\n};\n```\n\nTo use dynamic database name you must pass empty object for instance field:\n\n```js\nmodule.exports = {\n  mongodbMemoryServerOptions: {\n    binary: {\n      version: '4.0.3',\n      skipMD5: true,\n    },\n    instance: {},\n    autoStart: false,\n  },\n};\n```\n\nTo use another uri environment variable name you must set mongoURLEnvName field:\n\n```js\nmodule.exports = {\n  mongodbMemoryServerOptions: {\n    binary: {\n      version: '4.0.3',\n      skipMD5: true,\n    },\n    instance: {},\n    autoStart: false,\n  },\n  mongoURLEnvName: 'MONGODB_URI',\n};\n```\n\nTo use mongo as a replica set you must add the `replSet` config object and set\n`count` and `storageEngine` fields:\n\n```js\nmodule.exports = {\n  mongodbMemoryServerOptions: {\n    binary: {\n      skipMD5: true,\n    },\n    autoStart: false,\n    instance: {},\n    replSet: {\n      count: 3,\n      storageEngine: 'wiredTiger',\n    },\n  },\n};\n```\n\n### 3. Configure MongoDB client\n\nLibrary sets the `process.env.MONGO_URL` for your convenience, but using of `global.__MONGO_URI__` is preferable as it works with ` useSharedDBForAllJestWorkers: false`\n\n```js\nconst {MongoClient} = require('mongodb');\n\ndescribe('insert', () => {\n  let connection;\n  let db;\n\n  beforeAll(async () => {\n    connection = await MongoClient.connect(global.__MONGO_URI__, {});\n    db = await connection.db();\n  });\n\n  afterAll(async () => {\n    await connection.close();\n  });\n});\n```\n\n### 4. PROFIT! Write tests\n\n```js\nit('should insert a doc into collection', async () => {\n  const users = db.collection('users');\n\n  const mockUser = {_id: 'some-user-id', name: 'John'};\n  await users.insertOne(mockUser);\n\n  const insertedUser = await users.findOne({_id: 'some-user-id'});\n  expect(insertedUser).toEqual(mockUser);\n});\n```\n\nCache MongoDB binary in CI by putting this folder to the list of cached paths: `./node_modules/.cache/mongodb-memory-server/mongodb-binaries`\n\nYou can enable debug logs by setting environment variable `DEBUG=jest-mongodb:*`\n\n#### 5. Clean collections before each test (optional)\n\n```js\nbeforeEach(async () => {\n  await db.collection('COLLECTION_NAME').deleteMany({});\n});\n```\n\n<sub>See [this issue](https://github.com/shelfio/jest-mongodb/issues/173) for discussion</sub>\n\n#### 6. Jest watch mode gotcha\n\nThis package creates the file `globalConfig.json` in the project root, when using jest `--watch` flag, changes to `globalConfig.json` can cause an infinite loop\n\nIn order to avoid this unwanted behaviour, add `globalConfig` to ignored files in watch mode in the Jest configuation\n\n```js\n// jest.config.js\nmodule.exports = {\n  watchPathIgnorePatterns: ['globalConfig'],\n};\n```\n\n## Node 22.12+ and ESM configs\n\nNode 22.12 turned on `require()` support for ESM by default. If your config is an `.mjs` file with a default export, `@shelf/jest-mongodb` now imports it automatically (and still supports CommonJS configs). If you prefer the old behavior, you can run Jest with `--no-experimental-require-module`.\n\n## See Also\n\n- [jest-dynamodb](https://github.com/shelfio/jest-dynamodb)\n\n## Publish\n\n```sh\n$ git checkout master\n$ yarn version\n$ yarn publish\n$ git push origin master --tags\n```\n\n## License\n\nMIT © [Shelf](https://shelf.io)\n"
  },
  {
    "path": "renovate.json",
    "content": "{\n  \"extends\": [\"github>shelfio/renovate-config-public\"],\n  \"labels\": [\"backend\"]\n}\n"
  },
  {
    "path": "src/environment.ts",
    "content": "import {join as pathJoin} from 'path';\nimport {readFileSync} from 'fs';\nimport {randomUUID} from 'crypto';\nimport {TestEnvironment} from 'jest-environment-node';\nimport {MongoMemoryReplSet, MongoMemoryServer} from 'mongodb-memory-server';\nimport type {EnvironmentContext} from '@jest/environment';\nimport type {JestEnvironmentConfig} from '@jest/environment';\nimport {getMongodbMemoryOptions, isMongoMemoryReplSetOptions} from './helpers';\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst debug = require('debug')('jest-mongodb:environment');\n\nmodule.exports = class MongoEnvironment extends TestEnvironment {\n  globalConfigPath: string;\n  mongo: MongoMemoryReplSet | MongoMemoryServer;\n  constructor(config: JestEnvironmentConfig, context: EnvironmentContext) {\n    super(config, context);\n    this.globalConfigPath = pathJoin(config.globalConfig.rootDir, 'globalConfig.json');\n\n    const options = getMongodbMemoryOptions(config.globalConfig.rootDir);\n    const isReplSet = isMongoMemoryReplSetOptions(options);\n    debug(`isReplSet`, isReplSet);\n\n    this.mongo = isReplSet ? new MongoMemoryReplSet(options) : new MongoMemoryServer(options);\n  }\n\n  async setup() {\n    debug('Setup MongoDB Test Environment');\n\n    const globalConfig = JSON.parse(readFileSync(this.globalConfigPath, 'utf-8'));\n\n    if (globalConfig.mongoUri) {\n      this.global.__MONGO_URI__ = globalConfig.mongoUri;\n    } else {\n      await this.mongo.start();\n\n      this.global.__MONGO_URI__ = this.mongo.getUri();\n    }\n\n    this.global.__MONGO_DB_NAME__ = globalConfig.mongoDBName || randomUUID();\n\n    await super.setup();\n  }\n\n  async teardown() {\n    debug('Teardown MongoDB Test Environment');\n\n    await this.mongo.stop();\n\n    await super.teardown();\n  }\n\n  // @ts-expect-error - runScript has incompatible type definitions\n  runScript(script) {\n    // @ts-expect-error - parent class method call\n    return super.runScript(script);\n  }\n};\n"
  },
  {
    "path": "src/helpers.ts",
    "content": "import {spawnSync} from 'child_process';\nimport {resolve} from 'path';\nimport type {MongoMemoryReplSet, MongoMemoryServer} from 'mongodb-memory-server';\nimport type {Config} from './types';\n\ntype MongoMemoryReplSetOpts = NonNullable<ConstructorParameters<typeof MongoMemoryReplSet>[0]>;\ntype MongoMemoryServerOpts = NonNullable<ConstructorParameters<typeof MongoMemoryServer>[0]>;\n\nexport function isMongoMemoryReplSetOptions(\n  options?: MongoMemoryReplSetOpts | MongoMemoryServerOpts\n): options is MongoMemoryReplSetOpts {\n  return Boolean((options as MongoMemoryReplSetOpts | undefined)?.replSet);\n}\n\nfunction getConfigFile() {\n  return process.env.MONGO_MEMORY_SERVER_FILE || 'jest-mongodb-config.js';\n}\n\nconst configCache = new Map<string, Config | null>();\n\nfunction importConfig(configPath: string): Config | undefined {\n  try {\n    // Node 22.12+ can let `require` load ESM by default. When Jest runs in CJS mode\n    // and the config is `.mjs`, spawn a one-off Node process to import it as ESM\n    // and return the plain JSON payload.\n    const {status, stdout} = spawnSync(\n      process.execPath,\n      [\n        '--input-type=module',\n        '--eval',\n        [\n          'import {pathToFileURL} from \"node:url\";',\n          `const mod = await import(pathToFileURL(${JSON.stringify(configPath)}).href);`,\n          'const payload = mod.default ?? mod;',\n          'console.log(JSON.stringify(payload));',\n        ].join('\\n'),\n      ],\n      {encoding: 'utf8'}\n    );\n\n    if (status === 0 && stdout.trim()) {\n      return JSON.parse(stdout) as Config;\n    }\n  } catch {\n    // ignore and fall through to undefined\n  }\n\n  return undefined;\n}\n\nfunction loadConfig(cwd?: string): Config | undefined {\n  const baseDir = cwd || process.cwd();\n\n  if (configCache.has(baseDir)) {\n    return configCache.get(baseDir) ?? undefined;\n  }\n\n  const configPath = resolve(baseDir, getConfigFile());\n\n  try {\n    // eslint-disable-next-line @typescript-eslint/no-require-imports\n    const loadedConfig = require(configPath) as Config | {default?: Config};\n\n    if (loadedConfig && typeof (loadedConfig as {default?: Config}).default !== 'undefined') {\n      const config = (loadedConfig as {default?: Config}).default;\n      configCache.set(baseDir, config ?? null);\n\n      return config;\n    }\n\n    const config = loadedConfig as Config;\n    configCache.set(baseDir, config ?? null);\n\n    return config;\n  } catch {\n    const importedConfig = importConfig(configPath);\n    configCache.set(baseDir, importedConfig ?? null);\n\n    return importedConfig;\n  }\n}\n\nexport function getMongodbMemoryOptions(\n  cwd?: string\n): MongoMemoryReplSetOpts | MongoMemoryServerOpts | undefined {\n  const config = loadConfig(cwd);\n\n  if (config?.mongodbMemoryServerOptions) {\n    return config.mongodbMemoryServerOptions;\n  }\n\n  return {\n    binary: {\n      checkMD5: false,\n    },\n    instance: {},\n  };\n}\n\nexport function getMongoURLEnvName(cwd?: string) {\n  const config = loadConfig(cwd);\n\n  return config?.mongoURLEnvName || 'MONGO_URL';\n}\n\nexport function shouldUseSharedDBForAllJestWorkers(cwd?: string) {\n  const config = loadConfig(cwd);\n\n  if (typeof config?.useSharedDBForAllJestWorkers === 'undefined') {\n    return true;\n  }\n\n  return config.useSharedDBForAllJestWorkers;\n}\n"
  },
  {
    "path": "src/index.ts",
    "content": "import {resolve} from 'path';\n\nexport * from './types';\n\nexport default {\n  globalSetup: resolve(__dirname, './setup.js'),\n  globalTeardown: resolve(__dirname, './teardown.js'),\n  testEnvironment: resolve(__dirname, './environment.js'),\n  transform: {\n    '^.+\\\\.(t|j)sx?$': [\n      '@swc/jest',\n      {\n        jsc: {\n          parser: {\n            syntax: 'typescript',\n          },\n        },\n      },\n    ],\n  },\n};\n"
  },
  {
    "path": "src/setup.ts",
    "content": "/* eslint-disable multiline-ternary */\nimport {writeFileSync} from 'fs';\nimport {join} from 'path';\nimport {MongoMemoryReplSet, MongoMemoryServer} from 'mongodb-memory-server';\nimport type {JestEnvironmentConfig} from '@jest/environment';\nimport type {Mongo} from './types';\nimport {\n  getMongoURLEnvName,\n  getMongodbMemoryOptions,\n  shouldUseSharedDBForAllJestWorkers,\n} from './helpers';\nimport {isMongoMemoryReplSetOptions} from './helpers';\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst debug = require('debug')('jest-mongodb:setup');\n\nmodule.exports = async (config: JestEnvironmentConfig['globalConfig']) => {\n  const globalConfigPath = join(config.rootDir, 'globalConfig.json');\n\n  const mongoMemoryServerOptions = getMongodbMemoryOptions(config.rootDir);\n  const isReplSet = isMongoMemoryReplSetOptions(mongoMemoryServerOptions);\n\n  debug(`isReplSet ${isReplSet}`);\n\n  // @ts-ignore\n  const mongo: Mongo = isReplSet\n    ? new MongoMemoryReplSet(mongoMemoryServerOptions)\n    : new MongoMemoryServer(mongoMemoryServerOptions);\n\n  const options = getMongodbMemoryOptions(config.rootDir);\n  const mongoConfig: {mongoUri?: string; mongoDBName?: string} = {};\n\n  debug(\n    `shouldUseSharedDBForAllJestWorkers: ${shouldUseSharedDBForAllJestWorkers(config.rootDir)}`\n  );\n\n  // if we run one mongodb instance for all tests\n  if (shouldUseSharedDBForAllJestWorkers(config.rootDir)) {\n    if (!mongo.isRunning) {\n      await mongo.start();\n    }\n\n    const mongoURLEnvName = getMongoURLEnvName(config.rootDir);\n\n    mongoConfig.mongoUri = await mongo.getUri();\n\n    process.env[mongoURLEnvName] = mongoConfig.mongoUri;\n\n    // Set reference to mongod in order to close the server during teardown.\n    global.__MONGOD__ = mongo;\n  }\n\n  mongoConfig.mongoDBName = isMongoMemoryReplSetOptions(options) ? '' : options?.instance?.dbName;\n\n  // Write global config to disk because all tests run in different contexts.\n  writeFileSync(globalConfigPath, JSON.stringify(mongoConfig));\n  debug('Config is written');\n};\n"
  },
  {
    "path": "src/teardown.ts",
    "content": "import {join} from 'path';\nimport {unlink} from 'fs';\nimport type {JestEnvironmentConfig} from '@jest/environment';\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst debug = require('debug')('jest-mongodb:teardown');\n\nmodule.exports = async function (config: JestEnvironmentConfig['globalConfig']) {\n  const globalConfigPath = join(config.rootDir, 'globalConfig.json');\n\n  debug('Teardown mongod');\n  if (global.__MONGOD__) {\n    await global.__MONGOD__.stop();\n  }\n  unlink(globalConfigPath, err => {\n    if (err) {\n      debug('Config could not be deleted');\n\n      return;\n    }\n    debug('Config is deleted');\n  });\n};\n"
  },
  {
    "path": "src/types.ts",
    "content": "/* eslint-disable */\nimport { MongoMemoryReplSet, MongoMemoryServer } from \"mongodb-memory-server\";\n\ndeclare global {\n  var __MONGOD__: Mongo;\n  var __MONGO_URI__: string;\n  var __MONGO_DB_NAME__: string\n}\n\nexport type Mongo = (MongoMemoryReplSet | MongoMemoryServer) & {isRunning: boolean}\n\ntype MongoMemoryReplSetOpts = NonNullable<ConstructorParameters<typeof MongoMemoryReplSet>[0]>;\ntype MongoMemoryServerOpts = NonNullable<ConstructorParameters<typeof MongoMemoryServer>[0]>;\n\nexport interface Config {\n  mongodbMemoryServerOptions?: MongoMemoryReplSetOpts | MongoMemoryServerOpts;\n  /**\n   * @default 'MONGO_URL'\n   */\n  mongoURLEnvName?: string;\n  /**\n   * @default true\n   */\n  useSharedDBForAllJestWorkers?: boolean;\n}\n"
  },
  {
    "path": "test/helpers-esm-config.test.ts",
    "content": "import {mkdtempSync, writeFileSync} from 'fs';\nimport {tmpdir} from 'os';\nimport {join} from 'path';\nimport {\n  getMongoURLEnvName,\n  getMongodbMemoryOptions,\n  isMongoMemoryReplSetOptions,\n  shouldUseSharedDBForAllJestWorkers,\n} from '../src/helpers';\n\ndescribe('helpers with ESM default export config', () => {\n  const originalConfigFile = process.env.MONGO_MEMORY_SERVER_FILE;\n  const tempDir = mkdtempSync(join(tmpdir(), 'jest-mongodb-esm-config-'));\n  const configPath = join(tempDir, 'jest-mongodb-config.mjs');\n\n  beforeAll(() => {\n    writeFileSync(\n      configPath,\n      [\n        'export default {',\n        '  mongodbMemoryServerOptions: {replSet: {count: 1}},',\n        \"  mongoURLEnvName: 'CUSTOM_URL',\",\n        '  useSharedDBForAllJestWorkers: false,',\n        '};',\n        '',\n      ].join('\\n')\n    );\n\n    process.env.MONGO_MEMORY_SERVER_FILE = configPath;\n  });\n\n  afterAll(() => {\n    if (typeof originalConfigFile === 'undefined') {\n      delete process.env.MONGO_MEMORY_SERVER_FILE;\n    } else {\n      process.env.MONGO_MEMORY_SERVER_FILE = originalConfigFile;\n    }\n  });\n\n  it('loads options from default export without throwing', () => {\n    const options = getMongodbMemoryOptions(tempDir);\n\n    expect(options).toEqual(expect.objectContaining({replSet: {count: 1}}));\n    expect(getMongoURLEnvName(tempDir)).toBe('CUSTOM_URL');\n    expect(shouldUseSharedDBForAllJestWorkers(tempDir)).toBe(false);\n    expect(isMongoMemoryReplSetOptions(options)).toBe(true);\n  });\n\n  it('treats missing options as non-replSet', () => {\n    expect(isMongoMemoryReplSetOptions(undefined)).toBe(false);\n  });\n});\n"
  },
  {
    "path": "test/mongo-aggregate.test.ts",
    "content": "import {MongoClient} from 'mongodb';\nimport type {Db} from 'mongodb';\nimport '../src/types';\n\ndescribe('insert', () => {\n  const uri = global.__MONGO_URI__;\n  let connection: MongoClient;\n  let db: Db;\n\n  beforeAll(async () => {\n    connection = await MongoClient.connect(uri, {});\n    db = await connection.db();\n  });\n\n  afterAll(async () => {\n    await connection.close();\n  });\n\n  it('should aggregate docs from collection', async () => {\n    const files = db.collection('files');\n\n    await files.insertMany([\n      {type: 'Document'},\n      {type: 'Video'},\n      {type: 'Image'},\n      {type: 'Document'},\n      {type: 'Image'},\n      {type: 'Document'},\n    ]);\n\n    const topFiles = await files\n      .aggregate([{$group: {_id: '$type', count: {$sum: 1}}}, {$sort: {count: -1}}])\n      .toArray();\n\n    expect(topFiles).toEqual([\n      {_id: 'Document', count: 3},\n      {_id: 'Image', count: 2},\n      {_id: 'Video', count: 1},\n    ]);\n  });\n});\n"
  },
  {
    "path": "test/mongo-insert.test.ts",
    "content": "import {MongoClient} from 'mongodb';\nimport type {Db} from 'mongodb';\nimport '../src/types';\n\ndescribe('insert', () => {\n  const uri = global.__MONGO_URI__;\n  let connection: MongoClient;\n  let db: Db;\n\n  beforeAll(async () => {\n    connection = await MongoClient.connect(uri, {});\n    db = await connection.db();\n  });\n\n  afterAll(async () => {\n    await connection.close();\n  });\n\n  it('should insert a doc into collection', async () => {\n    const users = db.collection('users');\n\n    const mockUser = {_id: 'some-user-id', name: 'John'};\n    // @ts-ignore\n    await users.insertOne(mockUser);\n\n    const insertedUser = await users.findOne({_id: 'some-user-id'});\n\n    expect(insertedUser).toEqual(mockUser);\n  });\n\n  it('should insert many docs into collection', async () => {\n    const users = db.collection('users');\n\n    const mockUsers = [{name: 'Alice'}, {name: 'Bob'}];\n    await users.insertMany(mockUsers);\n\n    const insertedUsers = await users.find().toArray();\n\n    expect(insertedUsers).toEqual([\n      expect.objectContaining({name: 'John'}),\n      expect.objectContaining({name: 'Alice'}),\n      expect.objectContaining({name: 'Bob'}),\n    ]);\n  });\n});\n"
  },
  {
    "path": "test/mongo-parallelism.test.ts",
    "content": "import {MongoClient} from 'mongodb';\nimport type {Db} from 'mongodb';\nimport '../src/types';\nimport {shouldUseSharedDBForAllJestWorkers} from '../src/helpers';\n\ndescribe('parallelism: first worker', () => {\n  const uri = global.__MONGO_URI__;\n  let connection: MongoClient;\n  let db: Db;\n\n  beforeAll(async () => {\n    connection = await MongoClient.connect(uri, {});\n    db = await connection.db();\n  });\n\n  afterAll(async () => {\n    await connection.close();\n  });\n\n  it('should have separate database', async () => {\n    const collection = db.collection('parallelism-test');\n\n    await collection.insertOne({a: 1});\n    const count = await collection.count({});\n\n    if (!shouldUseSharedDBForAllJestWorkers()) {\n      expect(count).toBe(1);\n    }\n  });\n});\n"
  },
  {
    "path": "test/mongo-parallelism2.test.ts",
    "content": "import {MongoClient} from 'mongodb';\nimport type {Db} from 'mongodb';\nimport '../src/types';\nimport {shouldUseSharedDBForAllJestWorkers} from '../src/helpers';\n\ndescribe('parallelism: second worker', () => {\n  const uri = global.__MONGO_URI__;\n  let connection: MongoClient;\n  let db: Db;\n\n  beforeAll(async () => {\n    connection = await MongoClient.connect(uri, {});\n    db = await connection.db();\n  });\n\n  afterAll(async () => {\n    await connection.close();\n  });\n\n  it('should have separate database', async () => {\n    const collection = db.collection('parallelism-test');\n\n    await collection.insertMany([{a: 1}, {b: 2}]);\n    const count = await collection.count({});\n\n    if (!shouldUseSharedDBForAllJestWorkers()) {\n      expect(count).toBe(2);\n    }\n  });\n});\n"
  },
  {
    "path": "test/mongo-parallelism3.test.ts",
    "content": "import {MongoClient} from 'mongodb';\nimport type {Db} from 'mongodb';\nimport '../src/types';\nimport {shouldUseSharedDBForAllJestWorkers} from '../src/helpers';\n\ndescribe('parallelism: third worker', () => {\n  const uri = global.__MONGO_URI__;\n  let connection: MongoClient;\n  let db: Db;\n\n  beforeAll(async () => {\n    connection = await MongoClient.connect(uri, {});\n    db = await connection.db();\n  });\n\n  afterAll(async () => {\n    await connection.close();\n  });\n\n  it('should have separate database', async () => {\n    const collection = db.collection('parallelism-test');\n\n    await collection.insertMany([{a: 1}, {b: 2}, {c: 3}]);\n    const count = await collection.count({});\n\n    if (!shouldUseSharedDBForAllJestWorkers()) {\n      expect(count).toBe(3);\n    }\n  });\n});\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"extends\": \"@shelf/tsconfig/backend\",\n  \"compilerOptions\": {\n    \"strict\": true,\n    \"module\": \"commonjs\",\n    \"target\": \"ESNext\",\n    \"moduleResolution\": \"node\",\n    \"declaration\": true,\n    \"resolveJsonModule\": false,\n    \"outDir\": \"lib\"\n  },\n  \"exclude\": [\"node_modules\", \"**/*.test.*\", \"**/*.mock.ts\"],\n  \"include\": [\"src\"]\n}\n"
  }
]