UNPKG

4.41 kBJavaScriptView Raw
1/* @flow */
2"use strict";
3
4const _ = require("lodash");
5
6/*:: type messageType = {
7 type: string,
8 text: string,
9 line: number,
10 column: number,
11 severity: string,
12 rule: string,
13 node: Object,
14 index: number,
15 stylelintType?: string,
16 stylelintReference?: string,
17}
18*/
19
20/*:: type postcssResultType = {
21 processor: {
22 version: string,
23 plugins: Array<any>,
24 },
25 messages: Array<messageType>,
26 root: {
27 raws: {
28 semicolon: boolean,
29 after: string,
30 },
31 type: string,
32 nodes: Array<Object>,
33 source: {
34 input: Object,
35 start: Object,
36 },
37 lastEach: number,
38 indexes: Object,
39 },
40 opts: {
41 from: ?string,
42 syntax: ?{
43 parse: Function,
44 stringify: Function,
45 },
46 },
47 css: string,
48 map: ?any,
49 stylelint: {
50 ruleSeverities: Object,
51 customMessages: Object,
52 quiet: ?any,
53 disabledRanges: {
54 all: Array<any>,
55 },
56 ignored?: boolean,
57 stylelintError?: boolean,
58 },
59}
60*/
61
62/*:: type configForFileType = {
63 config: {
64 codeProcessors?: Array<Function>,
65 ignorePatterns?: string,
66 processors?: Array<any>,
67 quiet?: boolean,
68 resultProcessors?: Array<Function>,
69 rules: Object,
70 },
71 filepath: string,
72}
73*/
74
75module.exports = function(
76 stylelint /*: stylelint$internalApi*/,
77 postcssResult /*: ?postcssResultType*/,
78 filePath /*: ?string*/,
79 cssSyntaxError /*: ?stylelint$cssSyntaxError*/
80) /*: Promise<stylelint$result>*/ {
81 let stylelintResult;
82 let source;
83
84 if (postcssResult) {
85 source = !postcssResult.root.source
86 ? undefined
87 : postcssResult.root.source.input.file ||
88 postcssResult.root.source.input.id;
89
90 // Strip out deprecation warnings from the messages
91 const deprecationMessages = _.remove(postcssResult.messages, {
92 stylelintType: "deprecation"
93 });
94 const deprecations = deprecationMessages.map((
95 deprecationMessage /*: messageType*/
96 ) => {
97 return {
98 text: deprecationMessage.text,
99 reference: deprecationMessage.stylelintReference
100 };
101 });
102
103 // Also strip out invalid options
104 const invalidOptionMessages = _.remove(postcssResult.messages, {
105 stylelintType: "invalidOption"
106 });
107 const invalidOptionWarnings = invalidOptionMessages.map((
108 invalidOptionMessage /*: messageType*/
109 ) => {
110 return {
111 text: invalidOptionMessage.text
112 };
113 });
114
115 const parseErrors = _.remove(postcssResult.messages, {
116 stylelintType: "parseError"
117 });
118
119 // This defines the stylelint result object that formatters receive
120 stylelintResult = {
121 source,
122 deprecations,
123 invalidOptionWarnings,
124 parseErrors,
125 errored: postcssResult.stylelint.stylelintError,
126 warnings: postcssResult.messages.map((message /*: messageType*/) => {
127 return {
128 line: message.line,
129 column: message.column,
130 rule: message.rule,
131 severity: message.severity,
132 text: message.text
133 };
134 }),
135 ignored: postcssResult.stylelint.ignored,
136 _postcssResult: postcssResult
137 };
138 } else if (cssSyntaxError) {
139 if (cssSyntaxError.name !== "CssSyntaxError") {
140 throw cssSyntaxError;
141 }
142
143 stylelintResult = {
144 source: cssSyntaxError.file || "<input css 1>",
145 deprecations: [],
146 invalidOptionWarnings: [],
147 parseErrors: [],
148 errored: true,
149 warnings: [
150 {
151 line: cssSyntaxError.line,
152 column: cssSyntaxError.column,
153 rule: cssSyntaxError.name,
154 severity: "error",
155 text: cssSyntaxError.reason + " (" + cssSyntaxError.name + ")"
156 }
157 ]
158 };
159 } else {
160 throw new Error(
161 "createStylelintResult must be called with either postcssResult or CssSyntaxError"
162 );
163 }
164
165 return stylelint.getConfigForFile(filePath).then((
166 configForFile /*: configForFileType*/
167 ) => {
168 const config = configForFile.config;
169 const file = source || (cssSyntaxError && cssSyntaxError.file);
170
171 if (config.resultProcessors) {
172 config.resultProcessors.forEach(resultProcessor => {
173 // Result processors might just mutate the result object,
174 // or might return a new one
175 const returned = resultProcessor(stylelintResult, file);
176
177 if (returned) {
178 stylelintResult = returned;
179 }
180 });
181 }
182
183 return stylelintResult;
184 });
185};