Reads the current state of projects from modules manifest for pnpm workspace management
npx @tessl/cli install tessl/npm-pnpm--read-projects-context@1000.0.00
# @pnpm/read-projects-context
1
2
@pnpm/read-projects-context provides functionality to read and process the current state of projects from modules manifest files in pnpm workspaces. It analyzes project configurations, hoisting patterns, and module states to provide comprehensive context for pnpm operations.
3
4
## Package Information
5
6
- **Package Name**: @pnpm/read-projects-context
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @pnpm/read-projects-context`
10
11
## Core Imports
12
13
```typescript
14
import { readProjectsContext, type ProjectOptions } from "@pnpm/read-projects-context";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { readProjectsContext } = require("@pnpm/read-projects-context");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import { readProjectsContext, type ProjectOptions } from "@pnpm/read-projects-context";
27
28
// Define projects to read context for
29
const projects: ProjectOptions[] = [
30
{
31
rootDir: "/path/to/project1",
32
modulesDir: "node_modules", // optional
33
binsDir: "node_modules/.bin" // optional
34
},
35
{
36
rootDir: "/path/to/project2"
37
}
38
];
39
40
// Read projects context
41
const context = await readProjectsContext(projects, {
42
lockfileDir: "/path/to/workspace/root",
43
modulesDir: "node_modules" // optional
44
});
45
46
// Access the results
47
console.log("Root modules directory:", context.rootModulesDir);
48
console.log("Hoisted dependencies:", context.hoistedDependencies);
49
console.log("Registry configurations:", context.registries);
50
console.log("Projects with resolved paths:", context.projects);
51
```
52
53
## Capabilities
54
55
### Project Context Reading
56
57
Reads and processes the current state of multiple projects from their modules manifest files, providing comprehensive workspace context.
58
59
```typescript { .api }
60
/**
61
* Reads project context including modules state, registries, and project configurations
62
* @param projects - Array of project configurations with optional generic extensions
63
* @param opts - Options containing lockfile directory and optional modules directory
64
* @returns Promise resolving to comprehensive project context
65
*/
66
function readProjectsContext<T>(
67
projects: Array<ProjectOptions & T>,
68
opts: {
69
lockfileDir: string;
70
modulesDir?: string;
71
}
72
): Promise<{
73
currentHoistPattern?: string[];
74
currentPublicHoistPattern?: string[];
75
hoist?: boolean;
76
hoistedDependencies: HoistedDependencies;
77
projects: Array<{
78
id: ProjectId;
79
} & T & Required<ProjectOptions>>;
80
include: IncludedDependencies;
81
modules: Modules | null;
82
pendingBuilds: string[];
83
registries: Registries | null | undefined;
84
rootModulesDir: string;
85
skipped: Set<DepPath>;
86
virtualStoreDirMaxLength?: number;
87
}>;
88
```
89
90
### Project Configuration Interface
91
92
Defines the structure for individual project options that can be passed to readProjectsContext.
93
94
```typescript { .api }
95
/**
96
* Configuration options for a single project
97
*/
98
interface ProjectOptions {
99
/** Optional binary directory path */
100
binsDir?: string;
101
/** Optional modules directory path */
102
modulesDir?: string;
103
/** Required project root directory */
104
rootDir: ProjectRootDir;
105
/** Optional real path to root directory */
106
rootDirRealPath?: ProjectRootDirRealPath;
107
}
108
```
109
110
## Types
111
112
```typescript { .api }
113
// Core type definitions (from @pnpm/types)
114
// Note: These are branded string types for type safety but work as regular strings at runtime
115
type ProjectRootDir = string;
116
type ProjectRootDirRealPath = string;
117
type ProjectId = string;
118
type DepPath = string;
119
type DependenciesField = "dependencies" | "devDependencies" | "optionalDependencies";
120
121
// Return type interfaces
122
interface HoistedDependencies {
123
[depPath: string]: {
124
[alias: string]: "public" | "private";
125
};
126
}
127
128
interface Registries {
129
default: string;
130
[scope: string]: string;
131
}
132
133
type IncludedDependencies = {
134
[dependenciesField in DependenciesField]: boolean;
135
};
136
137
interface Modules {
138
hoistedAliases?: { [depPath: string]: string[] }; // for backward compatibility
139
hoistedDependencies: HoistedDependencies;
140
hoistPattern?: string[];
141
included: IncludedDependencies;
142
layoutVersion: number;
143
nodeLinker?: "hoisted" | "isolated" | "pnp";
144
packageManager: string;
145
pendingBuilds: string[];
146
ignoredBuilds?: string[];
147
prunedAt: string;
148
registries?: Registries; // nullable for backward compatibility
149
shamefullyHoist?: boolean; // for backward compatibility
150
publicHoistPattern?: string[];
151
skipped: string[];
152
storeDir: string;
153
virtualStoreDir: string;
154
virtualStoreDirMaxLength: number;
155
injectedDeps?: Record<string, string[]>;
156
hoistedLocations?: Record<string, string[]>;
157
}
158
```
159
160
## Usage Examples
161
162
### Generic Project Extensions
163
164
```typescript
165
interface CustomProjectData {
166
customField: string;
167
buildScript?: string;
168
}
169
170
const projectsWithCustomData: Array<ProjectOptions & CustomProjectData> = [
171
{
172
rootDir: "/path/to/project",
173
customField: "custom value",
174
buildScript: "npm run build"
175
}
176
];
177
178
const context = await readProjectsContext(projectsWithCustomData, {
179
lockfileDir: "/workspace/root"
180
});
181
182
// Projects will now include custom fields along with resolved paths
183
context.projects.forEach(project => {
184
console.log(project.customField); // "custom value"
185
console.log(project.id); // resolved project ID
186
console.log(project.modulesDir); // resolved modules directory
187
});
188
```
189
190
### Working with Hoisting Configuration
191
192
```typescript
193
const context = await readProjectsContext(projects, {
194
lockfileDir: "/workspace/root"
195
});
196
197
if (context.hoist) {
198
console.log("Hoisting is enabled");
199
console.log("Current hoist pattern:", context.currentHoistPattern);
200
console.log("Public hoist pattern:", context.currentPublicHoistPattern);
201
202
// Access hoisted dependencies
203
Object.entries(context.hoistedDependencies).forEach(([depPath, aliases]) => {
204
Object.entries(aliases).forEach(([alias, visibility]) => {
205
console.log(`Dependency ${depPath} has alias ${alias} with visibility: ${visibility}`);
206
});
207
});
208
}
209
```
210
211
### Registry Configuration
212
213
```typescript
214
const context = await readProjectsContext(projects, {
215
lockfileDir: "/workspace/root"
216
});
217
218
if (context.registries) {
219
// Process normalized registry configurations
220
console.log("Default registry:", context.registries.default);
221
Object.entries(context.registries).forEach(([scope, registry]) => {
222
if (scope !== "default") {
223
console.log(`Scope ${scope} uses registry: ${registry}`);
224
}
225
});
226
}
227
228
// Access complete modules information if available
229
if (context.modules) {
230
console.log("Package manager:", context.modules.packageManager);
231
console.log("Layout version:", context.modules.layoutVersion);
232
console.log("Store directory:", context.modules.storeDir);
233
console.log("Virtual store directory:", context.modules.virtualStoreDir);
234
console.log("Node linker:", context.modules.nodeLinker);
235
console.log("Pruned at:", context.modules.prunedAt);
236
}
237
```