0
# Dependency Relationships
1
2
The Edge class represents dependency relationships between packages in the tree. Edges automatically update to point to the appropriate target when the tree structure changes, providing validation and error reporting for dependency resolution.
3
4
## Capabilities
5
6
### Constructor
7
8
Creates a new Edge representing a dependency relationship.
9
10
```javascript { .api }
11
/**
12
* Create a new dependency edge
13
* @param options - Edge configuration options
14
*/
15
constructor(options: EdgeOptions): Edge;
16
17
interface EdgeOptions {
18
/** Edge type */
19
type: 'prod' | 'dev' | 'optional' | 'peer' | 'peerOptional' | 'workspace';
20
/** Dependency name */
21
name: string;
22
/** Version specifier */
23
spec: string;
24
/** Source node that has the dependency */
25
from: Node;
26
/** Accept range (optional) */
27
accept?: string;
28
/** Override configuration (optional) */
29
overrides?: object;
30
}
31
```
32
33
**Usage Example:**
34
35
```javascript
36
const { Edge } = require('@npmcli/arborist');
37
38
// Create a production dependency edge
39
const edge = new Edge({
40
type: 'prod',
41
name: 'express',
42
spec: '^4.18.0',
43
from: rootNode
44
});
45
```
46
47
### Static Properties
48
49
Static properties available on the Edge class.
50
51
```javascript { .api }
52
interface EdgeStatics {
53
/** Array of valid edge types */
54
static types: ['prod', 'dev', 'optional', 'peer', 'peerOptional', 'workspace'];
55
/** Array of possible error types */
56
static errors: ['DETACHED', 'MISSING', 'PEER LOCAL', 'INVALID'];
57
}
58
```
59
60
### Basic Information Properties
61
62
Core properties that identify and describe the dependency relationship.
63
64
```javascript { .api }
65
interface EdgeBasicInfo {
66
/** Dependency name */
67
name: string;
68
/** Edge type */
69
type: 'prod' | 'dev' | 'optional' | 'peer' | 'peerOptional' | 'workspace';
70
/** Version specifier (may be overridden) */
71
spec: string;
72
/** Original version specifier */
73
rawSpec: string;
74
/** Accept range */
75
accept: string;
76
/** Source node that has the dependency */
77
from: Node;
78
/** Target node that satisfies the dependency */
79
to: Node | null;
80
}
81
```
82
83
**Usage Example:**
84
85
```javascript
86
// Examine edge properties
87
console.log(`Dependency: ${edge.name}@${edge.spec}`);
88
console.log(`Type: ${edge.type}`);
89
console.log(`From: ${edge.from.name}`);
90
console.log(`To: ${edge.to?.name || 'unresolved'}`);
91
```
92
93
### Type Flag Properties
94
95
Boolean properties indicating the specific type of dependency.
96
97
```javascript { .api }
98
interface EdgeTypeFlags {
99
/** Is production dependency */
100
prod: boolean;
101
/** Is development dependency */
102
dev: boolean;
103
/** Is optional dependency */
104
optional: boolean;
105
/** Is peer dependency */
106
peer: boolean;
107
/** Is workspace dependency */
108
workspace: boolean;
109
/** Is bundled dependency */
110
bundled: boolean;
111
}
112
```
113
114
**Usage Example:**
115
116
```javascript
117
// Check dependency type
118
if (edge.prod) {
119
console.log('Production dependency');
120
} else if (edge.dev) {
121
console.log('Development dependency');
122
} else if (edge.optional) {
123
console.log('Optional dependency');
124
} else if (edge.peer) {
125
console.log('Peer dependency');
126
}
127
```
128
129
### Validation Properties
130
131
Properties indicating the validation state and any errors with the dependency.
132
133
```javascript { .api }
134
interface EdgeValidation {
135
/** Is edge valid (target satisfies spec) */
136
valid: boolean;
137
/** Error type if invalid, null if valid */
138
error: string | null;
139
/** Target is missing */
140
missing: boolean;
141
/** Target doesn't satisfy spec */
142
invalid: boolean;
143
/** Peer dependency found locally (invalid) */
144
peerLocal: boolean;
145
/** Has peer dependency conflicts */
146
peerConflicted: boolean;
147
}
148
```
149
150
**Usage Examples:**
151
152
```javascript
153
// Check validation status
154
if (edge.valid) {
155
console.log('Dependency is satisfied');
156
} else {
157
console.log(`Dependency error: ${edge.error}`);
158
159
if (edge.missing) {
160
console.log('Target package is missing');
161
} else if (edge.invalid) {
162
console.log('Target package version does not satisfy spec');
163
} else if (edge.peerLocal) {
164
console.log('Peer dependency found in local node_modules (invalid)');
165
}
166
}
167
168
// Handle different error types
169
switch (edge.error) {
170
case 'MISSING':
171
console.log('Package needs to be installed');
172
break;
173
case 'INVALID':
174
console.log('Package version is incompatible');
175
break;
176
case 'PEER LOCAL':
177
console.log('Peer dependency incorrectly installed locally');
178
break;
179
case 'DETACHED':
180
console.log('Edge has been detached from tree');
181
break;
182
}
183
```
184
185
### Override Configuration
186
187
Properties related to dependency overrides and resolution modifications.
188
189
```javascript { .api }
190
interface EdgeOverrides {
191
/** Override configuration */
192
overrides: object | null;
193
}
194
```
195
196
### Satisfaction Testing
197
198
Methods for testing whether a node satisfies this dependency edge.
199
200
```javascript { .api }
201
/**
202
* Test if a node satisfies this dependency edge
203
* @param node - Node to test for satisfaction
204
* @returns True if the node satisfies this edge
205
*/
206
satisfiedBy(node: Node): boolean;
207
```
208
209
**Usage Example:**
210
211
```javascript
212
// Test if a node satisfies the dependency
213
const candidateNode = tree.resolve(edge.name);
214
215
if (candidateNode && edge.satisfiedBy(candidateNode)) {
216
console.log(`${candidateNode.name}@${candidateNode.version} satisfies ${edge.spec}`);
217
} else {
218
console.log('Candidate node does not satisfy dependency');
219
}
220
```
221
222
### Edge Management
223
224
Methods for managing edge state and resolution.
225
226
```javascript { .api }
227
/**
228
* Reload edge resolution, optionally forcing a hard reload
229
* @param hard - Force complete re-resolution
230
*/
231
reload(hard?: boolean): void;
232
233
/**
234
* Detach edge from the tree (marks as DETACHED)
235
*/
236
detach(): void;
237
```
238
239
**Usage Examples:**
240
241
```javascript
242
// Reload edge resolution after tree changes
243
edge.reload();
244
245
// Force complete re-resolution
246
edge.reload(true);
247
248
// Detach edge when removing dependency
249
edge.detach();
250
```
251
252
### Information and Debugging
253
254
Methods for getting detailed information about the edge and its resolution.
255
256
```javascript { .api }
257
/**
258
* Explain the edge relationship and resolution
259
* @param seen - Array of already seen edges (for cycle detection)
260
* @returns Explanation object
261
*/
262
explain(seen?: Edge[]): any;
263
264
/**
265
* Convert edge to JSON representation
266
* @returns JSON representation of the edge
267
*/
268
toJSON(): object;
269
```
270
271
**Usage Example:**
272
273
```javascript
274
// Get detailed explanation of edge
275
const explanation = edge.explain();
276
console.log('Edge explanation:', explanation);
277
278
// Convert to JSON for inspection
279
const edgeData = edge.toJSON();
280
console.log('Edge data:', JSON.stringify(edgeData, null, 2));
281
```
282
283
## Edge Types
284
285
### Production Dependencies (`prod`)
286
287
Regular runtime dependencies required for the package to function.
288
289
```javascript
290
const prodEdge = new Edge({
291
type: 'prod',
292
name: 'express',
293
spec: '^4.18.0',
294
from: rootNode
295
});
296
```
297
298
### Development Dependencies (`dev`)
299
300
Dependencies only needed during development, testing, or building.
301
302
```javascript
303
const devEdge = new Edge({
304
type: 'dev',
305
name: 'jest',
306
spec: '^29.0.0',
307
from: rootNode
308
});
309
```
310
311
### Optional Dependencies (`optional`)
312
313
Dependencies that are optional and won't cause installation to fail if unavailable.
314
315
```javascript
316
const optionalEdge = new Edge({
317
type: 'optional',
318
name: 'fsevents',
319
spec: '^2.3.0',
320
from: rootNode
321
});
322
```
323
324
### Peer Dependencies (`peer`)
325
326
Dependencies that should be provided by the consuming application.
327
328
```javascript
329
const peerEdge = new Edge({
330
type: 'peer',
331
name: 'react',
332
spec: '>=16.8.0',
333
from: componentNode
334
});
335
```
336
337
### Optional Peer Dependencies (`peerOptional`)
338
339
Peer dependencies that are optional and won't cause warnings if missing.
340
341
```javascript
342
const peerOptionalEdge = new Edge({
343
type: 'peerOptional',
344
name: 'typescript',
345
spec: '>=4.0.0',
346
from: libNode
347
});
348
```
349
350
### Workspace Dependencies (`workspace`)
351
352
Dependencies between packages in a monorepo workspace.
353
354
```javascript
355
const workspaceEdge = new Edge({
356
type: 'workspace',
357
name: 'shared-utils',
358
spec: '*',
359
from: appNode
360
});
361
```
362
363
## Error Types
364
365
### MISSING
366
367
The dependency target cannot be found in the tree.
368
369
```javascript
370
if (edge.error === 'MISSING') {
371
console.log(`${edge.name} needs to be installed`);
372
}
373
```
374
375
### INVALID
376
377
The dependency target exists but doesn't satisfy the version specification.
378
379
```javascript
380
if (edge.error === 'INVALID') {
381
console.log(`${edge.name}@${edge.to.version} doesn't satisfy ${edge.spec}`);
382
}
383
```
384
385
### PEER LOCAL
386
387
A peer dependency was found in the local node_modules, which violates the peer contract.
388
389
```javascript
390
if (edge.error === 'PEER LOCAL') {
391
console.log(`Peer dependency ${edge.name} should not be installed locally`);
392
}
393
```
394
395
### DETACHED
396
397
The edge has been detached from its source node, typically during tree modifications.
398
399
```javascript
400
if (edge.error === 'DETACHED') {
401
console.log(`Edge ${edge.name} has been detached from tree`);
402
}
403
```