UNPKG

3.03 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.buildDepGraphYarnLockV1SimpleCyclesPruned = void 0;
4const dep_graph_1 = require("@snyk/dep-graph");
5const util_1 = require("../util");
6const event_loop_spinner_1 = require("event-loop-spinner");
7var Color;
8(function (Color) {
9 Color[Color["GRAY"] = 0] = "GRAY";
10 Color[Color["BLACK"] = 1] = "BLACK";
11})(Color || (Color = {}));
12const buildDepGraphYarnLockV1SimpleCyclesPruned = async (extractedYarnLockV1Pkgs, pkgJson, options) => {
13 const { includeDevDeps, strictOutOfSync, includeOptionalDeps } = options;
14 const depGraphBuilder = new dep_graph_1.DepGraphBuilder({ name: 'yarn' }, { name: pkgJson.name, version: pkgJson.version });
15 const colorMap = {};
16 const topLevelDeps = (0, util_1.getTopLevelDeps)(pkgJson, { includeDevDeps });
17 const rootNode = {
18 id: 'root-node',
19 name: pkgJson.name,
20 version: pkgJson.version,
21 dependencies: topLevelDeps,
22 isDev: false,
23 };
24 await dfsVisit(depGraphBuilder, rootNode, colorMap, extractedYarnLockV1Pkgs, strictOutOfSync, includeOptionalDeps);
25 return depGraphBuilder.build();
26};
27exports.buildDepGraphYarnLockV1SimpleCyclesPruned = buildDepGraphYarnLockV1SimpleCyclesPruned;
28/**
29 * Use DFS to add all nodes and edges to the depGraphBuilder and prune cyclic nodes.
30 * The colorMap keep track of the state of node during traversal.
31 * - If a node doesn't exist in the map, it means it hasn't been visited.
32 * - If a node is GRAY, it means it has already been discovered but its subtree hasn't been fully traversed.
33 * - If a node is BLACK, it means its subtree has already been fully traversed.
34 * - When first exploring an edge, if it points to a GRAY node, a cycle is found and the GRAY node is pruned.
35 * - A pruned node has id `${originalId}|1`
36 */
37const dfsVisit = async (depGraphBuilder, node, colorMap, extractedYarnLockV1Pkgs, strictOutOfSync, includeOptionalDeps) => {
38 colorMap[node.id] = Color.GRAY;
39 for (const [name, depInfo] of Object.entries(node.dependencies || {})) {
40 if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
41 await event_loop_spinner_1.eventLoopSpinner.spin();
42 }
43 const childNode = (0, util_1.getChildNode)(name, depInfo, extractedYarnLockV1Pkgs, strictOutOfSync, includeOptionalDeps);
44 if (!colorMap.hasOwnProperty(childNode.id)) {
45 (0, util_1.addPkgNodeToGraph)(depGraphBuilder, childNode, {});
46 await dfsVisit(depGraphBuilder, childNode, colorMap, extractedYarnLockV1Pkgs, strictOutOfSync, includeOptionalDeps);
47 }
48 else if (colorMap[childNode.id] === Color.GRAY) {
49 // cycle detected
50 childNode.id = `${childNode.id}:pruned`;
51 (0, util_1.addPkgNodeToGraph)(depGraphBuilder, childNode, { isCyclic: true });
52 }
53 depGraphBuilder.connectDep(node.id, childNode.id);
54 }
55 colorMap[node.id] = Color.BLACK;
56};
57//# sourceMappingURL=build-depgraph-simple-pruned.js.map
\No newline at end of file