UNPKG

3.09 kBJavaScriptView Raw
1'use strict';
2
3const _ = require('lodash');
4
5/** @typedef {{
6 ruleName: string,
7 result: import('stylelint').PostcssResult,
8 message: string,
9 node: import('postcss').Node & {
10 positionBy(opts: { index?: number, word?: string }): { line: number, column: number }
11 },
12 index?: number,
13 word?: string,
14 line?: number
15}} Violation */
16
17/**
18 * Report a violation.
19 *
20 * This function accounts for `disabledRanges` attached to the result.
21 * That is, if the reported violation is within a disabledRange,
22 * it is ignored. Otherwise, it is attached to the result as a
23 * postcss warning.
24 *
25 * It also accounts for the rule's severity.
26 *
27 * You *must* pass *either* a node or a line number.
28 * @param {Violation} violation
29 */
30module.exports = function (violation) {
31 const ruleName = violation.ruleName;
32 const result = violation.result;
33 const message = violation.message;
34 const line = violation.line;
35 const node = violation.node;
36 const index = violation.index;
37 const word = violation.word;
38
39 result.stylelint = result.stylelint || {
40 ruleSeverities: {},
41 customMessages: {},
42 };
43
44 // In quiet mode, mere warnings are ignored
45 if (result.stylelint.quiet && result.stylelint.ruleSeverities[ruleName] !== 'error') {
46 return;
47 }
48
49 // If a line is not passed, use the node.positionBy method to get the
50 // line number that the complaint pertains to
51 const startLine = line || node.positionBy({ index }).line;
52
53 if (
54 result.stylelint.disabledRanges &&
55 (!result.stylelint.ignoreDisables || result.stylelint.reportNeedlessDisables)
56 ) {
57 const ranges = result.stylelint.disabledRanges[ruleName] || result.stylelint.disabledRanges.all;
58
59 for (const range of ranges) {
60 if (
61 // If the violation is within a disabledRange,
62 // and that disabledRange's rules include this one,
63 // do not register a warning
64 range.start <= startLine &&
65 (range.end === undefined || range.end >= startLine) &&
66 (!range.rules || range.rules.includes(ruleName))
67 ) {
68 if (result.stylelint.reportNeedlessDisables) {
69 // Collect disabled warnings
70 // Used to report `needlessDisables` in subsequent processing.
71 const disabledWarnings =
72 result.stylelint.disabledWarnings || (result.stylelint.disabledWarnings = []);
73
74 disabledWarnings.push({
75 rule: ruleName,
76 line: startLine,
77 });
78
79 if (!result.stylelint.ignoreDisables) {
80 return;
81 }
82
83 break;
84 } else {
85 return;
86 }
87 }
88 }
89 }
90
91 /** @type {string} */
92 const severity = _.get(result.stylelint, ['ruleSeverities', ruleName], 'ignore');
93
94 if (!result.stylelint.stylelintError && severity === 'error') {
95 result.stylelint.stylelintError = true;
96 }
97
98 /** @type {import('stylelint').StylelintWarningOptions} */
99 const warningProperties = {
100 severity,
101 rule: ruleName,
102 };
103
104 if (node) {
105 warningProperties.node = node;
106 }
107
108 if (index) {
109 warningProperties.index = index;
110 }
111
112 if (word) {
113 warningProperties.word = word;
114 }
115
116 const warningMessage = _.get(result.stylelint, ['customMessages', ruleName], message);
117
118 result.warn(warningMessage, warningProperties);
119};