snyk-nodejs-lockfile-parser 1.30.0 → 1.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/parsers/index.d.ts +2 -2
- package/dist/parsers/lock-parser-base.d.ts +35 -0
- package/dist/parsers/lock-parser-base.js +292 -0
- package/dist/parsers/lock-parser-base.js.map +1 -0
- package/dist/parsers/package-lock-parser.d.ts +6 -12
- package/dist/parsers/package-lock-parser.js +12 -280
- package/dist/parsers/package-lock-parser.js.map +1 -1
- package/dist/parsers/{yarn-lock-parse-base.d.ts → yarn-lock-parser.d.ts} +12 -14
- package/dist/parsers/yarn-lock-parser.js +54 -0
- package/dist/parsers/yarn-lock-parser.js.map +1 -0
- package/package.json +4 -4
- package/dist/parsers/yarn-lock-parse-base.js +0 -114
- package/dist/parsers/yarn-lock-parse-base.js.map +0 -1
- package/dist/parsers/yarn-lock-parse.d.ts +0 -8
- package/dist/parsers/yarn-lock-parse.js +0 -24
- package/dist/parsers/yarn-lock-parse.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.Scope = parsers_1.Scope;
|
|
|
7
7
|
exports.LockfileType = parsers_1.LockfileType;
|
|
8
8
|
exports.getYarnWorkspaces = parsers_1.getYarnWorkspaces;
|
|
9
9
|
const package_lock_parser_1 = require("./parsers/package-lock-parser");
|
|
10
|
-
const
|
|
10
|
+
const yarn_lock_parser_1 = require("./parsers/yarn-lock-parser");
|
|
11
11
|
// import { Yarn2LockParser } from './parsers/yarn2-lock-parse';
|
|
12
12
|
// import getRuntimeVersion from './get-node-runtime-version';
|
|
13
13
|
const errors_1 = require("./errors");
|
|
@@ -27,7 +27,7 @@ async function buildDepTree(manifestFileContents, lockFileContents, includeDev =
|
|
|
27
27
|
lockfileParser = new package_lock_parser_1.PackageLockParser();
|
|
28
28
|
break;
|
|
29
29
|
case parsers_1.LockfileType.yarn:
|
|
30
|
-
lockfileParser = new
|
|
30
|
+
lockfileParser = new yarn_lock_parser_1.YarnLockParser();
|
|
31
31
|
break;
|
|
32
32
|
case parsers_1.LockfileType.yarn2:
|
|
33
33
|
throw new errors_1.UnsupportedError('Yarn2 support has been temporarily removed to support Node.js versions 8.x.x');
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":";;AAAA,yBAAyB;AACzB,6BAA6B;AAC7B,uCASmB;AAkBjB,gBAtBA,eAAK,CAsBA;AACL,uBArBA,sBAAY,CAqBA;AAHZ,4BAjBA,2BAAiB,CAiBA;AAfnB,uEAAkE;AAClE
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"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"}
|
package/dist/parsers/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PackageLock } from './package-lock-parser';
|
|
2
|
-
import { YarnLock } from './yarn-lock-
|
|
2
|
+
import { YarnLock } from './yarn-lock-parser';
|
|
3
3
|
export interface Dep {
|
|
4
4
|
name: string;
|
|
5
5
|
version: string;
|
|
@@ -43,7 +43,7 @@ export interface PkgTree extends DepTreeDep {
|
|
|
43
43
|
[depName: string]: DepTreeDep;
|
|
44
44
|
};
|
|
45
45
|
meta?: {
|
|
46
|
-
nodeVersion
|
|
46
|
+
nodeVersion?: string;
|
|
47
47
|
packageManagerVersion?: string;
|
|
48
48
|
};
|
|
49
49
|
hasDevDependencies?: boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Dep, DepTreeDep, Lockfile, LockfileParser, LockfileType, ManifestFile, PkgTree } from './';
|
|
2
|
+
export interface PackageLockDeps {
|
|
3
|
+
[depName: string]: PackageLockDep;
|
|
4
|
+
}
|
|
5
|
+
export interface PackageLockDep {
|
|
6
|
+
version: string;
|
|
7
|
+
requires?: {
|
|
8
|
+
[depName: string]: string;
|
|
9
|
+
};
|
|
10
|
+
dependencies?: PackageLockDeps;
|
|
11
|
+
dev?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface DepMap {
|
|
14
|
+
[path: string]: DepMapItem;
|
|
15
|
+
}
|
|
16
|
+
export interface DepMapItem extends DepTreeDep {
|
|
17
|
+
requires: string[];
|
|
18
|
+
}
|
|
19
|
+
export declare abstract class LockParserBase implements LockfileParser {
|
|
20
|
+
protected type: LockfileType;
|
|
21
|
+
protected treeSizeLimit: number;
|
|
22
|
+
protected pathDelimiter: string;
|
|
23
|
+
constructor(type: LockfileType, treeSizeLimit: number);
|
|
24
|
+
abstract parseLockFile(lockFileContents: string): Lockfile;
|
|
25
|
+
getDependencyTree(manifestFile: ManifestFile, lockfile: Lockfile, includeDev?: boolean, strict?: boolean): Promise<PkgTree>;
|
|
26
|
+
private setDevDepRec;
|
|
27
|
+
private removeCycle;
|
|
28
|
+
private cloneAcyclicNodeEdges;
|
|
29
|
+
private cloneNodeWithoutEdges;
|
|
30
|
+
private createGraphOfDependencies;
|
|
31
|
+
private findDepsPath;
|
|
32
|
+
private createDepTrees;
|
|
33
|
+
protected getDepMap(lockfile: Lockfile): DepMap;
|
|
34
|
+
protected getDepTreeKey(dep: Dep): string;
|
|
35
|
+
}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const _cloneDeep = require("lodash.clonedeep");
|
|
4
|
+
const _isEmpty = require("lodash.isempty");
|
|
5
|
+
const _set = require("lodash.set");
|
|
6
|
+
const _toPairs = require("lodash.topairs");
|
|
7
|
+
const graphlib = require("@snyk/graphlib");
|
|
8
|
+
const uuid_1 = require("uuid");
|
|
9
|
+
const event_loop_spinner_1 = require("event-loop-spinner");
|
|
10
|
+
const _1 = require("./");
|
|
11
|
+
const errors_1 = require("../errors");
|
|
12
|
+
class LockParserBase {
|
|
13
|
+
constructor(type, treeSizeLimit) {
|
|
14
|
+
this.type = type;
|
|
15
|
+
this.treeSizeLimit = treeSizeLimit;
|
|
16
|
+
this.pathDelimiter = '|';
|
|
17
|
+
}
|
|
18
|
+
async getDependencyTree(manifestFile, lockfile, includeDev = false, strict = true) {
|
|
19
|
+
var _a;
|
|
20
|
+
if (lockfile.type !== this.type) {
|
|
21
|
+
throw new errors_1.InvalidUserInputError('Unsupported lockfile provided. Please ' +
|
|
22
|
+
'provide `package-lock.json`.');
|
|
23
|
+
}
|
|
24
|
+
const yarnLock = lockfile;
|
|
25
|
+
const depTree = {
|
|
26
|
+
dependencies: {},
|
|
27
|
+
hasDevDependencies: !_isEmpty(manifestFile.devDependencies),
|
|
28
|
+
name: manifestFile.name,
|
|
29
|
+
size: 1,
|
|
30
|
+
version: manifestFile.version || '',
|
|
31
|
+
};
|
|
32
|
+
const nodeVersion = (_a = manifestFile === null || manifestFile === void 0 ? void 0 : manifestFile.engines) === null || _a === void 0 ? void 0 : _a.node;
|
|
33
|
+
if (nodeVersion) {
|
|
34
|
+
_set(depTree, 'meta.nodeVersion', nodeVersion);
|
|
35
|
+
}
|
|
36
|
+
// asked to process empty deps
|
|
37
|
+
if (_isEmpty(manifestFile.dependencies) && !includeDev) {
|
|
38
|
+
return depTree;
|
|
39
|
+
}
|
|
40
|
+
// prepare a flat map, where dependency path is a key to dependency object
|
|
41
|
+
// path is an unique identifier for each dependency and corresponds to the
|
|
42
|
+
// relative path on disc
|
|
43
|
+
const depMap = this.getDepMap(yarnLock);
|
|
44
|
+
// all paths are identified, we can create a graph representing what depends on what
|
|
45
|
+
const depGraph = this.createGraphOfDependencies(depMap);
|
|
46
|
+
// topological sort will be applied and it requires acyclic graphs
|
|
47
|
+
let cycleStarts = {};
|
|
48
|
+
if (!graphlib.alg.isAcyclic(depGraph)) {
|
|
49
|
+
const cycles = graphlib.alg.findCycles(depGraph);
|
|
50
|
+
for (const cycle of cycles) {
|
|
51
|
+
// Since one of top level dependencies can be a start of cycle and that node
|
|
52
|
+
// will be duplicated, we need to store a link between original node
|
|
53
|
+
// and the new one in order to identify those duplicated top level dependencies
|
|
54
|
+
cycleStarts = Object.assign(Object.assign({}, cycleStarts), this.removeCycle(cycle, depMap, depGraph));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// transform depMap to a map of PkgTrees
|
|
58
|
+
const { depTrees, depTreesSizes } = await this.createDepTrees(depMap, depGraph);
|
|
59
|
+
// get trees for dependencies from manifest file
|
|
60
|
+
const topLevelDeps = _1.getTopLevelDeps(manifestFile, includeDev);
|
|
61
|
+
// number of dependencies including root one
|
|
62
|
+
let treeSize = 1;
|
|
63
|
+
for (const dep of topLevelDeps) {
|
|
64
|
+
if (treeSize > this.treeSizeLimit) {
|
|
65
|
+
throw new errors_1.TreeSizeLimitError();
|
|
66
|
+
}
|
|
67
|
+
// if any of top level dependencies is a part of cycle
|
|
68
|
+
// it now has a different item in the map
|
|
69
|
+
const key = this.getDepTreeKey(dep);
|
|
70
|
+
const depName = cycleStarts[key] || key;
|
|
71
|
+
if (depTrees[depName]) {
|
|
72
|
+
// if the top level dependency is dev, all children are dev
|
|
73
|
+
depTree.dependencies[dep.name] = dep.dev
|
|
74
|
+
? this.setDevDepRec(_cloneDeep(depTrees[depName]))
|
|
75
|
+
: depTrees[depName];
|
|
76
|
+
treeSize += depTreesSizes[depName];
|
|
77
|
+
if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
|
|
78
|
+
await event_loop_spinner_1.eventLoopSpinner.spin();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (/^file:/.test(dep.version)) {
|
|
82
|
+
depTree.dependencies[dep.name] = _1.createDepTreeDepFromDep(dep);
|
|
83
|
+
treeSize++;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// TODO: also check the package version
|
|
87
|
+
// for a stricter check
|
|
88
|
+
if (strict) {
|
|
89
|
+
throw new errors_1.OutOfSyncError(dep.name, this.type);
|
|
90
|
+
}
|
|
91
|
+
depTree.dependencies[dep.name] = _1.createDepTreeDepFromDep(dep);
|
|
92
|
+
if (!depTree.dependencies[dep.name].labels) {
|
|
93
|
+
depTree.dependencies[dep.name].labels = {};
|
|
94
|
+
}
|
|
95
|
+
depTree.dependencies[dep.name].labels.missingLockFileEntry = 'true';
|
|
96
|
+
treeSize++;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
depTree.size = treeSize;
|
|
100
|
+
return depTree;
|
|
101
|
+
}
|
|
102
|
+
setDevDepRec(pkgTree) {
|
|
103
|
+
for (const [name, subTree] of _toPairs(pkgTree.dependencies)) {
|
|
104
|
+
pkgTree.dependencies[name] = this.setDevDepRec(subTree);
|
|
105
|
+
}
|
|
106
|
+
pkgTree.labels = {
|
|
107
|
+
scope: _1.Scope.dev,
|
|
108
|
+
};
|
|
109
|
+
return pkgTree;
|
|
110
|
+
}
|
|
111
|
+
/* Algorithm for cycle removal:
|
|
112
|
+
For every node in a cycle:
|
|
113
|
+
1. Create a duplicate of entry node (without edges)
|
|
114
|
+
2. For every cyclic dependency of entry node, create a duplicate of
|
|
115
|
+
the dependency and connect it with the duplicated entry node
|
|
116
|
+
3.a If edge goes to already-visited dependency, end of cycle is found;
|
|
117
|
+
update metadata and do not continue traversing
|
|
118
|
+
3.b Follow the edge and repeat the process, storing visited dependency-paths.
|
|
119
|
+
All non-cyclic dependencies of duplicated node need to be updated.
|
|
120
|
+
4. All non-cyclic dependencies or dependants of original node need to be
|
|
121
|
+
updated to be connected with the duplicated one
|
|
122
|
+
|
|
123
|
+
Once completed for all nodes in a cycle, original cyclic nodes can
|
|
124
|
+
be removed.
|
|
125
|
+
*/
|
|
126
|
+
removeCycle(cycle, depMap, depGraph) {
|
|
127
|
+
/* FUNCTION DEFINITION
|
|
128
|
+
To keep an order of algorithm steps readable, function is defined on-the-fly
|
|
129
|
+
Arrow function is used for calling `this` without .bind(this) in the end
|
|
130
|
+
*/
|
|
131
|
+
const acyclicDuplicationRec = (node, traversed, currentCycle, nodeCopy) => {
|
|
132
|
+
// 2. For every cyclic dependency of entry node...
|
|
133
|
+
const edgesToProcess = depGraph.inEdges(node).filter((e) => currentCycle.includes(e.v));
|
|
134
|
+
for (const edge of edgesToProcess) {
|
|
135
|
+
// ... create a duplicate of the dependency...
|
|
136
|
+
const child = edge.v;
|
|
137
|
+
const dependencyCopy = this.cloneNodeWithoutEdges(child, depMap, depGraph);
|
|
138
|
+
// ...and connect it with the duplicated entry node
|
|
139
|
+
depGraph.setEdge(dependencyCopy, nodeCopy);
|
|
140
|
+
// 3.a If edge goes to already-visited dependency, end of cycle is found;
|
|
141
|
+
if (traversed.includes(child)) {
|
|
142
|
+
// update metadata and labels and do not continue traversing
|
|
143
|
+
if (!depMap[dependencyCopy].labels) {
|
|
144
|
+
depMap[dependencyCopy].labels = {};
|
|
145
|
+
}
|
|
146
|
+
depMap[dependencyCopy].labels.pruned = 'cyclic';
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
// 3.b Follow the edge and repeat the process, storing visited dependency-paths
|
|
150
|
+
acyclicDuplicationRec(child, [...traversed, node], currentCycle, dependencyCopy);
|
|
151
|
+
// All non-cyclic dependencies of duplicated node need to be updated.
|
|
152
|
+
this.cloneAcyclicNodeEdges(child, dependencyCopy, cycle, depGraph, {
|
|
153
|
+
inEdges: true,
|
|
154
|
+
outEdges: false,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const cycleStarts = {};
|
|
160
|
+
// For every node in a cycle:
|
|
161
|
+
for (const start of cycle) {
|
|
162
|
+
// 1. Create a uniqe duplicate of entry node (without edges)
|
|
163
|
+
const clonedNode = this.cloneNodeWithoutEdges(start, depMap, depGraph);
|
|
164
|
+
cycleStarts[start] = clonedNode;
|
|
165
|
+
// CALL of previously defined function
|
|
166
|
+
acyclicDuplicationRec(start, [], cycle, clonedNode);
|
|
167
|
+
// 4. All non-cyclic dependencies or dependants of original node need to be
|
|
168
|
+
// updated to be connected with the duplicated one
|
|
169
|
+
this.cloneAcyclicNodeEdges(start, clonedNode, cycle, depGraph, {
|
|
170
|
+
inEdges: true,
|
|
171
|
+
outEdges: true,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// Once completed for all nodes in a cycle, original cyclic nodes can
|
|
175
|
+
// be removed.
|
|
176
|
+
for (const start of cycle) {
|
|
177
|
+
depGraph.removeNode(start);
|
|
178
|
+
}
|
|
179
|
+
return cycleStarts;
|
|
180
|
+
}
|
|
181
|
+
cloneAcyclicNodeEdges(nodeFrom, nodeTo, cycle, depGraph, { inEdges, outEdges }) {
|
|
182
|
+
// node has to have edges
|
|
183
|
+
const edges = depGraph.nodeEdges(nodeFrom);
|
|
184
|
+
if (outEdges) {
|
|
185
|
+
const parentEdges = edges.filter((e) => !cycle.includes(e.w));
|
|
186
|
+
for (const edge of parentEdges) {
|
|
187
|
+
const parent = edge.w;
|
|
188
|
+
depGraph.setEdge(nodeTo, parent);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (inEdges) {
|
|
192
|
+
const childEdges = edges.filter((e) => !cycle.includes(e.v));
|
|
193
|
+
for (const edge of childEdges) {
|
|
194
|
+
const child = edge.v;
|
|
195
|
+
depGraph.setEdge(child, nodeTo);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
cloneNodeWithoutEdges(node, depMap, depGraph) {
|
|
200
|
+
const newNode = node + uuid_1.v4();
|
|
201
|
+
// update depMap with new node
|
|
202
|
+
depMap[newNode] = _cloneDeep(depMap[node]);
|
|
203
|
+
// add new node to the graph
|
|
204
|
+
depGraph.setNode(newNode);
|
|
205
|
+
return newNode;
|
|
206
|
+
}
|
|
207
|
+
createGraphOfDependencies(depMap) {
|
|
208
|
+
const depGraph = new graphlib.Graph();
|
|
209
|
+
for (const depKey of Object.keys(depMap)) {
|
|
210
|
+
depGraph.setNode(depKey);
|
|
211
|
+
}
|
|
212
|
+
for (const [depPath, dep] of Object.entries(depMap)) {
|
|
213
|
+
for (const depName of dep.requires) {
|
|
214
|
+
const subDepPath = this.findDepsPath(depPath, depName, depMap);
|
|
215
|
+
// direction is from the dependency to the package requiring it
|
|
216
|
+
depGraph.setEdge(subDepPath, depPath);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return depGraph;
|
|
220
|
+
}
|
|
221
|
+
// dependency in package-lock.json v1 can be defined either inside `dependencies`
|
|
222
|
+
// of other dependency or anywhere upward towards root
|
|
223
|
+
findDepsPath(startPath, depName, depMap) {
|
|
224
|
+
const depPath = startPath.split(this.pathDelimiter);
|
|
225
|
+
while (depPath.length) {
|
|
226
|
+
const currentPath = depPath.concat(depName).join(this.pathDelimiter);
|
|
227
|
+
if (depMap[currentPath]) {
|
|
228
|
+
return currentPath;
|
|
229
|
+
}
|
|
230
|
+
depPath.pop();
|
|
231
|
+
}
|
|
232
|
+
if (!depMap[depName]) {
|
|
233
|
+
throw new errors_1.OutOfSyncError(depName, this.type);
|
|
234
|
+
}
|
|
235
|
+
return depName;
|
|
236
|
+
}
|
|
237
|
+
// Algorithm is based on dynamic programming technique and tries to build
|
|
238
|
+
// "more simple" trees and compose them into bigger ones.
|
|
239
|
+
async createDepTrees(depMap, depGraph) {
|
|
240
|
+
// Graph has to be acyclic
|
|
241
|
+
if (!graphlib.alg.isAcyclic(depGraph)) {
|
|
242
|
+
throw new Error('Cycles were not removed from graph.');
|
|
243
|
+
}
|
|
244
|
+
const depTrees = {};
|
|
245
|
+
const depTreesSizes = {};
|
|
246
|
+
// topological sort guarantees that when we create a pkg-tree for a dep,
|
|
247
|
+
// all it's sub-trees were already created. This also implies that leaf
|
|
248
|
+
// packages will be processed first as they have no sub-trees.
|
|
249
|
+
const depOrder = graphlib.alg.topsort(depGraph);
|
|
250
|
+
while (depOrder.length) {
|
|
251
|
+
const depKey = depOrder.shift();
|
|
252
|
+
const dep = depMap[depKey];
|
|
253
|
+
let treeSize = 1;
|
|
254
|
+
// direction is from the dependency to the package requiring it, so we are
|
|
255
|
+
// looking for predecessors
|
|
256
|
+
for (const subDepPath of depGraph.predecessors(depKey)) {
|
|
257
|
+
const subDep = depTrees[subDepPath];
|
|
258
|
+
if (!dep.dependencies) {
|
|
259
|
+
dep.dependencies = {};
|
|
260
|
+
}
|
|
261
|
+
dep.dependencies[subDep.name] = subDep;
|
|
262
|
+
treeSize += depTreesSizes[subDepPath];
|
|
263
|
+
}
|
|
264
|
+
const depTreeDep = {
|
|
265
|
+
labels: dep.labels,
|
|
266
|
+
name: dep.name,
|
|
267
|
+
version: dep.version,
|
|
268
|
+
};
|
|
269
|
+
if (dep.dependencies) {
|
|
270
|
+
depTreeDep.dependencies = dep.dependencies;
|
|
271
|
+
}
|
|
272
|
+
depTrees[depKey] = depTreeDep;
|
|
273
|
+
depTreesSizes[depKey] = treeSize;
|
|
274
|
+
// Since this code doesn't handle any I/O or network, we need to force
|
|
275
|
+
// event loop to tick while being used in server for request processing
|
|
276
|
+
if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
|
|
277
|
+
await event_loop_spinner_1.eventLoopSpinner.spin();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return { depTrees, depTreesSizes };
|
|
281
|
+
}
|
|
282
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
283
|
+
getDepMap(lockfile) {
|
|
284
|
+
throw new Error('Not implemented');
|
|
285
|
+
}
|
|
286
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
287
|
+
getDepTreeKey(dep) {
|
|
288
|
+
throw new Error('Not implemented');
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
exports.LockParserBase = LockParserBase;
|
|
292
|
+
//# sourceMappingURL=lock-parser-base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock-parser-base.js","sourceRoot":"","sources":["../../lib/parsers/lock-parser-base.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dep, Lockfile, LockfileType } from './index';
|
|
2
|
+
import { DepMap, LockParserBase } from './lock-parser-base';
|
|
2
3
|
export interface PackageLock {
|
|
3
4
|
name: string;
|
|
4
5
|
version: string;
|
|
@@ -17,16 +18,9 @@ export interface PackageLockDep {
|
|
|
17
18
|
dependencies?: PackageLockDeps;
|
|
18
19
|
dev?: boolean;
|
|
19
20
|
}
|
|
20
|
-
export declare class PackageLockParser
|
|
21
|
-
|
|
21
|
+
export declare class PackageLockParser extends LockParserBase {
|
|
22
|
+
constructor();
|
|
22
23
|
parseLockFile(lockFileContents: string): PackageLock;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
private removeCycle;
|
|
26
|
-
private cloneAcyclicNodeEdges;
|
|
27
|
-
private cloneNodeWithoutEdges;
|
|
28
|
-
private createGraphOfDependencies;
|
|
29
|
-
private findDepsPath;
|
|
30
|
-
private createDepTrees;
|
|
31
|
-
private flattenLockfile;
|
|
24
|
+
protected getDepMap(lockfile: Lockfile): DepMap;
|
|
25
|
+
protected getDepTreeKey(dep: Dep): string;
|
|
32
26
|
}
|
|
@@ -1,302 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
4
|
-
const _isEmpty = require("lodash.isempty");
|
|
5
|
-
const _set = require("lodash.set");
|
|
6
|
-
const _toPairs = require("lodash.topairs");
|
|
7
|
-
const graphlib = require("graphlib");
|
|
8
|
-
const uuid_1 = require("uuid");
|
|
9
|
-
const config_1 = require("../config");
|
|
10
|
-
const event_loop_spinner_1 = require("event-loop-spinner");
|
|
11
|
-
const _1 = require("./");
|
|
3
|
+
const index_1 = require("./index");
|
|
12
4
|
const errors_1 = require("../errors");
|
|
13
|
-
|
|
5
|
+
const lock_parser_base_1 = require("./lock-parser-base");
|
|
6
|
+
const config_1 = require("../config");
|
|
7
|
+
class PackageLockParser extends lock_parser_base_1.LockParserBase {
|
|
14
8
|
constructor() {
|
|
15
|
-
|
|
16
|
-
// a good delimiter (https://www.ietf.org/rfc/rfc1738.txt)
|
|
17
|
-
this.pathDelimiter = '|';
|
|
9
|
+
super(index_1.LockfileType.npm, config_1.config.NPM_TREE_SIZE_LIMIT);
|
|
18
10
|
}
|
|
19
11
|
parseLockFile(lockFileContents) {
|
|
20
12
|
try {
|
|
21
13
|
const packageLock = JSON.parse(lockFileContents);
|
|
22
|
-
packageLock.type =
|
|
14
|
+
packageLock.type = index_1.LockfileType.npm;
|
|
23
15
|
return packageLock;
|
|
24
16
|
}
|
|
25
17
|
catch (e) {
|
|
26
18
|
throw new errors_1.InvalidUserInputError('package-lock.json parsing failed with ' + `error ${e.message}`);
|
|
27
19
|
}
|
|
28
20
|
}
|
|
29
|
-
|
|
30
|
-
var _a;
|
|
31
|
-
if (lockfile.type !== _1.LockfileType.npm) {
|
|
32
|
-
throw new errors_1.InvalidUserInputError('Unsupported lockfile provided. Please ' +
|
|
33
|
-
'provide `package-lock.json`.');
|
|
34
|
-
}
|
|
21
|
+
getDepMap(lockfile) {
|
|
35
22
|
const packageLock = lockfile;
|
|
36
|
-
const depTree = {
|
|
37
|
-
dependencies: {},
|
|
38
|
-
hasDevDependencies: !_isEmpty(manifestFile.devDependencies),
|
|
39
|
-
name: manifestFile.name,
|
|
40
|
-
size: 1,
|
|
41
|
-
version: manifestFile.version || '',
|
|
42
|
-
};
|
|
43
|
-
const nodeVersion = (_a = manifestFile === null || manifestFile === void 0 ? void 0 : manifestFile.engines) === null || _a === void 0 ? void 0 : _a.node;
|
|
44
|
-
if (nodeVersion) {
|
|
45
|
-
_set(depTree, 'meta.nodeVersion', nodeVersion);
|
|
46
|
-
}
|
|
47
|
-
// asked to process empty deps
|
|
48
|
-
if (_isEmpty(manifestFile.dependencies) && !includeDev) {
|
|
49
|
-
return depTree;
|
|
50
|
-
}
|
|
51
|
-
// prepare a flat map, where dependency path is a key to dependency object
|
|
52
|
-
// path is an unique identifier for each dependency and corresponds to the
|
|
53
|
-
// relative path on disc
|
|
54
|
-
const depMap = this.flattenLockfile(packageLock);
|
|
55
|
-
// all paths are identified, we can create a graph representing what depends on what
|
|
56
|
-
const depGraph = this.createGraphOfDependencies(depMap);
|
|
57
|
-
// topological sort will be applied and it requires acyclic graphs
|
|
58
|
-
let cycleStarts = {};
|
|
59
|
-
if (!graphlib.alg.isAcyclic(depGraph)) {
|
|
60
|
-
const cycles = graphlib.alg.findCycles(depGraph);
|
|
61
|
-
for (const cycle of cycles) {
|
|
62
|
-
// Since one of top level dependencies can be a start of cycle and that node
|
|
63
|
-
// will be duplicated, we need to store a link between original node
|
|
64
|
-
// and the new one in order to identify those duplicated top level dependencies
|
|
65
|
-
cycleStarts = Object.assign(Object.assign({}, cycleStarts), this.removeCycle(cycle, depMap, depGraph));
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
// transform depMap to a map of PkgTrees
|
|
69
|
-
const { depTrees, depTreesSizes } = await this.createDepTrees(depMap, depGraph);
|
|
70
|
-
// get trees for dependencies from manifest file
|
|
71
|
-
const topLevelDeps = _1.getTopLevelDeps(manifestFile, includeDev);
|
|
72
|
-
// number of dependencies including root one
|
|
73
|
-
let treeSize = 1;
|
|
74
|
-
for (const dep of topLevelDeps) {
|
|
75
|
-
// tree size limit should be 6 millions.
|
|
76
|
-
if (treeSize > config_1.config.NPM_TREE_SIZE_LIMIT) {
|
|
77
|
-
throw new errors_1.TreeSizeLimitError();
|
|
78
|
-
}
|
|
79
|
-
// if any of top level dependencies is a part of cycle
|
|
80
|
-
// it now has a different item in the map
|
|
81
|
-
const depName = cycleStarts[dep.name] || dep.name;
|
|
82
|
-
if (depTrees[depName]) {
|
|
83
|
-
// if the top level dependency is dev, all children are dev
|
|
84
|
-
depTree.dependencies[dep.name] = dep.dev
|
|
85
|
-
? this.setDevDepRec(_cloneDeep(depTrees[depName]))
|
|
86
|
-
: depTrees[depName];
|
|
87
|
-
treeSize += depTreesSizes[depName];
|
|
88
|
-
if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
|
|
89
|
-
await event_loop_spinner_1.eventLoopSpinner.spin();
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
else if (/^file:/.test(dep.version)) {
|
|
93
|
-
depTree.dependencies[dep.name] = _1.createDepTreeDepFromDep(dep);
|
|
94
|
-
treeSize++;
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
// TODO: also check the package version
|
|
98
|
-
// for a stricter check
|
|
99
|
-
if (strict) {
|
|
100
|
-
throw new errors_1.OutOfSyncError(depName, _1.LockfileType.npm);
|
|
101
|
-
}
|
|
102
|
-
depTree.dependencies[dep.name] = _1.createDepTreeDepFromDep(dep);
|
|
103
|
-
if (!depTree.dependencies[dep.name].labels) {
|
|
104
|
-
depTree.dependencies[dep.name].labels = {};
|
|
105
|
-
}
|
|
106
|
-
depTree.dependencies[dep.name].labels.missingLockFileEntry = 'true';
|
|
107
|
-
treeSize++;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
depTree.size = treeSize;
|
|
111
|
-
return depTree;
|
|
112
|
-
}
|
|
113
|
-
setDevDepRec(pkgTree) {
|
|
114
|
-
for (const [name, subTree] of _toPairs(pkgTree.dependencies)) {
|
|
115
|
-
pkgTree.dependencies[name] = this.setDevDepRec(subTree);
|
|
116
|
-
}
|
|
117
|
-
pkgTree.labels = {
|
|
118
|
-
scope: _1.Scope.dev,
|
|
119
|
-
};
|
|
120
|
-
return pkgTree;
|
|
121
|
-
}
|
|
122
|
-
/* Algorithm for cycle removal:
|
|
123
|
-
For every node in a cycle:
|
|
124
|
-
1. Create a duplicate of entry node (without edges)
|
|
125
|
-
2. For every cyclic dependency of entry node, create a duplicate of
|
|
126
|
-
the dependency and connect it with the duplicated entry node
|
|
127
|
-
3.a If edge goes to already-visited dependency, end of cycle is found;
|
|
128
|
-
update metadata and do not continue traversing
|
|
129
|
-
3.b Follow the edge and repeat the process, storing visited dependency-paths.
|
|
130
|
-
All non-cyclic dependencies of duplicated node need to be updated.
|
|
131
|
-
4. All non-cyclic dependencies or dependants of original node need to be
|
|
132
|
-
updated to be connected with the duplicated one
|
|
133
|
-
|
|
134
|
-
Once completed for all nodes in a cycle, original cyclic nodes can
|
|
135
|
-
be removed.
|
|
136
|
-
*/
|
|
137
|
-
removeCycle(cycle, depMap, depGraph) {
|
|
138
|
-
/* FUNCTION DEFINITION
|
|
139
|
-
To keep an order of algorithm steps readable, function is defined on-the-fly
|
|
140
|
-
Arrow function is used for calling `this` without .bind(this) in the end
|
|
141
|
-
*/
|
|
142
|
-
const acyclicDuplicationRec = (node, traversed, currentCycle, nodeCopy) => {
|
|
143
|
-
// 2. For every cyclic dependency of entry node...
|
|
144
|
-
const edgesToProcess = depGraph.inEdges(node).filter((e) => currentCycle.includes(e.v));
|
|
145
|
-
for (const edge of edgesToProcess) {
|
|
146
|
-
// ... create a duplicate of the dependency...
|
|
147
|
-
const child = edge.v;
|
|
148
|
-
const dependencyCopy = this.cloneNodeWithoutEdges(child, depMap, depGraph);
|
|
149
|
-
// ...and connect it with the duplicated entry node
|
|
150
|
-
depGraph.setEdge(dependencyCopy, nodeCopy);
|
|
151
|
-
// 3.a If edge goes to already-visited dependency, end of cycle is found;
|
|
152
|
-
if (traversed.includes(child)) {
|
|
153
|
-
// update metadata and labels and do not continue traversing
|
|
154
|
-
if (!depMap[dependencyCopy].labels) {
|
|
155
|
-
depMap[dependencyCopy].labels = {};
|
|
156
|
-
}
|
|
157
|
-
depMap[dependencyCopy].labels.pruned = 'cyclic';
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
// 3.b Follow the edge and repeat the process, storing visited dependency-paths
|
|
161
|
-
acyclicDuplicationRec(child, [...traversed, node], currentCycle, dependencyCopy);
|
|
162
|
-
// All non-cyclic dependencies of duplicated node need to be updated.
|
|
163
|
-
this.cloneAcyclicNodeEdges(child, dependencyCopy, cycle, depGraph, {
|
|
164
|
-
inEdges: true,
|
|
165
|
-
outEdges: false,
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
const cycleStarts = {};
|
|
171
|
-
// For every node in a cycle:
|
|
172
|
-
for (const start of cycle) {
|
|
173
|
-
// 1. Create a uniqe duplicate of entry node (without edges)
|
|
174
|
-
const clonedNode = this.cloneNodeWithoutEdges(start, depMap, depGraph);
|
|
175
|
-
cycleStarts[start] = clonedNode;
|
|
176
|
-
// CALL of previously defined function
|
|
177
|
-
acyclicDuplicationRec(start, [], cycle, clonedNode);
|
|
178
|
-
// 4. All non-cyclic dependencies or dependants of original node need to be
|
|
179
|
-
// updated to be connected with the duplicated one
|
|
180
|
-
this.cloneAcyclicNodeEdges(start, clonedNode, cycle, depGraph, {
|
|
181
|
-
inEdges: true,
|
|
182
|
-
outEdges: true,
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
// Once completed for all nodes in a cycle, original cyclic nodes can
|
|
186
|
-
// be removed.
|
|
187
|
-
for (const start of cycle) {
|
|
188
|
-
depGraph.removeNode(start);
|
|
189
|
-
}
|
|
190
|
-
return cycleStarts;
|
|
191
|
-
}
|
|
192
|
-
cloneAcyclicNodeEdges(nodeFrom, nodeTo, cycle, depGraph, { inEdges, outEdges }) {
|
|
193
|
-
// node has to have edges
|
|
194
|
-
const edges = depGraph.nodeEdges(nodeFrom);
|
|
195
|
-
if (outEdges) {
|
|
196
|
-
const parentEdges = edges.filter((e) => !cycle.includes(e.w));
|
|
197
|
-
for (const edge of parentEdges) {
|
|
198
|
-
const parent = edge.w;
|
|
199
|
-
depGraph.setEdge(nodeTo, parent);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
if (inEdges) {
|
|
203
|
-
const childEdges = edges.filter((e) => !cycle.includes(e.v));
|
|
204
|
-
for (const edge of childEdges) {
|
|
205
|
-
const child = edge.v;
|
|
206
|
-
depGraph.setEdge(child, nodeTo);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
cloneNodeWithoutEdges(node, depMap, depGraph) {
|
|
211
|
-
const newNode = node + uuid_1.v4();
|
|
212
|
-
// update depMap with new node
|
|
213
|
-
depMap[newNode] = _cloneDeep(depMap[node]);
|
|
214
|
-
// add new node to the graph
|
|
215
|
-
depGraph.setNode(newNode);
|
|
216
|
-
return newNode;
|
|
217
|
-
}
|
|
218
|
-
createGraphOfDependencies(depMap) {
|
|
219
|
-
const depGraph = new graphlib.Graph();
|
|
220
|
-
for (const depKey of Object.keys(depMap)) {
|
|
221
|
-
depGraph.setNode(depKey);
|
|
222
|
-
}
|
|
223
|
-
for (const [depPath, dep] of Object.entries(depMap)) {
|
|
224
|
-
for (const depName of dep.requires) {
|
|
225
|
-
const subDepPath = this.findDepsPath(depPath, depName, depMap);
|
|
226
|
-
// direction is from the dependency to the package requiring it
|
|
227
|
-
depGraph.setEdge(subDepPath, depPath);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
return depGraph;
|
|
231
|
-
}
|
|
232
|
-
// dependency in package-lock.json v1 can be defined either inside `dependencies`
|
|
233
|
-
// of other dependency or anywhere upward towards root
|
|
234
|
-
findDepsPath(startPath, depName, depMap) {
|
|
235
|
-
const depPath = startPath.split(this.pathDelimiter);
|
|
236
|
-
while (depPath.length) {
|
|
237
|
-
const currentPath = depPath.concat(depName).join(this.pathDelimiter);
|
|
238
|
-
if (depMap[currentPath]) {
|
|
239
|
-
return currentPath;
|
|
240
|
-
}
|
|
241
|
-
depPath.pop();
|
|
242
|
-
}
|
|
243
|
-
if (!depMap[depName]) {
|
|
244
|
-
throw new errors_1.OutOfSyncError(depName, _1.LockfileType.npm);
|
|
245
|
-
}
|
|
246
|
-
return depName;
|
|
247
|
-
}
|
|
248
|
-
// Algorithm is based on dynamic programming technique and tries to build
|
|
249
|
-
// "more simple" trees and compose them into bigger ones.
|
|
250
|
-
async createDepTrees(depMap, depGraph) {
|
|
251
|
-
// Graph has to be acyclic
|
|
252
|
-
if (!graphlib.alg.isAcyclic(depGraph)) {
|
|
253
|
-
throw new Error('Cycles were not removed from graph.');
|
|
254
|
-
}
|
|
255
|
-
const depTrees = {};
|
|
256
|
-
const depTreesSizes = {};
|
|
257
|
-
// topological sort guarantees that when we create a pkg-tree for a dep,
|
|
258
|
-
// all it's sub-trees were already created. This also implies that leaf
|
|
259
|
-
// packages will be processed first as they have no sub-trees.
|
|
260
|
-
const depOrder = graphlib.alg.topsort(depGraph);
|
|
261
|
-
while (depOrder.length) {
|
|
262
|
-
const depKey = depOrder.shift();
|
|
263
|
-
const dep = depMap[depKey];
|
|
264
|
-
let treeSize = 1;
|
|
265
|
-
// direction is from the dependency to the package requiring it, so we are
|
|
266
|
-
// looking for predecessors
|
|
267
|
-
for (const subDepPath of depGraph.predecessors(depKey)) {
|
|
268
|
-
const subDep = depTrees[subDepPath];
|
|
269
|
-
if (!dep.dependencies) {
|
|
270
|
-
dep.dependencies = {};
|
|
271
|
-
}
|
|
272
|
-
dep.dependencies[subDep.name] = subDep;
|
|
273
|
-
treeSize += depTreesSizes[subDepPath];
|
|
274
|
-
}
|
|
275
|
-
const depTreeDep = {
|
|
276
|
-
labels: dep.labels,
|
|
277
|
-
name: dep.name,
|
|
278
|
-
version: dep.version,
|
|
279
|
-
};
|
|
280
|
-
if (dep.dependencies) {
|
|
281
|
-
depTreeDep.dependencies = dep.dependencies;
|
|
282
|
-
}
|
|
283
|
-
depTrees[depKey] = depTreeDep;
|
|
284
|
-
depTreesSizes[depKey] = treeSize;
|
|
285
|
-
// Since this code doesn't handle any I/O or network, we need to force
|
|
286
|
-
// event loop to tick while being used in server for request processing
|
|
287
|
-
if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
|
|
288
|
-
await event_loop_spinner_1.eventLoopSpinner.spin();
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return { depTrees, depTreesSizes };
|
|
292
|
-
}
|
|
293
|
-
flattenLockfile(lockfile) {
|
|
294
23
|
const depMap = {};
|
|
295
24
|
const flattenLockfileRec = (lockfileDeps, path) => {
|
|
296
25
|
for (const [depName, dep] of Object.entries(lockfileDeps)) {
|
|
297
26
|
const depNode = {
|
|
298
27
|
labels: {
|
|
299
|
-
scope: dep.dev ?
|
|
28
|
+
scope: dep.dev ? index_1.Scope.dev : index_1.Scope.prod,
|
|
300
29
|
},
|
|
301
30
|
name: depName,
|
|
302
31
|
requires: [],
|
|
@@ -313,9 +42,12 @@ class PackageLockParser {
|
|
|
313
42
|
}
|
|
314
43
|
}
|
|
315
44
|
};
|
|
316
|
-
flattenLockfileRec(
|
|
45
|
+
flattenLockfileRec(packageLock.dependencies || {}, []);
|
|
317
46
|
return depMap;
|
|
318
47
|
}
|
|
48
|
+
getDepTreeKey(dep) {
|
|
49
|
+
return dep.name;
|
|
50
|
+
}
|
|
319
51
|
}
|
|
320
52
|
exports.PackageLockParser = PackageLockParser;
|
|
321
53
|
//# sourceMappingURL=package-lock-parser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-lock-parser.js","sourceRoot":"","sources":["../../lib/parsers/package-lock-parser.ts"],"names":[],"mappings":";;AAAA
|
|
1
|
+
{"version":3,"file":"package-lock-parser.js","sourceRoot":"","sources":["../../lib/parsers/package-lock-parser.ts"],"names":[],"mappings":";;AAAA,mCAA6D;AAC7D,sCAAkD;AAClD,yDAAwE;AACxE,sCAAmC;AAuBnC,MAAa,iBAAkB,SAAQ,iCAAc;IACnD;QACE,KAAK,CAAC,oBAAY,CAAC,GAAG,EAAE,eAAM,CAAC,mBAAmB,CAAC,CAAC;IACtD,CAAC;IAEM,aAAa,CAAC,gBAAwB;QAC3C,IAAI;YACF,MAAM,WAAW,GAAgB,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAC9D,WAAW,CAAC,IAAI,GAAG,oBAAY,CAAC,GAAG,CAAC;YACpC,OAAO,WAAW,CAAC;SACpB;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,IAAI,8BAAqB,CAC7B,wCAAwC,GAAG,SAAS,CAAC,CAAC,OAAO,EAAE,CAChE,CAAC;SACH;IACH,CAAC;IAES,SAAS,CAAC,QAAkB;QACpC,MAAM,WAAW,GAAG,QAAuB,CAAC;QAC5C,MAAM,MAAM,GAAW,EAAE,CAAC;QAE1B,MAAM,kBAAkB,GAAG,CACzB,YAA6B,EAC7B,IAAc,EACd,EAAE;YACF,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;gBACzD,MAAM,OAAO,GAAe;oBAC1B,MAAM,EAAE;wBACN,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,aAAK,CAAC,GAAG,CAAC,CAAC,CAAC,aAAK,CAAC,IAAI;qBACxC;oBACD,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE,EAAE;oBACZ,OAAO,EAAE,GAAG,CAAC,OAAO;iBACrB,CAAC;gBAEF,IAAI,GAAG,CAAC,QAAQ,EAAE;oBAChB,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;iBAC9C;gBAED,MAAM,OAAO,GAAa,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;gBAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBAChD,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;gBACzB,IAAI,GAAG,CAAC,YAAY,EAAE;oBACpB,kBAAkB,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;iBAC/C;aACF;QACH,CAAC,CAAC;QAEF,kBAAkB,CAAC,WAAW,CAAC,YAAY,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAEvD,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,aAAa,CAAC,GAAQ;QAC9B,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;CACF;AAxDD,8CAwDC"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dep, Lockfile, LockfileType, ManifestFile, PkgTree } from './index';
|
|
2
|
+
import { DepMap, LockParserBase } from './lock-parser-base';
|
|
2
3
|
export declare type YarnLockFileTypes = LockfileType.yarn | LockfileType.yarn2;
|
|
3
|
-
export interface
|
|
4
|
-
[depName: string]: YarnLockDep;
|
|
5
|
-
}
|
|
6
|
-
export interface YarnLockBase<T extends YarnLockFileTypes> {
|
|
4
|
+
export interface YarnLock {
|
|
7
5
|
type: string;
|
|
8
6
|
object: YarnLockDeps;
|
|
9
7
|
dependencies?: YarnLockDeps;
|
|
10
|
-
lockfileType:
|
|
8
|
+
lockfileType: YarnLockFileTypes;
|
|
9
|
+
}
|
|
10
|
+
export interface YarnLockDeps {
|
|
11
|
+
[depName: string]: YarnLockDep;
|
|
11
12
|
}
|
|
12
13
|
export interface YarnLockDep {
|
|
13
14
|
version: string;
|
|
@@ -18,13 +19,10 @@ export interface YarnLockDep {
|
|
|
18
19
|
[depName: string]: string;
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
|
-
export declare
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
private eventLoopSpinRate;
|
|
25
|
-
constructor(type: T);
|
|
26
|
-
abstract parseLockFile(lockFileContents: string): Lockfile;
|
|
22
|
+
export declare class YarnLockParser extends LockParserBase {
|
|
23
|
+
constructor();
|
|
24
|
+
parseLockFile(lockFileContents: string): YarnLock;
|
|
27
25
|
getDependencyTree(manifestFile: ManifestFile, lockfile: Lockfile, includeDev?: boolean, strict?: boolean): Promise<PkgTree>;
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
protected getDepMap(lockfile: Lockfile): DepMap;
|
|
27
|
+
protected getDepTreeKey(dep: Dep): string;
|
|
30
28
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const yarnLockfileParser = require("@yarnpkg/lockfile");
|
|
4
|
+
const index_1 = require("./index");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const lock_parser_base_1 = require("./lock-parser-base");
|
|
7
|
+
const config_1 = require("../config");
|
|
8
|
+
class YarnLockParser extends lock_parser_base_1.LockParserBase {
|
|
9
|
+
constructor() {
|
|
10
|
+
super(index_1.LockfileType.yarn, config_1.config.YARN_TREE_SIZE_LIMIT);
|
|
11
|
+
}
|
|
12
|
+
parseLockFile(lockFileContents) {
|
|
13
|
+
try {
|
|
14
|
+
const yarnLock = yarnLockfileParser.parse(lockFileContents);
|
|
15
|
+
yarnLock.dependencies = yarnLock.object;
|
|
16
|
+
yarnLock.type = this.type;
|
|
17
|
+
return yarnLock;
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
throw new errors_1.InvalidUserInputError(`yarn.lock parsing failed with an error: ${e.message}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async getDependencyTree(manifestFile, lockfile, includeDev = false, strict = true) {
|
|
24
|
+
const depTree = await super.getDependencyTree(manifestFile, lockfile, includeDev, strict);
|
|
25
|
+
if (!depTree.meta)
|
|
26
|
+
depTree.meta = {};
|
|
27
|
+
depTree.meta.packageManagerVersion = '1';
|
|
28
|
+
return depTree;
|
|
29
|
+
}
|
|
30
|
+
getDepMap(lockfile) {
|
|
31
|
+
const yarnLockfile = lockfile;
|
|
32
|
+
const depMap = {};
|
|
33
|
+
for (const [depName, dep] of Object.entries(yarnLockfile.object)) {
|
|
34
|
+
const subDependencies = Object.entries(Object.assign(Object.assign({}, (dep.dependencies || {})), (dep.optionalDependencies || {})));
|
|
35
|
+
depMap[depName] = {
|
|
36
|
+
labels: {
|
|
37
|
+
scope: index_1.Scope.prod,
|
|
38
|
+
},
|
|
39
|
+
name: getName(depName),
|
|
40
|
+
requires: subDependencies.map(([key, ver]) => `${key}@${ver}`),
|
|
41
|
+
version: dep.version,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return depMap;
|
|
45
|
+
}
|
|
46
|
+
getDepTreeKey(dep) {
|
|
47
|
+
return `${dep.name}@${dep.version}`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.YarnLockParser = YarnLockParser;
|
|
51
|
+
function getName(depName) {
|
|
52
|
+
return depName.slice(0, depName.indexOf('@', 1));
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=yarn-lock-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yarn-lock-parser.js","sourceRoot":"","sources":["../../lib/parsers/yarn-lock-parser.ts"],"names":[],"mappings":";;AAAA,wDAAwD;AAExD,mCAOiB;AACjB,sCAAkD;AAClD,yDAA4D;AAC5D,sCAAmC;AAyBnC,MAAa,cAAe,SAAQ,iCAAc;IAChD;QACE,KAAK,CAAC,oBAAY,CAAC,IAAI,EAAE,eAAM,CAAC,oBAAoB,CAAC,CAAC;IACxD,CAAC;IAEM,aAAa,CAAC,gBAAwB;QAC3C,IAAI;YACF,MAAM,QAAQ,GAAa,kBAAkB,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACtE,QAAQ,CAAC,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC;YACxC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YAC1B,OAAO,QAAQ,CAAC;SACjB;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,IAAI,8BAAqB,CAC7B,2CAA2C,CAAC,CAAC,OAAO,EAAE,CACvD,CAAC;SACH;IACH,CAAC;IAEM,KAAK,CAAC,iBAAiB,CAC5B,YAA0B,EAC1B,QAAkB,EAClB,UAAU,GAAG,KAAK,EAClB,MAAM,GAAG,IAAI;QAEb,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,iBAAiB,CAC3C,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,MAAM,CACP,CAAC;QAEF,IAAI,CAAC,OAAO,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,qBAAqB,GAAG,GAAG,CAAC;QAEzC,OAAO,OAAO,CAAC;IACjB,CAAC;IAES,SAAS,CAAC,QAAkB;QACpC,MAAM,YAAY,GAAG,QAAoB,CAAC;QAC1C,MAAM,MAAM,GAAW,EAAE,CAAC;QAE1B,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;YAChE,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,iCACjC,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,GACxB,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC,EACnC,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,GAAG;gBAChB,MAAM,EAAE;oBACN,KAAK,EAAE,aAAK,CAAC,IAAI;iBAClB;gBACD,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC;gBACtB,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;gBAC9D,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC;SACH;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,aAAa,CAAC,GAAQ;QAC9B,OAAO,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;IACtC,CAAC;CACF;AA9DD,wCA8DC;AAED,SAAS,OAAO,CAAC,OAAe;IAC9B,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC"}
|
package/package.json
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"author": "snyk.io",
|
|
23
23
|
"license": "Apache-2.0",
|
|
24
24
|
"engines": {
|
|
25
|
-
"node": ">=
|
|
25
|
+
"node": ">=10"
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
28
|
"bin",
|
|
@@ -30,17 +30,17 @@
|
|
|
30
30
|
],
|
|
31
31
|
"homepage": "https://github.com/snyk/nodejs-lockfile-parser#readme",
|
|
32
32
|
"dependencies": {
|
|
33
|
+
"@snyk/graphlib": "2.1.9-patch.3",
|
|
33
34
|
"@yarnpkg/lockfile": "^1.1.0",
|
|
34
35
|
"event-loop-spinner": "^2.0.0",
|
|
35
36
|
"got": "11.4.0",
|
|
36
|
-
"graphlib": "2.1.8",
|
|
37
37
|
"lodash.clonedeep": "^4.5.0",
|
|
38
38
|
"lodash.flatmap": "^4.5.0",
|
|
39
39
|
"lodash.isempty": "^4.4.0",
|
|
40
40
|
"lodash.set": "^4.3.2",
|
|
41
41
|
"lodash.topairs": "^4.3.0",
|
|
42
42
|
"p-map": "2.1.0",
|
|
43
|
-
"snyk-config": "^
|
|
43
|
+
"snyk-config": "^4.0.0-rc.2",
|
|
44
44
|
"tslib": "^1.9.3",
|
|
45
45
|
"uuid": "^8.3.0",
|
|
46
46
|
"yaml": "^1.9.2"
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"tap": "^12.6.1",
|
|
58
58
|
"typescript": "3.8.3"
|
|
59
59
|
},
|
|
60
|
-
"version": "1.
|
|
60
|
+
"version": "1.31.1"
|
|
61
61
|
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const _isEmpty = require("lodash.isempty");
|
|
4
|
-
const _set = require("lodash.set");
|
|
5
|
-
const pMap = require("p-map");
|
|
6
|
-
const _1 = require("./");
|
|
7
|
-
const event_loop_spinner_1 = require("event-loop-spinner");
|
|
8
|
-
const errors_1 = require("../errors");
|
|
9
|
-
const config_1 = require("../config");
|
|
10
|
-
const EVENT_PROCESSING_CONCURRENCY = 5;
|
|
11
|
-
class YarnLockParseBase {
|
|
12
|
-
constructor(type) {
|
|
13
|
-
this.type = type;
|
|
14
|
-
this.eventLoopSpinRate = 20;
|
|
15
|
-
// Number of dependencies including root one.
|
|
16
|
-
this.treeSize = 1;
|
|
17
|
-
}
|
|
18
|
-
async getDependencyTree(manifestFile, lockfile, includeDev = false, strict = true) {
|
|
19
|
-
var _a;
|
|
20
|
-
if (lockfile.type !== this.type) {
|
|
21
|
-
throw new errors_1.InvalidUserInputError('Unsupported lockfile provided. Please provide `yarn.lock`.');
|
|
22
|
-
}
|
|
23
|
-
const yarnLock = lockfile;
|
|
24
|
-
const depTree = {
|
|
25
|
-
dependencies: {},
|
|
26
|
-
hasDevDependencies: !_isEmpty(manifestFile.devDependencies),
|
|
27
|
-
name: manifestFile.name,
|
|
28
|
-
size: 1,
|
|
29
|
-
version: manifestFile.version || '',
|
|
30
|
-
};
|
|
31
|
-
const nodeVersion = (_a = manifestFile === null || manifestFile === void 0 ? void 0 : manifestFile.engines) === null || _a === void 0 ? void 0 : _a.node;
|
|
32
|
-
if (nodeVersion) {
|
|
33
|
-
_set(depTree, 'meta.nodeVersion', nodeVersion);
|
|
34
|
-
}
|
|
35
|
-
const packageManagerVersion = lockfile.type === _1.LockfileType.yarn ? '1' : '2';
|
|
36
|
-
_set(depTree, 'meta.packageManagerVersion', packageManagerVersion);
|
|
37
|
-
const topLevelDeps = _1.getTopLevelDeps(manifestFile, includeDev);
|
|
38
|
-
// asked to process empty deps
|
|
39
|
-
if (_isEmpty(manifestFile.dependencies) && !includeDev) {
|
|
40
|
-
return depTree;
|
|
41
|
-
}
|
|
42
|
-
await pMap(topLevelDeps, (dep) => this.resolveDep(dep, depTree, yarnLock, strict), { concurrency: EVENT_PROCESSING_CONCURRENCY });
|
|
43
|
-
depTree.size = this.treeSize;
|
|
44
|
-
return depTree;
|
|
45
|
-
}
|
|
46
|
-
async buildSubTree(lockFile, tree, strict) {
|
|
47
|
-
const queue = [{ path: [], tree }];
|
|
48
|
-
while (queue.length > 0) {
|
|
49
|
-
const queueItem = queue.pop();
|
|
50
|
-
const depKey = `${queueItem.tree.name}@${queueItem.tree.version}`;
|
|
51
|
-
const dependency = lockFile.object[depKey];
|
|
52
|
-
if (!dependency) {
|
|
53
|
-
if (strict) {
|
|
54
|
-
throw new errors_1.OutOfSyncError(queueItem.tree.name, this.type);
|
|
55
|
-
}
|
|
56
|
-
if (!queueItem.tree.labels) {
|
|
57
|
-
queueItem.tree.labels = {};
|
|
58
|
-
}
|
|
59
|
-
queueItem.tree.labels.missingLockFileEntry = 'true';
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
// Overwrite version pattern with exact version.
|
|
63
|
-
queueItem.tree.version = dependency.version;
|
|
64
|
-
if (queueItem.path.indexOf(depKey) >= 0) {
|
|
65
|
-
if (!queueItem.tree.labels) {
|
|
66
|
-
queueItem.tree.labels = {};
|
|
67
|
-
}
|
|
68
|
-
queueItem.tree.labels.pruned = 'cyclic';
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
const subDependencies = Object.entries(Object.assign(Object.assign({}, dependency.dependencies), dependency.optionalDependencies));
|
|
72
|
-
for (const [subName, subVersion] of subDependencies) {
|
|
73
|
-
// tree size limit should be 6 millions.
|
|
74
|
-
if (this.treeSize > config_1.config.YARN_TREE_SIZE_LIMIT) {
|
|
75
|
-
throw new errors_1.TreeSizeLimitError();
|
|
76
|
-
}
|
|
77
|
-
const subDependency = {
|
|
78
|
-
labels: {
|
|
79
|
-
scope: tree.labels.scope,
|
|
80
|
-
},
|
|
81
|
-
name: subName,
|
|
82
|
-
version: subVersion,
|
|
83
|
-
};
|
|
84
|
-
if (!queueItem.tree.dependencies) {
|
|
85
|
-
queueItem.tree.dependencies = {};
|
|
86
|
-
}
|
|
87
|
-
queueItem.tree.dependencies[subName] = subDependency;
|
|
88
|
-
queue.push({
|
|
89
|
-
path: [...queueItem.path, depKey],
|
|
90
|
-
tree: subDependency,
|
|
91
|
-
});
|
|
92
|
-
this.treeSize++;
|
|
93
|
-
if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
|
|
94
|
-
await event_loop_spinner_1.eventLoopSpinner.spin();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return tree;
|
|
99
|
-
}
|
|
100
|
-
async resolveDep(dep, depTree, yarnLock, strict) {
|
|
101
|
-
if (/^file:/.test(dep.version)) {
|
|
102
|
-
depTree.dependencies[dep.name] = _1.createDepTreeDepFromDep(dep);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
depTree.dependencies[dep.name] = await this.buildSubTree(yarnLock, _1.createDepTreeDepFromDep(dep), strict);
|
|
106
|
-
}
|
|
107
|
-
this.treeSize++;
|
|
108
|
-
if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
|
|
109
|
-
await event_loop_spinner_1.eventLoopSpinner.spin();
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
exports.YarnLockParseBase = YarnLockParseBase;
|
|
114
|
-
//# sourceMappingURL=yarn-lock-parse-base.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"yarn-lock-parse-base.js","sourceRoot":"","sources":["../../lib/parsers/yarn-lock-parse-base.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { LockfileType } from './';
|
|
2
|
-
import { YarnLockBase } from './yarn-lock-parse-base';
|
|
3
|
-
import { YarnLockParseBase } from './yarn-lock-parse-base';
|
|
4
|
-
export declare type YarnLock = YarnLockBase<LockfileType.yarn>;
|
|
5
|
-
export declare class YarnLockParser extends YarnLockParseBase<LockfileType.yarn> {
|
|
6
|
-
constructor();
|
|
7
|
-
parseLockFile(lockFileContents: string): YarnLock;
|
|
8
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const yarnLockfileParser = require("@yarnpkg/lockfile");
|
|
4
|
-
const _1 = require("./");
|
|
5
|
-
const errors_1 = require("../errors");
|
|
6
|
-
const yarn_lock_parse_base_1 = require("./yarn-lock-parse-base");
|
|
7
|
-
class YarnLockParser extends yarn_lock_parse_base_1.YarnLockParseBase {
|
|
8
|
-
constructor() {
|
|
9
|
-
super(_1.LockfileType.yarn);
|
|
10
|
-
}
|
|
11
|
-
parseLockFile(lockFileContents) {
|
|
12
|
-
try {
|
|
13
|
-
const yarnLock = yarnLockfileParser.parse(lockFileContents);
|
|
14
|
-
yarnLock.dependencies = yarnLock.object;
|
|
15
|
-
yarnLock.type = _1.LockfileType.yarn;
|
|
16
|
-
return yarnLock;
|
|
17
|
-
}
|
|
18
|
-
catch (e) {
|
|
19
|
-
throw new errors_1.InvalidUserInputError(`yarn.lock parsing failed with an error: ${e.message}`);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
exports.YarnLockParser = YarnLockParser;
|
|
24
|
-
//# sourceMappingURL=yarn-lock-parse.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"yarn-lock-parse.js","sourceRoot":"","sources":["../../lib/parsers/yarn-lock-parse.ts"],"names":[],"mappings":";;AAAA,wDAAwD;AAExD,yBAAkC;AAClC,sCAAkD;AAElD,iEAA2D;AAI3D,MAAa,cAAe,SAAQ,wCAAoC;IACtE;QACE,KAAK,CAAC,eAAY,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAEM,aAAa,CAAC,gBAAwB;QAC3C,IAAI;YACF,MAAM,QAAQ,GAAa,kBAAkB,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YACtE,QAAQ,CAAC,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC;YACxC,QAAQ,CAAC,IAAI,GAAG,eAAY,CAAC,IAAI,CAAC;YAClC,OAAO,QAAQ,CAAC;SACjB;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,IAAI,8BAAqB,CAC7B,2CAA2C,CAAC,CAAC,OAAO,EAAE,CACvD,CAAC;SACH;IACH,CAAC;CACF;AAjBD,wCAiBC"}
|