UNPKG

3.59 kBJavaScriptView Raw
1'use strict';
2
3const _ = require('lodash');
4
5/** @typedef {import('stylelint').PostcssResult} PostcssResult */
6/** @typedef {import('postcss').NodeSource} NodeSource */
7/** @typedef {import('stylelint').StylelintResult} StylelintResult */
8
9/**
10 * @param {import('stylelint').StylelintInternalApi} stylelint
11 * @param {PostcssResult} [postcssResult]
12 * @param {string} [filePath]
13 * @param {import('stylelint').StylelintCssSyntaxError} [cssSyntaxError]
14 * @return {Promise<StylelintResult>}
15 */
16module.exports = function(stylelint, postcssResult, filePath, cssSyntaxError) {
17 /** @type {StylelintResult} */
18 let stylelintResult;
19 /** @type {string | undefined} */
20 let source;
21
22 if (postcssResult && postcssResult.root) {
23 if (postcssResult.root.source) {
24 source = postcssResult.root.source.input.file;
25
26 if (!source && 'id' in postcssResult.root.source.input) {
27 source = postcssResult.root.source.input.id;
28 }
29 }
30
31 // Strip out deprecation warnings from the messages
32 const deprecationMessages = _.remove(postcssResult.messages, {
33 stylelintType: 'deprecation',
34 });
35 const deprecations = deprecationMessages.map((deprecationMessage) => {
36 return {
37 text: deprecationMessage.text,
38 reference: deprecationMessage.stylelintReference,
39 };
40 });
41
42 // Also strip out invalid options
43 const invalidOptionMessages = _.remove(postcssResult.messages, {
44 stylelintType: 'invalidOption',
45 });
46 const invalidOptionWarnings = invalidOptionMessages.map((invalidOptionMessage) => {
47 return {
48 text: invalidOptionMessage.text,
49 };
50 });
51
52 const parseErrors = _.remove(postcssResult.messages, {
53 stylelintType: 'parseError',
54 });
55
56 // This defines the stylelint result object that formatters receive
57 stylelintResult = {
58 source,
59 deprecations,
60 invalidOptionWarnings,
61 // TODO TYPES check which types are valid? postcss? stylelint?
62 /* eslint-disable-next-line */
63 parseErrors: /** @type {any} */ (parseErrors),
64 errored: postcssResult.stylelint.stylelintError,
65 warnings: postcssResult.messages.map((message) => {
66 return {
67 line: message.line,
68 column: message.column,
69 rule: message.rule,
70 severity: message.severity,
71 text: message.text,
72 };
73 }),
74 ignored: postcssResult.stylelint.ignored,
75 _postcssResult: postcssResult,
76 };
77 } else if (cssSyntaxError) {
78 if (cssSyntaxError.name !== 'CssSyntaxError') {
79 throw cssSyntaxError;
80 }
81
82 stylelintResult = {
83 source: cssSyntaxError.file || '<input css 1>',
84 deprecations: [],
85 invalidOptionWarnings: [],
86 parseErrors: [],
87 errored: true,
88 warnings: [
89 {
90 line: cssSyntaxError.line,
91 column: cssSyntaxError.column,
92 rule: cssSyntaxError.name,
93 severity: 'error',
94 text: `${cssSyntaxError.reason} (${cssSyntaxError.name})`,
95 },
96 ],
97 };
98 } else {
99 throw new Error(
100 'createStylelintResult must be called with either postcssResult or CssSyntaxError',
101 );
102 }
103
104 return stylelint.getConfigForFile(filePath).then((configForFile) => {
105 // TODO TYPES handle possible null here
106 const config =
107 /** @type {{ config: import('stylelint').StylelintConfig, filepath: string }} */ (configForFile).config;
108 const file = source || (cssSyntaxError && cssSyntaxError.file);
109
110 if (config.resultProcessors) {
111 config.resultProcessors.forEach((resultProcessor) => {
112 // Result processors might just mutate the result object,
113 // or might return a new one
114 const returned = resultProcessor(stylelintResult, file);
115
116 if (returned) {
117 stylelintResult = returned;
118 }
119 });
120 }
121
122 return stylelintResult;
123 });
124};