[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = tab\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.yml]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: CI\non:\n  - push\n  - pull_request\njobs:\n  test:\n    name: Node.js ${{ matrix.node-version }}\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        node-version:\n          - 14\n          - 12\n          - 10\n          - 8\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-node@v6\n        with:\n          node-version: ${{ matrix.node-version }}\n      - run: npm install\n      - run: npm test\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\nyarn.lock\n"
  },
  {
    "path": ".npmrc",
    "content": "package-lock=false\n"
  },
  {
    "path": "fixture-circular-1.js",
    "content": "'use strict';\n\nconst other = require('./fixture-circular-2');\n\nmodule.exports = other;\n"
  },
  {
    "path": "fixture-circular-2.js",
    "content": "'use strict';\n\nconst other = require('./fixture-circular-1');\n\nmodule.exports = other;\n"
  },
  {
    "path": "fixture-empty.js",
    "content": "'use strict';\n\nmodule.exports = {};\n"
  },
  {
    "path": "fixture-match.js",
    "content": "'use strict';\nlet i = 0;\nmodule.exports = () => ++i;\n"
  },
  {
    "path": "fixture-with-dependency.js",
    "content": "'use strict';\n\n// eslint-disable-next-line no-unused-vars\nconst _ = require('./fixture-empty');\nconst fixture = require('./fixture');\n\nmodule.exports = () => fixture();\n"
  },
  {
    "path": "fixture.js",
    "content": "'use strict';\nlet i = 0;\nmodule.exports = () => ++i;\n"
  },
  {
    "path": "index.d.ts",
    "content": "declare const clear: {\n\t/**\n\tClear a module from the [cache](https://nodejs.org/api/modules.html#modules_caching).\n\n\t@param moduleId - What you would use with `require()`.\n\n\t@example\n\t```\n\t// foo.ts\n\tlet i = 0;\n\tmodule.exports = () => ++i;\n\n\t// test.ts\n\timport clearModule = require('clear-module');\n\n\trequire('./foo')();\n\t//=> 1\n\n\trequire('./foo')();\n\t//=> 2\n\n\tclearModule('./foo');\n\n\trequire('./foo')();\n\t//=> 1\n\t```\n\t*/\n\t(moduleId: string): void;\n\n\t/**\n\tClear all modules from the cache.\n\t*/\n\tall(): void;\n\n\t/**\n\tClear all matching modules from the cache.\n\n\t@param regex - Regex to match against the module IDs.\n\t*/\n\tmatch(regex: RegExp): void;\n\n\t/**\n\tClear a single module from the cache non-recursively. No parent or children modules will be affected.\n\n\tThis is mostly only useful if you use singletons, where you would want to clear a specific module without causing any side effects.\n\n\t@param moduleId - What you would use with `require()`.\n\t*/\n\tsingle(moduleId: string): void;\n};\n\nexport = clear;\n"
  },
  {
    "path": "index.js",
    "content": "'use strict';\nconst path = require('path');\nconst resolveFrom = require('resolve-from');\nconst parentModule = require('parent-module');\n\nconst resolve = moduleId => {\n\ttry {\n\t\treturn resolveFrom(path.dirname(parentModule(__filename)), moduleId);\n\t} catch (_) {}\n};\n\nconst isNativeModule = filePath => path.extname(filePath) === '.node';\n\nconst clear = moduleId => {\n\tif (typeof moduleId !== 'string') {\n\t\tthrow new TypeError(`Expected a \\`string\\`, got \\`${typeof moduleId}\\``);\n\t}\n\n\tconst filePath = resolve(moduleId);\n\n\tif (!filePath) {\n\t\treturn;\n\t}\n\n\tif (isNativeModule(filePath)) {\n\t\treturn;\n\t}\n\n\t// Delete itself from module parent\n\tif (require.cache[filePath] && require.cache[filePath].parent) {\n\t\tlet i = require.cache[filePath].parent.children.length;\n\n\t\twhile (i--) {\n\t\t\tif (require.cache[filePath].parent.children[i].id === filePath) {\n\t\t\t\trequire.cache[filePath].parent.children.splice(i, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove all descendants from cache as well\n\tif (require.cache[filePath]) {\n\t\tconst children = require.cache[filePath].children.map(child => child.id);\n\n\t\t// Delete module from cache\n\t\tdelete require.cache[filePath];\n\n\t\tfor (const id of children) {\n\t\t\tclear(id);\n\t\t}\n\t}\n};\n\nclear.all = () => {\n\tfor (const filePath of Object.keys(require.cache)) {\n\t\tif (!isNativeModule(filePath)) {\n\t\t\tdelete require.cache[filePath];\n\t\t}\n\t}\n};\n\nclear.match = regex => {\n\tfor (const moduleId of Object.keys(require.cache)) {\n\t\tif (regex.test(moduleId)) {\n\t\t\tclear(moduleId);\n\t\t}\n\t}\n};\n\nclear.single = moduleId => {\n\tif (typeof moduleId !== 'string') {\n\t\tthrow new TypeError(`Expected a \\`string\\`, got \\`${typeof moduleId}\\``);\n\t}\n\n\tconst filePath = resolve(moduleId);\n\n\tif (!filePath || isNativeModule(filePath)) {\n\t\treturn;\n\t}\n\n\tdelete require.cache[filePath];\n};\n\nmodule.exports = clear;\n"
  },
  {
    "path": "index.test-d.ts",
    "content": "import clear = require('.');\n\nclear('my-module');\nclear.all();\nclear.match(/^.*$/);\n"
  },
  {
    "path": "license",
    "content": "MIT License\n\nCopyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)\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\t\"name\": \"clear-module\",\n\t\"version\": \"4.1.3\",\n\t\"description\": \"Clear a module from the cache\",\n\t\"license\": \"MIT\",\n\t\"repository\": \"sindresorhus/clear-module\",\n\t\"funding\": \"https://github.com/sponsors/sindresorhus\",\n\t\"author\": {\n\t\t\"name\": \"Sindre Sorhus\",\n\t\t\"email\": \"sindresorhus@gmail.com\",\n\t\t\"url\": \"https://sindresorhus.com\"\n\t},\n\t\"sideEffects\": false,\n\t\"engines\": {\n\t\t\"node\": \">=8\"\n\t},\n\t\"scripts\": {\n\t\t\"//test\": \"xo && ava && tsd\",\n\t\t\"test\": \"ava\"\n\t},\n\t\"files\": [\n\t\t\"index.js\",\n\t\t\"index.d.ts\"\n\t],\n\t\"keywords\": [\n\t\t\"clear\",\n\t\t\"module\",\n\t\t\"require\",\n\t\t\"import\",\n\t\t\"cache\",\n\t\t\"uncache\",\n\t\t\"uncached\",\n\t\t\"unrequire\",\n\t\t\"derequire\",\n\t\t\"delete\",\n\t\t\"remove\",\n\t\t\"rm\",\n\t\t\"fresh\"\n\t],\n\t\"dependencies\": {\n\t\t\"parent-module\": \"^2.0.0\",\n\t\t\"resolve-from\": \"^5.0.0\"\n\t},\n\t\"devDependencies\": {\n\t\t\"ava\": \"^2.1.0\",\n\t\t\"tsd\": \"^0.7.2\",\n\t\t\"xo\": \"^0.24.0\"\n\t}\n}\n"
  },
  {
    "path": "readme.md",
    "content": "# clear-module\n\n> Clear a module from the [cache](https://nodejs.org/api/modules.html#modules_caching)\n\nUseful for testing purposes when you need to freshly import a module.\n\n## Install\n\n```sh\nnpm install clear-module\n```\n\n## Usage\n\n```js\n// foo.js\nlet i = 0;\nmodule.exports = () => ++i;\n```\n\n```js\nconst clearModule = require('clear-module');\n\nrequire('./foo')();\n//=> 1\n\nrequire('./foo')();\n//=> 2\n\nclearModule('./foo');\n\nrequire('./foo')();\n//=> 1\n```\n\n## API\n\n### clearModule(moduleId)\n\n#### moduleId\n\nType: `string`\n\nWhat you would use with `require()`.\n\n### clearModule.all()\n\nClear all modules from the cache.\n\n### clearModule.match(regex)\n\nClear all matching modules from the cache.\n\n#### regex\n\nType: `RegExp`\n\nRegex to match against the module IDs.\n\n### clearModule.single(moduleId)\n\nClear a single module from the cache non-recursively. No parent or children modules will be affected.\n\nThis is mostly only useful if you use singletons, where you would want to clear a specific module without causing any side effects.\n\n#### moduleId\n\nType: `string`\n\nWhat you would use with `require()`.\n\n## Related\n\n- [import-fresh](https://github.com/sindresorhus/import-fresh) - Import a module while bypassing the cache\n- [import-from](https://github.com/sindresorhus/import-from) - Import a module from a given path\n- [import-cwd](https://github.com/sindresorhus/import-cwd) - Import a module from the current working directory\n- [import-lazy](https://github.com/sindresorhus/import-lazy) - Import a module lazily\n"
  },
  {
    "path": "test.js",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport test from 'ava';\nimport clearModule from '.';\n\nconst nativeModulePath = path.join(process.cwd(), '.ai-temporary', 'fixture-native.node');\n\nconst nonNativeModuleIds = () => Object.keys(require.cache).filter(moduleId => path.extname(moduleId) !== '.node');\n\nconst seedNativeModule = () => {\n\tif (!fs.existsSync(path.dirname(nativeModulePath))) {\n\t\tfs.mkdirSync(path.dirname(nativeModulePath));\n\t}\n\n\tfs.writeFileSync(nativeModulePath, '');\n\n\tconst nativeModule = {\n\t\tid: nativeModulePath,\n\t\tfilename: nativeModulePath,\n\t\tloaded: true,\n\t\texports: {},\n\t\tchildren: [],\n\t\tparent: module\n\t};\n\n\trequire.cache[nativeModulePath] = nativeModule;\n\n\treturn nativeModule;\n};\n\nconst clearNativeModule = () => {\n\tdelete require.cache[nativeModulePath];\n\n\tif (fs.existsSync(nativeModulePath)) {\n\t\tfs.unlinkSync(nativeModulePath);\n\t}\n};\n\ntest.after.always(clearNativeModule);\n\ntest('clearModule()', t => {\n\tconst id = './fixture';\n\tt.is(require(id)(), 1);\n\tt.is(require(id)(), 2);\n\tclearModule(id);\n\tt.is(require(id)(), 1);\n});\n\ntest('clearModule.all()', t => {\n\tt.true(nonNativeModuleIds().length > 0);\n\tclearModule.all();\n\tt.is(nonNativeModuleIds().length, 0);\n});\n\ntest('clearModule.match()', t => {\n\tconst id = './fixture';\n\tconst match = './fixture-match';\n\tt.is(require(id)(), 1);\n\tt.is(require(match)(), 1);\n\tclearModule.match(/match/);\n\tt.is(require(id)(), 2);\n\tt.is(require(match)(), 1);\n});\n\ntest('clearModule() recursively', t => {\n\tclearModule.all();\n\tconst id = './fixture-with-dependency';\n\tt.is(require(id)(), 1);\n\tt.is(require(id)(), 2);\n\tdelete require.cache[require.resolve(id)];\n\tt.is(require(id)(), 3);\n\tclearModule(id);\n\tt.is(require(id)(), 1);\n});\n\ntest('clearModule() recursively, multiple imports', t => {\n\tclearModule.all();\n\tconst id = './fixture-with-dependency';\n\tt.is(require(id)(), 1);\n\tt.is(require(id)(), 2);\n\tt.is(require(id)(), 3);\n\tclearModule(id);\n\tt.is(require(id)(), 1);\n});\n\ntest('clearModule.single()', t => {\n\tclearModule.all();\n\tconst id = './fixture-with-dependency';\n\tt.is(require(id)(), 1);\n\tt.is(require(id)(), 2);\n\tclearModule.single(id);\n\tt.is(require(id)(), 3);\n\tclearModule(id);\n\tt.is(require(id)(), 1);\n});\n\ntest.serial('native modules are not cleared', t => {\n\ttry {\n\t\tlet nativeModule = seedNativeModule();\n\t\tclearModule(nativeModulePath);\n\t\tt.is(require.cache[nativeModulePath], nativeModule);\n\n\t\tnativeModule = seedNativeModule();\n\t\tclearModule.single(nativeModulePath);\n\t\tt.is(require.cache[nativeModulePath], nativeModule);\n\n\t\tnativeModule = seedNativeModule();\n\t\tclearModule.all();\n\t\tt.is(require.cache[nativeModulePath], nativeModule);\n\n\t\tnativeModule = seedNativeModule();\n\t\tclearModule.match(/fixture-native/);\n\t\tt.is(require.cache[nativeModulePath], nativeModule);\n\n\t\tconst id = './fixture';\n\t\trequire(id);\n\t\tconst fixtureModule = require.cache[require.resolve(id)];\n\t\tnativeModule = seedNativeModule();\n\t\tfixtureModule.children.push(nativeModule);\n\t\tclearModule(id);\n\t\tt.is(require.cache[nativeModulePath], nativeModule);\n\t} finally {\n\t\tclearNativeModule();\n\t}\n});\n\ntest('works with circular dependencies', t => {\n\tconst id1 = './fixture-circular-1';\n\trequire(id1);\n\n\tlet parentCalls = 0;\n\tlet childrenCalls = 0;\n\n\tconst {children, parents} = require.cache[require.resolve(id1)];\n\n\tObject.defineProperty(\n\t\trequire.cache[require.resolve(id1)],\n\t\t'children',\n\t\t{\n\t\t\tget: () => {\n\t\t\t\tchildrenCalls++;\n\t\t\t\treturn children;\n\t\t\t}\n\t\t}\n\t);\n\n\tObject.defineProperty(\n\t\trequire.cache[require.resolve(id1)],\n\t\t'parent',\n\t\t{\n\t\t\tget: () => {\n\t\t\t\tparentCalls++;\n\t\t\t\treturn parents;\n\t\t\t}\n\t\t}\n\t);\n\n\tclearModule(id1);\n\tt.is(parentCalls, 1);\n\tt.is(childrenCalls, 4);\n\tclearModule.all();\n});\n"
  }
]