@@ -11,6 +11,7 @@ const { inspect } = require('util')
1111const { packument } = require ( 'pacote' )
1212const Queryable = require ( '../utils/queryable.js' )
1313const BaseCommand = require ( '../base-cmd.js' )
14+ const { getError, jsonError, outputError } = require ( '../utils/error-message.js' )
1415
1516const readJson = async file => jsonParse ( await readFile ( file , 'utf8' ) )
1617
@@ -77,11 +78,7 @@ class View extends BaseCommand {
7778 }
7879
7980 async exec ( args ) {
80- if ( ! args . length ) {
81- args = [ '.' ]
82- }
83- let pkg = args . shift ( )
84- const local = / ^ \. @ / . test ( pkg ) || pkg === '.'
81+ let { pkg, local, rest } = parseArgs ( args )
8582
8683 if ( local ) {
8784 if ( this . npm . global ) {
@@ -96,91 +93,87 @@ class View extends BaseCommand {
9693 pkg = `${ manifest . name } ${ pkg . slice ( 1 ) } `
9794 }
9895
99- let wholePackument = false
100- if ( ! args . length ) {
101- args = [ '' ]
102- wholePackument = true
103- }
104- const [ pckmnt , data ] = await this . getData ( pkg , args )
105-
106- if ( ! this . npm . config . get ( 'json' ) && wholePackument ) {
107- // pretty view (entire packument)
108- data . map ( ( v ) => this . prettyView ( pckmnt , v [ Object . keys ( v ) [ 0 ] ] [ '' ] ) )
109- } else {
110- // JSON formatted output (JSON or specific attributes from packument)
111- let reducedData = data . reduce ( reducer , { } )
112- if ( wholePackument ) {
113- // No attributes
114- reducedData = cleanBlanks ( reducedData )
115- log . silly ( 'view' , reducedData )
116- }
117-
118- const msg = await this . jsonData ( reducedData , pckmnt . _id )
119- if ( msg !== '' ) {
120- output . standard ( msg )
121- }
122- }
96+ await this . #viewPackage( pkg , rest )
12397 }
12498
12599 async execWorkspaces ( args ) {
126- if ( ! args . length ) {
127- args = [ '.' ]
128- }
129-
130- const pkg = args . shift ( )
100+ const { pkg, local, rest } = parseArgs ( args )
131101
132- const local = / ^ \. @ / . test ( pkg ) || pkg === '.'
133102 if ( ! local ) {
134103 log . warn ( 'Ignoring workspaces for specified package(s)' )
135- return this . exec ( [ pkg , ...args ] )
104+ return this . exec ( [ pkg , ...rest ] )
136105 }
137- let wholePackument = false
138- if ( ! args . length ) {
139- wholePackument = true
140- args = [ '' ] // getData relies on this
141- }
142- const results = { }
106+
107+ const json = this . npm . config . get ( 'json' )
143108 await this . setWorkspaces ( )
144- for ( const name of this . workspaceNames ) {
145- const wsPkg = `${ name } ${ pkg . slice ( 1 ) } `
146- const [ pckmnt , data ] = await this . getData ( wsPkg , args )
147-
148- let reducedData = data . reduce ( reducer , { } )
149- if ( wholePackument ) {
150- // No attributes
151- reducedData = cleanBlanks ( reducedData )
152- log . silly ( 'view' , reducedData )
153- }
154109
155- if ( ! this . npm . config . get ( 'json' ) ) {
156- if ( wholePackument ) {
157- data . map ( ( v ) => this . prettyView ( pckmnt , v [ Object . keys ( v ) [ 0 ] ] [ '' ] ) )
110+ let hasError = false
111+ for ( const name of this . workspaceNames ) {
112+ try {
113+ await this . #viewPackage(
114+ `${ name } ${ pkg . slice ( 1 ) } ` ,
115+ rest ,
116+ { multiple : ! ! this . workspaceNames . length }
117+ )
118+ } catch ( e ) {
119+ hasError = true
120+ const err = getError ( e , { npm : this . npm , command : this } )
121+ if ( json ) {
122+ output . buffer ( { [ name ] : jsonError ( err , this . npm ) } )
158123 } else {
159- output . standard ( `${ name } :` )
160- const msg = await this . jsonData ( reducedData , pckmnt . _id )
161- if ( msg !== '' ) {
162- output . standard ( msg )
163- }
164- }
165- } else {
166- const msg = await this . jsonData ( reducedData , pckmnt . _id )
167- if ( msg !== '' ) {
168- results [ name ] = JSON . parse ( msg )
124+ outputError ( err )
169125 }
170126 }
171127 }
172- if ( Object . keys ( results ) . length > 0 ) {
173- output . standard ( JSON . stringify ( results , null , 2 ) )
128+
129+ if ( hasError ) {
130+ process . exitCode = 1
174131 }
175132 }
176133
177- async getData ( pkg , args ) {
178- const opts = {
179- ...this . npm . flatOptions ,
180- preferOnline : true ,
181- fullMetadata : true ,
134+ async #viewPackage ( name , args , { multiple = false } = { } ) {
135+ const wholePackument = ! args . length
136+ const json = this . npm . config . get ( 'json' )
137+
138+ // If we are viewing many packages output the name before doing
139+ // any async activity
140+ if ( ! json && ! wholePackument && multiple ) {
141+ output . standard ( `${ name } :` )
182142 }
183143
144+ const [ pckmnt , data , version ] = await this . #getData( name , wholePackument ? [ '' ] : args )
145+ if ( wholePackument ) {
146+ pckmnt . version = version
147+ }
148+
149+ // This already outputs to the terminal
150+ if ( ! json && wholePackument ) {
151+ // pretty view (entire packument)
152+ for ( const v of data ) {
153+ this . #prettyView( pckmnt , v [ Object . keys ( v ) [ 0 ] ] [ '' ] )
154+ }
155+ return
156+ }
157+
158+ // JSON formatted output (JSON or specific attributes from packument)
159+ let reducedData = data . reduce ( reducer , { } )
160+ if ( wholePackument ) {
161+ // No attributes
162+ reducedData = cleanBlanks ( reducedData )
163+ log . silly ( 'view' , reducedData )
164+ }
165+
166+ const msg = this . #packageOutput( reducedData , pckmnt . _id )
167+ if ( msg !== '' ) {
168+ if ( json && multiple ) {
169+ output . buffer ( { [ name ] : JSON . parse ( msg ) } )
170+ } else {
171+ output . standard ( msg )
172+ }
173+ }
174+ }
175+
176+ async #getData ( pkg , args = [ ] ) {
184177 const spec = npa ( pkg )
185178
186179 // get the data about this package
@@ -190,13 +183,17 @@ class View extends BaseCommand {
190183 version = spec . rawSpec
191184 }
192185
193- const pckmnt = await packument ( spec , opts )
186+ const pckmnt = await packument ( spec , {
187+ ...this . npm . flatOptions ,
188+ preferOnline : true ,
189+ fullMetadata : true ,
190+ } )
194191
195192 if ( pckmnt [ 'dist-tags' ] ?. [ version ] ) {
196193 version = pckmnt [ 'dist-tags' ] [ version ]
197194 }
198195
199- if ( pckmnt . time && pckmnt . time . unpublished ) {
196+ if ( pckmnt . time ? .unpublished ) {
200197 const u = pckmnt . time . unpublished
201198 const er = new Error ( `Unpublished on ${ u . time } ` )
202199 er . statusCode = 404
@@ -234,26 +231,18 @@ class View extends BaseCommand {
234231 } )
235232
236233 // No data has been pushed because no data is matching the specified version
237- if ( data . length === 0 && version !== 'latest' ) {
234+ if ( ! data . length && version !== 'latest' ) {
238235 const er = new Error ( `No match found for version ${ version } ` )
239236 er . statusCode = 404
240237 er . code = 'E404'
241238 er . pkgid = `${ pckmnt . _id } @${ version } `
242239 throw er
243240 }
244241
245- if (
246- ! this . npm . config . get ( 'json' ) &&
247- args . length === 1 &&
248- args [ 0 ] === ''
249- ) {
250- pckmnt . version = version
251- }
252-
253- return [ pckmnt , data ]
242+ return [ pckmnt , data , version ]
254243 }
255244
256- async jsonData ( data , name ) {
245+ #packageOutput ( data , name ) {
257246 const versions = Object . keys ( data )
258247 let msg = ''
259248 let msgJson = [ ]
@@ -313,7 +302,7 @@ class View extends BaseCommand {
313302 return msg . trim ( )
314303 }
315304
316- prettyView ( packu , manifest ) {
305+ # prettyView ( packu , manifest ) {
317306 // More modern, pretty printing of default view
318307 const unicode = this . npm . config . get ( 'unicode' )
319308 const chalk = this . npm . chalk
@@ -409,6 +398,20 @@ class View extends BaseCommand {
409398
410399module . exports = View
411400
401+ function parseArgs ( args ) {
402+ if ( ! args . length ) {
403+ args = [ '.' ]
404+ }
405+
406+ const pkg = args . shift ( )
407+
408+ return {
409+ pkg,
410+ local : / ^ \. @ / . test ( pkg ) || pkg === '.' ,
411+ rest : args ,
412+ }
413+ }
414+
412415function cleanBlanks ( obj ) {
413416 const clean = { }
414417 Object . keys ( obj ) . forEach ( ( version ) => {
0 commit comments