1
1
const proggy = require ( 'proggy' )
2
- const { log, output } = require ( 'proc-log' )
2
+ const { log, output, META } = require ( 'proc-log' )
3
3
const { explain } = require ( './explain-eresolve.js' )
4
4
const { formatWithOptions } = require ( './format' )
5
5
@@ -32,17 +32,6 @@ const COLOR_PALETTE = ({ chalk: c }) => ({
32
32
silly : c . blue . dim ,
33
33
} )
34
34
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
-
46
35
const LEVEL_OPTIONS = {
47
36
silent : {
48
37
index : 0 ,
@@ -76,7 +65,7 @@ const LEVEL_OPTIONS = {
76
65
77
66
const LEVEL_METHODS = {
78
67
...LEVEL_OPTIONS ,
79
- [ LOG_LEVELS . timing ] : {
68
+ [ log . KEYS . timing ] : {
80
69
show : ( { timing, index } ) => ! ! timing && index !== 0 ,
81
70
} ,
82
71
}
@@ -102,11 +91,13 @@ const setBlocking = (stream) => {
102
91
return stream
103
92
}
104
93
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 ( )
108
99
}
109
- return stringOrLevelObject
100
+ return handler ( level , meta , ... args )
110
101
}
111
102
112
103
class Display {
@@ -136,6 +127,7 @@ class Display {
136
127
#timing
137
128
#json
138
129
#heading
130
+ #silent
139
131
140
132
// display streams
141
133
#stdout
@@ -205,19 +197,11 @@ class Display {
205
197
this . #timing = timing
206
198
this . #json = json
207
199
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
214
201
215
202
// Emit resume event on the logs which will flush output
216
203
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 ( )
221
205
this . #startProgress( { progress, unicode } )
222
206
}
223
207
@@ -236,107 +220,98 @@ class Display {
236
220
237
221
// Arrow function assigned to a private class field so it can be passed
238
222
// 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 ) {
241
225
this . #logState. buffering = false
242
226
this . #logState. buffer . forEach ( ( item ) => this . #tryWriteLog( ...item ) )
243
227
this . #logState. buffer . length = 0
244
228
return
245
229
}
246
230
247
- if ( args [ 0 ] === LOG_LEVELS . pause ) {
231
+ if ( level === log . KEYS . pause ) {
248
232
this . #logState. buffering = true
249
233
return
250
234
}
251
235
252
236
if ( this . #logState. buffering ) {
253
- this . #logState. buffer . push ( args )
237
+ this . #logState. buffer . push ( [ level , meta , ... args ] )
254
238
return
255
239
}
256
240
257
- this . #tryWriteLog( ...args )
258
- }
241
+ this . #tryWriteLog( level , meta , ...args )
242
+ } )
259
243
260
244
// Arrow function assigned to a private class field so it can be passed
261
245
// 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 ) {
264
248
this . #outputState. buffering = false
265
- if ( args [ 1 ] && this . #json) {
249
+
250
+ if ( meta . jsonError && this . #json) {
266
251
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 ] ) )
269
255
}
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
+ )
271
261
} else {
272
262
this . #outputState. buffer . forEach ( ( item ) => this . #writeOutput( ...item ) )
273
263
}
264
+
274
265
this . #outputState. buffer . length = 0
275
266
return
276
267
}
277
268
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 ] )
280
271
return
281
272
}
282
273
283
274
if ( this . #outputState. buffering ) {
284
- this . #outputState. buffer . push ( args )
275
+ this . #outputState. buffer . push ( [ level , meta , ... args ] )
285
276
return
286
277
}
287
278
288
- this . #writeOutput( ...args )
289
- }
279
+ this . #writeOutput( level , meta , ...args )
280
+ } )
290
281
291
282
// OUTPUT
292
283
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 ) {
297
286
this . #stdoutWrite( { } , ...args )
298
287
return
299
288
}
300
289
301
- if ( level === OUTPUT_LEVELS . error ) {
290
+ if ( level === output . KEYS . error ) {
302
291
this . #stderrWrite( { } , ...args )
303
292
}
304
293
}
305
294
306
- // TODO: move this to proc-log and remove this public method
307
- flushOutput ( jsonError ) {
308
- this . #outputHandler( OUTPUT_LEVELS . flush , jsonError )
309
- }
310
-
311
295
// LOGS
312
296
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 ) {
323
298
try {
324
299
// Also (and this is a really inexcusable kludge), we patch the
325
300
// log.warn() method so that when we see a peerDep override
326
301
// explanation from Arborist, we can replace the object with a
327
302
// highly abbreviated explanation of what's being overridden.
328
303
// 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 ) )
333
308
return
334
309
}
335
- this . #writeLog( ...args )
310
+ this . #writeLog( level , meta , ...args )
336
311
} catch ( ex ) {
337
312
try {
338
313
// 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 )
340
315
} catch ( ex2 ) {
341
316
// This happens if the object has an inspect method that crashes so just console.error
342
317
// with the errors but don't do anything else that might error again.
@@ -346,11 +321,10 @@ class Display {
346
321
}
347
322
}
348
323
349
- #writeLog ( ...args ) {
350
- const { level, force = false } = getLevel ( args . shift ( ) )
351
-
324
+ #writeLog ( level , meta , ...args ) {
352
325
const levelOpts = LEVEL_METHODS [ level ]
353
326
const show = levelOpts . show ?? ( ( { index } ) => levelOpts . index <= index )
327
+ const force = meta . force && ! this . #silent
354
328
355
329
if ( force || show ( { index : this . #levelIndex, timing : this . #timing } ) ) {
356
330
// this mutates the array so we can pass args directly to format later
@@ -369,7 +343,7 @@ class Display {
369
343
// PROGRESS
370
344
371
345
#startProgress ( { progress, unicode } ) {
372
- if ( ! progress ) {
346
+ if ( ! progress || this . #silent ) {
373
347
return
374
348
}
375
349
this . #progress = proggy . createClient ( { normalize : true } )
0 commit comments