Find all packages inside a directory with customizable pattern matching for monorepos
npx @tessl/cli install tessl/npm-pnpm--fs--find-packages@1000.0.00
# @pnpm/fs.find-packages
1
2
@pnpm/fs.find-packages provides functionality to find all packages inside a directory with customizable pattern matching. It's designed for working with monorepos and workspaces, allowing developers to discover package.json, package.yaml, and package.json5 files across complex directory structures.
3
4
## Package Information
5
6
- **Package Name**: @pnpm/fs.find-packages
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `pnpm add @pnpm/fs.find-packages`
10
11
## Core Imports
12
13
CommonJS (primary):
14
15
```javascript
16
const { findPackages } = require("@pnpm/fs.find-packages");
17
```
18
19
TypeScript:
20
21
```typescript
22
import { findPackages, type Options } from "@pnpm/fs.find-packages";
23
```
24
25
## Basic Usage
26
27
```typescript
28
import { findPackages } from "@pnpm/fs.find-packages";
29
import path from "path";
30
31
// Find all packages in a directory with default patterns
32
const packages = await findPackages(path.join(__dirname, "my-monorepo"));
33
34
// Each package contains:
35
// - rootDir: path to package directory
36
// - rootDirRealPath: resolved real path
37
// - manifest: parsed package.json/yaml/json5 content
38
// - writeProjectManifest: function to write manifest changes
39
40
console.log(packages[0].manifest.name); // package name
41
console.log(packages[0].rootDir); // package directory
42
```
43
44
## Capabilities
45
46
### Package Discovery
47
48
Asynchronously finds all packages in a directory based on configurable glob patterns and ignore rules.
49
50
```typescript { .api }
51
/**
52
* Find all packages in a directory
53
* @param root - Root directory to search in
54
* @param opts - Optional configuration for search behavior
55
* @returns Promise resolving to array of discovered projects
56
*/
57
function findPackages(root: string, opts?: Options): Promise<Project[]>;
58
59
interface Options {
60
/** Patterns to ignore when searching (default: node_modules, bower_components, test, tests) */
61
ignore?: string[];
62
/** Whether to include the workspace root package (default: false) */
63
includeRoot?: boolean;
64
/**
65
* Glob patterns for package locations (default: ['.', '**'])
66
* Supports positive patterns ('components/**') and negative patterns ('!test/**', '!/libs/**')
67
* Negative patterns starting with '!/' are treated as absolute paths from the search root
68
*/
69
patterns?: string[];
70
}
71
```
72
73
**Usage Examples:**
74
75
```typescript
76
import { findPackages } from "@pnpm/fs.find-packages";
77
78
// Basic usage - find all packages with default patterns
79
const allPackages = await findPackages("/path/to/monorepo");
80
81
// Custom patterns - only search in specific directories
82
const componentPackages = await findPackages("/path/to/monorepo", {
83
patterns: ["components/**", "libs/**"]
84
});
85
86
// Include workspace root and custom ignore patterns
87
const packagesWithRoot = await findPackages("/path/to/monorepo", {
88
includeRoot: true,
89
ignore: ["**/node_modules/**", "**/dist/**", "**/.tmp/**"]
90
});
91
92
// Exclude specific directories using negative patterns
93
const filteredPackages = await findPackages("/path/to/monorepo", {
94
patterns: ["**", "!test-fixtures/**", "!examples/**"]
95
});
96
97
// Negative patterns with absolute paths (note the leading slash)
98
const alternativeFiltered = await findPackages("/path/to/monorepo", {
99
patterns: ["**", "!/libs/**"] // absolute exclusion from root
100
});
101
```
102
103
## Types
104
105
```typescript { .api }
106
interface Project {
107
/** Directory path containing the package */
108
rootDir: ProjectRootDir;
109
/** Real filesystem path to the package directory */
110
rootDirRealPath: ProjectRootDirRealPath;
111
/** Optional modules directory path */
112
modulesDir?: string;
113
/** Parsed package manifest (package.json/yaml/json5) */
114
manifest: ProjectManifest;
115
/** Function to write changes back to the manifest file */
116
writeProjectManifest: (manifest: ProjectManifest, force?: boolean) => Promise<void>;
117
}
118
119
type ProjectRootDir = string & { __brand: 'ProjectRootDir' };
120
type ProjectRootDirRealPath = string & { __brand: 'ProjectRootDirRealPath' };
121
122
interface ProjectManifest {
123
// Basic package information
124
name?: string;
125
version?: string;
126
description?: string;
127
keywords?: string[];
128
author?: string | { name?: string; email?: string; url?: string };
129
maintainers?: Array<{ name?: string; email?: string; url?: string }>;
130
contributors?: Array<string | { name?: string; email?: string; url?: string }>;
131
license?: string;
132
133
// Entry points and module configuration
134
main?: string;
135
module?: string;
136
browser?: string | Record<string, string | false>;
137
type?: "module" | "commonjs";
138
types?: string;
139
typings?: string;
140
bin?: string | Record<string, string>;
141
files?: string[];
142
exports?: string | Record<string, any>;
143
144
// Scripts and lifecycle hooks
145
scripts?: Record<string, string>;
146
147
// Dependencies
148
dependencies?: Record<string, string>;
149
devDependencies?: Record<string, string>;
150
peerDependencies?: Record<string, string>;
151
peerDependenciesMeta?: Record<string, { optional?: boolean }>;
152
optionalDependencies?: Record<string, string>;
153
bundleDependencies?: string[] | boolean;
154
bundledDependencies?: string[] | boolean;
155
156
// Configuration and constraints
157
engines?: Record<string, string>;
158
engineStrict?: boolean;
159
os?: string[];
160
cpu?: string[];
161
162
// Publishing and repository
163
private?: boolean;
164
publishConfig?: Record<string, any>;
165
homepage?: string;
166
repository?: string | { type?: string; url: string; directory?: string };
167
bugs?: string | { url?: string; email?: string };
168
funding?: string | { type?: string; url: string } | Array<string | { type?: string; url: string }>;
169
170
// Workspace and monorepo (pnpm-specific)
171
packageManager?: string;
172
workspaces?: string[] | { packages?: string[]; nohoist?: string[] };
173
resolutions?: Record<string, string>;
174
175
// pnpm-specific configuration
176
pnpm?: {
177
overrides?: Record<string, string>;
178
packageExtensions?: Record<string, any>;
179
peerDependencyRules?: {
180
ignoreMissing?: string[];
181
allowedVersions?: Record<string, string>;
182
allowAny?: string[];
183
};
184
neverBuiltDependencies?: string[];
185
onlyBuiltDependencies?: string[];
186
allowedDeprecatedVersions?: Record<string, string>;
187
188
// Workspace-specific settings
189
requiredScripts?: string[];
190
191
// Publishing settings
192
updateConfig?: {
193
ignoreDependencies?: string[];
194
};
195
};
196
197
// Additional fields (for extensibility)
198
[key: string]: any;
199
}
200
```
201
202
## Supported Manifest Formats
203
204
The package automatically detects and parses multiple manifest file formats:
205
206
- `package.json` - Standard JSON format
207
- `package.yaml` - YAML format
208
- `package.json5` - JSON5 format with comments and trailing commas
209
210
## Default Ignore Patterns
211
212
By default, the following directories are ignored during package discovery:
213
214
- `**/node_modules/**` - npm/yarn dependency directories
215
- `**/bower_components/**` - Bower dependency directories
216
- `**/test/**` - Test directories
217
- `**/tests/**` - Test directories (alternative naming)
218
219
## Error Handling
220
221
The function handles filesystem errors gracefully:
222
223
- Missing manifest files (`ENOENT` errors) are silently ignored
224
- Other filesystem errors are propagated to the caller
225
- Invalid manifest files are handled by the underlying manifest parser
226
- Results are automatically filtered to exclude failed reads
227
228
## Performance Characteristics
229
230
- Uses `tinyglobby` for efficient glob pattern matching
231
- Employs `Set` data structure to automatically deduplicate discovered paths
232
- Sorts results lexicographically by directory path for consistent ordering
233
- Supports concurrent manifest reading through `p-filter` for improved performance
234
- Resolves real filesystem paths to handle symlinks correctly