.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / stylelint / lib / getPostcssResult.js
1 /* @flow */
2 "use strict";
3
4 const autoSyntax = require("postcss-html");
5 const dynamicRequire = require("./dynamicRequire");
6 const fs = require("fs");
7 const less = require("postcss-less");
8 const path = require("path");
9 const postcss = require("postcss");
10 const safeParser = require("postcss-safe-parser");
11 const scss = require("postcss-scss");
12 const sugarss = require("sugarss");
13 const syntaxes /*: {
14   [syntaxName: string]: postcss$syntax,
15 }*/ = {
16   css: {
17     stringify: postcss.stringify
18   },
19   less,
20   scss,
21   sss: sugarss,
22   sugarss
23 };
24
25 const postcssProcessor = postcss();
26
27 module.exports = function(
28   stylelint /*: stylelint$internalApi*/
29 ) /*: Promise<?Object>*/ {
30   const options /*: {
31     code?: string,
32     codeFilename?: string,
33     filePath?: string,
34     codeProcessors?: Array<Function>,
35     syntax?: stylelint$syntaxes,
36     customSyntax?: string
37   }*/ =
38     arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
39
40   const cached /*: ?postcss$result*/ = stylelint._postcssResultCache.get(
41     options.filePath
42   );
43   if (cached) return Promise.resolve(cached);
44
45   let getCode;
46   if (options.code !== undefined) {
47     getCode = Promise.resolve(options.code);
48   } else if (options.filePath) {
49     getCode = readFile(options.filePath);
50   }
51
52   if (!getCode) {
53     throw new Error("code or filePath required");
54   }
55
56   return getCode
57     .then(code => {
58       const customSyntax = stylelint._options.customSyntax;
59       let syntax = stylelint._options.syntax;
60
61       if (customSyntax) {
62         try {
63           syntax = dynamicRequire(customSyntax);
64         } catch (e) {
65           throw new Error(
66             `Cannot resolve custom syntax module ${customSyntax}`
67           );
68         }
69       } else if (syntax) {
70         syntax = syntaxes[syntax];
71         if (!syntax) {
72           throw new Error(
73             "You must use a valid syntax option, either: scss, less or sugarss"
74           );
75         }
76       } else {
77         syntaxes.css.parse = stylelint._options.fix
78           ? safeParser
79           : postcss.parse;
80         const fileExtension = path
81           .extname(options.filePath || "")
82           .slice(1)
83           .toLowerCase();
84         syntax = syntaxes[fileExtension] || autoSyntax(syntaxes);
85       }
86
87       const postcssOptions /*: postcss$options*/ = {};
88
89       postcssOptions.from = options.filePath;
90
91       /*
92      * PostCSS allows for syntaxes that only contain a parser, however,
93      * it then expects the syntax to be set as the `parser` option rather than `syntax.
94      */
95       if (syntax && !syntax.stringify) {
96         postcssOptions.parser = syntax;
97       } else {
98         postcssOptions.syntax = syntax;
99       }
100
101       const source = options.code ? options.codeFilename : options.filePath;
102       let preProcessedCode = code;
103       if (options.codeProcessors) {
104         options.codeProcessors.forEach(codeProcessor => {
105           preProcessedCode = codeProcessor(preProcessedCode, source);
106         });
107       }
108
109       return postcssProcessor.process(preProcessedCode, postcssOptions);
110     })
111     .then(postcssResult => {
112       stylelint._postcssResultCache.set(options.filePath, postcssResult);
113       return postcssResult;
114     });
115 };
116
117 function readFile(filePath /*: string*/) /*: Promise<string>*/ {
118   return new Promise((resolve, reject) => {
119     fs.readFile(filePath, "utf8", (err, content) => {
120       if (err) {
121         return reject(err);
122       }
123       resolve(content);
124     });
125   });
126 }