UNPKG

5.88 kBMarkdownView Raw
1![Snyk logo](https://snyk.io/style/asset/logo/snyk-print.svg)
2
3***
4
5[![Known Vulnerabilities](https://snyk.io/test/npm/@snyk/dep-graph/badge.svg)](https://snyk.io/test/npm/@snyk/dep-graph)
6
7Snyk helps you find, fix and monitor for known vulnerabilities in your dependencies, both on an ad hoc basis and as part of your CI (Build) system.
8
9# Snyk dep-graph
10
11This library provides a time and space efficient representation of a resolved package dependency graph, which can be used to construct, query and de/serialize dep-graphs.
12
13## The Graph
14
15A directed graph, where a node represents a package instance and an edge from node `foo` to node `bar` means `bar` is a dependency of `foo`.
16
17A package (`name@version`) can have several different nodes (i.e. instances) in the graph. This flexibility is useful for some ecosystems, for example:
18
19* in `npm` due to conflict-resolutions by duplication. e.g. try to `npm i tap@5.7` and then run `npm ls` and look for `strip-ansi@3.0.1`. You'll see that in some instances it depends on `ansi-regex@2.0.0` while in others on `ansi-regex@2.1.1`.
20* in `maven` due to "exclusion" rules. A dependency `foo` can be declared in the `pom.xml` such that some of it's sub-dependencies are excluded via the `<exclusions>` tag. If the same dependency is required elsewhere without (or with different) exclusions then `foo` can appear in the tree with different sub-trees.
21
22This can also be used to break cycles in the graph, e.g.:
23
24instead of:
25```
26A -> B -> C -> A
27```
28can have:
29```
30A -> B -> C -> A'
31```
32
33## API Reference
34
35### `DepGraph`
36
37#### Interface
38
39A dep-graph instance can be queried using the following interface:
40
41```typescript
42export interface DepGraph {
43 readonly pkgManager: {
44 name: string;
45 version?: string;
46 repositories?: Array<{
47 alias: string;
48 }>;
49 };
50 readonly rootPkg: {
51 name: string;
52 version?: string;
53 purl?: string;
54 };
55 // all unique packages in the graph (including root package)
56 getPkgs(): Array<{
57 name: string;
58 version?: string;
59 purl?: string;
60 }>;
61 // all unique packages in the graph, except the root package
62 getDepPkgs(): Array<{
63 name: string;
64 version?: string;
65 purl?: string;
66 }>;
67 pkgPathsToRoot(pkg: Pkg): Array<Array<{
68 name: string;
69 version?: string;
70 purl?: string;
71 }>>;
72 directDepsLeadingTo(pkg: Pkg): Array<{
73 name: string;
74 version?: string;
75 purl?: string;
76 }>;
77 countPathsToRoot(pkg: Pkg): number;
78 toJSON(): DepGraphData;
79 equals(other: DepGraph, options?: { compareRoot?: boolean }): boolean;
80}
81```
82
83### `DepGraphData`
84
85A dep-graph can be serialised into the following format:
86
87```typescript
88export interface DepGraphData {
89 schemaVersion: string;
90 pkgManager: {
91 name: string;
92 version?: string;
93 repositories?: Array<{
94 alias: string;
95 }>;
96 };
97 pkgs: Array<{
98 id: string;
99 info: {
100 name: string;
101 version?: string;
102 purl?: string;
103 };
104 }>;
105 graph: {
106 rootNodeId: string;
107 nodes: Array<{
108 nodeId: string;
109 pkgId: string;
110 info?: {
111 versionProvenance?: {
112 type: string;
113 location: string;
114 property?: {
115 name: string;
116 };
117 },
118 labels?: {
119 [key: string]: string | undefined;
120 };
121 };
122 deps: Array<{
123 nodeId: string;
124 }>;
125 }>;
126 };
127}
128```
129
130### `createFromJSON`
131
132`DepGraphData` can be used to construct a `DepGraph` instance using `createFromJSON`
133
134### `DepGraphBuilder`
135`DepGraphBuilder` is used to create new `DepGraph` instances by adding packages and their connections.
136
137```typescript
138 /**
139 * Instantiates build for given package manager
140 *
141 * @param pkgManager - package manager for which dependcy graph is created
142 * @param rootPkg - root package information
143 *
144 */
145 public constructor(pkgManager: types.PkgManager, rootPkg?: types.PkgInfo)
146
147 /**
148 * Adds node to the graph. Every node represents logical instance of the package in the dependency graph.
149 *
150 * @param pkgInfo - name and version of the package
151 * @param nodeId - identifier for node in the graph, e.g. `package@version`.
152 * Must uniquely identify this "instance" of the package in the graph,
153 * so may need to be more than `package@version` for many ecosystems.
154 * If in doubt - ask a contributor!
155 * @param nodeInfo - additional node info, e.g. for version provenance
156 *
157 */
158 public addPkgNode(pkgInfo: types.PkgInfo, nodeId: string, nodeInfo?: types.NodeInfo)
159
160 /**
161 * Makes a connection between parent and its dependency.
162 *
163 * @param parentNodeId - id of the parent node
164 * @param depNodeId - id of the dependency node
165 *
166 */
167 public connectDep(parentNodeId: string, depNodeId: string)
168
169 /**
170 * Creates an instance of DepGraph
171 *
172 * @return DepGraph instance built from provided packages and their connections
173 *
174 */
175 public build(): types.DepGraph
176
177```
178### The `legacy` module
179
180A `DepTree` is a legacy structure used by the Snyk CLI to represent dependency trees. Conversion functions in the `legacy` module ease the gradual migration of code that relies on the legacy format.
181
182#### Legacy `DepTree`
183
184A `DepTree` is a recursive structure that is quite similar to the output of `npm list --json`, and (omitting some details) looks like:
185
186```typescript
187interface DepTree {
188 name: string;
189 version: string;
190 dependencies?: {
191 [depName: string]: DepTree
192 };
193}
194```
195
196The `legacy` conversion functions aim to maintain extra data that might be attached to the dep-tree and is dependant upon in code that wasn't yet updated to use solely dep-graphs:
197* `targetOS` which exists on tree roots for Docker scans
198* `versionProvenance` which might exist on the nodes of maven trees, storing information about the source manifest that caused the specfic version to be resolved