stylelint-webpack-plugin 3.3.0 → 4.0.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 CHANGED
@@ -5,7 +5,6 @@
5
5
 
6
6
  [![npm][npm]][npm-url]
7
7
  [![node][node]][node-url]
8
- [![deps][deps]][deps-url]
9
8
  [![tests][tests]][tests-url]
10
9
  [![coverage][cover]][cover-url]
11
10
  [![chat][chat]][chat-url]
@@ -37,7 +36,9 @@ or
37
36
  pnpm add -D stylelint-webpack-plugin
38
37
  ```
39
38
 
40
- **Note**: You also need to install `stylelint >= 13` from npm, if you haven't already:
39
+ > **Note**:
40
+ >
41
+ > You also need to install `stylelint >= 13` from npm, if you haven't already:
41
42
 
42
43
  ```console
43
44
  npm install stylelint --save-dev
@@ -55,7 +56,9 @@ or
55
56
  pnpm add -D stylelint
56
57
  ```
57
58
 
58
- **Note**: If you are using Stylelint 13 rather than 14+, you might also need to install `@types/stylelint` as a dev dependency if getting stylelint related type errors.
59
+ > **Note**:
60
+ >
61
+ > If you are using Stylelint 13 rather than 14+, you might also need to install `@types/stylelint` as a dev dependency if getting stylelint related type errors.
59
62
 
60
63
  Then add the plugin to your webpack config. For example:
61
64
 
@@ -85,7 +88,9 @@ type context = string;
85
88
 
86
89
  Specify the config file location to be used by `stylelint`.
87
90
 
88
- **Note:** By default this is [handled by `stylelint`](https://stylelint.io/user-guide/configure).
91
+ > **Note:**
92
+ >
93
+ > By default this is [handled by `stylelint`](https://stylelint.io/user-guide/configure).
89
94
 
90
95
  ### `context`
91
96
 
@@ -305,8 +310,6 @@ You can pass in a different formatter for the output file, if none is passed in
305
310
  [npm-url]: https://npmjs.com/package/stylelint-webpack-plugin
306
311
  [node]: https://img.shields.io/node/v/stylelint-webpack-plugin.svg
307
312
  [node-url]: https://nodejs.org
308
- [deps]: https://david-dm.org/webpack-contrib/stylelint-webpack-plugin.svg
309
- [deps-url]: https://david-dm.org/webpack-contrib/stylelint-webpack-plugin
310
313
  [tests]: https://github.com/webpack-contrib/stylelint-webpack-plugin/workflows/stylelint-webpack-plugin/badge.svg
311
314
  [tests-url]: https://github.com/webpack-contrib/stylelint-webpack-plugin/actions
312
315
  [cover]: https://codecov.io/gh/webpack-contrib/stylelint-webpack-plugin/branch/master/graph/badge.svg
@@ -9,7 +9,5 @@ class StylelintError extends Error {
9
9
  this.name = 'StylelintError';
10
10
  this.stack = '';
11
11
  }
12
-
13
12
  }
14
-
15
13
  module.exports = StylelintError;
@@ -3,94 +3,90 @@
3
3
  const {
4
4
  cpus
5
5
  } = require('os');
6
-
7
6
  const {
8
7
  Worker: JestWorker
9
- } = require('jest-worker'); // @ts-ignore
10
-
8
+ } = require('jest-worker');
11
9
 
10
+ // @ts-ignore
12
11
  const {
13
12
  setup,
14
13
  lintFiles
15
14
  } = require('./worker');
16
-
17
15
  const {
18
16
  jsonStringifyReplacerSortKeys
19
17
  } = require('./utils');
20
-
21
18
  const {
22
19
  getStylelintOptions
23
20
  } = require('./options');
24
- /** @type {{[key: string]: any}} */
25
-
26
21
 
22
+ /** @type {{[key: string]: any}} */
27
23
  const cache = {};
28
- /** @typedef {import('stylelint')} Stylelint */
29
24
 
25
+ /** @typedef {import('stylelint')} Stylelint */
30
26
  /** @typedef {import('stylelint').LintResult} LintResult */
31
-
32
27
  /** @typedef {import('./options').Options} Options */
33
-
28
+ /** @typedef {(stylelint: Stylelint, filePath: string) => Promise<boolean>} isPathIgnored */
34
29
  /** @typedef {() => Promise<void>} AsyncTask */
35
-
36
30
  /** @typedef {(files: string|string[]) => Promise<LintResult[]>} LintTask */
37
-
38
- /** @typedef {{api: import('stylelint').InternalApi, stylelint: Stylelint, lintFiles: LintTask, cleanup: AsyncTask, threads: number, }} Linter */
39
-
31
+ /** @typedef {{stylelint: Stylelint, isPathIgnored: isPathIgnored, lintFiles: LintTask, cleanup: AsyncTask, threads: number }} Linter */
40
32
  /** @typedef {JestWorker & {lintFiles: LintTask}} Worker */
41
33
 
42
34
  /**
43
35
  * @param {Options} options
44
36
  * @returns {Linter}
45
37
  */
46
-
47
38
  function loadStylelint(options) {
48
39
  const stylelintOptions = getStylelintOptions(options);
49
40
  const stylelint = setup(options, stylelintOptions);
41
+
42
+ /** @type {isPathIgnored} */
43
+ let isPathIgnored;
44
+ try {
45
+ isPathIgnored = require(`${options.stylelintPath}/lib/isPathIgnored`);
46
+ } catch (e) {
47
+ try {
48
+ // @ts-ignore
49
+ isPathIgnored = require('stylelint/lib/isPathIgnored');
50
+ } catch (_) {
51
+ isPathIgnored = () => Promise.resolve(false);
52
+ }
53
+ }
50
54
  return {
51
55
  stylelint,
52
- api: stylelint.createLinter(stylelintOptions),
56
+ isPathIgnored,
53
57
  lintFiles,
54
58
  cleanup: async () => {},
55
59
  threads: 1
56
60
  };
57
61
  }
62
+
58
63
  /**
59
64
  * @param {string|undefined} key
60
65
  * @param {number} poolSize
61
66
  * @param {Options} options
62
67
  * @returns {Linter}
63
68
  */
64
-
65
-
66
69
  function loadStylelintThreaded(key, poolSize, options) {
67
70
  const cacheKey = getCacheKey(key, options);
68
-
69
71
  const source = require.resolve('./worker');
70
-
71
72
  const workerOptions = {
72
73
  enableWorkerThreads: true,
73
74
  numWorkers: poolSize,
74
75
  setupArgs: [options, getStylelintOptions(options)]
75
76
  };
76
77
  const local = loadStylelint(options);
77
- let worker =
78
- /** @type {Worker?} */
79
- new JestWorker(source, workerOptions);
80
- /** @type {Linter} */
78
+ let worker = /** @type {Worker?} */new JestWorker(source, workerOptions);
81
79
 
82
- const context = { ...local,
80
+ /** @type {Linter} */
81
+ const context = {
82
+ ...local,
83
83
  threads: poolSize,
84
- lintFiles: async files =>
85
- /* istanbul ignore next */
84
+ lintFiles: async files => /* istanbul ignore next */
86
85
  worker ? worker.lintFiles(files) : local.lintFiles(files),
87
86
  cleanup: async () => {
88
87
  cache[cacheKey] = local;
89
-
90
88
  context.lintFiles = files => local.lintFiles(files);
91
89
  /* istanbul ignore next */
92
-
93
-
94
90
  if (worker) {
95
91
  worker.end();
96
92
  worker = null;
@@ -99,13 +95,12 @@ function loadStylelintThreaded(key, poolSize, options) {
99
95
  };
100
96
  return context;
101
97
  }
98
+
102
99
  /**
103
100
  * @param {string|undefined} key
104
101
  * @param {Options} options
105
102
  * @returns {Linter}
106
103
  */
107
-
108
-
109
104
  function getStylelint(key, {
110
105
  threads,
111
106
  ...options
@@ -115,25 +110,21 @@ function getStylelint(key, {
115
110
  threads,
116
111
  ...options
117
112
  });
118
-
119
113
  if (!cache[cacheKey]) {
120
114
  cache[cacheKey] = max > 1 ? loadStylelintThreaded(key, max, options) : loadStylelint(options);
121
115
  }
122
-
123
116
  return cache[cacheKey];
124
117
  }
118
+
125
119
  /**
126
120
  * @param {string|undefined} key
127
121
  * @param {Options} options
128
122
  * @returns {string}
129
123
  */
130
-
131
-
132
124
  function getCacheKey(key, options) {
133
125
  return JSON.stringify({
134
126
  key,
135
127
  options
136
128
  }, jsonStringifyReplacerSortKeys);
137
129
  }
138
-
139
130
  module.exports = getStylelint;
package/dist/index.js CHANGED
@@ -4,36 +4,27 @@ const {
4
4
  isAbsolute,
5
5
  join
6
6
  } = require('path');
7
-
8
7
  const globby = require('globby');
9
-
10
8
  const {
11
9
  isMatch
12
10
  } = require('micromatch');
13
-
14
11
  const {
15
12
  getOptions
16
13
  } = require('./options');
17
-
18
14
  const linter = require('./linter');
19
-
20
15
  const {
21
16
  arrify,
22
17
  parseFiles,
23
18
  parseFoldersToGlobs
24
19
  } = require('./utils');
25
- /** @typedef {import('webpack').Compiler} Compiler */
26
20
 
21
+ /** @typedef {import('webpack').Compiler} Compiler */
27
22
  /** @typedef {import('webpack').Module} Module */
28
-
29
23
  /** @typedef {import('./options').Options} Options */
30
-
31
24
  /** @typedef {Partial<{timestamp:number} | number>} FileSystemInfoEntry */
32
25
 
33
-
34
26
  const STYLELINT_PLUGIN = 'StylelintWebpackPlugin';
35
27
  let counter = 0;
36
-
37
28
  class StylelintWebpackPlugin {
38
29
  /**
39
30
  * @param {Options} options
@@ -45,78 +36,78 @@ class StylelintWebpackPlugin {
45
36
  this.startTime = Date.now();
46
37
  this.prevTimestamps = new Map();
47
38
  }
39
+
48
40
  /**
49
41
  * @param {Compiler} compiler
50
42
  * @returns {void}
51
43
  */
52
-
53
-
54
44
  apply(compiler) {
55
45
  // Generate key for each compilation,
56
46
  // this differentiates one from the other when being cached.
57
47
  this.key = compiler.name || `${this.key}_${counter += 1}`;
58
48
  const context = this.getContext(compiler);
59
49
  const excludeDefault = ['**/node_modules/**', String(compiler.options.output.path)];
60
- const options = { ...this.options,
50
+ const options = {
51
+ ...this.options,
61
52
  context,
62
53
  exclude: parseFiles(this.options.exclude || excludeDefault, context),
63
54
  extensions: arrify(this.options.extensions),
64
55
  files: parseFiles(this.options.files || '', context)
65
56
  };
66
57
  const wanted = parseFoldersToGlobs(options.files, options.extensions);
67
- const exclude = parseFoldersToGlobs(options.exclude); // If `lintDirtyModulesOnly` is disabled,
68
- // execute the linter on the build
58
+ const exclude = parseFoldersToGlobs(options.exclude);
69
59
 
60
+ // If `lintDirtyModulesOnly` is disabled,
61
+ // execute the linter on the build
70
62
  if (!this.options.lintDirtyModulesOnly) {
71
63
  compiler.hooks.run.tapPromise(this.key, c => this.run(c, options, wanted, exclude));
72
64
  }
73
-
74
65
  let isFirstRun = this.options.lintDirtyModulesOnly;
75
66
  compiler.hooks.watchRun.tapPromise(this.key, c => {
76
67
  if (isFirstRun) {
77
68
  isFirstRun = false;
78
69
  return Promise.resolve();
79
70
  }
80
-
81
71
  return this.run(c, options, wanted, exclude);
82
72
  });
83
73
  }
74
+
84
75
  /**
85
76
  * @param {Compiler} compiler
86
77
  * @param {Options} options
87
78
  * @param {string[]} wanted
88
79
  * @param {string[]} exclude
89
80
  */
90
-
91
-
92
81
  async run(compiler, options, wanted, exclude) {
93
82
  // Do not re-hook
94
-
95
83
  /* istanbul ignore if */
96
- if ( // @ts-ignore
84
+ if (
85
+ // @ts-ignore
97
86
  compiler.hooks.thisCompilation.taps.find(({
98
87
  name
99
88
  }) => name === this.key)) {
100
89
  return;
101
90
  }
102
-
103
91
  compiler.hooks.thisCompilation.tap(this.key, compilation => {
92
+ /** @type {import('stylelint')} */
93
+ let stylelint;
94
+
104
95
  /** @type {import('./linter').Linter} */
105
96
  let lint;
106
- /** @type {import('stylelint').InternalApi} */
107
97
 
108
- let api;
109
- /** @type {import('./linter').Reporter} */
98
+ /** @type {import('./linter').isPathIgnored} */
99
+ let isPathIgnored;
110
100
 
101
+ /** @type {import('./linter').Reporter} */
111
102
  let report;
112
- /** @type number */
113
103
 
104
+ /** @type number */
114
105
  let threads;
115
-
116
106
  try {
117
107
  ({
108
+ stylelint,
118
109
  lint,
119
- api,
110
+ isPathIgnored,
120
111
  report,
121
112
  threads
122
113
  } = linter(this.key, options, compilation));
@@ -124,7 +115,6 @@ class StylelintWebpackPlugin {
124
115
  compilation.errors.push(e);
125
116
  return;
126
117
  }
127
-
128
118
  compilation.hooks.finishModules.tapPromise(this.key, async () => {
129
119
  /** @type {string[]} */
130
120
  // @ts-ignore
@@ -137,30 +127,28 @@ class StylelintWebpackPlugin {
137
127
  ignore: exclude
138
128
  })).map(async file => {
139
129
  try {
140
- return (await api.isPathIgnored(file)) ? false : file;
130
+ return (await isPathIgnored(stylelint, file)) ? false : file;
141
131
  } catch (e) {
142
132
  return file;
143
133
  }
144
134
  }))).filter(file => file !== false);
145
-
146
135
  if (threads > 1) {
147
136
  for (const file of files) {
148
- lint(parseFiles(file, options.context || ''));
137
+ lint(parseFiles(file, String(options.context)));
149
138
  }
150
139
  } else if (files.length > 0) {
151
- lint(parseFiles(files, options.context || ''));
140
+ lint(parseFiles(files, String(options.context)));
152
141
  }
153
- }); // await and interpret results
142
+ });
154
143
 
144
+ // await and interpret results
155
145
  compilation.hooks.additionalAssets.tapPromise(this.key, processResults);
156
-
157
146
  async function processResults() {
158
147
  const {
159
148
  errors,
160
149
  warnings,
161
150
  generateReportAsset
162
151
  } = await report();
163
-
164
152
  if (warnings && !options.failOnWarning) {
165
153
  // @ts-ignore
166
154
  compilation.warnings.push(warnings);
@@ -168,7 +156,6 @@ class StylelintWebpackPlugin {
168
156
  // @ts-ignore
169
157
  compilation.errors.push(warnings);
170
158
  }
171
-
172
159
  if (errors && options.failOnError) {
173
160
  // @ts-ignore
174
161
  compilation.errors.push(errors);
@@ -176,32 +163,26 @@ class StylelintWebpackPlugin {
176
163
  // @ts-ignore
177
164
  compilation.warnings.push(errors);
178
165
  }
179
-
180
166
  if (generateReportAsset) {
181
167
  await generateReportAsset(compilation);
182
168
  }
183
169
  }
184
170
  });
185
171
  }
172
+
186
173
  /**
187
174
  *
188
175
  * @param {Compiler} compiler
189
176
  * @returns {string}
190
177
  */
191
-
192
-
193
178
  getContext(compiler) {
194
179
  if (!this.options.context) {
195
180
  return String(compiler.options.context);
196
181
  }
197
-
198
182
  if (!isAbsolute(this.options.context)) {
199
183
  return join(String(compiler.options.context), this.options.context);
200
184
  }
201
-
202
185
  return this.options.context;
203
186
  }
204
-
205
187
  }
206
-
207
188
  module.exports = StylelintWebpackPlugin;
package/dist/linter.js CHANGED
@@ -5,75 +5,59 @@ const {
5
5
  isAbsolute,
6
6
  join
7
7
  } = require('path');
8
-
9
8
  const StylelintError = require('./StylelintError');
10
-
11
9
  const getStylelint = require('./getStylelint');
12
-
13
10
  const {
14
11
  arrify
15
12
  } = require('./utils');
16
- /** @typedef {import('stylelint')} Stylelint */
17
13
 
14
+ /** @typedef {import('stylelint')} Stylelint */
18
15
  /** @typedef {import('stylelint').LintResult} LintResult */
19
-
20
- /** @typedef {import('stylelint').InternalApi} InternalApi */
21
-
16
+ /** @typedef {import('stylelint').LinterResult} LinterResult */
17
+ /** @typedef {import('stylelint').Formatter} Formatter */
18
+ /** @typedef {import('stylelint').FormatterType} FormatterType */
22
19
  /** @typedef {import('webpack').Compiler} Compiler */
23
-
24
20
  /** @typedef {import('webpack').Compilation} Compilation */
25
-
26
21
  /** @typedef {import('./options').Options} Options */
27
-
28
- /** @typedef {import('./options').FormatterType} FormatterType */
29
-
30
- /** @typedef {((results: LintResult[]) => string)} FormatterFunction */
31
-
22
+ /** @typedef {import('./getStylelint').isPathIgnored} isPathIgnored */
32
23
  /** @typedef {(compilation: Compilation) => Promise<void>} GenerateReport */
33
-
34
24
  /** @typedef {{errors?: StylelintError, warnings?: StylelintError, generateReportAsset?: GenerateReport}} Report */
35
-
36
25
  /** @typedef {() => Promise<Report>} Reporter */
37
-
38
26
  /** @typedef {(files: string|string[]) => void} Linter */
39
-
40
27
  /** @typedef {{[files: string]: LintResult}} LintResultMap */
41
28
 
42
29
  /** @type {WeakMap<Compiler, LintResultMap>} */
43
-
44
-
45
30
  const resultStorage = new WeakMap();
31
+
46
32
  /**
47
33
  * @param {string|undefined} key
48
34
  * @param {Options} options
49
35
  * @param {Compilation} compilation
50
- * @returns {{api: InternalApi, lint: Linter, report: Reporter, threads: number}}
36
+ * @returns {{stylelint: Stylelint, isPathIgnored: isPathIgnored, lint: Linter, report: Reporter, threads: number}}
51
37
  */
52
-
53
38
  function linter(key, options, compilation) {
54
39
  /** @type {Stylelint} */
55
40
  let stylelint;
56
- /** @type {InternalApi} */
57
41
 
58
- let api;
59
- /** @type {(files: string|string[]) => Promise<LintResult[]>} */
42
+ /** @type {isPathIgnored} */
43
+ let isPathIgnored;
60
44
 
45
+ /** @type {(files: string|string[]) => Promise<LintResult[]>} */
61
46
  let lintFiles;
62
- /** @type {() => Promise<void>} */
63
47
 
48
+ /** @type {() => Promise<void>} */
64
49
  let cleanup;
65
- /** @type number */
66
50
 
51
+ /** @type number */
67
52
  let threads;
68
- /** @type {Promise<LintResult[]>[]} */
69
53
 
54
+ /** @type {Promise<LintResult[]>[]} */
70
55
  const rawResults = [];
71
56
  const crossRunResultStorage = getResultStorage(compilation);
72
-
73
57
  try {
74
58
  ({
75
59
  stylelint,
76
- api,
60
+ isPathIgnored,
77
61
  lintFiles,
78
62
  cleanup,
79
63
  threads
@@ -81,60 +65,68 @@ function linter(key, options, compilation) {
81
65
  } catch (e) {
82
66
  throw new StylelintError(e.message);
83
67
  }
84
-
85
68
  return {
69
+ stylelint,
86
70
  lint,
87
- api,
71
+ isPathIgnored,
88
72
  report,
89
73
  threads
90
74
  };
75
+
91
76
  /**
92
77
  * @param {string | string[]} files
93
78
  */
94
-
95
79
  function lint(files) {
96
80
  for (const file of arrify(files)) {
97
81
  delete crossRunResultStorage[file];
98
82
  }
99
-
100
83
  rawResults.push(lintFiles(files).catch(e => {
101
84
  // @ts-ignore
102
85
  compilation.errors.push(new StylelintError(e.message));
103
86
  return [];
104
87
  }));
105
88
  }
106
-
107
89
  async function report() {
108
90
  // Filter out ignored files.
109
- let results = removeIgnoredWarnings( // Get the current results, resetting the rawResults to empty
91
+ let results = removeIgnoredWarnings(
92
+ // Get the current results, resetting the rawResults to empty
110
93
  await flatten(rawResults.splice(0, rawResults.length)));
111
94
  await cleanup();
112
-
113
95
  for (const result of results) {
114
96
  crossRunResultStorage[String(result.source)] = result;
115
97
  }
98
+ results = Object.values(crossRunResultStorage);
116
99
 
117
- results = Object.values(crossRunResultStorage); // do not analyze if there are no results or stylelint config
118
-
100
+ // do not analyze if there are no results or stylelint config
119
101
  if (!results || results.length < 1) {
120
102
  return {};
121
103
  }
122
-
123
104
  const formatter = loadFormatter(stylelint, options.formatter);
105
+
106
+ /** @type {LinterResult} */
107
+ const returnValue = {
108
+ // @ts-ignore
109
+ cwd: options.cwd,
110
+ errored: false,
111
+ results: [],
112
+ output: '',
113
+ reportedDisables: [],
114
+ ruleMetadata: getRuleMetadata(results)
115
+ };
124
116
  const {
125
117
  errors,
126
118
  warnings
127
- } = formatResults(formatter, parseResults(options, results));
119
+ } = formatResults(formatter, parseResults(options, results), returnValue);
128
120
  return {
129
121
  errors,
130
122
  warnings,
131
123
  generateReportAsset
132
124
  };
125
+
133
126
  /**
134
127
  * @param {Compilation} compilation
135
128
  * @returns {Promise<void>}
136
129
  */
137
-
138
130
  async function generateReportAsset({
139
131
  compiler
140
132
  }) {
@@ -145,16 +137,14 @@ function linter(key, options, compilation) {
145
137
  * @param {string} name
146
138
  * @param {string | Buffer} content
147
139
  */
148
-
149
- const save = (name, content) =>
150
- /** @type {Promise<void>} */
140
+ const save = (name, content) => /** @type {Promise<void>} */
151
141
  new Promise((finish, bail) => {
152
142
  const {
153
143
  mkdir,
154
144
  writeFile
155
- } = compiler.outputFileSystem; // ensure directory exists
145
+ } = compiler.outputFileSystem;
146
+ // ensure directory exists
156
147
  // @ts-ignore - the types for `outputFileSystem` are missing the 3 arg overload
157
-
158
148
  mkdir(dirname(name), {
159
149
  recursive: true
160
150
  }, err => {
@@ -165,74 +155,67 @@ function linter(key, options, compilation) {
165
155
  });
166
156
  });
167
157
  });
168
-
169
158
  if (!outputReport || !outputReport.filePath) {
170
159
  return;
171
160
  }
172
-
173
- const content = outputReport.formatter ? loadFormatter(stylelint, outputReport.formatter)(results) : formatter(results);
161
+ const content = outputReport.formatter;
162
+ loadFormatter(stylelint, outputReport.formatter)(results, returnValue);
163
+ formatter(results, returnValue);
174
164
  let {
175
165
  filePath
176
166
  } = outputReport;
177
-
178
167
  if (!isAbsolute(filePath)) {
179
168
  filePath = join(compiler.outputPath, filePath);
180
169
  }
181
-
182
- await save(filePath, content);
170
+ await save(filePath, String(content));
183
171
  }
184
172
  }
185
173
  }
174
+
186
175
  /**
187
- * @param {FormatterFunction} formatter
176
+ * @param {Formatter} formatter
188
177
  * @param {{ errors: LintResult[]; warnings: LintResult[]; }} results
178
+ * @param {LinterResult} returnValue
189
179
  * @returns {{errors?: StylelintError, warnings?: StylelintError}}
190
180
  */
191
-
192
-
193
- function formatResults(formatter, results) {
181
+ function formatResults(formatter, results, returnValue) {
194
182
  let errors;
195
183
  let warnings;
196
-
197
184
  if (results.warnings.length > 0) {
198
- warnings = new StylelintError(formatter(results.warnings));
185
+ warnings = new StylelintError(formatter(results.warnings, returnValue));
199
186
  }
200
-
201
187
  if (results.errors.length > 0) {
202
- errors = new StylelintError(formatter(results.errors));
188
+ errors = new StylelintError(formatter(results.errors, returnValue));
203
189
  }
204
-
205
190
  return {
206
191
  errors,
207
192
  warnings
208
193
  };
209
194
  }
195
+
210
196
  /**
211
197
  * @param {Options} options
212
198
  * @param {LintResult[]} results
213
199
  * @returns {{errors: LintResult[], warnings: LintResult[]}}
214
200
  */
215
-
216
-
217
201
  function parseResults(options, results) {
218
202
  /** @type {LintResult[]} */
219
203
  const errors = [];
220
- /** @type {LintResult[]} */
221
204
 
205
+ /** @type {LintResult[]} */
222
206
  const warnings = [];
223
207
  results.forEach(file => {
224
208
  const fileErrors = file.warnings.filter(message => options.emitError && message.severity === 'error');
225
-
226
209
  if (fileErrors.length > 0) {
227
- errors.push({ ...file,
210
+ errors.push({
211
+ ...file,
228
212
  warnings: fileErrors
229
213
  });
230
214
  }
231
-
232
215
  const fileWarnings = file.warnings.filter(message => options.emitWarning && message.severity === 'warning');
233
-
234
216
  if (fileWarnings.length > 0) {
235
- warnings.push({ ...file,
217
+ warnings.push({
218
+ ...file,
236
219
  warnings: fileWarnings
237
220
  });
238
221
  }
@@ -242,67 +225,75 @@ function parseResults(options, results) {
242
225
  warnings
243
226
  };
244
227
  }
228
+
245
229
  /**
246
230
  * @param {Stylelint} stylelint
247
231
  * @param {FormatterType=} formatter
248
- * @returns {FormatterFunction}
232
+ * @returns {Formatter}
249
233
  */
250
-
251
-
252
234
  function loadFormatter(stylelint, formatter) {
253
235
  if (typeof formatter === 'function') {
254
236
  return formatter;
255
237
  }
256
-
257
238
  if (typeof formatter === 'string') {
258
239
  try {
259
240
  return stylelint.formatters[formatter];
260
- } catch (_) {// Load the default formatter.
241
+ } catch (_) {
242
+ // Load the default formatter.
261
243
  }
262
244
  }
263
-
264
245
  return stylelint.formatters.string;
265
246
  }
247
+
266
248
  /**
267
249
  * @param {LintResult[]} results
268
250
  * @returns {LintResult[]}
269
251
  */
270
-
271
-
272
252
  function removeIgnoredWarnings(results) {
273
253
  return results.filter(result => !result.ignored);
274
254
  }
255
+
275
256
  /**
276
257
  * @param {Promise<LintResult[]>[]} results
277
258
  * @returns {Promise<LintResult[]>}
278
259
  */
279
-
280
-
281
260
  async function flatten(results) {
282
261
  /**
283
262
  * @param {LintResult[]} acc
284
263
  * @param {LintResult[]} list
285
264
  */
286
265
  const flat = (acc, list) => [...acc, ...list];
287
-
288
266
  return (await Promise.all(results)).reduce(flat, []);
289
267
  }
268
+
290
269
  /**
291
270
  * @param {Compilation} compilation
292
271
  * @returns {LintResultMap}
293
272
  */
294
-
295
-
296
273
  function getResultStorage({
297
274
  compiler
298
275
  }) {
299
276
  let storage = resultStorage.get(compiler);
300
-
301
277
  if (!storage) {
302
278
  resultStorage.set(compiler, storage = {});
303
279
  }
304
-
305
280
  return storage;
306
281
  }
307
282
 
283
+ /**
284
+ * @param {LintResult[]} lintResults
285
+ */
286
+ /* istanbul ignore next */
287
+ function getRuleMetadata(lintResults) {
288
+ const [lintResult] = lintResults;
289
+
290
+ // eslint-disable-next-line no-undefined
291
+ if (lintResult === undefined) return {};
292
+
293
+ // eslint-disable-next-line no-underscore-dangle, no-undefined
294
+ if (lintResult._postcssResult === undefined) return {};
295
+
296
+ // eslint-disable-next-line no-underscore-dangle
297
+ return lintResult._postcssResult.stylelint.ruleMetadata;
298
+ }
308
299
  module.exports = linter;
package/dist/options.js CHANGED
@@ -3,12 +3,10 @@
3
3
  const {
4
4
  validate
5
5
  } = require('schema-utils');
6
-
7
6
  const schema = require('./options.json');
8
- /** @typedef {import("stylelint")} stylelint */
9
7
 
8
+ /** @typedef {import("stylelint")} stylelint */
10
9
  /** @typedef {import("stylelint").LinterOptions} StylelintOptions */
11
-
12
10
  /** @typedef {import("stylelint").FormatterType} FormatterType */
13
11
 
14
12
  /**
@@ -41,8 +39,6 @@ const schema = require('./options.json');
41
39
  * @param {Options} pluginOptions
42
40
  * @returns {Partial<PluginOptions>}
43
41
  */
44
-
45
-
46
42
  function getOptions(pluginOptions) {
47
43
  const options = {
48
44
  extensions: ['css', 'scss', 'sass'],
@@ -54,39 +50,40 @@ function getOptions(pluginOptions) {
54
50
  emitError: true,
55
51
  emitWarning: false
56
52
  } : {})
57
- }; // @ts-ignore
53
+ };
58
54
 
55
+ // @ts-ignore
59
56
  validate(schema, options, {
60
57
  name: 'Stylelint Webpack Plugin',
61
58
  baseDataPath: 'options'
62
59
  });
63
60
  return options;
64
61
  }
62
+
65
63
  /**
66
64
  * @param {Options} pluginOptions
67
65
  * @returns {Partial<StylelintOptions>}
68
66
  */
69
-
70
-
71
67
  function getStylelintOptions(pluginOptions) {
72
- const stylelintOptions = { ...pluginOptions
73
- }; // Keep the files and formatter option because it is common to both the plugin and Stylelint.
68
+ const stylelintOptions = {
69
+ ...pluginOptions
70
+ };
74
71
 
72
+ // Keep the files and formatter option because it is common to both the plugin and Stylelint.
75
73
  const {
76
74
  files,
77
75
  formatter,
78
76
  ...stylelintOnlyOptions
79
- } = schema.properties; // No need to guard the for-in because schema.properties has hardcoded keys.
80
- // eslint-disable-next-line guard-for-in
77
+ } = schema.properties;
81
78
 
79
+ // No need to guard the for-in because schema.properties has hardcoded keys.
80
+ // eslint-disable-next-line guard-for-in
82
81
  for (const option in stylelintOnlyOptions) {
83
82
  // @ts-ignore
84
83
  delete stylelintOptions[option];
85
84
  }
86
-
87
85
  return stylelintOptions;
88
86
  }
89
-
90
87
  module.exports = {
91
88
  getOptions,
92
89
  getStylelintOptions
package/dist/options.json CHANGED
@@ -31,7 +31,7 @@
31
31
  "type": "boolean"
32
32
  },
33
33
  "files": {
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`.",
34
+ "description": "Specify directories, files, or globs. Must be relative to `options.context`. Directories are traversed recursively looking for files matching `options.extensions`. File and glob patterns ignore `options.extensions`.",
35
35
  "anyOf": [{ "type": "string" }, { "type": "array" }]
36
36
  },
37
37
  "formatter": {
package/dist/utils.js CHANGED
@@ -3,12 +3,11 @@
3
3
  const {
4
4
  resolve
5
5
  } = require('path');
6
-
7
6
  const {
8
7
  statSync
9
8
  } = require('fs');
10
-
11
9
  const normalizePath = require('normalize-path');
10
+
12
11
  /**
13
12
  * @template T
14
13
  * @param {T} value
@@ -24,85 +23,70 @@ const normalizePath = require('normalize-path');
24
23
  : [T]
25
24
  }
26
25
  */
27
-
28
26
  /* istanbul ignore next */
29
-
30
-
31
27
  function arrify(value) {
32
28
  // eslint-disable-next-line no-undefined
33
29
  if (value === null || value === undefined) {
34
30
  // @ts-ignore
35
31
  return [];
36
32
  }
37
-
38
33
  if (Array.isArray(value)) {
39
34
  // @ts-ignore
40
35
  return value;
41
36
  }
42
-
43
37
  if (typeof value === 'string') {
44
38
  // @ts-ignore
45
39
  return [value];
46
- } // @ts-ignore
47
-
40
+ }
48
41
 
42
+ // @ts-ignore
49
43
  if (typeof value[Symbol.iterator] === 'function') {
50
44
  // @ts-ignore
51
45
  return [...value];
52
- } // @ts-ignore
53
-
46
+ }
54
47
 
48
+ // @ts-ignore
55
49
  return [value];
56
50
  }
51
+
57
52
  /**
58
53
  * @param {string|string[]} files
59
54
  * @param {string} context
60
55
  * @returns {string[]}
61
56
  */
62
-
63
-
64
57
  function parseFiles(files, context) {
65
- return arrify(files).map((
66
- /** @type {string} */
67
- file) => normalizePath(resolve(context, file)));
58
+ return arrify(files).map(( /** @type {string} */file) => normalizePath(resolve(context, file)));
68
59
  }
60
+
69
61
  /**
70
62
  * @param {string|string[]} patterns
71
63
  * @param {string|string[]} extensions
72
64
  * @returns {string[]}
73
65
  */
74
-
75
-
76
66
  function parseFoldersToGlobs(patterns, extensions = []) {
77
67
  const extensionsList = arrify(extensions);
78
68
  const [prefix, postfix] = extensionsList.length > 1 ? ['{', '}'] : ['', ''];
79
- const extensionsGlob = extensionsList.map((
80
- /** @type {string} */
81
- extension) => extension.replace(/^\./u, '')).join(',');
82
- return arrify(patterns).map((
83
- /** @type {string} */
84
- pattern) => {
69
+ const extensionsGlob = extensionsList.map(( /** @type {string} */extension) => extension.replace(/^\./u, '')).join(',');
70
+ return arrify(patterns).map(( /** @type {string} */pattern) => {
85
71
  try {
86
72
  // The patterns are absolute because they are prepended with the context.
87
73
  const stats = statSync(pattern);
88
74
  /* istanbul ignore else */
89
-
90
75
  if (stats.isDirectory()) {
91
76
  return pattern.replace(/[/\\]*?$/u, `/**${extensionsGlob ? `/*.${prefix + extensionsGlob + postfix}` : ''}`);
92
77
  }
93
- } catch (_) {// Return the pattern as is on error.
78
+ } catch (_) {
79
+ // Return the pattern as is on error.
94
80
  }
95
-
96
81
  return pattern;
97
82
  });
98
83
  }
84
+
99
85
  /**
100
86
  *
101
87
  * @param {string} _ key, but unused
102
88
  * @param {any} value
103
89
  */
104
-
105
-
106
90
  const jsonStringifyReplacerSortKeys = (_, value) => {
107
91
  /**
108
92
  * @param {{ [x: string]: any; }} sorted
@@ -113,10 +97,8 @@ const jsonStringifyReplacerSortKeys = (_, value) => {
113
97
  sorted[key] = value[key];
114
98
  return sorted;
115
99
  };
116
-
117
100
  return value instanceof Object && !(value instanceof Array) ? Object.keys(value).sort().reduce(insert, {}) : value;
118
101
  };
119
-
120
102
  module.exports = {
121
103
  arrify,
122
104
  parseFiles,
package/dist/worker.js CHANGED
@@ -1,42 +1,42 @@
1
1
  "use strict";
2
2
 
3
3
  /** @typedef {import('stylelint')} Stylelint */
4
-
5
4
  /** @typedef {import("stylelint").LinterOptions} StylelintOptions */
6
-
7
5
  /** @typedef {import('./options').Options} Options */
6
+
8
7
  Object.assign(module.exports, {
9
8
  lintFiles,
10
9
  setup
11
10
  });
12
- /** @type {Stylelint} */
13
11
 
12
+ /** @type {Stylelint} */
14
13
  let stylelint;
15
- /** @type {Partial<StylelintOptions>} */
16
14
 
15
+ /** @type {Partial<StylelintOptions>} */
17
16
  let linterOptions;
17
+
18
18
  /**
19
19
  * @param {Options} options
20
20
  * @param {Partial<StylelintOptions>} stylelintOptions
21
21
  */
22
-
23
22
  function setup(options, stylelintOptions) {
24
23
  stylelint = require(options.stylelintPath || 'stylelint');
25
24
  linterOptions = stylelintOptions;
26
25
  return stylelint;
27
26
  }
27
+
28
28
  /**
29
29
  * @param {string | string[]} files
30
30
  */
31
-
32
-
33
31
  async function lintFiles(files) {
34
32
  const {
35
33
  results
36
- } = await stylelint.lint({ ...linterOptions,
34
+ } = await stylelint.lint({
35
+ ...linterOptions,
37
36
  files
38
- }); // Reset result to work with worker
37
+ });
39
38
 
39
+ // Reset result to work with worker
40
40
  return results.map(result => {
41
41
  return {
42
42
  source: result.source,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stylelint-webpack-plugin",
3
- "version": "3.3.0",
3
+ "version": "4.0.0",
4
4
  "description": "A Stylelint plugin for webpack",
5
5
  "license": "MIT",
6
6
  "repository": "webpack-contrib/stylelint-webpack-plugin",
@@ -14,7 +14,7 @@
14
14
  "main": "dist/index.js",
15
15
  "types": "types/index.d.ts",
16
16
  "engines": {
17
- "node": ">= 12.13.0"
17
+ "node": ">= 14.15.0"
18
18
  },
19
19
  "scripts": {
20
20
  "start": "npm run build -- -w",
@@ -27,6 +27,7 @@
27
27
  "security": "npm audit",
28
28
  "lint:prettier": "prettier -w --list-different .",
29
29
  "lint:js": "eslint --cache .",
30
+ "lint:spelling": "cspell \"**/*.*\"",
30
31
  "lint:types": "tsc --pretty --noEmit",
31
32
  "lint": "npm-run-all -l -p \"lint:**\"",
32
33
  "test:only": "cross-env NODE_ENV=test jest --testTimeout=60000",
@@ -46,44 +47,47 @@
46
47
  "webpack": "^5.0.0"
47
48
  },
48
49
  "dependencies": {
49
- "jest-worker": "^28.1.0",
50
50
  "globby": "^11.1.0",
51
+ "jest-worker": "^29.4.1",
51
52
  "micromatch": "^4.0.5",
52
53
  "normalize-path": "^3.0.0",
53
54
  "schema-utils": "^4.0.0"
54
55
  },
55
56
  "devDependencies": {
56
- "@babel/cli": "^7.17.10",
57
- "@babel/core": "^7.18.0",
58
- "@babel/preset-env": "^7.18.0",
59
- "@commitlint/cli": "^16.2.3",
60
- "@commitlint/config-conventional": "^16.2.1",
57
+ "@babel/cli": "^7.20.7",
58
+ "@babel/core": "^7.20.12",
59
+ "@babel/preset-env": "^7.20.2",
60
+ "@commitlint/cli": "^17.4.2",
61
+ "@commitlint/config-conventional": "^17.4.2",
62
+ "@types/file-entry-cache": "^5.0.2",
61
63
  "@types/fs-extra": "^9.0.13",
62
64
  "@types/micromatch": "^4.0.2",
65
+ "@types/node": "^18.11.18",
63
66
  "@types/normalize-path": "^3.0.0",
64
67
  "@types/webpack": "^5.28.0",
65
68
  "@webpack-contrib/eslint-config-webpack": "^3.0.0",
66
69
  "babel-eslint": "^10.1.0",
67
- "babel-jest": "^28.1.0",
70
+ "babel-jest": "^29.4.1",
68
71
  "chokidar": "^3.5.3",
69
72
  "cross-env": "^7.0.3",
70
- "del": "^6.1.0",
73
+ "cspell": "^6.20.1",
74
+ "del": "^6.1.1",
71
75
  "del-cli": "^4.0.1",
72
- "eslint": "^8.15.0",
73
- "eslint-config-prettier": "^8.5.0",
74
- "eslint-plugin-import": "^2.26.0",
76
+ "eslint": "^8.33.0",
77
+ "eslint-config-prettier": "^8.6.0",
78
+ "eslint-plugin-import": "^2.27.5",
75
79
  "file-loader": "^6.2.0",
76
80
  "fs-extra": "^10.1.0",
77
- "husky": "^7.0.4",
78
- "jest": "^28.1.0",
79
- "lint-staged": "^12.4.1",
81
+ "husky": "^8.0.3",
82
+ "jest": "^29.4.1",
83
+ "lint-staged": "^13.1.0",
80
84
  "npm-run-all": "^4.1.5",
81
- "postcss-scss": "^4.0.4",
82
- "prettier": "^2.6.2",
85
+ "postcss-scss": "^4.0.6",
86
+ "prettier": "^2.8.3",
83
87
  "standard-version": "^9.5.0",
84
- "stylelint": "^14.8.2",
85
- "typescript": "^4.6.2",
86
- "webpack": "^5.72.1"
88
+ "stylelint": "^14.16.1",
89
+ "typescript": "^4.9.5",
90
+ "webpack": "^5.75.0"
87
91
  },
88
92
  "keywords": [
89
93
  "stylelint",
@@ -14,6 +14,7 @@ declare namespace getStylelint {
14
14
  Stylelint,
15
15
  LintResult,
16
16
  Options,
17
+ isPathIgnored,
17
18
  AsyncTask,
18
19
  LintTask,
19
20
  Linter,
@@ -22,8 +23,8 @@ declare namespace getStylelint {
22
23
  }
23
24
  type Options = import('./options').Options;
24
25
  type Linter = {
25
- api: import('stylelint').InternalApi;
26
26
  stylelint: Stylelint;
27
+ isPathIgnored: isPathIgnored;
27
28
  lintFiles: LintTask;
28
29
  cleanup: AsyncTask;
29
30
  threads: number;
@@ -42,7 +43,7 @@ type Stylelint = import('postcss').PluginCreator<
42
43
  };
43
44
  createPlugin: (
44
45
  ruleName: string,
45
- plugin: import('stylelint').Plugin<any, any>
46
+ rule: import('stylelint').Rule<any, any>
46
47
  ) => {
47
48
  ruleName: string;
48
49
  rule: import('stylelint').Rule<any, any>;
@@ -78,12 +79,21 @@ type Stylelint = import('postcss').PluginCreator<
78
79
  ruleName: string;
79
80
  ruleSettings: import('stylelint').ConfigRuleSettings<T_1, O>;
80
81
  root: import('postcss').Root;
82
+ result?: import('stylelint').PostcssResult | undefined;
83
+ context?: import('stylelint').RuleContext | undefined;
81
84
  },
82
85
  callback: (warning: import('postcss').Warning) => void
83
86
  ) => void;
84
87
  };
88
+ reference: {
89
+ longhandSubPropertiesOfShorthandProperties: import('stylelint').LonghandSubPropertiesOfShorthandProperties;
90
+ };
85
91
  };
86
92
  type LintResult = import('stylelint').LintResult;
93
+ type isPathIgnored = (
94
+ stylelint: Stylelint,
95
+ filePath: string
96
+ ) => Promise<boolean>;
87
97
  type AsyncTask = () => Promise<void>;
88
98
  type LintTask = (files: string | string[]) => Promise<LintResult[]>;
89
99
  type Worker = JestWorker & {
package/types/linter.d.ts CHANGED
@@ -4,14 +4,15 @@ export = linter;
4
4
  * @param {string|undefined} key
5
5
  * @param {Options} options
6
6
  * @param {Compilation} compilation
7
- * @returns {{api: InternalApi, lint: Linter, report: Reporter, threads: number}}
7
+ * @returns {{stylelint: Stylelint, isPathIgnored: isPathIgnored, lint: Linter, report: Reporter, threads: number}}
8
8
  */
9
9
  declare function linter(
10
10
  key: string | undefined,
11
11
  options: Options,
12
12
  compilation: Compilation
13
13
  ): {
14
- api: InternalApi;
14
+ stylelint: Stylelint;
15
+ isPathIgnored: getStylelint.isPathIgnored;
15
16
  lint: Linter;
16
17
  report: Reporter;
17
18
  threads: number;
@@ -20,12 +21,13 @@ declare namespace linter {
20
21
  export {
21
22
  Stylelint,
22
23
  LintResult,
23
- InternalApi,
24
+ LinterResult,
25
+ Formatter,
26
+ FormatterType,
24
27
  Compiler,
25
28
  Compilation,
26
29
  Options,
27
- FormatterType,
28
- FormatterFunction,
30
+ isPathIgnored,
29
31
  GenerateReport,
30
32
  Report,
31
33
  Reporter,
@@ -35,9 +37,6 @@ declare namespace linter {
35
37
  }
36
38
  type Options = import('./options').Options;
37
39
  type Compilation = import('webpack').Compilation;
38
- type InternalApi = import('stylelint').InternalApi;
39
- type Linter = (files: string | string[]) => void;
40
- type Reporter = () => Promise<Report>;
41
40
  type Stylelint = import('postcss').PluginCreator<
42
41
  import('stylelint').PostcssPluginOptions
43
42
  > & {
@@ -52,7 +51,7 @@ type Stylelint = import('postcss').PluginCreator<
52
51
  };
53
52
  createPlugin: (
54
53
  ruleName: string,
55
- plugin: import('stylelint').Plugin<any, any>
54
+ rule: import('stylelint').Rule<any, any>
56
55
  ) => {
57
56
  ruleName: string;
58
57
  rule: import('stylelint').Rule<any, any>;
@@ -88,15 +87,25 @@ type Stylelint = import('postcss').PluginCreator<
88
87
  ruleName: string;
89
88
  ruleSettings: import('stylelint').ConfigRuleSettings<T_1, O>;
90
89
  root: import('postcss').Root;
90
+ result?: import('stylelint').PostcssResult | undefined;
91
+ context?: import('stylelint').RuleContext | undefined;
91
92
  },
92
93
  callback: (warning: import('postcss').Warning) => void
93
94
  ) => void;
94
95
  };
96
+ reference: {
97
+ longhandSubPropertiesOfShorthandProperties: import('stylelint').LonghandSubPropertiesOfShorthandProperties;
98
+ };
95
99
  };
100
+ type Linter = (files: string | string[]) => void;
101
+ type Reporter = () => Promise<Report>;
102
+ import getStylelint = require('./getStylelint');
96
103
  type LintResult = import('stylelint').LintResult;
104
+ type LinterResult = import('stylelint').LinterResult;
105
+ type Formatter = import('stylelint').Formatter;
106
+ type FormatterType = import('stylelint').FormatterType;
97
107
  type Compiler = import('webpack').Compiler;
98
- type FormatterType = import('./options').FormatterType;
99
- type FormatterFunction = (results: LintResult[]) => string;
108
+ type isPathIgnored = import('./getStylelint').isPathIgnored;
100
109
  type GenerateReport = (compilation: Compilation) => Promise<void>;
101
110
  type Report = {
102
111
  errors?: StylelintError;
@@ -13,7 +13,7 @@ export type stylelint = import('postcss').PluginCreator<
13
13
  };
14
14
  createPlugin: (
15
15
  ruleName: string,
16
- plugin: import('stylelint').Plugin<any, any>
16
+ rule: import('stylelint').Rule<any, any>
17
17
  ) => {
18
18
  ruleName: string;
19
19
  rule: import('stylelint').Rule<any, any>;
@@ -49,10 +49,15 @@ export type stylelint = import('postcss').PluginCreator<
49
49
  ruleName: string;
50
50
  ruleSettings: import('stylelint').ConfigRuleSettings<T_1, O>;
51
51
  root: import('postcss').Root;
52
+ result?: import('stylelint').PostcssResult | undefined;
53
+ context?: import('stylelint').RuleContext | undefined;
52
54
  },
53
55
  callback: (warning: import('postcss').Warning) => void
54
56
  ) => void;
55
57
  };
58
+ reference: {
59
+ longhandSubPropertiesOfShorthandProperties: import('stylelint').LonghandSubPropertiesOfShorthandProperties;
60
+ };
56
61
  };
57
62
  export type StylelintOptions = import('stylelint').LinterOptions;
58
63
  export type FormatterType = import('stylelint').FormatterType;
package/types/worker.d.ts CHANGED
@@ -13,7 +13,7 @@ export type Stylelint = import('postcss').PluginCreator<
13
13
  };
14
14
  createPlugin: (
15
15
  ruleName: string,
16
- plugin: import('stylelint').Plugin<any, any>
16
+ rule: import('stylelint').Rule<any, any>
17
17
  ) => {
18
18
  ruleName: string;
19
19
  rule: import('stylelint').Rule<any, any>;
@@ -49,10 +49,15 @@ export type Stylelint = import('postcss').PluginCreator<
49
49
  ruleName: string;
50
50
  ruleSettings: import('stylelint').ConfigRuleSettings<T_1, O>;
51
51
  root: import('postcss').Root;
52
+ result?: import('stylelint').PostcssResult | undefined;
53
+ context?: import('stylelint').RuleContext | undefined;
52
54
  },
53
55
  callback: (warning: import('postcss').Warning) => void
54
56
  ) => void;
55
57
  };
58
+ reference: {
59
+ longhandSubPropertiesOfShorthandProperties: import('stylelint').LonghandSubPropertiesOfShorthandProperties;
60
+ };
56
61
  };
57
62
  export type StylelintOptions = import('stylelint').LinterOptions;
58
63
  export type Options = import('./options').Options;