2
2
* @typedef {import('vfile').VFile } VFile
3
3
* @typedef {import('vfile-message').VFileMessage } VFileMessage
4
4
* @typedef {import('vfile-statistics').Statistics } Statistics
5
- *
5
+ */
6
+
7
+ /**
6
8
* @typedef Options
7
9
* Configuration (optional).
8
- * @property {boolean } [color]
10
+ * @property {boolean | null | undefined } [color]
9
11
* Use ANSI colors in report (default: depends).
10
12
* The default behavior in Node.js is the check if color is supported.
11
- * @property {boolean } [verbose=false]
13
+ * @property {boolean | null | undefined } [verbose=false]
12
14
* Show message `note`s.
13
15
* Notes are optional, additional, long descriptions.
14
- * @property {boolean } [quiet=false]
16
+ * @property {boolean | null | undefined } [quiet=false]
15
17
* Do not show files without messages.
16
- * @property {boolean } [silent=false]
18
+ * @property {boolean | null | undefined } [silent=false]
17
19
* Show errors only.
18
20
* This does not show info and warning messages.
19
21
* Also sets `quiet` to `true`.
20
- * @property {string } [defaultName='<stdin>']
22
+ * @property {string | null | undefined } [defaultName='<stdin>']
21
23
* Label to use for files without file path.
22
24
* If one file and no `defaultName` is given, no name will show up in the report.
23
25
*
24
- * @typedef Row
26
+ * @typedef MessageRow
27
+ * Message.
25
28
* @property {string } place
29
+ * Serialized positional info.
26
30
* @property {string } label
31
+ * Kind of message.
27
32
* @property {string } reason
33
+ * Reason.
28
34
* @property {string } ruleId
35
+ * Rule.
29
36
* @property {string } source
37
+ * Source.
38
+ *
39
+ * @typedef {keyof MessageRow } MessageColumn
30
40
*
31
41
* @typedef FileRow
42
+ * File header row.
32
43
* @property {'file' } type
44
+ * Kind.
33
45
* @property {VFile } file
46
+ * Virtual file.
34
47
* @property {Statistics } stats
48
+ * Statistics.
35
49
*
36
- * @typedef {Record<string, number> } Sizes
50
+ * @typedef {Record<MessageColumn, number> } Sizes
51
+ * Sizes for message columns.
37
52
*
38
53
* @typedef Info
39
- * @property {Array<FileRow|Row> } rows
54
+ * Result.
55
+ * @property {Array<FileRow | MessageRow> } rows
56
+ * Rows.
40
57
* @property {Statistics } stats
58
+ * Total statistics.
41
59
* @property {Sizes } sizes
60
+ * Sizes for message columns.
42
61
*/
43
62
44
63
import width from 'string-width'
@@ -65,17 +84,14 @@ const labels = {
65
84
/**
66
85
* Create a report from an error, one file, or multiple files.
67
86
*
68
- * @param {Error| VFile| Array<VFile> } [files]
87
+ * @param {Error | VFile | Array<VFile> | null | undefined } [files]
69
88
* File(s) or error to report.
70
- * @param {Options } [options]
89
+ * @param {Options | null | undefined } [options]
71
90
* Configuration.
72
91
* @returns {string }
73
92
* Report.
74
93
*/
75
- export function reporter ( files , options = { } ) {
76
- /** @type {boolean|undefined } */
77
- let one
78
-
94
+ export function reporter ( files , options ) {
79
95
if ( ! files ) {
80
96
return ''
81
97
}
@@ -85,33 +101,39 @@ export function reporter(files, options = {}) {
85
101
return String ( files . stack || files )
86
102
}
87
103
104
+ const options_ = options || { }
105
+
88
106
// One file.
89
- if ( ! Array . isArray ( files ) ) {
90
- one = true
91
- files = [ files ]
107
+ if ( Array . isArray ( files ) ) {
108
+ return format ( transform ( files , options_ ) , false , options_ )
92
109
}
93
110
94
- return format ( transform ( files , options ) , one , options )
111
+ return format ( transform ( [ files ] , options_ ) , true , options_ )
95
112
}
96
113
97
114
/**
115
+ * Parse a list of messages.
116
+ *
98
117
* @param {Array<VFile> } files
118
+ * List of files.
99
119
* @param {Options } options
120
+ * Options.
100
121
* @returns {Info }
122
+ * Rows.
101
123
*/
102
124
function transform ( files , options ) {
103
- /** @type {Array<FileRow|Row > } */
125
+ /** @type {Array<FileRow | MessageRow > } */
104
126
const rows = [ ]
105
127
/** @type {Array<VFileMessage> } */
106
128
const all = [ ]
107
129
/** @type {Sizes } */
108
- const sizes = { }
130
+ const sizes = { place : 0 , label : 0 , reason : 0 , ruleId : 0 , source : 0 }
109
131
let index = - 1
110
132
111
133
while ( ++ index < files . length ) {
112
134
// @ts -expect-error it works fine.
113
135
const messages = sort ( { messages : [ ...files [ index ] . messages ] } ) . messages
114
- /** @type {Array<Row > } */
136
+ /** @type {Array<MessageRow > } */
115
137
const messageRows = [ ]
116
138
let offset = - 1
117
139
@@ -137,7 +159,7 @@ function transform(files, options) {
137
159
source : message . source || ''
138
160
}
139
161
140
- /** @type {keyof row } */
162
+ /** @type {MessageColumn } */
141
163
let key
142
164
143
165
for ( key in row ) {
@@ -164,8 +186,13 @@ function transform(files, options) {
164
186
165
187
/**
166
188
* @param {Info } map
167
- * @param {boolean|undefined } one
189
+ * Rows.
190
+ * @param {boolean } one
191
+ * Whether the input was explicitly one file (not an array).
168
192
* @param {Options } options
193
+ * Configuration.
194
+ * @returns {string }
195
+ * Report.
169
196
*/
170
197
// eslint-disable-next-line complexity
171
198
function format ( map , one , options ) {
@@ -298,10 +325,12 @@ function format(map, one, options) {
298
325
}
299
326
300
327
/**
301
- * Get the length of `value`, ignoring ANSI sequences.
328
+ * Get the length of the first line of `value`, ignoring ANSI sequences.
302
329
*
303
330
* @param {string } value
331
+ * Message.
304
332
* @returns {number }
333
+ * Width.
305
334
*/
306
335
function size ( value ) {
307
336
const match = / \r ? \n | \r / . exec ( value )
0 commit comments