@@ -7,12 +7,13 @@ const fs = require('fs')
7
7
const jsonParse = require ( 'json-parse-even-better-errors' )
8
8
const log = require ( 'npmlog' )
9
9
const npa = require ( 'npm-package-arg' )
10
- const path = require ( 'path' )
10
+ const { resolve } = require ( 'path' )
11
11
const relativeDate = require ( 'tiny-relative-date' )
12
12
const semver = require ( 'semver' )
13
13
const style = require ( 'ansistyles' )
14
14
const { inspect, promisify } = require ( 'util' )
15
15
const { packument } = require ( 'pacote' )
16
+ const getWorkspaces = require ( './workspaces/get-workspaces.js' )
16
17
17
18
const readFile = promisify ( fs . readFile )
18
19
const readJson = async file => jsonParse ( await readFile ( file , 'utf8' ) )
@@ -24,6 +25,15 @@ class View extends BaseCommand {
24
25
return 'View registry info'
25
26
}
26
27
28
+ /* istanbul ignore next - see test/lib/load-all-commands.js */
29
+ static get params ( ) {
30
+ return [
31
+ 'json' ,
32
+ 'workspace' ,
33
+ 'workspaces' ,
34
+ ]
35
+ }
36
+
27
37
/* istanbul ignore next - see test/lib/load-all-commands.js */
28
38
static get name ( ) {
29
39
return 'view'
@@ -85,43 +95,120 @@ class View extends BaseCommand {
85
95
this . view ( args ) . then ( ( ) => cb ( ) ) . catch ( cb )
86
96
}
87
97
98
+ execWorkspaces ( args , filters , cb ) {
99
+ this . viewWorkspaces ( args , filters ) . then ( ( ) => cb ( ) ) . catch ( cb )
100
+ }
101
+
88
102
async view ( args ) {
89
103
if ( ! args . length )
90
104
args = [ '.' ]
105
+ let pkg = args . shift ( )
106
+ const local = / ^ \. @ / . test ( pkg ) || pkg === '.'
107
+
108
+ if ( local ) {
109
+ if ( this . npm . config . get ( 'global' ) )
110
+ throw new Error ( 'Cannot use view command in global mode.' )
111
+ const dir = this . npm . prefix
112
+ const manifest = await readJson ( resolve ( dir , 'package.json' ) )
113
+ if ( ! manifest . name )
114
+ throw new Error ( 'Invalid package.json, no "name" field' )
115
+ // put the version back if it existed
116
+ pkg = `${ manifest . name } ${ pkg . slice ( 1 ) } `
117
+ }
118
+ let wholePackument = false
119
+ if ( ! args . length ) {
120
+ args = [ '' ]
121
+ wholePackument = true
122
+ }
123
+ const [ pckmnt , data ] = await this . getData ( pkg , args )
124
+
125
+ if ( ! this . npm . config . get ( 'json' ) && wholePackument ) {
126
+ // pretty view (entire packument)
127
+ await Promise . all (
128
+ data . map ( ( v ) => this . prettyView ( pckmnt , v [ Object . keys ( v ) [ 0 ] ] [ '' ] ) )
129
+ )
130
+ } else {
131
+ // JSON formatted output (JSON or specific attributes from packument)
132
+ let reducedData = data . reduce ( reducer , { } )
133
+ if ( wholePackument ) {
134
+ // No attributes
135
+ reducedData = cleanBlanks ( reducedData )
136
+ log . silly ( 'view' , reducedData )
137
+ }
138
+ // disable the progress bar entirely, as we can't meaningfully update it if
139
+ // we may have partial lines printed.
140
+ log . disableProgress ( )
141
+
142
+ const msg = await this . jsonData ( reducedData , pckmnt . _id )
143
+ if ( msg !== '' )
144
+ console . log ( msg )
145
+ }
146
+ }
147
+
148
+ async viewWorkspaces ( args , filters ) {
149
+ if ( ! args . length ) {
150
+ args = [ '.' ]
151
+ }
152
+
153
+ let pkg = args . shift ( )
91
154
155
+ const local = / ^ \. @ / . test ( pkg ) || pkg === '.'
156
+ if ( ! local ) {
157
+ this . npm . log . warn ( 'Ignoring workspaces for remote package' )
158
+ return this . view ( [ pkg , ...args ] )
159
+ }
160
+
161
+ let wholePackument = false
162
+ if ( ! args . length ) {
163
+ wholePackument = true
164
+ args = [ '' ] //getData relies on this
165
+ }
166
+ const results = { }
167
+ const workspaces = await getWorkspaces ( filters , { path : this . npm . localPrefix } )
168
+ for ( const workspace of [ ...workspaces . entries ( ) ] ) {
169
+ const wsPkg = `${ workspace [ 0 ] } ${ pkg . slice ( 1 ) } `
170
+ const [ pckmnt , data ] = await this . getData ( wsPkg , args )
171
+
172
+ let reducedData = data . reduce ( reducer , { } )
173
+ if ( wholePackument ) {
174
+ // No attributes
175
+ reducedData = cleanBlanks ( reducedData )
176
+ log . silly ( 'view' , reducedData )
177
+ }
178
+
179
+ if ( ! this . npm . config . get ( 'json' ) ) {
180
+ if ( wholePackument ) {
181
+ data . map ( ( v ) => this . prettyView ( pckmnt , v [ Object . keys ( v ) [ 0 ] ] [ '' ] ) )
182
+ } else {
183
+ console . log ( workspace [ 0 ] )
184
+ const msg = await this . jsonData ( reducedData , pckmnt . _id )
185
+ if ( msg !== '' )
186
+ console . log ( msg )
187
+ }
188
+ } else {
189
+ const msg = await this . jsonData ( reducedData , pckmnt . _id )
190
+ if ( msg !== '' )
191
+ results [ workspace [ 0 ] ] = JSON . parse ( msg )
192
+ }
193
+ }
194
+ if ( Object . keys ( results ) . length > 0 ) {
195
+ console . log ( results )
196
+ }
197
+ }
198
+
199
+ async getData ( pkg , args ) {
92
200
const opts = {
93
201
...this . npm . flatOptions ,
94
202
preferOnline : true ,
95
203
fullMetadata : true ,
96
204
}
97
- const pkg = args . shift ( )
98
- let nv
99
- if ( / ^ [ . ] @ / . test ( pkg ) )
100
- nv = npa . resolve ( null , pkg . slice ( 2 ) )
101
- else
102
- nv = npa ( pkg )
103
205
104
- const name = nv . name
105
- const local = ( name === '.' || ! name )
106
-
107
- if ( this . npm . config . get ( 'global' ) && local )
108
- throw new Error ( 'Cannot use view command in global mode.' )
109
-
110
- if ( local ) {
111
- const dir = this . npm . prefix
112
- const manifest = await readJson ( path . resolve ( dir , 'package.json' ) )
113
- if ( ! manifest . name )
114
- throw new Error ( 'Invalid package.json, no "name" field' )
115
- const p = manifest . name
116
- nv = npa ( p )
117
- if ( pkg && ~ pkg . indexOf ( '@' ) )
118
- nv . rawSpec = pkg . split ( '@' ) [ pkg . indexOf ( '@' ) ]
119
- }
206
+ const spec = npa ( pkg )
120
207
121
208
// get the data about this package
122
- let version = nv . rawSpec || this . npm . config . get ( 'tag' )
209
+ let version = spec . rawSpec || this . npm . config . get ( 'tag' )
123
210
124
- const pckmnt = await packument ( nv , opts )
211
+ const pckmnt = await packument ( spec , opts )
125
212
126
213
if ( pckmnt [ 'dist-tags' ] && pckmnt [ 'dist-tags' ] [ version ] )
127
214
version = pckmnt [ 'dist-tags' ] [ version ]
@@ -135,11 +222,9 @@ class View extends BaseCommand {
135
222
throw er
136
223
}
137
224
138
- const results = [ ]
225
+ const data = [ ]
139
226
const versions = pckmnt . versions || { }
140
227
pckmnt . versions = Object . keys ( versions ) . sort ( semver . compareLoose )
141
- if ( ! args . length )
142
- args = [ '' ]
143
228
144
229
// remove readme unless we asked for it
145
230
if ( args . indexOf ( 'readme' ) === - 1 )
@@ -152,36 +237,22 @@ class View extends BaseCommand {
152
237
if ( args . indexOf ( 'readme' ) !== - 1 )
153
238
delete versions [ v ] . readme
154
239
155
- results . push ( showFields ( pckmnt , versions [ v ] , arg ) )
240
+ data . push ( showFields ( pckmnt , versions [ v ] , arg ) )
156
241
} )
157
242
}
158
243
} )
159
- let retval = results . reduce ( reducer , { } )
160
-
161
- if ( args . length === 1 && args [ 0 ] === '' ) {
162
- retval = cleanBlanks ( retval )
163
- log . silly ( 'view' , retval )
164
- }
165
244
166
245
if (
167
246
! this . npm . config . get ( 'json' ) &&
168
247
args . length === 1 &&
169
248
args [ 0 ] === ''
170
- ) {
171
- // general view
249
+ )
172
250
pckmnt . version = version
173
- await Promise . all (
174
- results . map ( ( v ) => this . prettyView ( pckmnt , v [ Object . keys ( v ) [ 0 ] ] [ '' ] ) )
175
- )
176
- return retval
177
- } else {
178
- // view by field name
179
- await this . printData ( retval , pckmnt . _id )
180
- return retval
181
- }
251
+
252
+ return [ pckmnt , data ]
182
253
}
183
254
184
- async printData ( data , name ) {
255
+ async jsonData ( data , name ) {
185
256
const versions = Object . keys ( data )
186
257
let msg = ''
187
258
let msgJson = [ ]
@@ -233,13 +304,7 @@ class View extends BaseCommand {
233
304
msg = JSON . stringify ( msgJson , null , 2 ) + '\n'
234
305
}
235
306
236
- // disable the progress bar entirely, as we can't meaningfully update it if
237
- // we may have partial lines printed.
238
- log . disableProgress ( )
239
-
240
- // only log if there is something to log
241
- if ( msg !== '' )
242
- console . log ( msg . trim ( ) )
307
+ return msg . trim ( )
243
308
}
244
309
245
310
async prettyView ( packument , manifest ) {
@@ -375,17 +440,18 @@ function cleanBlanks (obj) {
375
440
return clean
376
441
}
377
442
378
- function reducer ( l , r ) {
379
- if ( r ) {
380
- Object . keys ( r ) . forEach ( ( v ) => {
381
- l [ v ] = l [ v ] || { }
382
- Object . keys ( r [ v ] ) . forEach ( ( t ) => {
383
- l [ v ] [ t ] = r [ v ] [ t ]
443
+ // takes an array of objects and merges them into one object
444
+ function reducer ( acc , cur ) {
445
+ if ( cur ) {
446
+ Object . keys ( cur ) . forEach ( ( v ) => {
447
+ acc [ v ] = acc [ v ] || { }
448
+ Object . keys ( cur [ v ] ) . forEach ( ( t ) => {
449
+ acc [ v ] [ t ] = cur [ v ] [ t ]
384
450
} )
385
451
} )
386
452
}
387
453
388
- return l
454
+ return acc
389
455
}
390
456
391
457
// return whatever was printed
0 commit comments