{"id":16146552,"url":"https://github.com/voxpelli/list-installed","last_synced_at":"2025-09-13T00:32:18.171Z","repository":{"id":40784591,"uuid":"306122134","full_name":"voxpelli/list-installed","owner":"voxpelli","description":"A modern typed async alternative to read-installed / readdir-scoped-modules","archived":false,"fork":false,"pushed_at":"2025-01-04T19:49:39.000Z","size":125,"stargazers_count":5,"open_issues_count":6,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-04T20:33:49.759Z","etag":null,"topics":["async","dependency-tree","npm","package-json"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"0bsd","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/voxpelli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["voxpelli"]}},"created_at":"2020-10-21T19:06:05.000Z","updated_at":"2025-01-04T19:48:46.000Z","dependencies_parsed_at":"2024-02-13T01:35:41.923Z","dependency_job_id":"6cbf16b5-e0b1-46fb-ad24-bd81b676f595","html_url":"https://github.com/voxpelli/list-installed","commit_stats":{"total_commits":81,"total_committers":3,"mean_commits":27.0,"dds":0.2098765432098766,"last_synced_commit":"7fc8413000e56b15d2df496635b9fbf212cb25e7"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Flist-installed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Flist-installed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Flist-installed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Flist-installed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voxpelli","download_url":"https://codeload.github.com/voxpelli/list-installed/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232802688,"owners_count":18578684,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","dependency-tree","npm","package-json"],"created_at":"2024-10-10T00:20:30.983Z","updated_at":"2025-01-07T00:07:32.542Z","avatar_url":"https://github.com/voxpelli.png","language":"JavaScript","funding_links":["https://github.com/sponsors/voxpelli"],"categories":[],"sub_categories":[],"readme":"# List Installed\n\nA modern typed async alternative to [`read-installed`](https://www.npmjs.com/package/read-installed) and [`readdir-scoped-modules`](https://www.npmjs.com/package/readdir-scoped-modules). Used to list and return all modules installed in `node_modules`, either just their names or their `package.json` files.\n\n[![npm version](https://img.shields.io/npm/v/list-installed.svg?style=flat)](https://www.npmjs.com/package/list-installed)\n[![npm downloads](https://img.shields.io/npm/dm/list-installed.svg?style=flat)](https://www.npmjs.com/package/list-installed)\n[![Module type: ESM](https://img.shields.io/badge/module%20type-esm-brightgreen)](https://github.com/voxpelli/badges-cjs-esm)\n[![Types in JS](https://img.shields.io/badge/types_in_js-yes-brightgreen)](https://github.com/voxpelli/types-in-js)\n[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-7fffff?style=flat\u0026labelColor=ff80ff)](https://github.com/neostandard/neostandard)\n[![Follow @voxpelli@mastodon.social](https://img.shields.io/mastodon/follow/109247025527949675?domain=https%3A%2F%2Fmastodon.social\u0026style=social)](https://mastodon.social/@voxpelli)\n\n## Usage\n\n### Simple\n\n```bash\nnpm install list-installed\n```\n\n```javascript\nimport { listInstalled } from 'list-installed';\n\nconst pkgMap = await listInstalled(__dirname);\n\n// Eg. iterate over the map\nfor (const [moduleName, pkg] of pkgMap.entries()) {\n  // \"moduleName\" is identical to pkg.name\n}\n```\n\n## Methods\n\n### `readdirScoped(path)`\n\n* **`path`**: A `string` pointing to the path of a _directory_, either absolute or relative to the current working directory. Eg: `./node_modules/`\n\n**Returns:** `AsyncGenerator` that emits `string` of the name of each found directory\n\nSimilar functionality to `readdir()` from [`readdir-scoped-modules`](https://www.npmjs.com/package/readdir-scoped-modules).\n\nReturns all directories in `path`, with the scoped directories (like `@foo`) expanded and joined with the directories directly beneath them (like eg. `@foo/abc` and `@foo/bar` if `abc` and `bar` are the two directories in `@foo`, though it will never expand to `@`- or `.`-prefixed subdirectories and will hence never return `@foo/@xyz` or `@foo/.bin`).\n\nWill not return any directory with a name that begins with `.`.\n\n### `readdirModuleTree(path, depth=0)`\n\n* **`path`**: A `string` pointing to the path of a _directory_, either absolute or relative to the current working directory. Eg: * `./node_modules/`\n* **`depth`**: If set to `0`, then this method is identical to `readdirScoped(path)`, else this will return also modules found this many layers deep\n\n**Returns:** `AsyncGenerator` that emits `string` paths, relative to the provided `path`, for each found module\n\nWorks the same as `readdirScoped` with the addition that if `depth` is set to higher than `0`, then for every result of `readdirScoped` a `node_modules` subdirectory is looked for and if found, `readdirScoped` is run on that directory as well, prefixing all results with the parent name/prefix followed by `/node_modules/`.\n\nFor a two level deep tree the name returned would be like `foo/node_modules/bar/node_modules/xyz`, which one can do `.split('/node_modules/')` on to get in array shape.\n\n### `listInstalled(path, [{ filter(pkg, alias) }])`\n\n* **`path`**: A `string` pointing to the path of a _module_, either absolute or relative to the current working directory. Eg: `./* `\n* **`filter`**: An optional callback that's similar to [`Array.prototype.filter()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter). Called with the resolved package file + if the module is aliased also the alias. Like `Array.prototype.filter()` it expects a truthy value back to include the item and a falsy to skip it. If the value returned is a `Promise` it will be resolved before the value is checked.\n\n**Returns:** `Promise` that resolves to a `Map` that has `string` keys of the names of the found dependencies and values being the parsed `package.json` files.\n\nSimilar functionality to `readInstalled()` from [`read-installed`](https://www.npmjs.com/package/read-installed).\n\nReturns all top level dependencies found installed for a module.\n\nParses all `package.json` in parallell using [`read-pkg`](https://github.com/sindresorhus/read-pkg) with results corresponding to the [`read-pkg`](https://github.com/sindresorhus/read-pkg) [`NormalizedPackageJson`](https://github.com/sindresorhus/read-pkg/blob/f50f5ffd4d5d25ef3387562c2e32e22ba68552dd/index.d.ts#L24) type.\n\n### `listInstalledGenerator(path, [{ filter }])`\n\n* **`path`**: A `string` pointing to the path of a _module_, either absolute or relative to the current working directory. Eg: `./* `\n* **`filter`**: An optional callback that's similar to [`Array.prototype.filter()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter). Called with the resolved package file + if the module is aliased also the alias. Like `Array.prototype.filter()` it expects a truthy value back to include the item and a falsy to skip it. If the value returned is a `Promise` it will be resolved before the value is checked.\n\n**Returns:** `AsyncGenerator` that emits an object for each of the found dependencies. The object has two properties: `alias`, containing the alias when the module has been installed under an alias, and `pkg`, containing the parsed `package.json` files of the found dependencies.\n\nSame as `listInstalled(path)`, but rather than parsing `package.json` in parallell, it parses it sequentially at the pace that it is consumed.\n\n### `workspaceLookup([options])`\n\n* **`options.ignorePaths`**: An array of strings, `string[]`, with paths to ignore during the lookup of workspaces\n* **`options.includeWorkspaceRoot=true`**: If set to `false`, then the workspace root will not be returned\n* **`options.path='.'`**: A `string` pointing to the path of the module to look up the `package.json` and installed modules for\n* **`options.skipWorkspaces=false`**: If set, then no workspace lookup will be done and no workspaces be returned\n* **`options.workspace`**: An array of strings that should match the name of a workspace, its path or its path prefix. Only matching workspaces will be returned (as well as the root if `includeWorkspaceRoot` is `true`). If a workspace can't be found, then an error will be thrown when the generator has been fully iterated through.\n* ...and any other option available in [`read-workspaces`](https://github.com/voxpelli/read-workspaces?tab=readme-ov-file#readworkspacesoptions)\n\n**Returns:** `AsyncGenerator` that emits `{ cwd, installed, pkg, workspace }` for the root (if `includeWorkspaceRoot` is `true`) and each matching workspace (if `skipWorkspaces` isn't `true`). `cwd` is the path to the workspace or root, `installed` is an object that's the combined result of a `listInstalled` for the root and that `cwd`, `pkg` is the `package.json` of the workspace or root and `workspace` is the name of the workspace and is not set on the root result.\n\n## Used by\n\n* [`installed-check`](https://github.com/voxpelli/node-installed-check) / [`installed-check-core`](https://github.com/voxpelli/node-installed-check-core)\n\n## Similar modules\n\n* [`list-dependents`](https://github.com/voxpelli/list-dependents) – looks up the the modules depending on a provided module them and returns them in a similar way to this module\n* [`read-workspaces`](https://github.com/voxpelli/read-workspaces) – provides the workspace lookup functionality that this module uses\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpelli%2Flist-installed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoxpelli%2Flist-installed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpelli%2Flist-installed/lists"}