Find all packages inside a directory using glob patterns with intelligent filtering
npx @tessl/cli install tessl/npm-pnpm-fs--find-packages@1000.0.00
# @pnpm/fs.find-packages
1
2
@pnpm/fs.find-packages is a TypeScript library that discovers and locates package.json files within directory structures. It uses intelligent glob patterns to search through directories while filtering out common non-package locations, making it essential for build tools, package managers, and workspace management systems.
3
4
## Package Information
5
6
- **Package Name**: @pnpm/fs.find-packages
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @pnpm/fs.find-packages`
10
11
## Core Imports
12
13
```typescript
14
import { findPackages, type Options } from "@pnpm/fs.find-packages";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { findPackages } = require("@pnpm/fs.find-packages");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import { findPackages } from "@pnpm/fs.find-packages";
27
28
// Find all packages in a directory
29
const packages = await findPackages("/path/to/workspace");
30
31
// Find packages with custom patterns
32
const packages = await findPackages("/path/to/workspace", {
33
patterns: ["components/**", "libs/**"],
34
ignore: ["**/test/**"]
35
});
36
37
// Access package information
38
packages.forEach(pkg => {
39
console.log(`Found package: ${pkg.manifest.name} at ${pkg.rootDir}`);
40
});
41
```
42
43
## Capabilities
44
45
### Package Discovery
46
47
Finds all packages in a directory using glob patterns with intelligent filtering for common non-package locations.
48
49
```typescript { .api }
50
/**
51
* Find all packages inside a directory
52
* @param root - The directory to search for packages
53
* @param opts - Optional configuration options
54
* @returns Promise resolving to array of discovered projects
55
*/
56
export function findPackages(root: string, opts?: Options): Promise<Project[]>;
57
58
export interface Options {
59
/** Custom patterns to ignore when searching (overrides defaults) */
60
ignore?: string[];
61
/** Whether to include the workspace root in results */
62
includeRoot?: boolean;
63
/** Custom glob patterns for package locations (default: ['.', '**']) */
64
patterns?: string[];
65
}
66
```
67
68
**Usage Examples:**
69
70
```typescript
71
import { findPackages, type Options } from "@pnpm/fs.find-packages";
72
73
// Find all packages using default patterns (searches '.' and '**')
74
const allPackages = await findPackages("/path/to/monorepo");
75
console.log(`Found ${allPackages.length} packages`);
76
77
// Find packages in specific directories only
78
const componentPackages = await findPackages("/path/to/workspace", {
79
patterns: ["components/**"]
80
});
81
82
// Find packages using wildcard patterns
83
const specificPackages = await findPackages("/path/to/workspace", {
84
patterns: [".", "components/*"] // Include root and direct subdirs of components
85
});
86
87
// Find packages with custom ignore patterns
88
const filteredPackages = await findPackages("/path/to/workspace", {
89
patterns: ["**"],
90
ignore: ["**/node_modules/**", "**/dist/**", "**/build/**", "**/test/**"]
91
});
92
93
// Include workspace root as a package (useful for monorepo root)
94
const withRoot = await findPackages("/path/to/workspace", {
95
includeRoot: true
96
});
97
98
// Exclude specific directories using negation patterns
99
const excludeLibs = await findPackages("/path/to/workspace", {
100
patterns: ["**", "!libs/**"] // Find all except libs directory
101
});
102
103
// Exclude from root level only (different from general exclusion)
104
const excludeRootLibs = await findPackages("/path/to/workspace", {
105
patterns: ["**", "!/libs/**"] // Exclude libs at root level only
106
});
107
108
// Access package information
109
allPackages.forEach(pkg => {
110
console.log(`Package: ${pkg.manifest.name}`);
111
console.log(`Version: ${pkg.manifest.version}`);
112
console.log(`Location: ${pkg.rootDir}`);
113
console.log(`Real path: ${pkg.rootDirRealPath}`);
114
115
// Check if it has dependencies
116
if (pkg.manifest.dependencies) {
117
console.log(`Dependencies: ${Object.keys(pkg.manifest.dependencies).join(', ')}`);
118
}
119
120
// Write updated manifest if needed
121
// pkg.writeProjectManifest({ ...pkg.manifest, version: '2.0.0' });
122
});
123
```
124
125
## Types
126
127
```typescript { .api }
128
/** Configuration options for findPackages function */
129
interface Options {
130
/**
131
* Patterns to ignore when searching for packages
132
* Default: ['**/node_modules/**', '**/bower_components/**', '**/test/**', '**/tests/**']
133
*/
134
ignore?: string[];
135
/** Whether to include the workspace root directory as a package */
136
includeRoot?: boolean;
137
/**
138
* Glob patterns to use as package locations
139
* Default: ['.', '**'] (searches current directory and all subdirectories)
140
*/
141
patterns?: string[];
142
}
143
144
/** Represents a discovered package project */
145
interface Project {
146
/** Project root directory path */
147
rootDir: ProjectRootDir;
148
/** Real path to project root (resolved symlinks) */
149
rootDirRealPath: ProjectRootDirRealPath;
150
/** Optional modules directory path */
151
modulesDir?: string;
152
/** Package manifest data (package.json contents) */
153
manifest: ProjectManifest;
154
/** Function to write updated manifest to disk */
155
writeProjectManifest: (manifest: ProjectManifest, force?: boolean) => Promise<void>;
156
}
157
158
/** Branded string type for project root directory paths */
159
type ProjectRootDir = string & { __brand: 'ProjectRootDir' };
160
161
/** Branded string type for real project root directory paths */
162
type ProjectRootDirRealPath = string & { __brand: 'ProjectRootDirRealPath' };
163
164
/** Package dependencies mapping */
165
type Dependencies = Record<string, string>;
166
167
/** Package bin configuration */
168
type PackageBin = string | { [commandName: string]: string };
169
170
/** Package scripts configuration with known lifecycle hooks */
171
type PackageScripts = {
172
[name: string]: string;
173
} & {
174
prepublish?: string;
175
prepare?: string;
176
prepublishOnly?: string;
177
prepack?: string;
178
postpack?: string;
179
publish?: string;
180
postpublish?: string;
181
preinstall?: string;
182
install?: string;
183
postinstall?: string;
184
preuninstall?: string;
185
uninstall?: string;
186
postuninstall?: string;
187
preversion?: string;
188
version?: string;
189
postversion?: string;
190
pretest?: string;
191
test?: string;
192
posttest?: string;
193
prestop?: string;
194
stop?: string;
195
poststop?: string;
196
prestart?: string;
197
start?: string;
198
poststart?: string;
199
prerestart?: string;
200
restart?: string;
201
postrestart?: string;
202
preshrinkwrap?: string;
203
shrinkwrap?: string;
204
postshrinkwrap?: string;
205
};
206
207
/** Peer dependencies metadata */
208
interface PeerDependenciesMeta {
209
[dependencyName: string]: {
210
optional?: boolean;
211
};
212
}
213
214
/** Dependencies metadata for custom configuration */
215
interface DependenciesMeta {
216
[dependencyName: string]: {
217
injected?: boolean;
218
node?: string;
219
patch?: string;
220
};
221
}
222
223
/** Development engine dependency configuration */
224
interface DevEngineDependency {
225
name: string;
226
version?: string;
227
onFail?: 'ignore' | 'warn' | 'error' | 'download';
228
}
229
230
/** Development engines configuration */
231
interface DevEngines {
232
os?: DevEngineDependency | DevEngineDependency[];
233
cpu?: DevEngineDependency | DevEngineDependency[];
234
libc?: DevEngineDependency | DevEngineDependency[];
235
runtime?: DevEngineDependency | DevEngineDependency[];
236
packageManager?: DevEngineDependency | DevEngineDependency[];
237
}
238
239
/** Publish configuration */
240
interface PublishConfig extends Record<string, unknown> {
241
directory?: string;
242
linkDirectory?: boolean;
243
executableFiles?: string[];
244
registry?: string;
245
}
246
247
/** TypeScript types versions mapping */
248
interface TypesVersions {
249
[version: string]: {
250
[pattern: string]: string[];
251
};
252
}
253
254
/** Peer dependency rules configuration */
255
interface PeerDependencyRules {
256
ignoreMissing?: string[];
257
allowAny?: string[];
258
allowedVersions?: Record<string, string>;
259
}
260
261
/** Audit configuration */
262
interface AuditConfig {
263
ignoreCves?: string[];
264
ignoreGhsas?: string[];
265
}
266
267
/** Supported architectures configuration */
268
interface SupportedArchitectures {
269
os?: string[];
270
cpu?: string[];
271
libc?: string[];
272
}
273
274
/** pnpm-specific settings */
275
interface PnpmSettings {
276
configDependencies?: Record<string, string>;
277
neverBuiltDependencies?: string[];
278
onlyBuiltDependencies?: string[];
279
onlyBuiltDependenciesFile?: string;
280
ignoredBuiltDependencies?: string[];
281
overrides?: Record<string, string>;
282
packageExtensions?: Record<string, any>;
283
ignoredOptionalDependencies?: string[];
284
peerDependencyRules?: PeerDependencyRules;
285
allowedDeprecatedVersions?: Record<string, string>;
286
allowNonAppliedPatches?: boolean;
287
allowUnusedPatches?: boolean;
288
ignorePatchFailures?: boolean;
289
patchedDependencies?: Record<string, string>;
290
updateConfig?: {
291
ignoreDependencies?: string[];
292
};
293
auditConfig?: AuditConfig;
294
requiredScripts?: string[];
295
supportedArchitectures?: SupportedArchitectures;
296
}
297
298
/** Complete package manifest data structure (package.json contents) */
299
interface ProjectManifest {
300
name?: string;
301
version?: string;
302
type?: string;
303
bin?: PackageBin;
304
description?: string;
305
directories?: {
306
bin?: string;
307
};
308
files?: string[];
309
funding?: string;
310
dependencies?: Dependencies;
311
devDependencies?: Dependencies;
312
optionalDependencies?: Dependencies;
313
peerDependencies?: Dependencies;
314
peerDependenciesMeta?: PeerDependenciesMeta;
315
dependenciesMeta?: DependenciesMeta;
316
bundleDependencies?: string[] | boolean;
317
bundledDependencies?: string[] | boolean;
318
homepage?: string;
319
repository?: string | { url: string };
320
bugs?: string | {
321
url?: string;
322
email?: string;
323
};
324
scripts?: PackageScripts;
325
config?: object;
326
engines?: {
327
node?: string;
328
npm?: string;
329
pnpm?: string;
330
};
331
devEngines?: DevEngines;
332
cpu?: string[];
333
os?: string[];
334
libc?: string[];
335
main?: string;
336
module?: string;
337
typings?: string;
338
types?: string;
339
publishConfig?: PublishConfig;
340
typesVersions?: TypesVersions;
341
readme?: string;
342
keywords?: string[];
343
author?: string;
344
license?: string;
345
exports?: Record<string, string>;
346
imports?: Record<string, unknown>;
347
packageManager?: string;
348
workspaces?: string[];
349
pnpm?: PnpmSettings;
350
private?: boolean;
351
resolutions?: Record<string, string>;
352
}
353
```
354
355
## Default Ignore Patterns
356
357
By default, the following patterns are ignored to avoid scanning non-package directories:
358
359
- `**/node_modules/**` - Node.js dependencies
360
- `**/bower_components/**` - Bower dependencies
361
- `**/test/**` - Test directories
362
- `**/tests/**` - Test directories (plural)
363
364
## Error Handling
365
366
The function handles common filesystem errors gracefully:
367
368
- **ENOENT errors**: Silently filters out packages where manifest files don't exist
369
- **Other filesystem errors**: Re-thrown to caller for proper error handling
370
- **Invalid manifests**: Filtered out of results automatically
371
372
## Pattern Syntax
373
374
Glob patterns follow standard glob syntax with these behaviors:
375
376
- `**` matches any number of directories recursively
377
- `*` matches any characters except directory separators
378
- `!pattern` excludes matches from the pattern
379
- `!/pattern` (with leading slash) excludes from root level only
380
- Patterns are automatically normalized to search for manifest files (`/package.{json,yaml,json5}`)
381
382
### Pattern Normalization
383
384
All patterns are automatically normalized by appending `/package.{json,yaml,json5}` to search for package manifest files. This means:
385
386
- `"."` becomes `"./package.{json,yaml,json5}"` (searches current directory)
387
- `"**"` becomes `"**/package.{json,yaml,json5}"` (searches all subdirectories)
388
- `"components/**"` becomes `"components/**/package.{json,yaml,json5}"`
389
390
### Default Patterns
391
392
If no patterns are specified, the default patterns `['.', '**']` are used, which searches:
393
1. The current directory (root) for package files
394
2. All subdirectories recursively for package files
395
396
### Supported Manifest File Types
397
398
The library automatically searches for packages using any of these manifest file formats:
399
- `package.json` - Standard JSON format
400
- `package.yaml` - YAML format
401
- `package.json5` - JSON5 format with comments and trailing commas