1 | 'use strict';
|
2 |
|
3 | const fs = require('fs');
|
4 | const LazyResult = require('postcss/lib/lazy-result');
|
5 | const postcss = require('postcss');
|
6 |
|
7 | let autoSyntax = null;
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | const postcssProcessor = postcss();
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | module.exports = function (stylelint, options = {}) {
|
21 | const cached = options.filePath ? stylelint._postcssResultCache.get(options.filePath) : undefined;
|
22 |
|
23 | if (cached) return Promise.resolve(cached);
|
24 |
|
25 |
|
26 | let getCode;
|
27 |
|
28 | if (options.code !== undefined) {
|
29 | getCode = Promise.resolve(options.code);
|
30 | } else if (options.filePath) {
|
31 | getCode = readFile(options.filePath);
|
32 | }
|
33 |
|
34 | if (!getCode) {
|
35 | throw new Error('code or filePath required');
|
36 | }
|
37 |
|
38 | return getCode
|
39 | .then((code) => {
|
40 | const customSyntax = stylelint._options.customSyntax;
|
41 |
|
42 | let syntax = null;
|
43 |
|
44 | if (customSyntax) {
|
45 | try {
|
46 |
|
47 | const useCustomSyntax = require(customSyntax);
|
48 |
|
49 | |
50 |
|
51 |
|
52 |
|
53 | if (!useCustomSyntax.parse) {
|
54 | syntax = {
|
55 | parse: useCustomSyntax,
|
56 | stringify: postcss.stringify,
|
57 | };
|
58 | } else {
|
59 | syntax = useCustomSyntax;
|
60 | }
|
61 | } catch (e) {
|
62 | throw new Error(`Cannot resolve custom syntax module ${customSyntax}`);
|
63 | }
|
64 | } else if (stylelint._options.syntax === 'css') {
|
65 | syntax = cssSyntax(stylelint);
|
66 | } else if (stylelint._options.syntax) {
|
67 |
|
68 | const syntaxes = {
|
69 | 'css-in-js': '@stylelint/postcss-css-in-js',
|
70 | html: 'postcss-html',
|
71 | less: 'postcss-less',
|
72 | markdown: '@stylelint/postcss-markdown',
|
73 | sass: 'postcss-sass',
|
74 | scss: 'postcss-scss',
|
75 | sugarss: 'sugarss',
|
76 | };
|
77 |
|
78 | const syntaxFromOptions = syntaxes[stylelint._options.syntax];
|
79 |
|
80 | if (!syntaxFromOptions) {
|
81 | throw new Error(
|
82 | 'You must use a valid syntax option, either: css, css-in-js, html, less, markdown, sass, scss, or sugarss',
|
83 | );
|
84 | }
|
85 |
|
86 | syntax = require(syntaxFromOptions);
|
87 | } else if (
|
88 | !(options.codeProcessors && options.codeProcessors.length) ||
|
89 | (options.filePath && /\.(scss|sass|less)$/.test(options.filePath))
|
90 | ) {
|
91 | if (!autoSyntax) {
|
92 | autoSyntax = require('postcss-syntax');
|
93 | }
|
94 |
|
95 | syntax = autoSyntax({
|
96 | css: cssSyntax(stylelint),
|
97 | jsx: require('@stylelint/postcss-css-in-js'),
|
98 | markdown: require('@stylelint/postcss-markdown'),
|
99 | });
|
100 | }
|
101 |
|
102 | const postcssOptions = {
|
103 | from: options.filePath,
|
104 | syntax,
|
105 | };
|
106 |
|
107 | const source = options.code ? options.codeFilename : options.filePath;
|
108 | let preProcessedCode = code;
|
109 |
|
110 | if (options.codeProcessors && options.codeProcessors.length) {
|
111 | if (stylelint._options.fix) {
|
112 |
|
113 | console.warn(
|
114 | 'Autofix is incompatible with processors and will be disabled. Are you sure you need a processor?',
|
115 | );
|
116 | stylelint._options.fix = false;
|
117 | }
|
118 |
|
119 | options.codeProcessors.forEach((codeProcessor) => {
|
120 | preProcessedCode = codeProcessor(preProcessedCode, source);
|
121 | });
|
122 | }
|
123 |
|
124 | const result = new LazyResult(postcssProcessor, preProcessedCode, postcssOptions);
|
125 |
|
126 | return result;
|
127 | })
|
128 | .then((postcssResult) => {
|
129 | if (options.filePath) {
|
130 | stylelint._postcssResultCache.set(options.filePath, postcssResult);
|
131 | }
|
132 |
|
133 | return postcssResult;
|
134 | });
|
135 | };
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 | function readFile(filePath) {
|
142 | return new Promise((resolve, reject) => {
|
143 | fs.readFile(filePath, 'utf8', (err, content) => {
|
144 | if (err) {
|
145 | return reject(err);
|
146 | }
|
147 |
|
148 | resolve(content);
|
149 | });
|
150 | });
|
151 | }
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 | function cssSyntax(stylelint) {
|
158 | return {
|
159 | parse: stylelint._options.fix ? require('postcss-safe-parser') : postcss.parse,
|
160 | stringify: postcss.stringify,
|
161 | };
|
162 | }
|