UNPKG

workspaces-filter

Version:

A companion for filtering monorepo workspaces, by package name or package dir. Because all package manager's are weird. Useful for running scripts on a subset of workspaces. The primary reason is because Bun's "--filter" feature is buggy, but it's also us

247 lines (168 loc) 7.9 kB
# workspaces-filter > A companion for filtering monorepo workspaces, by package name or package dir. Because all package > manager's are weird. Useful for running scripts on a subset of workspaces. The primary reason is > because Bun's --filter feature is buggy, but it's also useful for other package manger, it also > runs shell scripts using the `execa` package. <!-- prettier-ignore-start --> [![][npm-version-src]][npm-version-href] [![][github-actions-src]][github-actions-href] [![][codecov-src]][codecov-href] [![][npm-downloads-src]][npm-downloads-href] [![][codestyle-src]][codestyle-href] [![][license-src]][license-href] <!-- prettier-ignore-end --> <!-- [![][npm-weekly-img]][npmv-url] --> <!-- [![][npm-monthly-img]][npmv-url] --> <!-- [![][npm-yearly-img]][npmv-url] --> <!-- [![][npm-alltime-img]][npmv-url] --> ## Highlights The library is especially useful when you need to: - Programmatically find and filter workspace packages - Run commands or scripts on a subset of packages - Execute package manager commands across filtered workspaces - Run shell commands in specific workspace directories ## Install ```sh bun add workspaces-filter npm install workspaces-filter ``` or use the CLI directly: ```sh bunx workspaces-filter npx workspaces-filter pnpm dlx workspaces-filter # or install globally npm install -g workspaces-filter ``` ## Usage as CLI ```sh workspaces-filter/0.8.1 Usage: $ workspaces-filter <pattern> [...command] Commands: <pattern> [...command] Select by package name or workspace directory For more info, run any command with the `--help` flag: $ workspaces-filter --help Options: --print <mode> Print the names/folders of selected packages, without running command --cwd <dir> Current working directory (default: /home/charlike/code/mid-april-2025/workspaces-filter) --pm, --package-manager <pm> The package manager to use. Defaults to packageManager from root package.json, or Bun -v, --version Display version number -h, --help Display this message Examples: workspaces-filter . build # run in all packages of all workspaces workspaces-filter _ build # because the "*" would not work if raw workspaces-filter '*' build # should be quoted to avoid shell globbing workspaces-filter "*preset*" build workspaces-filter "*preset*" add foo-pkg barry-pkg workspaces-filter "*preset*" add --dev typescript workspaces-filter "./packages/foo" -- echo "Hello, World!" workspaces-filter "./packages/*preset*" -- pwd workspaces-filter "*preset*" --print names workspaces-filter "*preset*" --print json workspaces-filter "*preset*" --print dirs ``` > [!NOTE] > > To run a shell command in selected/filtered packages, use `--` right after the pattern! > [!CAUTION] > > Keep in mind that if a workspace package has a script called `add`, it would run it while you may want to run `bun add`, `npm add` or `pnpm add`. > Just don't name your scripts like that or expect buggy behaviors. It's easy to assume it would have conflicts. Or use `--` to run a shell command in selected package dirs. ### Examples ```sh npx workspaces-filter '*preset*' build pnpm dlx workspaces-filter '*preset*' add foo-pkg bunx workspaces-filter '*preset*' add --dev typescript ``` It checks if there is a script in package's scripts field (thus runs it with `bun run`, `npm run` or `pnpm run`), if not runs the package manager command (`bun add`, `npm add`), or a shell command if `_` or `sh` is provided right after the pattern, like so ```sh bunx workspaces-filter './packages/foo' -- echo 'Hello, World!' # runs `echo 'Hello, World!'` in the `./packages/foo` workspace bunx workspaces-filter './packages/*preset*' -- pwd # runs `pwd` in each workspace ``` You can run `pnpm dlx` like so ```sh pnpx workspaces-filter '*preset*' dlx esmc ``` ## Using as a Library The package can also be used programmatically in your Node.js/TypeScript applications: ### API <!-- prettier-ignore-start --> <!-- docks-start --> _Generated using [docks](https://github.com/tunnckoCore/workspaces-filter/blob/master/docks.ts)._ ### [filter](./src/index.ts#L51) Filters workspace packages based on provided glob patterns and search patterns. <span id="filter-params"></span> #### Params - `wsGlobs` **{Array&lt;string&gt;}** - Array of workspace glob patterns to search for package.json files. - `pattern` **{Array&lt;string&gt;}** - String or array of strings to filter workspaces by name or directory. - `cwd` - Optional current working directory (defaults to `process.cwd()`). <span id="filter-throws"></span> #### Throws - **{Error}** - When no workspace globs are provided. - **{Error}** - When no pattern is provided. <span id="filter-returns"></span> #### Returns - **{Promise&lt;Graph&gt;}** - Resolving to a Graph object containing filtered workspace metadata. <span id="filter-examples"></span> #### Examples ```ts import { filter } from 'workspaces-filter'; // Filter workspaces matching 'pkg-*' pattern const graph = await filter(['packages/*'], 'pkg-*'); // Filter multiple patterns const graph = await filter(['packages/*'], ['pkg-1', 'pkg-2']); // Filter with package dirs const graph = await filter(['packages/*'], ['packages/foo']); // Filter with custom working directory const graph = await filter(['packages/*'], '*', '/path/to/project'); ``` ### [runCommandOn](./src/index.ts#L167) Executes a shell command or a package script in the context of each package in the graph. <span id="runcommandon-params"></span> #### Params - `args` **{Array&lt;string&gt;}** - Arguments to pass to the command. - `graph` **{Graph}** - Graph object containing package metadata. - `options` **{RunCommandOnOptions}** - Optional configuration for running the command. <span id="runcommandon-returns"></span> #### Returns - **{Promise&lt;Graph&gt;}** - Resolving to the input graph object. <span id="runcommandon-examples"></span> #### Examples ```ts import { filter, runCommandOn } from 'workspaces-filter'; const graph = await filter(['packages/*'], ['@scope/*']); console.log(graph); type RunCommandOnOptions = { cwd?: string; isShell?: boolean; packageManager?: string; onTestCallback?: (_err: any, _ok: any) => void | Promise<void>; }; // Run a shell command in each package await runCommandOn(['echo', 'Hello, World!'], graph, { isShell: true } as RunCommandOnOptions); // Run a package script in each package await runCommandOn(['build'], graph); ``` <!-- docks-end --> <!-- prettier-ignore-end --> ## License Licensed under the [MIT License](https://opensource.org/licenses/MIT) <!-- prettier-ignore-start --> [npm-version-src]: https://img.shields.io/npm/v/workspaces-filter?style=flat&logo=npm [npm-version-href]: https://npmjs.com/package/workspaces-filter [npm-downloads-src]: https://img.shields.io/npm/dm/workspaces-filter?style=flat&logo=npm [npm-downloads-href]: https://npmjs.com/package/workspaces-filter [github-actions-src]: https://img.shields.io/github/actions/workflow/status/tunnckoCore/workspaces-filter/ci.yml?style=flat&logo=github [github-actions-href]: https://github.com/tunnckocore/workspaces-filter/actions?query=workflow%3Aci [codecov-src]: https://img.shields.io/codecov/c/gh/tunnckocore/workspaces-filter/master?style=flat&logo=codecov [codecov-href]: https://codecov.io/gh/tunnckocore/workspaces-filter [bundle-src]: https://img.shields.io/bundlephobia/minzip/workspaces-filter?style=flat [bundle-href]: https://bundlephobia.com/result?p=workspaces-filter [license-src]: https://img.shields.io/npm/l/workspaces-filter?style=flat&colorB=blue [license-href]: https://github.com/tunnckocore/workspaces-filter/blob/master/LICENSE [codestyle-src]: https://badgen.net/badge/code%20style/xaxa/44cc11?icon=airbnb [codestyle-href]: https://github.com/tunnckoCore/eslint-config-xaxa <!-- prettier-ignore-end -->