stylelint-webpack-plugin 2.1.1 → 2.3.0
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 -30
- package/declarations/cjs.d.ts +2 -1
- package/declarations/getStylelint.d.ts +72 -0
- package/declarations/index.d.ts +41 -3
- package/declarations/linter.d.ts +73 -38
- package/declarations/options.d.ts +110 -0
- package/declarations/utils.d.ts +12 -7
- package/declarations/worker.d.ts +51 -0
- package/dist/StylelintError.js +3 -18
- package/dist/getStylelint.js +132 -0
- package/dist/index.js +215 -31
- package/dist/linter.js +246 -80
- package/dist/options.js +95 -0
- package/dist/options.json +38 -4
- package/dist/utils.js +66 -11
- package/dist/worker.js +50 -0
- package/package.json +39 -37
- package/CHANGELOG.md +0 -137
- package/declarations/LintDirtyModulesPlugin.d.ts +0 -64
- package/declarations/getOptions.d.ts +0 -32
- package/dist/LintDirtyModulesPlugin.js +0 -118
- package/dist/getOptions.js +0 -74
package/dist/linter.js
CHANGED
|
@@ -5,108 +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
|
-
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
|
|
20
|
+
/** @typedef {import('stylelint')} Stylelint */
|
|
13
21
|
|
|
14
22
|
/** @typedef {import('stylelint').LintResult} LintResult */
|
|
15
23
|
|
|
16
24
|
/** @typedef {import('webpack').Compiler} Compiler */
|
|
17
25
|
|
|
18
|
-
/** @typedef {import('
|
|
26
|
+
/** @typedef {import('webpack').Compilation} Compilation */
|
|
19
27
|
|
|
20
|
-
/**
|
|
21
|
-
* @callback Lint
|
|
22
|
-
* @param {Options} options
|
|
23
|
-
* @returns {Promise<LinterResult>}
|
|
24
|
-
*/
|
|
28
|
+
/** @typedef {import('./options').Options} Options */
|
|
25
29
|
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
*/
|
|
30
|
+
/** @typedef {import('./options').FormatterType} FormatterType */
|
|
31
|
+
|
|
32
|
+
/** @typedef {((results: LintResult[]) => string)} FormatterFunction */
|
|
33
|
+
|
|
34
|
+
/** @typedef {(compilation: Compilation) => Promise<void>} GenerateReport */
|
|
31
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();
|
|
32
46
|
/**
|
|
33
|
-
* @param {
|
|
47
|
+
* @param {string|undefined} key
|
|
34
48
|
* @param {Options} options
|
|
35
|
-
* @param {
|
|
36
|
-
* @
|
|
37
|
-
* @returns {void}
|
|
49
|
+
* @param {Compilation} compilation
|
|
50
|
+
* @returns {{lint: Linter, report: Reporter, threads: number}}
|
|
38
51
|
*/
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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 {
|
|
48
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[String(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 {
|
|
49
119
|
errors,
|
|
50
120
|
warnings
|
|
51
|
-
} = parseResults(options, results));
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
+
*/
|
|
58
131
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
132
|
+
async function generateReportAsset({
|
|
133
|
+
compiler
|
|
134
|
+
}) {
|
|
135
|
+
const {
|
|
136
|
+
outputReport
|
|
137
|
+
} = options;
|
|
138
|
+
/**
|
|
139
|
+
* @param {string} name
|
|
140
|
+
* @param {string | Buffer} content
|
|
141
|
+
*/
|
|
142
|
+
|
|
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;
|
|
63
165
|
}
|
|
64
166
|
|
|
65
|
-
|
|
66
|
-
|
|
167
|
+
const content = outputReport.formatter ? loadFormatter(stylelint, outputReport.formatter)(results) : formatter(results);
|
|
168
|
+
let {
|
|
169
|
+
filePath
|
|
170
|
+
} = outputReport;
|
|
171
|
+
|
|
172
|
+
if (!(0, _path.isAbsolute)(filePath)) {
|
|
173
|
+
filePath = (0, _path.join)(compiler.outputPath, filePath);
|
|
174
|
+
}
|
|
67
175
|
|
|
68
|
-
|
|
69
|
-
callback(_StylelintError.default.format(options, errors));
|
|
70
|
-
} else if (options.failOnWarning && warnings.length) {
|
|
71
|
-
callback(_StylelintError.default.format(options, warnings));
|
|
72
|
-
} else {
|
|
73
|
-
callback();
|
|
176
|
+
await save(filePath, content);
|
|
74
177
|
}
|
|
75
|
-
}
|
|
76
|
-
compiler.hooks.afterEmit.tapAsync('StylelintWebpackPlugin', (compilation, next) => {
|
|
77
|
-
// @ts-ignore
|
|
78
|
-
compilation.errors.push(new _StylelintError.default(e.message));
|
|
79
|
-
next();
|
|
80
|
-
});
|
|
81
|
-
callback();
|
|
82
|
-
});
|
|
178
|
+
}
|
|
83
179
|
}
|
|
84
180
|
/**
|
|
85
|
-
*
|
|
86
|
-
* @param {
|
|
87
|
-
* @
|
|
88
|
-
* @returns {{errors: Array<LintResult>, warnings: Array<LintResult>}}
|
|
181
|
+
* @param {FormatterFunction} formatter
|
|
182
|
+
* @param {{ errors: LintResult[]; warnings: LintResult[]; }} results
|
|
183
|
+
* @returns {{errors?: StylelintError, warnings?: StylelintError}}
|
|
89
184
|
*/
|
|
90
185
|
|
|
91
186
|
|
|
92
|
-
function
|
|
93
|
-
|
|
94
|
-
let
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (options.emitError) {
|
|
100
|
-
errors = results.filter(file => fileHasErrors(file) || fileHasWarnings(file));
|
|
101
|
-
} else if (options.emitWarning) {
|
|
102
|
-
warnings = results.filter(file => fileHasErrors(file) || fileHasWarnings(file));
|
|
103
|
-
} else {
|
|
104
|
-
warnings = results.filter(file => !fileHasErrors(file) && fileHasWarnings(file));
|
|
105
|
-
errors = results.filter(fileHasErrors);
|
|
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));
|
|
106
193
|
}
|
|
107
194
|
|
|
108
|
-
if (
|
|
109
|
-
|
|
195
|
+
if (results.errors.length > 0) {
|
|
196
|
+
errors = new _StylelintError.default(formatter(results.errors));
|
|
110
197
|
}
|
|
111
198
|
|
|
112
199
|
return {
|
|
@@ -115,20 +202,99 @@ function parseResults(options, results) {
|
|
|
115
202
|
};
|
|
116
203
|
}
|
|
117
204
|
/**
|
|
118
|
-
* @param {
|
|
119
|
-
* @
|
|
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
|
+
const fileErrors = file.warnings.filter(message => options.emitError && message.severity === 'error');
|
|
219
|
+
|
|
220
|
+
if (fileErrors.length > 0) {
|
|
221
|
+
errors.push({ ...file,
|
|
222
|
+
warnings: fileErrors
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const fileWarnings = file.warnings.filter(message => options.emitWarning && message.severity === 'warning');
|
|
227
|
+
|
|
228
|
+
if (fileWarnings.length > 0) {
|
|
229
|
+
warnings.push({ ...file,
|
|
230
|
+
warnings: fileWarnings
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
return {
|
|
235
|
+
errors,
|
|
236
|
+
warnings
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* @param {Stylelint} stylelint
|
|
241
|
+
* @param {FormatterType=} formatter
|
|
242
|
+
* @returns {FormatterFunction}
|
|
120
243
|
*/
|
|
121
244
|
|
|
122
245
|
|
|
123
|
-
function
|
|
124
|
-
|
|
246
|
+
function loadFormatter(stylelint, formatter) {
|
|
247
|
+
if (typeof formatter === 'function') {
|
|
248
|
+
return formatter;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (typeof formatter === 'string') {
|
|
252
|
+
try {
|
|
253
|
+
return stylelint.formatters[formatter];
|
|
254
|
+
} catch (_) {// Load the default formatter.
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return stylelint.formatters.string;
|
|
125
259
|
}
|
|
126
260
|
/**
|
|
127
|
-
* @param {LintResult}
|
|
128
|
-
* @returns {
|
|
261
|
+
* @param {LintResult[]} results
|
|
262
|
+
* @returns {LintResult[]}
|
|
129
263
|
*/
|
|
130
264
|
|
|
131
265
|
|
|
132
|
-
function
|
|
133
|
-
return
|
|
266
|
+
function removeIgnoredWarnings(results) {
|
|
267
|
+
return results.filter(result => !result.ignored);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* @param {Promise<LintResult[]>[]} results
|
|
271
|
+
* @returns {Promise<LintResult[]>}
|
|
272
|
+
*/
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
async function flatten(results) {
|
|
276
|
+
/**
|
|
277
|
+
* @param {LintResult[]} acc
|
|
278
|
+
* @param {LintResult[]} list
|
|
279
|
+
*/
|
|
280
|
+
const flat = (acc, list) => [...acc, ...list];
|
|
281
|
+
|
|
282
|
+
return (await Promise.all(results)).reduce(flat, []);
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* @param {Compilation} compilation
|
|
286
|
+
* @returns {LintResultMap}
|
|
287
|
+
*/
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
function getResultStorage({
|
|
291
|
+
compiler
|
|
292
|
+
}) {
|
|
293
|
+
let storage = resultStorage.get(compiler);
|
|
294
|
+
|
|
295
|
+
if (!storage) {
|
|
296
|
+
resultStorage.set(compiler, storage = {});
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return storage;
|
|
134
300
|
}
|
package/dist/options.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getOptions = getOptions;
|
|
7
|
+
exports.getStylelintOptions = getStylelintOptions;
|
|
8
|
+
|
|
9
|
+
var _schemaUtils = require("schema-utils");
|
|
10
|
+
|
|
11
|
+
var _options = _interopRequireDefault(require("./options.json"));
|
|
12
|
+
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
|
|
17
|
+
/** @typedef {import("stylelint")} stylelint */
|
|
18
|
+
|
|
19
|
+
/** @typedef {import("stylelint").LinterOptions} StylelintOptions */
|
|
20
|
+
|
|
21
|
+
/** @typedef {import("stylelint").FormatterType} FormatterType */
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} OutputReport
|
|
25
|
+
* @property {string=} filePath
|
|
26
|
+
* @property {FormatterType=} formatter
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {Object} PluginOptions
|
|
31
|
+
* @property {string} context
|
|
32
|
+
* @property {boolean} emitError
|
|
33
|
+
* @property {boolean} emitWarning
|
|
34
|
+
* @property {string|string[]=} exclude
|
|
35
|
+
* @property {string|string[]} extensions
|
|
36
|
+
* @property {boolean} failOnError
|
|
37
|
+
* @property {boolean} failOnWarning
|
|
38
|
+
* @property {string|string[]} files
|
|
39
|
+
* @property {FormatterType} formatter
|
|
40
|
+
* @property {boolean} lintDirtyModulesOnly
|
|
41
|
+
* @property {boolean} quiet
|
|
42
|
+
* @property {string} stylelintPath
|
|
43
|
+
* @property {OutputReport} outputReport
|
|
44
|
+
* @property {number|boolean=} threads
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
/** @typedef {Partial<PluginOptions & StylelintOptions>} Options */
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @param {Options} pluginOptions
|
|
51
|
+
* @returns {Partial<PluginOptions>}
|
|
52
|
+
*/
|
|
53
|
+
function getOptions(pluginOptions) {
|
|
54
|
+
const options = {
|
|
55
|
+
extensions: ['css', 'scss', 'sass'],
|
|
56
|
+
emitError: true,
|
|
57
|
+
emitWarning: true,
|
|
58
|
+
failOnError: true,
|
|
59
|
+
...pluginOptions,
|
|
60
|
+
...(pluginOptions.quiet ? {
|
|
61
|
+
emitError: true,
|
|
62
|
+
emitWarning: false
|
|
63
|
+
} : {})
|
|
64
|
+
}; // @ts-ignore
|
|
65
|
+
|
|
66
|
+
(0, _schemaUtils.validate)(_options.default, options, {
|
|
67
|
+
name: 'Stylelint Webpack Plugin',
|
|
68
|
+
baseDataPath: 'options'
|
|
69
|
+
});
|
|
70
|
+
return options;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* @param {Options} pluginOptions
|
|
74
|
+
* @returns {Partial<StylelintOptions>}
|
|
75
|
+
*/
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
function getStylelintOptions(pluginOptions) {
|
|
79
|
+
const stylelintOptions = { ...pluginOptions
|
|
80
|
+
}; // Keep the files and formatter option because it is common to both the plugin and Stylelint.
|
|
81
|
+
|
|
82
|
+
const {
|
|
83
|
+
files,
|
|
84
|
+
formatter,
|
|
85
|
+
...stylelintOnlyOptions
|
|
86
|
+
} = _options.default.properties; // No need to guard the for-in because schema.properties has hardcoded keys.
|
|
87
|
+
// eslint-disable-next-line guard-for-in
|
|
88
|
+
|
|
89
|
+
for (const option in stylelintOnlyOptions) {
|
|
90
|
+
// @ts-ignore
|
|
91
|
+
delete stylelintOptions[option];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return stylelintOptions;
|
|
95
|
+
}
|
package/dist/options.json
CHANGED
|
@@ -7,15 +7,23 @@
|
|
|
7
7
|
"type": "string"
|
|
8
8
|
},
|
|
9
9
|
"emitError": {
|
|
10
|
-
"description": "
|
|
10
|
+
"description": "The errors found will always be emitted, to disable set to `false`.",
|
|
11
11
|
"type": "boolean"
|
|
12
12
|
},
|
|
13
13
|
"emitWarning": {
|
|
14
|
-
"description": "
|
|
14
|
+
"description": "The warnings found will always be emitted, to disable set to `false`.",
|
|
15
15
|
"type": "boolean"
|
|
16
16
|
},
|
|
17
|
+
"exclude": {
|
|
18
|
+
"description": "Specify the files and/or directories to exclude. Must be relative to `options.context`.",
|
|
19
|
+
"anyOf": [{ "type": "string" }, { "type": "array" }]
|
|
20
|
+
},
|
|
21
|
+
"extensions": {
|
|
22
|
+
"description": "Specify extensions that should be checked.",
|
|
23
|
+
"anyOf": [{ "type": "string" }, { "type": "array" }]
|
|
24
|
+
},
|
|
17
25
|
"failOnError": {
|
|
18
|
-
"description": "Will cause the module build to fail if there are any errors,
|
|
26
|
+
"description": "Will cause the module build to fail if there are any errors, to disable set to `false`.",
|
|
19
27
|
"type": "boolean"
|
|
20
28
|
},
|
|
21
29
|
"failOnWarning": {
|
|
@@ -23,7 +31,7 @@
|
|
|
23
31
|
"type": "boolean"
|
|
24
32
|
},
|
|
25
33
|
"files": {
|
|
26
|
-
"description": "Specify
|
|
34
|
+
"description": "Specify directories, files, or globs. Must be relative to `options.context`. Directories are traveresed recursively looking for files matching `options.extensions`. File and glob patterns ignore `options.extensions`.",
|
|
27
35
|
"anyOf": [{ "type": "string" }, { "type": "array" }]
|
|
28
36
|
},
|
|
29
37
|
"formatter": {
|
|
@@ -41,6 +49,32 @@
|
|
|
41
49
|
"stylelintPath": {
|
|
42
50
|
"description": "Path to `stylelint` instance that will be used for linting.",
|
|
43
51
|
"type": "string"
|
|
52
|
+
},
|
|
53
|
+
"outputReport": {
|
|
54
|
+
"description": "Write the output of the errors to a file, for example a `json` file for use for reporting.",
|
|
55
|
+
"anyOf": [
|
|
56
|
+
{
|
|
57
|
+
"type": "boolean"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"type": "object",
|
|
61
|
+
"additionalProperties": false,
|
|
62
|
+
"properties": {
|
|
63
|
+
"filePath": {
|
|
64
|
+
"description": "The `filePath` is relative to the webpack config: `output.path`.",
|
|
65
|
+
"anyOf": [{ "type": "string" }]
|
|
66
|
+
},
|
|
67
|
+
"formatter": {
|
|
68
|
+
"description": "You can pass in a different formatter for the output file, if none is passed in the default/configured formatter will be used.",
|
|
69
|
+
"anyOf": [{ "type": "string" }, { "instanceof": "Function" }]
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"threads": {
|
|
76
|
+
"description": "Set to true for an auto-selected pool size based on number of cpus. Set to a number greater than 1 to set an explicit pool size. Set to false, 1, or less to disable and only run in main process.",
|
|
77
|
+
"anyOf": [{ "type": "number" }, { "type": "boolean" }]
|
|
44
78
|
}
|
|
45
79
|
}
|
|
46
80
|
}
|
package/dist/utils.js
CHANGED
|
@@ -3,29 +3,84 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.jsonStringifyReplacerSortKeys = void 0;
|
|
6
7
|
exports.parseFiles = parseFiles;
|
|
7
|
-
exports.
|
|
8
|
+
exports.parseFoldersToGlobs = parseFoldersToGlobs;
|
|
9
|
+
|
|
10
|
+
var _path = require("path");
|
|
11
|
+
|
|
12
|
+
var _fs = require("fs");
|
|
13
|
+
|
|
14
|
+
var _normalizePath = _interopRequireDefault(require("normalize-path"));
|
|
8
15
|
|
|
9
16
|
var _arrify = _interopRequireDefault(require("arrify"));
|
|
10
17
|
|
|
11
18
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
19
|
|
|
13
|
-
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
|
|
14
23
|
/**
|
|
15
|
-
* @param {
|
|
24
|
+
* @param {string|(string|undefined)[]} files
|
|
16
25
|
* @param {string} context
|
|
17
|
-
* @returns {
|
|
26
|
+
* @returns {string[]}
|
|
18
27
|
*/
|
|
19
|
-
|
|
20
28
|
function parseFiles(files, context) {
|
|
21
|
-
return (0, _arrify.default)(files).
|
|
29
|
+
return (0, _arrify.default)(files).filter((
|
|
30
|
+
/** @type {string} */
|
|
31
|
+
file) => typeof file === 'string').map((
|
|
32
|
+
/** @type {string} */
|
|
33
|
+
file) => (0, _normalizePath.default)((0, _path.resolve)(context, file)));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @param {string|string[]} patterns
|
|
37
|
+
* @param {string|string[]} extensions
|
|
38
|
+
* @returns {string[]}
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
function parseFoldersToGlobs(patterns, extensions = []) {
|
|
43
|
+
const extensionsList = (0, _arrify.default)(extensions);
|
|
44
|
+
const [prefix, postfix] = extensionsList.length > 1 ? ['{', '}'] : ['', ''];
|
|
45
|
+
const extensionsGlob = extensionsList.map((
|
|
46
|
+
/** @type {string} */
|
|
47
|
+
extension) => extension.replace(/^\./u, '')).join(',');
|
|
48
|
+
return (0, _arrify.default)(patterns).map((
|
|
49
|
+
/** @type {string} */
|
|
50
|
+
pattern) => {
|
|
51
|
+
try {
|
|
52
|
+
// The patterns are absolute because they are prepended with the context.
|
|
53
|
+
const stats = (0, _fs.statSync)(pattern);
|
|
54
|
+
/* istanbul ignore else */
|
|
55
|
+
|
|
56
|
+
if (stats.isDirectory()) {
|
|
57
|
+
return pattern.replace(/[/\\]*?$/u, `/**${extensionsGlob ? `/*.${prefix + extensionsGlob + postfix}` : ''}`);
|
|
58
|
+
}
|
|
59
|
+
} catch (_) {// Return the pattern as is on error.
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return pattern;
|
|
63
|
+
});
|
|
22
64
|
}
|
|
23
65
|
/**
|
|
24
|
-
*
|
|
25
|
-
* @
|
|
66
|
+
*
|
|
67
|
+
* @param {string} _ key, but unused
|
|
68
|
+
* @param {any} value
|
|
26
69
|
*/
|
|
27
70
|
|
|
28
71
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
72
|
+
const jsonStringifyReplacerSortKeys = (_, value) => {
|
|
73
|
+
/**
|
|
74
|
+
* @param {{ [x: string]: any; }} sorted
|
|
75
|
+
* @param {string | number} key
|
|
76
|
+
*/
|
|
77
|
+
const insert = (sorted, key) => {
|
|
78
|
+
// eslint-disable-next-line no-param-reassign
|
|
79
|
+
sorted[key] = value[key];
|
|
80
|
+
return sorted;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return value instanceof Object && !(value instanceof Array) ? Object.keys(value).sort().reduce(insert, {}) : value;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
exports.jsonStringifyReplacerSortKeys = jsonStringifyReplacerSortKeys;
|
package/dist/worker.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/** @typedef {import('stylelint')} Stylelint */
|
|
4
|
+
|
|
5
|
+
/** @typedef {import("stylelint").LinterOptions} StylelintOptions */
|
|
6
|
+
|
|
7
|
+
/** @typedef {import('./options').Options} Options */
|
|
8
|
+
Object.assign(module.exports, {
|
|
9
|
+
lintFiles,
|
|
10
|
+
setup
|
|
11
|
+
});
|
|
12
|
+
/** @type {Stylelint} */
|
|
13
|
+
|
|
14
|
+
let stylelint;
|
|
15
|
+
/** @type {Partial<StylelintOptions>} */
|
|
16
|
+
|
|
17
|
+
let linterOptions;
|
|
18
|
+
/**
|
|
19
|
+
* @param {Options} options
|
|
20
|
+
* @param {Partial<StylelintOptions>} stylelintOptions
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
function setup(options, stylelintOptions) {
|
|
24
|
+
stylelint = require(options.stylelintPath || 'stylelint');
|
|
25
|
+
linterOptions = stylelintOptions;
|
|
26
|
+
return stylelint;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* @param {string | string[]} files
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async function lintFiles(files) {
|
|
34
|
+
const {
|
|
35
|
+
results
|
|
36
|
+
} = await stylelint.lint({ ...linterOptions,
|
|
37
|
+
files
|
|
38
|
+
}); // Reset result to work with worker
|
|
39
|
+
|
|
40
|
+
return results.map(result => {
|
|
41
|
+
return {
|
|
42
|
+
source: result.source,
|
|
43
|
+
errored: result.errored,
|
|
44
|
+
ignored: result.ignored,
|
|
45
|
+
warnings: result.warnings,
|
|
46
|
+
deprecations: result.deprecations,
|
|
47
|
+
invalidOptionWarnings: result.invalidOptionWarnings
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
}
|