@@ -6,6 +6,7 @@ const BaseCommand = require('../base-command.js')
66
77class QuerySelectorItem {
88 constructor ( node ) {
9+ // all enumerable properties from the target
910 Object . assign ( this , node . target . package )
1011
1112 // append extra info
@@ -19,21 +20,10 @@ class QuerySelectorItem {
1920 }
2021}
2122
22- // retrieves a normalized inventory
23- const convertInventoryItemsToResponses = inventory => {
24- const responses = [ ]
25- const responsesSeen = new Set ( )
26- for ( const node of inventory ) {
27- if ( ! responsesSeen . has ( node . target . realpath ) ) {
28- const item = new QuerySelectorItem ( node )
29- responses . push ( item )
30- responsesSeen . add ( item . path )
31- }
32- }
33- return responses
34- }
35-
3623class Query extends BaseCommand {
24+ #response = [ ] // response is the query response
25+ #seen = new Set ( ) // paths we've seen so we can keep response deduped
26+
3727 static description = 'Retrieve a filtered list of packages'
3828 static name = 'query'
3929 static usage = [ '<selector>' ]
@@ -47,7 +37,11 @@ class Query extends BaseCommand {
4737 'include-workspace-root' ,
4838 ]
4939
50- async exec ( args , workspaces ) {
40+ get parsedResponse ( ) {
41+ return JSON . stringify ( this . #response, null , 2 )
42+ }
43+
44+ async exec ( args ) {
5145 // one dir up from wherever node_modules lives
5246 const where = resolve ( this . npm . dir , '..' )
5347 const opts = {
@@ -57,31 +51,42 @@ class Query extends BaseCommand {
5751 const arb = new Arborist ( opts )
5852 const tree = await arb . loadActual ( opts )
5953 const items = await tree . querySelectorAll ( args [ 0 ] )
60- const res = convertInventoryItemsToResponses ( items )
54+ this . buildResponse ( items )
6155
62- this . npm . output ( JSON . stringify ( res , null , 2 ) )
56+ this . npm . output ( this . parsedResponse )
6357 }
6458
6559 async execWorkspaces ( args , filters ) {
6660 await this . setWorkspaces ( filters )
67- const result = new Set ( )
6861 const opts = {
6962 ...this . npm . flatOptions ,
7063 path : this . npm . prefix ,
7164 }
7265 const arb = new Arborist ( opts )
7366 const tree = await arb . loadActual ( opts )
7467 for ( const workspacePath of this . workspacePaths ) {
75- const [ workspace ] = await tree . querySelectorAll ( `.workspace:path(${ workspacePath } )` )
76- const res = await workspace . querySelectorAll ( args [ 0 ] )
77- const converted = convertInventoryItemsToResponses ( res )
78- for ( const item of converted ) {
79- result . add ( item )
68+ let items
69+ if ( workspacePath === tree . root . path ) {
70+ // include-workspace-root
71+ items = await tree . querySelectorAll ( args [ 0 ] )
72+ } else {
73+ const [ workspace ] = await tree . querySelectorAll ( `.workspace:path(${ workspacePath } )` )
74+ items = await workspace . querySelectorAll ( args [ 0 ] )
75+ }
76+ this . buildResponse ( items )
77+ }
78+ this . npm . output ( this . parsedResponse )
79+ }
80+
81+ // builds a normalized inventory
82+ buildResponse ( items ) {
83+ for ( const node of items ) {
84+ if ( ! this . #seen. has ( node . target . realpath ) ) {
85+ const item = new QuerySelectorItem ( node )
86+ this . #response. push ( item )
87+ this . #seen. add ( item . realpath )
8088 }
8189 }
82- // when running in workspaces names, make sure to key by workspace
83- // name the results of each value retrieved in each ws
84- this . npm . output ( JSON . stringify ( [ ...result ] , null , 2 ) )
8590 }
8691}
8792
0 commit comments