11const proggy = require ( 'proggy' )
2- const { log, output } = require ( 'proc-log' )
2+ const { log, output, META } = require ( 'proc-log' )
33const { explain } = require ( './explain-eresolve.js' )
44const { formatWithOptions } = require ( './format' )
55
@@ -32,17 +32,6 @@ const COLOR_PALETTE = ({ chalk: c }) => ({
3232 silly : c . blue . dim ,
3333} )
3434
35- const LOG_LEVELS = log . LEVELS . reduce ( ( acc , key ) => {
36- acc [ key ] = key
37- return acc
38- } , { } )
39-
40- // TODO: move flush to proc-log
41- const OUTPUT_LEVELS = [ 'flush' , ...output . LEVELS ] . reduce ( ( acc , key ) => {
42- acc [ key ] = key
43- return acc
44- } , { } )
45-
4635const LEVEL_OPTIONS = {
4736 silent : {
4837 index : 0 ,
@@ -76,7 +65,7 @@ const LEVEL_OPTIONS = {
7665
7766const LEVEL_METHODS = {
7867 ...LEVEL_OPTIONS ,
79- [ LOG_LEVELS . timing ] : {
68+ [ log . KEYS . timing ] : {
8069 show : ( { timing, index } ) => ! ! timing && index !== 0 ,
8170 } ,
8271}
@@ -102,11 +91,13 @@ const setBlocking = (stream) => {
10291 return stream
10392}
10493
105- const getLevel = ( stringOrLevelObject ) => {
106- if ( typeof stringOrLevelObject === 'string' ) {
107- return { level : stringOrLevelObject }
94+ const withMeta = ( handler ) => ( level , ...args ) => {
95+ let meta = { }
96+ const last = args . at ( - 1 )
97+ if ( last && typeof last === 'object' && Object . hasOwn ( last , META ) ) {
98+ meta = args . pop ( )
10899 }
109- return stringOrLevelObject
100+ return handler ( level , meta , ... args )
110101}
111102
112103class Display {
@@ -136,6 +127,7 @@ class Display {
136127 #timing
137128 #json
138129 #heading
130+ #silent
139131
140132 // display streams
141133 #stdout
@@ -205,19 +197,11 @@ class Display {
205197 this . #timing = timing
206198 this . #json = json
207199 this . #heading = heading
208-
209- // In silent mode we remove all the handlers
210- if ( this . #levelIndex <= 0 ) {
211- this . off ( )
212- return
213- }
200+ this . #silent = this . #levelIndex <= 0
214201
215202 // Emit resume event on the logs which will flush output
216203 log . resume ( )
217-
218- // TODO: this should be a proc-log method `proc-log.output.flush`?
219- this . #outputHandler( OUTPUT_LEVELS . flush )
220-
204+ output . flush ( )
221205 this . #startProgress( { progress, unicode } )
222206 }
223207
@@ -236,107 +220,98 @@ class Display {
236220
237221 // Arrow function assigned to a private class field so it can be passed
238222 // directly as a listener and still reference "this"
239- #logHandler = ( ...args ) => {
240- if ( args [ 0 ] === LOG_LEVELS . resume ) {
223+ #logHandler = withMeta ( ( level , meta , ...args ) => {
224+ if ( level === log . KEYS . resume ) {
241225 this . #logState. buffering = false
242226 this . #logState. buffer . forEach ( ( item ) => this . #tryWriteLog( ...item ) )
243227 this . #logState. buffer . length = 0
244228 return
245229 }
246230
247- if ( args [ 0 ] === LOG_LEVELS . pause ) {
231+ if ( level === log . KEYS . pause ) {
248232 this . #logState. buffering = true
249233 return
250234 }
251235
252236 if ( this . #logState. buffering ) {
253- this . #logState. buffer . push ( args )
237+ this . #logState. buffer . push ( [ level , meta , ... args ] )
254238 return
255239 }
256240
257- this . #tryWriteLog( ...args )
258- }
241+ this . #tryWriteLog( level , meta , ...args )
242+ } )
259243
260244 // Arrow function assigned to a private class field so it can be passed
261245 // directly as a listener and still reference "this"
262- #outputHandler = ( ...args ) => {
263- if ( args [ 0 ] === OUTPUT_LEVELS . flush ) {
246+ #outputHandler = withMeta ( ( level , meta , ...args ) => {
247+ if ( level === output . KEYS . flush ) {
264248 this . #outputState. buffering = false
265- if ( args [ 1 ] && this . #json) {
249+
250+ if ( meta . jsonError && this . #json) {
266251 const json = { }
267- for ( const [ , item ] of this . #outputState. buffer ) {
268- Object . assign ( json , tryJsonParse ( item ) )
252+ for ( const item of this . #outputState. buffer ) {
253+ // index 2 skips the level and meta
254+ Object . assign ( json , tryJsonParse ( item [ 2 ] ) )
269255 }
270- this . #writeOutput( 'standard' , JSON . stringify ( { ...json , ...args [ 1 ] } , null , 2 ) )
256+ this . #writeOutput(
257+ output . KEYS . standard ,
258+ meta ,
259+ JSON . stringify ( { ...json , error : meta . jsonError } , null , 2 )
260+ )
271261 } else {
272262 this . #outputState. buffer . forEach ( ( item ) => this . #writeOutput( ...item ) )
273263 }
264+
274265 this . #outputState. buffer . length = 0
275266 return
276267 }
277268
278- if ( args [ 0 ] === OUTPUT_LEVELS . buffer ) {
279- this . #outputState. buffer . push ( [ ' standard' , ...args . slice ( 1 ) ] )
269+ if ( level === output . KEYS . buffer ) {
270+ this . #outputState. buffer . push ( [ output . KEYS . standard , meta , ...args ] )
280271 return
281272 }
282273
283274 if ( this . #outputState. buffering ) {
284- this . #outputState. buffer . push ( args )
275+ this . #outputState. buffer . push ( [ level , meta , ... args ] )
285276 return
286277 }
287278
288- this . #writeOutput( ...args )
289- }
279+ this . #writeOutput( level , meta , ...args )
280+ } )
290281
291282 // OUTPUT
292283
293- #writeOutput ( ...args ) {
294- const { level } = getLevel ( args . shift ( ) )
295-
296- if ( level === OUTPUT_LEVELS . standard ) {
284+ #writeOutput ( level , meta , ...args ) {
285+ if ( level === output . KEYS . standard ) {
297286 this . #stdoutWrite( { } , ...args )
298287 return
299288 }
300289
301- if ( level === OUTPUT_LEVELS . error ) {
290+ if ( level === output . KEYS . error ) {
302291 this . #stderrWrite( { } , ...args )
303292 }
304293 }
305294
306- // TODO: move this to proc-log and remove this public method
307- flushOutput ( jsonError ) {
308- this . #outputHandler( OUTPUT_LEVELS . flush , jsonError )
309- }
310-
311295 // LOGS
312296
313- // TODO: make proc-log able to send signal data like `force`
314- // when that happens, remove this public method
315- forceLog ( level , ...args ) {
316- // This will show the log regardless of the current loglevel except when silent
317- if ( this . #levelIndex !== 0 ) {
318- this . #logHandler( { level, force : true } , ...args )
319- }
320- }
321-
322- #tryWriteLog ( ...args ) {
297+ #tryWriteLog ( level , meta , ...args ) {
323298 try {
324299 // Also (and this is a really inexcusable kludge), we patch the
325300 // log.warn() method so that when we see a peerDep override
326301 // explanation from Arborist, we can replace the object with a
327302 // highly abbreviated explanation of what's being overridden.
328303 // TODO: this could probably be moved to arborist now that display is refactored
329- const [ level , heading , message , expl ] = args
330- if ( level === LOG_LEVELS . warn && heading === 'ERESOLVE' && expl && typeof expl === 'object' ) {
331- this . #writeLog( level , heading , message )
332- this . #writeLog( level , '' , explain ( expl , this . #stderrChalk, 2 ) )
304+ const [ heading , message , expl ] = args
305+ if ( level === log . KEYS . warn && heading === 'ERESOLVE' && expl && typeof expl === 'object' ) {
306+ this . #writeLog( level , meta , heading , message )
307+ this . #writeLog( level , meta , '' , explain ( expl , this . #stderrChalk, 2 ) )
333308 return
334309 }
335- this . #writeLog( ...args )
310+ this . #writeLog( level , meta , ...args )
336311 } catch ( ex ) {
337312 try {
338313 // if it crashed once, it might again!
339- this . #writeLog( LOG_LEVELS . verbose , null , `attempt to log crashed` , ...args , ex )
314+ this . #writeLog( log . KEYS . verbose , meta , '' , `attempt to log crashed` , ...args , ex )
340315 } catch ( ex2 ) {
341316 // This happens if the object has an inspect method that crashes so just console.error
342317 // with the errors but don't do anything else that might error again.
@@ -346,11 +321,10 @@ class Display {
346321 }
347322 }
348323
349- #writeLog ( ...args ) {
350- const { level, force = false } = getLevel ( args . shift ( ) )
351-
324+ #writeLog ( level , meta , ...args ) {
352325 const levelOpts = LEVEL_METHODS [ level ]
353326 const show = levelOpts . show ?? ( ( { index } ) => levelOpts . index <= index )
327+ const force = meta . force && ! this . #silent
354328
355329 if ( force || show ( { index : this . #levelIndex, timing : this . #timing } ) ) {
356330 // this mutates the array so we can pass args directly to format later
@@ -369,7 +343,7 @@ class Display {
369343 // PROGRESS
370344
371345 #startProgress ( { progress, unicode } ) {
372- if ( ! progress ) {
346+ if ( ! progress || this . #silent ) {
373347 return
374348 }
375349 this . #progress = proggy . createClient ( { normalize : true } )
0 commit comments