UNPKG

snyk-nodejs-lockfile-parser

Version:
73 lines 3.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildDepGraphYarnLockV1WorkspaceCyclesPruned = void 0; const dep_graph_1 = require("@snyk/dep-graph"); const util_1 = require("../util"); const util_2 = require("./util"); const event_loop_spinner_1 = require("event-loop-spinner"); var Color; (function (Color) { Color[Color["GRAY"] = 0] = "GRAY"; Color[Color["BLACK"] = 1] = "BLACK"; })(Color || (Color = {})); // Parse a single workspace package using yarn.lock v1 // workspaces feature const buildDepGraphYarnLockV1WorkspaceCyclesPruned = async (extractedYarnLockV1Pkgs, pkgJson, workspacePkgNameToVersion, options) => { const { includeDevDeps, strictOutOfSync, includeOptionalDeps } = options; const depGraphBuilder = new dep_graph_1.DepGraphBuilder({ name: 'yarn' }, { name: pkgJson.name, version: pkgJson.version }); const colorMap = {}; const topLevelDeps = (0, util_1.getTopLevelDeps)(pkgJson, { includeDevDeps }); const rootNode = { id: 'root-node', name: pkgJson.name, version: pkgJson.version, dependencies: topLevelDeps, isDev: false, }; await dfsVisit(depGraphBuilder, rootNode, colorMap, extractedYarnLockV1Pkgs, workspacePkgNameToVersion, strictOutOfSync, includeOptionalDeps); return depGraphBuilder.build(); }; exports.buildDepGraphYarnLockV1WorkspaceCyclesPruned = buildDepGraphYarnLockV1WorkspaceCyclesPruned; /** * Use DFS to add all nodes and edges to the depGraphBuilder and prune cyclic nodes. * The colorMap keep track of the state of node during traversal. * - If a node doesn't exist in the map, it means it hasn't been visited. * - If a node is GRAY, it means it has already been discovered but its subtree hasn't been fully traversed. * - If a node is BLACK, it means its subtree has already been fully traversed. * - When first exploring an edge, if it points to a GRAY node, a cycle is found and the GRAY node is pruned. * - A pruned node has id `${originalId}|1` * When coming across another workspace package as child node, simply add the node and edge to the graph and mark it as BLACK. */ const dfsVisit = async (depGraphBuilder, node, colorMap, extractedYarnLockV1Pkgs, workspacePkgNameToVersion, strictOutOfSync, includeOptionalDeps) => { colorMap[node.id] = Color.GRAY; for (const [name, depInfo] of Object.entries(node.dependencies || {})) { if (event_loop_spinner_1.eventLoopSpinner.isStarving()) { await event_loop_spinner_1.eventLoopSpinner.spin(); } const isWorkspacePkg = !!workspacePkgNameToVersion[name]; const childNode = (0, util_2.getChildNodeYarnLockV1Workspace)(name, depInfo, workspacePkgNameToVersion, extractedYarnLockV1Pkgs, strictOutOfSync, includeOptionalDeps); if (!colorMap.hasOwnProperty(childNode.id)) { (0, util_1.addPkgNodeToGraph)(depGraphBuilder, childNode, { isCyclic: false, isWorkspacePkg, }); if (!isWorkspacePkg) { await dfsVisit(depGraphBuilder, childNode, colorMap, extractedYarnLockV1Pkgs, workspacePkgNameToVersion, strictOutOfSync, includeOptionalDeps); } else { colorMap[childNode.id] = Color.BLACK; } } else if (colorMap[childNode.id] === Color.GRAY) { // cycle detected childNode.id = `${childNode.id}|1`; (0, util_1.addPkgNodeToGraph)(depGraphBuilder, childNode, { isCyclic: true, isWorkspacePkg, }); } depGraphBuilder.connectDep(node.id, childNode.id); } colorMap[node.id] = Color.BLACK; }; //# sourceMappingURL=build-depgraph-workspace-package-pruned.js.map