0
# Dependency Tree Navigation
1
2
The Node class represents packages in the dependency tree, providing methods for navigation, querying, and tree manipulation. Each node corresponds to a package folder and maintains relationships with parent, children, and dependency edges.
3
4
## Capabilities
5
6
### Constructor
7
8
Creates a new Node instance representing a package in the tree.
9
10
```javascript { .api }
11
/**
12
* Create a new Node instance
13
* @param options - Node configuration options
14
*/
15
constructor(options?: NodeOptions): Node;
16
17
interface NodeOptions {
18
/** Absolute path to package */
19
path?: string;
20
/** Parent node in tree */
21
parent?: Node;
22
/** Package name */
23
name?: string;
24
/** Root node reference */
25
root?: Node;
26
/** Real filesystem path */
27
realpath?: string;
28
/** Child node configurations */
29
children?: object;
30
/** Is development dependency */
31
dev?: boolean;
32
/** Is optional dependency */
33
optional?: boolean;
34
/** Is peer dependency */
35
peer?: boolean;
36
/** Is extraneous package */
37
extraneous?: boolean;
38
/** Is global package */
39
global?: boolean;
40
/** Error object if parsing failed */
41
error?: Error;
42
}
43
```
44
45
### Identity and Location Properties
46
47
Core properties that identify and locate the node in the filesystem and tree.
48
49
```javascript { .api }
50
interface NodeIdentity {
51
/** Package name */
52
name: string;
53
/** Package name from package.json */
54
packageName: string;
55
/** Package version */
56
version: string;
57
/** Filesystem path */
58
path: string;
59
/** Real filesystem path */
60
realpath: string;
61
/** Relative location from root */
62
location: string;
63
/** Unique package identifier */
64
pkgid: string;
65
}
66
```
67
68
### Tree Structure Properties
69
70
Properties defining the node's position and relationships in the tree hierarchy.
71
72
```javascript { .api }
73
interface NodeTreeStructure {
74
/** Parent node */
75
parent: Node | null;
76
/** Root node of tree */
77
root: Node;
78
/** Child nodes by name */
79
children: Map<string, Node>;
80
/** Filesystem children */
81
fsChildren: Set<Node>;
82
/** Top-level ancestor */
83
top: Node;
84
/** Is root node */
85
isRoot: boolean;
86
/** Is top-level dependency */
87
isTop: boolean;
88
/** Depth in tree */
89
depth: number;
90
}
91
```
92
93
**Usage Example:**
94
95
```javascript
96
// Navigate tree structure
97
console.log(`Node: ${node.name}@${node.version}`);
98
console.log(`Parent: ${node.parent?.name || 'none'}`);
99
console.log(`Children: ${Array.from(node.children.keys()).join(', ')}`);
100
console.log(`Depth: ${node.depth}`);
101
```
102
103
### Package Information Properties
104
105
Properties containing package metadata and content information.
106
107
```javascript { .api }
108
interface NodePackageInfo {
109
/** Contents of package.json */
110
package: object;
111
/** Resolved URL or path */
112
resolved: string;
113
/** Package integrity hash */
114
integrity: string;
115
/** Parsing errors */
116
errors: Error[];
117
}
118
```
119
120
### Dependency Information Properties
121
122
Properties describing the node's dependency relationships and flags.
123
124
```javascript { .api }
125
interface NodeDependencyInfo {
126
/** Outgoing dependency edges */
127
edgesOut: Map<string, Edge>;
128
/** Incoming dependency edges */
129
edgesIn: Set<Edge>;
130
/** Is development dependency */
131
dev: boolean;
132
/** Is optional dependency */
133
optional: boolean;
134
/** Is dev-optional dependency */
135
devOptional: boolean;
136
/** Is peer dependency */
137
peer: boolean;
138
/** Is extraneous */
139
extraneous: boolean;
140
/** Is bundled dependency */
141
bundled: boolean;
142
}
143
```
144
145
**Usage Example:**
146
147
```javascript
148
// Check dependency flags
149
if (node.dev) {
150
console.log('This is a development dependency');
151
}
152
153
if (node.optional) {
154
console.log('This is an optional dependency');
155
}
156
157
// Examine dependencies
158
for (const [name, edge] of node.edgesOut) {
159
console.log(`Depends on: ${name}@${edge.spec}`);
160
}
161
```
162
163
### Dependency Resolution
164
165
Resolves dependencies using Node.js module resolution algorithm.
166
167
```javascript { .api }
168
/**
169
* Resolve a dependency by name using Node.js resolution algorithm
170
* @param name - Dependency name to resolve
171
* @returns Resolved node or undefined if not found
172
*/
173
resolve(name: string): Node | undefined;
174
```
175
176
**Usage Example:**
177
178
```javascript
179
// Resolve a dependency
180
const expressNode = node.resolve('express');
181
if (expressNode) {
182
console.log(`Express resolved to: ${expressNode.path}`);
183
} else {
184
console.log('Express not found in resolution path');
185
}
186
```
187
188
### Tree Navigation
189
190
Methods for navigating the tree structure and examining relationships.
191
192
```javascript { .api }
193
/**
194
* Generator yielding all ancestors up to root
195
* @returns Generator of ancestor nodes
196
*/
197
ancestry(): Generator<Node>;
198
199
/**
200
* Check if this node is a descendant of another node
201
* @param node - Potential ancestor node
202
* @returns True if this is a descendant of the given node
203
*/
204
isDescendantOf(node: Node): boolean;
205
206
/**
207
* Check if node is located within a node_modules directory
208
* @returns True if in node_modules
209
*/
210
inNodeModules(): boolean;
211
```
212
213
**Usage Examples:**
214
215
```javascript
216
// Walk up ancestry
217
for (const ancestor of node.ancestry()) {
218
console.log(`Ancestor: ${ancestor.name}`);
219
}
220
221
// Check relationships
222
if (childNode.isDescendantOf(rootNode)) {
223
console.log('Child is descendant of root');
224
}
225
226
// Check location
227
if (node.inNodeModules()) {
228
console.log('Node is in node_modules');
229
}
230
```
231
232
### Node Comparison and Validation
233
234
Methods for comparing nodes and validating dependency satisfaction.
235
236
```javascript { .api }
237
/**
238
* Check if this node matches another node (same package and version)
239
* @param node - Node to compare against
240
* @returns True if nodes match
241
*/
242
matches(node: Node): boolean;
243
244
/**
245
* Check if this node satisfies a dependency request
246
* @param requested - Edge representing the dependency request
247
* @returns True if this node satisfies the request
248
*/
249
satisfies(requested: Edge): boolean;
250
251
/**
252
* Check if this node can replace another node
253
* @param node - Node to potentially replace
254
* @param ignorePeers - Ignore peer dependency conflicts
255
* @returns True if replacement is valid
256
*/
257
canReplace(node: Node, ignorePeers?: boolean): boolean;
258
259
/**
260
* Check if this node can be replaced by another node
261
* @param node - Node that would replace this one
262
* @param ignorePeers - Ignore peer dependency conflicts
263
* @returns True if replacement is valid
264
*/
265
canReplaceWith(node: Node, ignorePeers?: boolean): boolean;
266
267
/**
268
* Check if this node can be deduplicated
269
* @param preferDedupe - Prefer deduplication over newer versions
270
* @returns True if node can be deduplicated
271
*/
272
canDedupe(preferDedupe?: boolean): boolean;
273
```
274
275
**Usage Examples:**
276
277
```javascript
278
// Compare nodes
279
if (nodeA.matches(nodeB)) {
280
console.log('Nodes are identical');
281
}
282
283
// Check satisfaction
284
if (node.satisfies(edge)) {
285
console.log(`${node.name} satisfies ${edge.name}@${edge.spec}`);
286
}
287
288
// Check replacement possibility
289
if (newNode.canReplace(oldNode)) {
290
console.log('New node can replace old node');
291
}
292
```
293
294
### Tree Manipulation
295
296
Methods for modifying the tree structure by moving and replacing nodes.
297
298
```javascript { .api }
299
/**
300
* Replace this node with another node in the tree
301
* @param node - Node to replace this one with
302
*/
303
replace(node: Node): void;
304
305
/**
306
* Replace another node with this node
307
* @param node - Node to be replaced
308
*/
309
replaceWith(node: Node): void;
310
311
/**
312
* Get the bundling parent for this node
313
* @param path - Path for bundling resolution
314
* @returns Bundling parent node
315
*/
316
getBundler(path?: string[]): Node | null;
317
```
318
319
**Usage Example:**
320
321
```javascript
322
// Replace a node in the tree
323
if (newVersion.canReplace(oldVersion)) {
324
oldVersion.replace(newVersion);
325
console.log('Node replaced successfully');
326
}
327
```
328
329
### Query and Selection
330
331
CSS-like selector queries for finding nodes in the tree.
332
333
```javascript { .api }
334
/**
335
* Find nodes matching CSS-like selector
336
* @param query - CSS-like selector string
337
* @param opts - Query options
338
* @returns Array of matching nodes
339
*/
340
querySelectorAll(query: string, opts?: QueryOptions): Node[];
341
342
interface QueryOptions {
343
/** Return all matches vs first match */
344
all?: boolean;
345
}
346
```
347
348
**Usage Examples:**
349
350
```javascript
351
// Find all dev dependencies
352
const devDeps = tree.querySelectorAll('[dev]');
353
354
// Find nodes by name
355
const expressNodes = tree.querySelectorAll('[name="express"]');
356
357
// Find nodes with specific attributes
358
const optionalNodes = tree.querySelectorAll('[optional]');
359
```
360
361
### Information and Debugging
362
363
Methods for getting detailed information about the node and its presence in the tree.
364
365
```javascript { .api }
366
/**
367
* Explain why this node is present in the tree
368
* @param edge - Specific edge to explain
369
* @param seen - Array of already seen nodes (for cycle detection)
370
* @returns Explanation object
371
*/
372
explain(edge?: Edge | null, seen?: Node[]): any;
373
374
/**
375
* Convert node to JSON representation
376
* @returns JSON representation of the node
377
*/
378
toJSON(): object;
379
380
/**
381
* Validate root overrides configuration
382
* @throws Error if overrides are invalid
383
*/
384
assertRootOverrides(): void;
385
```
386
387
**Usage Example:**
388
389
```javascript
390
// Get explanation for why node exists
391
const explanation = node.explain();
392
console.log('Node explanation:', explanation);
393
394
// Convert to JSON for inspection
395
const nodeData = node.toJSON();
396
console.log('Node data:', JSON.stringify(nodeData, null, 2));
397
```
398
399
### Link Information Properties
400
401
Properties specific to identifying and working with symbolic links.
402
403
```javascript { .api }
404
interface NodeLinkInfo {
405
/** Is symbolic link (false for regular Node) */
406
isLink: boolean;
407
/** Link target (self for Node, target for Link) */
408
target: Node;
409
/** Incoming links */
410
linksIn: Set<Link>;
411
}
412
```
413
414
**Usage Example:**
415
416
```javascript
417
// Check if node is a link
418
if (node.isLink) {
419
console.log(`Link target: ${node.target.path}`);
420
} else {
421
console.log('Regular package node');
422
}
423
424
// Check for incoming links
425
if (node.linksIn.size > 0) {
426
console.log(`Node has ${node.linksIn.size} incoming links`);
427
}
428
```