stylelint-webpack-plugin 2.0.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -5
- package/declarations/StylelintError.d.ts +2 -0
- package/declarations/cjs.d.ts +3 -0
- package/declarations/getStylelint.d.ts +24 -0
- package/declarations/index.d.ts +49 -0
- package/declarations/linter.d.ts +34 -0
- package/declarations/options.d.ts +62 -0
- package/declarations/utils.d.ts +19 -0
- package/declarations/worker.d.ts +3 -0
- package/dist/StylelintError.js +6 -8
- package/dist/getStylelint.js +132 -0
- package/dist/index.js +224 -30
- package/dist/linter.js +286 -45
- package/dist/options.js +95 -0
- package/dist/options.json +38 -4
- package/dist/utils.js +71 -7
- package/dist/worker.js +50 -0
- package/package.json +47 -37
- package/CHANGELOG.md +0 -117
- package/dist/LintDirtyModulesPlugin.js +0 -74
- package/dist/getOptions.js +0 -45
package/dist/index.js
CHANGED
|
@@ -7,9 +7,13 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _path = require("path");
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _arrify = _interopRequireDefault(require("arrify"));
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var _globby = _interopRequireDefault(require("globby"));
|
|
13
|
+
|
|
14
|
+
var _micromatch = require("micromatch");
|
|
15
|
+
|
|
16
|
+
var _options = require("./options");
|
|
13
17
|
|
|
14
18
|
var _linter = _interopRequireDefault(require("./linter"));
|
|
15
19
|
|
|
@@ -17,54 +21,244 @@ var _utils = require("./utils");
|
|
|
17
21
|
|
|
18
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
23
|
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
|
|
27
|
+
/** @typedef {import('webpack').Compiler} Compiler */
|
|
28
|
+
|
|
29
|
+
/** @typedef {import('webpack').Module} Module */
|
|
30
|
+
|
|
31
|
+
/** @typedef {import('./options').Options} Options */
|
|
32
|
+
|
|
33
|
+
/** @typedef {Partial<{timestamp:number} | number>} FileSystemInfoEntry */
|
|
34
|
+
const STYLELINT_PLUGIN = 'StylelintWebpackPlugin';
|
|
35
|
+
let counter = 0;
|
|
36
|
+
|
|
20
37
|
class StylelintWebpackPlugin {
|
|
38
|
+
/**
|
|
39
|
+
* @param {Options} options
|
|
40
|
+
*/
|
|
21
41
|
constructor(options = {}) {
|
|
22
|
-
this.
|
|
42
|
+
this.key = STYLELINT_PLUGIN;
|
|
43
|
+
this.options = (0, _options.getOptions)(options);
|
|
44
|
+
this.run = this.run.bind(this);
|
|
45
|
+
this.startTime = Date.now();
|
|
46
|
+
this.prevTimestamps = new Map();
|
|
23
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* @param {Compiler} compiler
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
52
|
+
|
|
24
53
|
|
|
25
54
|
apply(compiler) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
55
|
+
// Generate key for each compilation,
|
|
56
|
+
// this differentiates one from the other when being cached.
|
|
57
|
+
this.key = compiler.name || `${this.key}_${counter += 1}`; // If `lintDirtyModulesOnly` is disabled,
|
|
58
|
+
// execute the linter on the build
|
|
59
|
+
|
|
60
|
+
if (!this.options.lintDirtyModulesOnly) {
|
|
61
|
+
compiler.hooks.run.tapPromise(this.key, this.run);
|
|
62
|
+
}
|
|
29
63
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
64
|
+
let isFirstRun = this.options.lintDirtyModulesOnly;
|
|
65
|
+
compiler.hooks.watchRun.tapPromise(this.key, c => {
|
|
66
|
+
if (isFirstRun) {
|
|
67
|
+
isFirstRun = false;
|
|
68
|
+
return Promise.resolve();
|
|
69
|
+
}
|
|
33
70
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
71
|
+
return this.run(c);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* @param {Compiler} compiler
|
|
76
|
+
*/
|
|
37
77
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
});
|
|
49
|
-
/* istanbul ignore next */
|
|
50
|
-
|
|
51
|
-
compiler.hooks.watchRun.tapAsync(plugin, (compilation, callback) => {
|
|
52
|
-
(0, _linter.default)(lint, options, compilation, callback);
|
|
53
|
-
});
|
|
78
|
+
|
|
79
|
+
async run(compiler) {
|
|
80
|
+
// Do not re-hook
|
|
81
|
+
|
|
82
|
+
/* istanbul ignore if */
|
|
83
|
+
if ( // @ts-ignore
|
|
84
|
+
compiler.hooks.thisCompilation.taps.find(({
|
|
85
|
+
name
|
|
86
|
+
}) => name === this.key)) {
|
|
87
|
+
return;
|
|
54
88
|
}
|
|
89
|
+
|
|
90
|
+
const context = this.getContext(compiler);
|
|
91
|
+
const options = { ...this.options,
|
|
92
|
+
exclude: (0, _utils.parseFiles)(this.options.exclude || ['**/node_modules/**', compiler.options.output.path], context),
|
|
93
|
+
extensions: (0, _arrify.default)(this.options.extensions),
|
|
94
|
+
files: (0, _utils.parseFiles)(this.options.files || '', context)
|
|
95
|
+
};
|
|
96
|
+
const wanted = (0, _utils.parseFoldersToGlobs)(options.files, options.extensions);
|
|
97
|
+
const exclude = (0, _utils.parseFoldersToGlobs)(options.exclude);
|
|
98
|
+
compiler.hooks.thisCompilation.tap(this.key, compilation => {
|
|
99
|
+
/** @type {import('./linter').Linter} */
|
|
100
|
+
let lint;
|
|
101
|
+
/** @type {import('./linter').Reporter} */
|
|
102
|
+
|
|
103
|
+
let report;
|
|
104
|
+
/** @type number */
|
|
105
|
+
|
|
106
|
+
let threads;
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
({
|
|
110
|
+
lint,
|
|
111
|
+
report,
|
|
112
|
+
threads
|
|
113
|
+
} = (0, _linter.default)(this.key, options, compilation));
|
|
114
|
+
} catch (e) {
|
|
115
|
+
compilation.errors.push(e);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
compilation.hooks.finishModules.tap(this.key, () => {
|
|
120
|
+
const files = this.getFiles(compiler, wanted, exclude);
|
|
121
|
+
|
|
122
|
+
if (threads > 1) {
|
|
123
|
+
for (const file of files) {
|
|
124
|
+
lint((0, _utils.parseFiles)(file, context));
|
|
125
|
+
}
|
|
126
|
+
} else if (files.length > 0) {
|
|
127
|
+
lint((0, _utils.parseFiles)(files, context));
|
|
128
|
+
}
|
|
129
|
+
}); // await and interpret results
|
|
130
|
+
|
|
131
|
+
compilation.hooks.additionalAssets.tapPromise(this.key, processResults);
|
|
132
|
+
|
|
133
|
+
async function processResults() {
|
|
134
|
+
const {
|
|
135
|
+
errors,
|
|
136
|
+
warnings,
|
|
137
|
+
generateReportAsset
|
|
138
|
+
} = await report();
|
|
139
|
+
|
|
140
|
+
if (warnings && !options.failOnWarning) {
|
|
141
|
+
// @ts-ignore
|
|
142
|
+
compilation.warnings.push(warnings);
|
|
143
|
+
} else if (warnings && options.failOnWarning) {
|
|
144
|
+
// @ts-ignore
|
|
145
|
+
compilation.errors.push(warnings);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (errors && options.failOnError) {
|
|
149
|
+
// @ts-ignore
|
|
150
|
+
compilation.errors.push(errors);
|
|
151
|
+
} else if (errors && !options.failOnError) {
|
|
152
|
+
// @ts-ignore
|
|
153
|
+
compilation.warnings.push(errors);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (generateReportAsset) {
|
|
157
|
+
await generateReportAsset(compilation);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
55
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
*
|
|
164
|
+
* @param {Compiler} compiler
|
|
165
|
+
* @returns {string}
|
|
166
|
+
*/
|
|
167
|
+
|
|
56
168
|
|
|
57
169
|
getContext(compiler) {
|
|
58
170
|
if (!this.options.context) {
|
|
59
|
-
return compiler.options.context;
|
|
171
|
+
return String(compiler.options.context);
|
|
60
172
|
}
|
|
61
173
|
|
|
62
174
|
if (!(0, _path.isAbsolute)(this.options.context)) {
|
|
63
|
-
return (0, _path.join)(compiler.options.context, this.options.context);
|
|
175
|
+
return (0, _path.join)(String(compiler.options.context), this.options.context);
|
|
64
176
|
}
|
|
65
177
|
|
|
66
178
|
return this.options.context;
|
|
67
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* @param {Compiler} compiler
|
|
182
|
+
* @param {string[]} wanted
|
|
183
|
+
* @param {string[]} exclude
|
|
184
|
+
* @returns {string[]}
|
|
185
|
+
*/
|
|
186
|
+
// eslint-disable-next-line no-unused-vars
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
getFiles(compiler, wanted, exclude) {
|
|
190
|
+
// webpack 5
|
|
191
|
+
if (compiler.modifiedFiles) {
|
|
192
|
+
return Array.from(compiler.modifiedFiles).filter(file => (0, _micromatch.isMatch)(file, wanted, {
|
|
193
|
+
dot: true
|
|
194
|
+
}) && !(0, _micromatch.isMatch)(file, exclude, {
|
|
195
|
+
dot: true
|
|
196
|
+
}));
|
|
197
|
+
} // webpack 4
|
|
198
|
+
|
|
199
|
+
/* istanbul ignore next */
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
if (compiler.fileTimestamps && compiler.fileTimestamps.size > 0) {
|
|
203
|
+
return this.getChangedFiles(compiler.fileTimestamps).filter(file => (0, _micromatch.isMatch)(file, wanted, {
|
|
204
|
+
dot: true
|
|
205
|
+
}) && !(0, _micromatch.isMatch)(file, exclude, {
|
|
206
|
+
dot: true
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return _globby.default.sync(wanted, {
|
|
211
|
+
dot: true,
|
|
212
|
+
ignore: exclude
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* @param {Map<string, null | FileSystemInfoEntry | "ignore">} fileTimestamps
|
|
217
|
+
* @returns {string[]}
|
|
218
|
+
*/
|
|
219
|
+
|
|
220
|
+
/* istanbul ignore next */
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
getChangedFiles(fileTimestamps) {
|
|
224
|
+
/**
|
|
225
|
+
* @param {null | FileSystemInfoEntry | "ignore"} fileSystemInfoEntry
|
|
226
|
+
* @returns {Partial<number>}
|
|
227
|
+
*/
|
|
228
|
+
const getTimestamps = fileSystemInfoEntry => {
|
|
229
|
+
// @ts-ignore
|
|
230
|
+
if (fileSystemInfoEntry && fileSystemInfoEntry.timestamp) {
|
|
231
|
+
// @ts-ignore
|
|
232
|
+
return fileSystemInfoEntry.timestamp;
|
|
233
|
+
} // @ts-ignore
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
return fileSystemInfoEntry;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* @param {string} filename
|
|
240
|
+
* @param {null | FileSystemInfoEntry | "ignore"} fileSystemInfoEntry
|
|
241
|
+
* @returns {boolean}
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
const hasFileChanged = (filename, fileSystemInfoEntry) => {
|
|
246
|
+
const prevTimestamp = getTimestamps(this.prevTimestamps.get(filename));
|
|
247
|
+
const timestamp = getTimestamps(fileSystemInfoEntry);
|
|
248
|
+
return (prevTimestamp || this.startTime) < (timestamp || Infinity);
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const changedFiles = [];
|
|
252
|
+
|
|
253
|
+
for (const [filename, timestamp] of fileTimestamps.entries()) {
|
|
254
|
+
if (hasFileChanged(filename, timestamp)) {
|
|
255
|
+
changedFiles.push(filename);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
this.prevTimestamps = fileTimestamps;
|
|
260
|
+
return changedFiles;
|
|
261
|
+
}
|
|
68
262
|
|
|
69
263
|
}
|
|
70
264
|
|
package/dist/linter.js
CHANGED
|
@@ -5,65 +5,195 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = linter;
|
|
7
7
|
|
|
8
|
+
var _path = require("path");
|
|
9
|
+
|
|
10
|
+
var _arrify = _interopRequireDefault(require("arrify"));
|
|
11
|
+
|
|
8
12
|
var _StylelintError = _interopRequireDefault(require("./StylelintError"));
|
|
9
13
|
|
|
14
|
+
var _getStylelint = _interopRequireDefault(require("./getStylelint"));
|
|
15
|
+
|
|
10
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
17
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
|
|
20
|
+
/** @typedef {import('stylelint')} Stylelint */
|
|
21
|
+
|
|
22
|
+
/** @typedef {import('stylelint').LintResult} LintResult */
|
|
23
|
+
|
|
24
|
+
/** @typedef {import('webpack').Compiler} Compiler */
|
|
25
|
+
|
|
26
|
+
/** @typedef {import('webpack').Compilation} Compilation */
|
|
27
|
+
|
|
28
|
+
/** @typedef {import('./options').Options} Options */
|
|
29
|
+
|
|
30
|
+
/** @typedef {import('./options').FormatterType} FormatterType */
|
|
31
|
+
|
|
32
|
+
/** @typedef {((results: LintResult[]) => string)} FormatterFunction */
|
|
33
|
+
|
|
34
|
+
/** @typedef {(compilation: Compilation) => Promise<void>} GenerateReport */
|
|
35
|
+
|
|
36
|
+
/** @typedef {{errors?: StylelintError, warnings?: StylelintError, generateReportAsset?: GenerateReport}} Report */
|
|
37
|
+
|
|
38
|
+
/** @typedef {() => Promise<Report>} Reporter */
|
|
39
|
+
|
|
40
|
+
/** @typedef {(files: string|string[]) => void} Linter */
|
|
41
|
+
|
|
42
|
+
/** @typedef {{[files: string]: LintResult}} LintResultMap */
|
|
43
|
+
|
|
44
|
+
/** @type {WeakMap<Compiler, LintResultMap>} */
|
|
45
|
+
const resultStorage = new WeakMap();
|
|
46
|
+
/**
|
|
47
|
+
* @param {string|undefined} key
|
|
48
|
+
* @param {Options} options
|
|
49
|
+
* @param {Compilation} compilation
|
|
50
|
+
* @returns {{lint: Linter, report: Reporter, threads: number}}
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
function linter(key, options, compilation) {
|
|
54
|
+
/** @type {Stylelint} */
|
|
55
|
+
let stylelint;
|
|
56
|
+
/** @type {(files: string|string[]) => Promise<LintResult[]>} */
|
|
57
|
+
|
|
58
|
+
let lintFiles;
|
|
59
|
+
/** @type {() => Promise<void>} */
|
|
60
|
+
|
|
61
|
+
let cleanup;
|
|
62
|
+
/** @type number */
|
|
63
|
+
|
|
64
|
+
let threads;
|
|
65
|
+
/** @type {Promise<LintResult[]>[]} */
|
|
66
|
+
|
|
67
|
+
const rawResults = [];
|
|
68
|
+
const crossRunResultStorage = getResultStorage(compilation);
|
|
69
|
+
|
|
70
|
+
try {
|
|
18
71
|
({
|
|
72
|
+
stylelint,
|
|
73
|
+
lintFiles,
|
|
74
|
+
cleanup,
|
|
75
|
+
threads
|
|
76
|
+
} = (0, _getStylelint.default)(key, options));
|
|
77
|
+
} catch (e) {
|
|
78
|
+
throw new _StylelintError.default(e.message);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
lint,
|
|
83
|
+
report,
|
|
84
|
+
threads
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* @param {string | string[]} files
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
function lint(files) {
|
|
91
|
+
for (const file of (0, _arrify.default)(files)) {
|
|
92
|
+
delete crossRunResultStorage[file];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
rawResults.push(lintFiles(files).catch(e => {
|
|
96
|
+
compilation.errors.push(e);
|
|
97
|
+
return [];
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function report() {
|
|
102
|
+
// Filter out ignored files.
|
|
103
|
+
let results = removeIgnoredWarnings( // Get the current results, resetting the rawResults to empty
|
|
104
|
+
await flatten(rawResults.splice(0, rawResults.length)));
|
|
105
|
+
await cleanup();
|
|
106
|
+
|
|
107
|
+
for (const result of results) {
|
|
108
|
+
crossRunResultStorage[result.source] = result;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
results = Object.values(crossRunResultStorage); // do not analyze if there are no results or stylelint config
|
|
112
|
+
|
|
113
|
+
if (!results || results.length < 1) {
|
|
114
|
+
return {};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const formatter = loadFormatter(stylelint, options.formatter);
|
|
118
|
+
const {
|
|
19
119
|
errors,
|
|
20
120
|
warnings
|
|
21
|
-
} = parseResults(options, results));
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
121
|
+
} = formatResults(formatter, parseResults(options, results));
|
|
122
|
+
return {
|
|
123
|
+
errors,
|
|
124
|
+
warnings,
|
|
125
|
+
generateReportAsset
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* @param {Compilation} compilation
|
|
129
|
+
* @returns {Promise<void>}
|
|
130
|
+
*/
|
|
131
|
+
|
|
132
|
+
async function generateReportAsset({
|
|
133
|
+
compiler
|
|
134
|
+
}) {
|
|
135
|
+
const {
|
|
136
|
+
outputReport
|
|
137
|
+
} = options;
|
|
138
|
+
/**
|
|
139
|
+
* @param {string} name
|
|
140
|
+
* @param {string | Buffer} content
|
|
141
|
+
*/
|
|
27
142
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
143
|
+
const save = (name, content) =>
|
|
144
|
+
/** @type {Promise<void>} */
|
|
145
|
+
new Promise((finish, bail) => {
|
|
146
|
+
const {
|
|
147
|
+
mkdir,
|
|
148
|
+
writeFile
|
|
149
|
+
} = compiler.outputFileSystem; // ensure directory exists
|
|
150
|
+
// @ts-ignore - the types for `outputFileSystem` are missing the 3 arg overload
|
|
151
|
+
|
|
152
|
+
mkdir((0, _path.dirname)(name), {
|
|
153
|
+
recursive: true
|
|
154
|
+
}, err => {
|
|
155
|
+
/* istanbul ignore if */
|
|
156
|
+
if (err) bail(err);else writeFile(name, content, err2 => {
|
|
157
|
+
/* istanbul ignore if */
|
|
158
|
+
if (err2) bail(err2);else finish();
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
if (!outputReport || !outputReport.filePath) {
|
|
164
|
+
return;
|
|
31
165
|
}
|
|
32
166
|
|
|
33
|
-
|
|
34
|
-
|
|
167
|
+
const content = outputReport.formatter ? loadFormatter(stylelint, outputReport.formatter)(results) : formatter(results);
|
|
168
|
+
let {
|
|
169
|
+
filePath
|
|
170
|
+
} = outputReport;
|
|
35
171
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
callback();
|
|
172
|
+
if (!(0, _path.isAbsolute)(filePath)) {
|
|
173
|
+
filePath = (0, _path.join)(compiler.outputPath, filePath);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
await save(filePath, content);
|
|
42
177
|
}
|
|
43
|
-
}
|
|
44
|
-
compiler.hooks.afterEmit.tapAsync('StylelintWebpackPlugin', (compilation, next) => {
|
|
45
|
-
compilation.errors.push(new _StylelintError.default(e.message));
|
|
46
|
-
next();
|
|
47
|
-
});
|
|
48
|
-
callback();
|
|
49
|
-
});
|
|
178
|
+
}
|
|
50
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* @param {FormatterFunction} formatter
|
|
182
|
+
* @param {{ errors: LintResult[]; warnings: LintResult[]; }} results
|
|
183
|
+
* @returns {{errors?: StylelintError, warnings?: StylelintError}}
|
|
184
|
+
*/
|
|
51
185
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
let
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
warnings = results.filter(file => fileHasErrors(file) || fileHasWarnings(file));
|
|
60
|
-
} else {
|
|
61
|
-
warnings = results.filter(file => !fileHasErrors(file) && fileHasWarnings(file));
|
|
62
|
-
errors = results.filter(fileHasErrors);
|
|
186
|
+
|
|
187
|
+
function formatResults(formatter, results) {
|
|
188
|
+
let errors;
|
|
189
|
+
let warnings;
|
|
190
|
+
|
|
191
|
+
if (results.warnings.length > 0) {
|
|
192
|
+
warnings = new _StylelintError.default(formatter(results.warnings));
|
|
63
193
|
}
|
|
64
194
|
|
|
65
|
-
if (
|
|
66
|
-
|
|
195
|
+
if (results.errors.length > 0) {
|
|
196
|
+
errors = new _StylelintError.default(formatter(results.errors));
|
|
67
197
|
}
|
|
68
198
|
|
|
69
199
|
return {
|
|
@@ -71,11 +201,122 @@ function parseResults(options, results) {
|
|
|
71
201
|
warnings
|
|
72
202
|
};
|
|
73
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* @param {Options} options
|
|
206
|
+
* @param {LintResult[]} results
|
|
207
|
+
* @returns {{errors: LintResult[], warnings: LintResult[]}}
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
function parseResults(options, results) {
|
|
212
|
+
/** @type {LintResult[]} */
|
|
213
|
+
const errors = [];
|
|
214
|
+
/** @type {LintResult[]} */
|
|
215
|
+
|
|
216
|
+
const warnings = [];
|
|
217
|
+
results.forEach(file => {
|
|
218
|
+
if (fileHasErrors(file)) {
|
|
219
|
+
const messages = file.warnings.filter(message => options.emitError && message.severity === 'error');
|
|
220
|
+
|
|
221
|
+
if (messages.length > 0) {
|
|
222
|
+
errors.push({ ...file,
|
|
223
|
+
warnings: messages
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (fileHasWarnings(file)) {
|
|
229
|
+
const messages = file.warnings.filter(message => options.emitWarning && message.severity === 'warning');
|
|
230
|
+
|
|
231
|
+
if (messages.length > 0) {
|
|
232
|
+
warnings.push({ ...file,
|
|
233
|
+
warnings: messages
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
return {
|
|
239
|
+
errors,
|
|
240
|
+
warnings
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* @param {LintResult} file
|
|
245
|
+
* @returns {boolean}
|
|
246
|
+
*/
|
|
247
|
+
|
|
74
248
|
|
|
75
249
|
function fileHasErrors(file) {
|
|
76
|
-
return file.errored;
|
|
250
|
+
return !!file.errored;
|
|
77
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* @param {LintResult} file
|
|
254
|
+
* @returns {boolean}
|
|
255
|
+
*/
|
|
256
|
+
|
|
78
257
|
|
|
79
258
|
function fileHasWarnings(file) {
|
|
80
|
-
return file.warnings && file.warnings.length;
|
|
259
|
+
return file.warnings && file.warnings.length > 0;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* @param {Stylelint} stylelint
|
|
263
|
+
* @param {FormatterType=} formatter
|
|
264
|
+
* @returns {FormatterFunction}
|
|
265
|
+
*/
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
function loadFormatter(stylelint, formatter) {
|
|
269
|
+
if (typeof formatter === 'function') {
|
|
270
|
+
return formatter;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (typeof formatter === 'string') {
|
|
274
|
+
try {
|
|
275
|
+
return stylelint.formatters[formatter];
|
|
276
|
+
} catch (_) {// Load the default formatter.
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return stylelint.formatters.string;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* @param {LintResult[]} results
|
|
284
|
+
* @returns {LintResult[]}
|
|
285
|
+
*/
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
function removeIgnoredWarnings(results) {
|
|
289
|
+
return results.filter(result => !result.ignored);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* @param {Promise<LintResult[]>[]} results
|
|
293
|
+
* @returns {Promise<LintResult[]>}
|
|
294
|
+
*/
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
async function flatten(results) {
|
|
298
|
+
/**
|
|
299
|
+
* @param {LintResult[]} acc
|
|
300
|
+
* @param {LintResult[]} list
|
|
301
|
+
*/
|
|
302
|
+
const flat = (acc, list) => [...acc, ...list];
|
|
303
|
+
|
|
304
|
+
return (await Promise.all(results)).reduce(flat, []);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* @param {Compilation} compilation
|
|
308
|
+
* @returns {LintResultMap}
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
function getResultStorage({
|
|
313
|
+
compiler
|
|
314
|
+
}) {
|
|
315
|
+
let storage = resultStorage.get(compiler);
|
|
316
|
+
|
|
317
|
+
if (!storage) {
|
|
318
|
+
resultStorage.set(compiler, storage = {});
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return storage;
|
|
81
322
|
}
|