diff --git a/lib/edge.js b/lib/edge.js index b6a5b957e..46b1f12f5 100644 --- a/lib/edge.js +++ b/lib/edge.js @@ -15,7 +15,8 @@ const types = new Set([ 'prod', 'dev', 'optional', - 'peer' + 'peer', + 'peerOptional', ]) class Edge { @@ -37,6 +38,14 @@ class Edge { this[_setFrom](from) } + get optional () { + return this[_type] === 'optional' || this[_type] === 'peerOptional' + } + + get peer () { + return this[_type] === 'peer' || this[_type] === 'peerOptional' + } + get type () { return this[_type] } @@ -58,8 +67,8 @@ class Edge { return this[_error] return this[_error] = ( - !this[_to] ? (this[_type] === 'optional' ? null : 'MISSING') - : this.type === 'peer' && + !this[_to] ? (this.optional ? null : 'MISSING') + : this.peer && this.from === this.to.parent && !this.from.isTop ? 'PEER LOCAL' diff --git a/lib/node.js b/lib/node.js index cc4d48954..8356c906b 100644 --- a/lib/node.js +++ b/lib/node.js @@ -79,7 +79,21 @@ class Node { // to have a different spec for a devDep than production dep. this[_loadDepType](this.package.optionalDependencies, 'optional') this[_loadDepType](this.package.dependencies, 'prod') - this[_loadDepType](this.package.peerDependencies, 'peer') + + const pd = this.package.peerDependencies + if (pd && typeof pd === 'object') { + const pm = this.package.peerDependenciesMeta || {} + const peerDependencies = {} + const peerOptional = {} + for (const [name, dep] of Object.entries(pd)) { + if (pm[name] && pm[name].optional) + peerOptional[name] = dep + else + peerDependencies[name] = dep + } + this[_loadDepType](peerDependencies, 'peer') + this[_loadDepType](peerOptional, 'peerOptional') + } // Linked targets that are disconnected from the tree are tops, // but don't have a 'path' field, only a 'realpath', because we diff --git a/tap-snapshots/test-node.js-TAP.test.js b/tap-snapshots/test-node.js-TAP.test.js index 7e243966e..52fe1b22f 100644 --- a/tap-snapshots/test-node.js-TAP.test.js +++ b/tap-snapshots/test-node.js-TAP.test.js @@ -191,7 +191,9 @@ Node { "edgesIn": Set { Edge {}, }, - "edgesOut": Map {}, + "edgesOut": Map { + "asdf" => Edge {}, + }, "errors": Array [], "extraneous": true, "inBundle": false, @@ -249,6 +251,14 @@ Node { "package": Object { "integrity": "newMeta", "name": "meta", + "peerDependencies": Object { + "asdf": "", + }, + "peerDependenciesMeta": Object { + "asdf": Object { + "optional": true, + }, + }, "resolved": "newMeta", "version": "2.3.4", }, @@ -2518,7 +2528,9 @@ Node { Edge {}, Edge {}, }, - "edgesOut": Map {}, + "edgesOut": Map { + "asdf" => Edge {}, + }, "errors": Array [], "extraneous": true, "inBundle": false, @@ -2572,6 +2584,14 @@ Node { "package": Object { "integrity": "newMeta", "name": "meta", + "peerDependencies": Object { + "asdf": "", + }, + "peerDependenciesMeta": Object { + "asdf": Object { + "optional": true, + }, + }, "resolved": "newMeta", "version": "2.3.4", }, @@ -3197,7 +3217,9 @@ Node { Edge {}, Edge {}, }, - "edgesOut": Map {}, + "edgesOut": Map { + "asdf" => Edge {}, + }, "errors": Array [], "extraneous": true, "inBundle": false, @@ -3251,6 +3273,14 @@ Node { "package": Object { "integrity": "newMeta", "name": "meta", + "peerDependencies": Object { + "asdf": "", + }, + "peerDependenciesMeta": Object { + "asdf": Object { + "optional": true, + }, + }, "resolved": "newMeta", "version": "2.3.4", }, @@ -3417,7 +3447,9 @@ Node { "edgesIn": Set { Edge {}, }, - "edgesOut": Map {}, + "edgesOut": Map { + "asdf" => Edge {}, + }, "errors": Array [], "extraneous": true, "inBundle": false, @@ -3429,6 +3461,14 @@ Node { "package": Object { "integrity": "newMeta", "name": "meta", + "peerDependencies": Object { + "asdf": "", + }, + "peerDependenciesMeta": Object { + "asdf": Object { + "optional": true, + }, + }, "resolved": "newMeta", "version": "2.3.4", }, @@ -4428,7 +4468,9 @@ Node { Edge {}, Edge {}, }, - "edgesOut": Map {}, + "edgesOut": Map { + "asdf" => Edge {}, + }, "errors": Array [], "extraneous": true, "inBundle": false, @@ -4440,6 +4482,14 @@ Node { "package": Object { "integrity": "newMeta", "name": "meta", + "peerDependencies": Object { + "asdf": "", + }, + "peerDependenciesMeta": Object { + "asdf": Object { + "optional": true, + }, + }, "resolved": "newMeta", "version": "2.3.4", }, @@ -4729,7 +4779,9 @@ Node { Edge {}, Edge {}, }, - "edgesOut": Map {}, + "edgesOut": Map { + "asdf" => Edge {}, + }, "errors": Array [], "extraneous": true, "inBundle": false, @@ -4741,6 +4793,14 @@ Node { "package": Object { "integrity": "newMeta", "name": "meta", + "peerDependencies": Object { + "asdf": "", + }, + "peerDependenciesMeta": Object { + "asdf": Object { + "optional": true, + }, + }, "resolved": "newMeta", "version": "2.3.4", }, diff --git a/test/edge.js b/test/edge.js index a55507871..82b2586c2 100644 --- a/test/edge.js +++ b/test/edge.js @@ -167,7 +167,7 @@ t.throws(() => new Edge({ from: top, type: 'not a valid type', name: 'yoinks', -}), new TypeError('invalid type: not a valid type\n(valid types are: prod, dev, optional, peer)')) +}), new TypeError('invalid type: not a valid type\n(valid types are: ')) t.throws(() => new Edge({ type: 'prod', diff --git a/test/node.js b/test/node.js index 11f3855b2..7cd88451f 100644 --- a/test/node.js +++ b/test/node.js @@ -124,6 +124,10 @@ t.test('testing with dep tree', t => { version: '2.3.4', resolved: 'newMeta', integrity: 'newMeta', + peerDependencies: { asdf: '' }, + peerDependenciesMeta: { + asdf: { optional: true }, + }, }, path: './node_modules/prod/node_modules/meta', realpath: '/home/user/projects/root/node_modules/prod/node_modules/meta',