1
1
const { Minipass } = require ( 'minipass' )
2
2
const columnify = require ( 'columnify' )
3
- const ansiTrim = require ( '../utils/ansi-trim.js' )
4
3
5
4
// This module consumes package data in the following format:
6
5
//
@@ -16,8 +15,8 @@ const ansiTrim = require('../utils/ansi-trim.js')
16
15
// The returned stream will format this package data
17
16
// into a byte stream of formatted, displayable output.
18
17
19
- module . exports = ( opts ) => {
20
- return opts . json ? new JSONOutputStream ( ) : new TextOutputStream ( opts )
18
+ module . exports = async ( opts , clean ) => {
19
+ return opts . json ? new JSONOutputStream ( ) : new TextOutputStream ( opts , clean )
21
20
}
22
21
23
22
class JSONOutputStream extends Minipass {
@@ -41,121 +40,96 @@ class JSONOutputStream extends Minipass {
41
40
}
42
41
43
42
class TextOutputStream extends Minipass {
44
- constructor ( opts ) {
43
+ #clean
44
+ #opts
45
+ #line = 0
46
+
47
+ constructor ( opts , clean ) {
45
48
super ( )
46
- this . _opts = opts
47
- this . _line = 0
49
+ this . #clean = clean
50
+ this . #opts = opts
48
51
}
49
52
50
53
write ( pkg ) {
51
- return super . write ( prettify ( pkg , ++ this . _line , this . _opts ) )
52
- }
53
- }
54
-
55
- function prettify ( data , num , opts ) {
56
- var truncate = ! opts . long
57
-
58
- var pkg = normalizePackage ( data , opts )
59
-
60
- var columns = [ 'name' , 'description' , 'author' , 'date' , 'version' , 'keywords' ]
61
-
62
- if ( opts . parseable ) {
63
- return columns . map ( function ( col ) {
64
- return pkg [ col ] && ( '' + pkg [ col ] ) . replace ( / \t / g, ' ' )
65
- } ) . join ( '\t' )
54
+ return super . write ( this . #prettify( pkg ) )
66
55
}
67
56
68
- // stdout in tap is never a tty
69
- /* istanbul ignore next */
70
- const maxWidth = process . stdout . isTTY ? process . stdout . getWindowSize ( ) [ 0 ] : Infinity
71
- let output = columnify (
72
- [ pkg ] ,
73
- {
74
- include : columns ,
75
- showHeaders : num <= 1 ,
76
- columnSplitter : ' | ' ,
77
- truncate : truncate ,
78
- config : {
79
- name : { minWidth : 25 , maxWidth : 25 , truncate : false , truncateMarker : '' } ,
80
- description : { minWidth : 20 , maxWidth : 20 } ,
81
- author : { minWidth : 15 , maxWidth : 15 } ,
82
- date : { maxWidth : 11 } ,
83
- version : { minWidth : 8 , maxWidth : 8 } ,
84
- keywords : { maxWidth : Infinity } ,
85
- } ,
57
+ #prettify ( data ) {
58
+ const pkg = {
59
+ author : data . maintainers . map ( ( m ) => `=${ this . #clean( m . username ) } ` ) . join ( ' ' ) ,
60
+ date : 'prehistoric' ,
61
+ description : this . #clean( data . description ?? '' ) ,
62
+ keywords : '' ,
63
+ name : this . #clean( data . name ) ,
64
+ version : data . version ,
65
+ }
66
+ if ( Array . isArray ( data . keywords ) ) {
67
+ pkg . keywords = data . keywords . map ( ( k ) => this . #clean( k ) ) . join ( ' ' )
68
+ } else if ( typeof data . keywords === 'string' ) {
69
+ pkg . keywords = this . #clean( data . keywords . replace ( / [ , \s ] + / , ' ' ) )
70
+ }
71
+ if ( data . date ) {
72
+ pkg . date = data . date . toISOString ( ) . split ( 'T' ) [ 0 ] // remove time
86
73
}
87
- ) . split ( '\n' ) . map ( line => line . slice ( 0 , maxWidth ) ) . join ( '\n' )
88
-
89
- if ( opts . color ) {
90
- output = highlightSearchTerms ( output , opts . args )
91
- }
92
-
93
- return output
94
- }
95
-
96
- var colors = [ 31 , 33 , 32 , 36 , 34 , 35 ]
97
- var cl = colors . length
98
-
99
- function addColorMarker ( str , arg , i ) {
100
- var m = i % cl + 1
101
- var markStart = String . fromCharCode ( m )
102
- var markEnd = String . fromCharCode ( 0 )
103
-
104
- if ( arg . charAt ( 0 ) === '/' ) {
105
- return str . replace (
106
- new RegExp ( arg . slice ( 1 , - 1 ) , 'gi' ) ,
107
- bit => markStart + bit + markEnd
108
- )
109
- }
110
-
111
- // just a normal string, do the split/map thing
112
- var pieces = str . toLowerCase ( ) . split ( arg . toLowerCase ( ) )
113
- var p = 0
114
-
115
- return pieces . map ( function ( piece ) {
116
- piece = str . slice ( p , p + piece . length )
117
- var mark = markStart +
118
- str . slice ( p + piece . length , p + piece . length + arg . length ) +
119
- markEnd
120
- p += piece . length + arg . length
121
- return piece + mark
122
- } ) . join ( '' )
123
- }
124
-
125
- function colorize ( line ) {
126
- for ( var i = 0 ; i < cl ; i ++ ) {
127
- var m = i + 1
128
- var color = '\u001B[' + colors [ i ] + 'm'
129
- line = line . split ( String . fromCharCode ( m ) ) . join ( color )
130
- }
131
- var uncolor = '\u001B[0m'
132
- return line . split ( '\u0000' ) . join ( uncolor )
133
- }
134
74
135
- function highlightSearchTerms ( str , terms ) {
136
- terms . forEach ( function ( arg , i ) {
137
- str = addColorMarker ( str , arg , i )
138
- } )
75
+ const columns = [ 'name' , 'description' , 'author' , 'date' , 'version' , 'keywords' ]
76
+ if ( this . #opts . parseable ) {
77
+ return columns . map ( ( col ) => pkg [ col ] && ( '' + pkg [ col ] ) . replace ( / \t / g , ' ' ) ) . join ( '\t' )
78
+ }
139
79
140
- return colorize ( str ) . trim ( )
141
- }
80
+ // stdout in tap is never a tty
81
+ /* istanbul ignore next */
82
+ const maxWidth = process . stdout . isTTY ? process . stdout . getWindowSize ( ) [ 0 ] : Infinity
83
+ let output = columnify (
84
+ [ pkg ] ,
85
+ {
86
+ include : columns ,
87
+ showHeaders : ++ this . #line <= 1 ,
88
+ columnSplitter : ' | ' ,
89
+ truncate : ! this . #opts. long ,
90
+ config : {
91
+ name : { minWidth : 25 , maxWidth : 25 , truncate : false , truncateMarker : '' } ,
92
+ description : { minWidth : 20 , maxWidth : 20 } ,
93
+ author : { minWidth : 15 , maxWidth : 15 } ,
94
+ date : { maxWidth : 11 } ,
95
+ version : { minWidth : 8 , maxWidth : 8 } ,
96
+ keywords : { maxWidth : Infinity } ,
97
+ } ,
98
+ }
99
+ ) . split ( '\n' ) . map ( line => line . slice ( 0 , maxWidth ) ) . join ( '\n' )
100
+
101
+ if ( ! this . #opts. color ) {
102
+ return output
103
+ }
142
104
143
- function normalizePackage ( data , opts ) {
144
- return {
145
- name : ansiTrim ( data . name ) ,
146
- description : ansiTrim ( data . description ?? '' ) ,
147
- author : data . maintainers . map ( ( m ) => `=${ ansiTrim ( m . username ) } ` ) . join ( ' ' ) ,
148
- keywords : Array . isArray ( data . keywords )
149
- ? data . keywords . map ( ansiTrim ) . join ( ' ' )
150
- : typeof data . keywords === 'string'
151
- ? ansiTrim ( data . keywords . replace ( / [ , \s ] + / , ' ' ) )
152
- : '' ,
153
- version : data . version ,
154
- date : ( data . date &&
155
- ( data . date . toISOString ( ) // remove time
156
- . split ( 'T' ) . join ( ' ' )
157
- . replace ( / : [ 0 - 9 ] { 2 } \. [ 0 - 9 ] { 3 } Z $ / , '' ) )
158
- . slice ( 0 , - 5 ) ) ||
159
- 'prehistoric' ,
105
+ const colors = [ '31m' , '33m' , '32m' , '36m' , '34m' , '35m' ]
106
+
107
+ this . #opts. args . forEach ( ( arg , i ) => {
108
+ const markStart = String . fromCharCode ( i % colors . length + 1 )
109
+ const markEnd = String . fromCharCode ( 0 )
110
+
111
+ if ( arg . charAt ( 0 ) === '/' ) {
112
+ output = output . replace (
113
+ new RegExp ( arg . slice ( 1 , - 1 ) , 'gi' ) ,
114
+ bit => `${ markStart } ${ bit } ${ markEnd } `
115
+ )
116
+ } else {
117
+ // just a normal string, do the split/map thing
118
+ let p = 0
119
+
120
+ output = output . toLowerCase ( ) . split ( arg . toLowerCase ( ) ) . map ( piece => {
121
+ piece = output . slice ( p , p + piece . length )
122
+ p += piece . length
123
+ const mark = `${ markStart } ${ output . slice ( p , p + arg . length ) } ${ markEnd } `
124
+ p += arg . length
125
+ return `${ piece } ${ mark } `
126
+ } ) . join ( '' )
127
+ }
128
+ } )
129
+
130
+ for ( let i = 1 ; i <= colors . length ; i ++ ) {
131
+ output = output . split ( String . fromCharCode ( i ) ) . join ( `\u001B[${ colors [ i - 1 ] } ` )
132
+ }
133
+ return output . split ( '\u0000' ) . join ( '\u001B[0m' ) . trim ( )
160
134
}
161
135
}
0 commit comments