TypeScript library that analyzes pnpm lockfiles to classify dependencies into different types (development-only, production-only, or both)
npx @tessl/cli install tessl/npm-pnpm--lockfile-detect-dep-types@1001.0.00
# @pnpm/lockfile.detect-dep-types
1
2
A TypeScript library that analyzes pnpm lockfiles to classify dependencies into different types: development-only, production-only, or both development and production dependencies. This utility is specifically designed for pnpm's lockfile format and is used internally by pnpm tooling to optimize dependency installation and bundling processes.
3
4
## Package Information
5
6
- **Package Name**: @pnpm/lockfile.detect-dep-types
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `pnpm add @pnpm/lockfile.detect-dep-types`
10
11
## Core Imports
12
13
```typescript
14
import { detectDepTypes, DepType, type DepTypes } from "@pnpm/lockfile.detect-dep-types";
15
```
16
17
CommonJS:
18
19
```javascript
20
const { detectDepTypes, DepType } = require("@pnpm/lockfile.detect-dep-types");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import { detectDepTypes, DepType, type DepTypes } from "@pnpm/lockfile.detect-dep-types";
27
import { type LockfileObject } from "@pnpm/lockfile.types";
28
29
// Analyze a pnpm lockfile to classify dependencies
30
const lockfile: LockfileObject = {
31
lockfileVersion: "9.0",
32
importers: {
33
".": {
34
specifiers: {
35
"lodash": "^4.17.21",
36
"typescript": "^5.0.0"
37
},
38
dependencies: {
39
"lodash": "4.17.21"
40
},
41
devDependencies: {
42
"typescript": "5.0.2"
43
}
44
}
45
},
46
packages: {
47
"lodash@4.17.21": {
48
resolution: { integrity: "sha512-..." }
49
},
50
"typescript@5.0.2": {
51
resolution: { integrity: "sha512-..." }
52
}
53
}
54
};
55
56
// Detect dependency types
57
const depTypes: DepTypes = detectDepTypes(lockfile);
58
59
// Check individual dependency classifications
60
if (depTypes["lodash@4.17.21"] === DepType.ProdOnly) {
61
console.log("lodash is production-only");
62
}
63
64
if (depTypes["typescript@5.0.2"] === DepType.DevOnly) {
65
console.log("typescript is development-only");
66
}
67
```
68
69
## Capabilities
70
71
### Dependency Type Detection
72
73
Analyzes pnpm lockfiles to classify each dependency as development-only, production-only, or used in both environments.
74
75
```typescript { .api }
76
function detectDepTypes(lockfile: LockfileObject): DepTypes;
77
```
78
79
**Parameters:**
80
- `lockfile`: LockfileObject - The pnpm lockfile data structure to analyze
81
82
**Returns:**
83
- `DepTypes` - A record mapping dependency paths to their classifications
84
85
**Usage Example:**
86
87
```typescript
88
import { detectDepTypes } from "@pnpm/lockfile.detect-dep-types";
89
90
const depTypes = detectDepTypes(lockfile);
91
// Returns object like: { "package@1.0.0": DepType.ProdOnly, "devtool@2.0.0": DepType.DevOnly }
92
```
93
94
### Dependency Type Classification
95
96
Enumeration defining the three possible dependency classifications.
97
98
```typescript { .api }
99
enum DepType {
100
DevOnly,
101
DevAndProd,
102
ProdOnly
103
}
104
```
105
106
**Values:**
107
- `DepType.DevOnly` - Dependencies only used in development environments
108
- `DepType.DevAndProd` - Dependencies used in both development and production environments
109
- `DepType.ProdOnly` - Dependencies only used in production environments
110
111
**Usage Example:**
112
113
```typescript
114
import { DepType } from "@pnpm/lockfile.detect-dep-types";
115
116
// Check if a dependency is production-only
117
if (depTypes["some-package@1.0.0"] === DepType.ProdOnly) {
118
console.log("This package is needed in production");
119
}
120
```
121
122
## Types
123
124
```typescript { .api }
125
/**
126
* Record mapping dependency paths to their type classifications
127
*/
128
type DepTypes = Record<string, DepType>;
129
130
/**
131
* Dependency path string (from @pnpm/types)
132
*/
133
type DepPath = string & { __brand: 'DepPath' };
134
135
/**
136
* Pnpm lockfile object structure (from @pnpm/lockfile.types)
137
*/
138
interface LockfileObject {
139
lockfileVersion: string;
140
importers: Record<string, ProjectSnapshot>;
141
packages?: PackageSnapshots;
142
// ... other lockfile properties
143
}
144
145
/**
146
* Project snapshot containing dependency information
147
*/
148
interface ProjectSnapshot {
149
specifiers: ResolvedDependencies;
150
dependencies?: ResolvedDependencies;
151
optionalDependencies?: ResolvedDependencies;
152
devDependencies?: ResolvedDependencies;
153
}
154
155
/**
156
* Resolved dependency mappings
157
*/
158
type ResolvedDependencies = Record<string, string>;
159
160
/**
161
* Collection of package snapshots
162
*/
163
interface PackageSnapshots {
164
[packagePath: string]: PackageSnapshot;
165
}
166
167
/**
168
* Individual package snapshot with metadata
169
*/
170
interface PackageSnapshot {
171
resolution: LockfileResolution;
172
dependencies?: ResolvedDependencies;
173
optionalDependencies?: ResolvedDependencies;
174
// ... other package properties
175
}
176
```
177
178
## Implementation Details
179
180
The library uses a graph traversal algorithm to analyze dependency relationships:
181
182
1. **Extraction**: Separates dependencies from lockfile importers into categories (dev, optional, production)
183
2. **Graph Walking**: Recursively traverses dependency graphs using depth-first search
184
3. **Classification**: Assigns types based on how dependencies are referenced across different sections
185
4. **Cycle Handling**: Tracks visited nodes to prevent infinite loops in circular dependencies
186
187
The analysis considers the entire dependency tree, not just direct dependencies, ensuring that transitive dependencies are properly classified based on how they're ultimately used in the project.