diff --git a/workspaces/arborist/lib/query-selector-all.js b/workspaces/arborist/lib/query-selector-all.js index b20b0ebee6936..96c52144060b8 100644 --- a/workspaces/arborist/lib/query-selector-all.js +++ b/workspaces/arborist/lib/query-selector-all.js @@ -695,7 +695,11 @@ const depTypes = { // the compare nodes array const hasParent = (node, compareNodes) => { // All it takes is one so we loop and return on the first hit - for (const compareNode of compareNodes) { + for (let compareNode of compareNodes) { + if (compareNode.isLink) { + compareNode = compareNode.target + } + // follows logical parent for link anscestors if (node.isTop && (node.resolveParent === compareNode)) { return true diff --git a/workspaces/arborist/test/query-selector-all.js b/workspaces/arborist/test/query-selector-all.js index 10a670a31f1fb..08d62034479ea 100644 --- a/workspaces/arborist/test/query-selector-all.js +++ b/workspaces/arborist/test/query-selector-all.js @@ -28,6 +28,8 @@ t.test('query-selector-all', async t => { │ └── bar@2.0.0 (production dep of b, deduped) ├─┬ bar@2.0.0 (production dep of query-selector-all-tests) │ └── moo@3.0.0 (production dep of bar) + |-┬ c@1.0.0 -> ./c (workspace) + │ └── b@1.0.0 (production dep of c, deduped) ├─┬ foo@2.2.2 (dev dep of query-selector-all-tests) │ ├─┬ bar@1.4.0 (production dep of foo, deduped) │ │ └── dasher@2.0.0 (overridden peer dep of bar) @@ -65,6 +67,9 @@ t.test('query-selector-all', async t => { '1.0.0': undefined, '1.0.1': yesterday, }, + c: { + '1.0.0': today, + }, 'dash-separated-pkg': { '1.0.0': dayBeforeYesterday, '2.0.0': yesterday, @@ -173,6 +178,7 @@ t.test('query-selector-all', async t => { }, }), }, + c: t.fixture('symlink', '../c'), foo: { node_modules: { bar: { @@ -275,10 +281,19 @@ t.test('query-selector-all', async t => { bar: '^2.0.0', }, }) }, + c: { + 'package.json': JSON.stringify({ + name: 'c', + version: '1.0.0', + dependencies: { + b: '^1.0.0', + }, + }), + }, 'package.json': JSON.stringify({ name: 'query-selector-all-tests', version: '1.0.0', - workspaces: ['a', 'b'], + workspaces: ['a', 'b', 'c'], dependencies: { a: '^1.0.0', abbrev: '^1.1.1', @@ -387,6 +402,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', '@npmcli/abbrev@2.0.0-beta.45', 'abbrev@1.1.1', 'bar@2.0.0', @@ -404,6 +420,7 @@ t.test('query-selector-all', async t => { ['* > *', [ 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', 'abbrev@1.1.1', 'bar@2.0.0', 'baz@1.0.0', @@ -425,6 +442,7 @@ t.test('query-selector-all', async t => { [':root > *', [ 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', 'abbrev@1.1.1', 'bar@2.0.0', 'foo@2.2.2', @@ -432,11 +450,11 @@ t.test('query-selector-all', async t => { 'moo@3.0.0', 'recur@1.0.0', ]], - [':root > .workspace', ['a@1.0.0', 'b@1.0.0']], - [':root > *.workspace', ['a@1.0.0', 'b@1.0.0']], + [':root > .workspace', ['a@1.0.0', 'b@1.0.0', 'c@1.0.0']], + [':root > *.workspace', ['a@1.0.0', 'b@1.0.0', 'c@1.0.0']], [':root > .workspace[name=a]', ['a@1.0.0']], [':root > [name=bar]', ['bar@2.0.0']], - [':root > .workspace[version=1.0.0]', ['a@1.0.0', 'b@1.0.0']], + [':root > .workspace[version=1.0.0]', ['a@1.0.0', 'b@1.0.0', 'c@1.0.0']], [':root > .workspace[name=a][version=1.0.0]', ['a@1.0.0']], [':root > :root', []], ['* > :root', []], @@ -452,6 +470,7 @@ t.test('query-selector-all', async t => { 'a@1.0.0', 'abbrev@1.1.1', 'b@1.0.0', + 'c@1.0.0', 'dash-separated-pkg@1.0.0', 'dasher@2.0.0', 'lorem@1.0.0', @@ -461,12 +480,12 @@ t.test('query-selector-all', async t => { 'a@1.0.0', 'abbrev@1.1.1', 'b@1.0.0', + 'c@1.0.0', 'moo@3.0.0', ]], [':extraneous', ['@npmcli/abbrev@2.0.0-beta.45']], [':invalid', ['lorem@1.0.0']], - [':link', ['a@1.0.0', 'b@1.0.0']], - [':link', ['a@1.0.0', 'b@1.0.0']], + [':link', ['a@1.0.0', 'b@1.0.0', 'c@1.0.0']], [':deduped', [ 'bar@2.0.0', 'moo@3.0.0', @@ -481,6 +500,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', '@npmcli/abbrev@2.0.0-beta.45', 'abbrev@1.1.1', 'bar@2.0.0', @@ -494,8 +514,8 @@ t.test('query-selector-all', async t => { 'recur@1.0.0', 'sive@1.0.0', ]], - [':root > .workspace:not(#b)', ['a@1.0.0']], - [':root > .workspace > *:not(#bar)', ['a@1.0.0', 'baz@1.0.0']], + [':root > .workspace:not(#b)', ['a@1.0.0', 'c@1.0.0']], + [':root > .workspace > *:not(#bar)', ['a@1.0.0', 'b@1.0.0', 'baz@1.0.0']], ['.bundled ~ :not(.workspace)', [ 'bar@2.0.0', 'foo@2.2.2', @@ -503,10 +523,11 @@ t.test('query-selector-all', async t => { 'moo@3.0.0', 'recur@1.0.0', ]], - ['*:root > *:empty:not(*[name^=a], #b)', ['moo@3.0.0']], + ['*:root > *:empty:not(*[name^=a], #b, #c)', ['moo@3.0.0']], [':not(:not(:link))', [ 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', ]], // has pseudo @@ -514,7 +535,7 @@ t.test('query-selector-all', async t => { ['*:has(* > #bar:semver(1.4.0))', ['foo@2.2.2']], ['*:has(> #bar:semver(1.4.0))', ['foo@2.2.2']], ['.workspace:has(> * > #lorem)', ['a@1.0.0']], - ['.workspace:has(* #lorem, ~ #b)', ['a@1.0.0', 'b@1.0.0']], + ['.workspace:has(* #lorem, ~ #b)', ['a@1.0.0', 'b@1.0.0', 'c@1.0.0']], // is pseudo [':is(#a, #b) > *', ['a@1.0.0', 'bar@2.0.0', 'baz@1.0.0']], @@ -522,6 +543,7 @@ t.test('query-selector-all', async t => { // result here [':root > *:is(.prod:not(:empty), .dev > [name=bar]) > *', [ 'a@1.0.0', + 'b@1.0.0', 'bar@2.0.0', 'baz@1.0.0', 'dasher@2.0.0', @@ -538,6 +560,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', '@npmcli/abbrev@2.0.0-beta.45', 'abbrev@1.1.1', 'bar@2.0.0', @@ -557,6 +580,7 @@ t.test('query-selector-all', async t => { [':type(range)', [ 'a@1.0.0', 'abbrev@1.1.1', + 'b@1.0.0', 'bar@2.0.0', 'baz@1.0.0', 'dash-separated-pkg@1.0.0', @@ -584,11 +608,12 @@ t.test('query-selector-all', async t => { [':path(./node_modules/bar)', ['bar@2.0.0']], [':path(node_modules/foo/node_modules/bar)', ['bar@1.4.0']], [':path(**/bar)', ['bar@2.0.0', 'bar@1.4.0']], - [':path(*)', ['a@1.0.0', 'b@1.0.0']], + [':path(*)', ['a@1.0.0', 'b@1.0.0', 'c@1.0.0']], [':path()', [ 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', '@npmcli/abbrev@2.0.0-beta.45', 'abbrev@1.1.1', 'bar@2.0.0', @@ -609,6 +634,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', '@npmcli/abbrev@2.0.0-beta.45', 'abbrev@1.1.1', 'bar@2.0.0', @@ -627,6 +653,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', 'abbrev@1.1.1', 'bar@2.0.0', 'baz@1.0.0', @@ -690,6 +717,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', 'baz@1.0.0', 'dash-separated-pkg@1.0.0', 'ipsum@npm:sit@1.0.0', @@ -702,6 +730,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', 'abbrev@1.1.1', 'baz@1.0.0', 'dash-separated-pkg@1.0.0', @@ -720,6 +749,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', 'baz@1.0.0', 'dash-separated-pkg@1.0.0', 'ipsum@npm:sit@1.0.0', @@ -731,6 +761,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', 'baz@1.0.0', 'dash-separated-pkg@1.0.0', 'ipsum@npm:sit@1.0.0', @@ -832,6 +863,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', '@npmcli/abbrev@2.0.0-beta.45', 'abbrev@1.1.1', 'bar@2.0.0', @@ -882,6 +914,7 @@ t.test('query-selector-all', async t => { 'query-selector-all-tests@1.0.0', 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', 'abbrev@1.1.1', 'bar@2.0.0', 'baz@1.0.0', @@ -889,8 +922,10 @@ t.test('query-selector-all', async t => { 'lorem@1.0.0', 'moo@3.0.0', ]], - ['.workspace', ['a@1.0.0', 'b@1.0.0']], - ['.workspace > *', ['a@1.0.0', 'bar@2.0.0', 'baz@1.0.0']], + ['.workspace', ['a@1.0.0', 'b@1.0.0', 'c@1.0.0']], + ['.workspace > *', ['a@1.0.0', 'b@1.0.0', 'bar@2.0.0', 'baz@1.0.0']], + ['.workspace .workspace', ['a@1.0.0', 'b@1.0.0']], + ['.workspace .workspace .workspace', ['a@1.0.0']], ['.workspace ~ *', [ 'abbrev@1.1.1', 'bar@2.0.0', @@ -911,9 +946,11 @@ t.test('query-selector-all', async t => { 'sive@1.0.0', ]], ['.dev *', [ + 'baz@1.0.0', 'dash-separated-pkg@1.0.0', 'dasher@2.0.0', 'bar@1.4.0', + 'lorem@1.0.0', 'recur@1.0.0', 'sive@1.0.0', ]], @@ -923,6 +960,7 @@ t.test('query-selector-all', async t => { ['.bundled ~ *', [ 'a@1.0.0', 'b@1.0.0', + 'c@1.0.0', 'bar@2.0.0', 'foo@2.2.2', 'ipsum@npm:sit@1.0.0',