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