diff --git a/workspaces/arborist/lib/calc-dep-flags.js b/workspaces/arborist/lib/calc-dep-flags.js index 45ed9562479af..bcd30d0f493c7 100644 --- a/workspaces/arborist/lib/calc-dep-flags.js +++ b/workspaces/arborist/lib/calc-dep-flags.js @@ -31,6 +31,10 @@ const calcDepFlagsStep = (node) => { // for links, map their hierarchy appropriately if (node.isLink) { + // node.target can be null, we check to ensure it's not null before proceeding + if (node.target == null) { + return node + } node.target.dev = node.dev node.target.optional = node.optional node.target.devOptional = node.devOptional @@ -97,15 +101,18 @@ const unsetFlag = (node, flag) => { tree: node, visit: node => { node.extraneous = node[flag] = false - if (node.isLink) { + if (node.isLink && node.target) { node.target.extraneous = node.target[flag] = false } }, getChildren: node => { const children = [] - for (const edge of node.target.edgesOut.values()) { - if (edge.to && edge.to[flag] && - (flag !== 'peer' && edge.type === 'peer' || edge.type === 'prod') + const targetNode = node.isLink && node.target ? node.target : node + for (const edge of targetNode.edgesOut.values()) { + if ( + edge.to && + edge.to[flag] && + ((flag !== 'peer' && edge.type === 'peer') || edge.type === 'prod') ) { children.push(edge.to) } diff --git a/workspaces/arborist/test/calc-dep-flags.js b/workspaces/arborist/test/calc-dep-flags.js index bba64fc5dd0dc..ff7f320ded29d 100644 --- a/workspaces/arborist/test/calc-dep-flags.js +++ b/workspaces/arborist/test/calc-dep-flags.js @@ -264,3 +264,16 @@ t.test('set parents to not extraneous when visiting', t => { t.equal(bazLink.devOptional, false, 'bazlink not devOptional') t.end() }) + +t.test('check null target in link', async t => { + const root = new Link({ + path: '/some/path', + realpath: '/some/path', + pkg: { + dependencies: { foo: '' }, + }, + }) + t.doesNotThrow(() => calcDepFlags(root)) + t.doesNotThrow(() => calcDepFlags(root, false)) + t.end() +})