Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / prettier-eslint / dist / index.js
1 "use strict";
2
3 require("core-js/modules/es.array.iterator");
4
5 require("core-js/modules/es.string.trim-start");
6
7 require("core-js/modules/es.string.trim-end");
8
9 var _fs = _interopRequireDefault(require("fs"));
10
11 var _path = _interopRequireDefault(require("path"));
12
13 var _requireRelative = _interopRequireDefault(require("require-relative"));
14
15 var _prettyFormat = _interopRequireDefault(require("pretty-format"));
16
17 var _commonTags = require("common-tags");
18
19 var _indentString = _interopRequireDefault(require("indent-string"));
20
21 var _loglevelColoredLevelPrefix = _interopRequireDefault(require("loglevel-colored-level-prefix"));
22
23 var _lodash = _interopRequireDefault(require("lodash.merge"));
24
25 var _utils = require("./utils");
26
27 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28
29 function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
30
31 function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
32
33 function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
34
35 const logger = (0, _loglevelColoredLevelPrefix.default)({
36   prefix: 'prettier-eslint'
37 }); // CommonJS + ES6 modules... is it worth it? Probably not...
38
39 module.exports = format;
40 /**
41  * Formats the text with prettier and then eslint based on the given options
42  * @param {String} options.filePath - the path of the file being formatted
43  *  can be used in leu of `eslintConfig` (eslint will be used to find the
44  *  relevant config for the file). Will also be used to load the `text` if
45  *  `text` is not provided.
46  * @param {String} options.text - the text (JavaScript code) to format
47  * @param {String} options.eslintPath - the path to the eslint module to use.
48  *   Will default to require.resolve('eslint')
49  * @param {String} options.prettierPath - the path to the prettier module.
50  *   Will default to require.resovlve('prettier')
51  * @param {Object} options.eslintConfig - the config to use for formatting
52  *  with ESLint.
53  * @param {Object} options.prettierOptions - the options to pass for
54  *  formatting with `prettier`. If not provided, prettier-eslint will attempt
55  *  to create the options based on the eslintConfig
56  * @param {Object} options.fallbackPrettierOptions - the options to pass for
57  *  formatting with `prettier` if the given option is not inferrable from the
58  *  eslintConfig.
59  * @param {String} options.logLevel - the level for the logs
60  *  (error, warn, info, debug, trace)
61  * @param {Boolean} options.prettierLast - Run Prettier Last
62  * @return {String} - the formatted string
63  */
64
65 function format(options) {
66   const {
67     logLevel = getDefaultLogLevel()
68   } = options;
69   logger.setLevel(logLevel);
70   logger.trace('called format with options:', (0, _prettyFormat.default)(options));
71   const {
72     filePath,
73     text = getTextFromFilePath(filePath),
74     eslintPath = getModulePath(filePath, 'eslint'),
75     prettierPath = getModulePath(filePath, 'prettier'),
76     prettierLast,
77     fallbackPrettierOptions
78   } = options;
79   const eslintConfig = (0, _lodash.default)({}, options.eslintConfig, getESLintConfig(filePath, eslintPath));
80
81   if (typeof eslintConfig.globals === 'object') {
82     eslintConfig.globals = Object.entries(eslintConfig.globals).map(([key, value]) => `${key}:${value}`);
83   }
84
85   const prettierOptions = (0, _lodash.default)({}, filePath && {
86     filepath: filePath
87   }, getPrettierConfig(filePath, prettierPath), options.prettierOptions);
88   const formattingOptions = (0, _utils.getOptionsForFormatting)(eslintConfig, prettierOptions, fallbackPrettierOptions, eslintPath);
89   logger.debug('inferred options:', (0, _prettyFormat.default)({
90     filePath,
91     text,
92     eslintPath,
93     prettierPath,
94     eslintConfig: formattingOptions.eslint,
95     prettierOptions: formattingOptions.prettier,
96     logLevel,
97     prettierLast
98   }));
99   const eslintExtensions = eslintConfig.extensions || ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.vue'];
100
101   const fileExtension = _path.default.extname(filePath || ''); // If we don't get filePath run eslint on text, otherwise only run eslint
102   // if it's a configured extension or fall back to a "supported" file type.
103
104
105   const onlyPrettier = filePath ? !eslintExtensions.includes(fileExtension) : false;
106   const prettify = createPrettify(formattingOptions.prettier, prettierPath);
107
108   if (onlyPrettier) {
109     return prettify(text);
110   }
111
112   if (['.ts', '.tsx'].includes(fileExtension)) {
113     formattingOptions.eslint.parser = formattingOptions.eslint.parser || require.resolve('@typescript-eslint/parser');
114   }
115
116   if (['.vue'].includes(fileExtension)) {
117     formattingOptions.eslint.parser = formattingOptions.eslint.parser || require.resolve('vue-eslint-parser');
118   }
119
120   const eslintFix = createEslintFix(formattingOptions.eslint, eslintPath);
121
122   if (prettierLast) {
123     return prettify(eslintFix(text, filePath));
124   }
125
126   return eslintFix(prettify(text), filePath);
127 }
128
129 function createPrettify(formatOptions, prettierPath) {
130   return function prettify(text) {
131     logger.debug('calling prettier on text');
132     logger.trace((0, _commonTags.stripIndent)`
133       prettier input:
134
135       ${(0, _indentString.default)(text, 2)}
136     `);
137     const prettier = (0, _utils.requireModule)(prettierPath, 'prettier');
138
139     try {
140       logger.trace(`calling prettier.format with the text and prettierOptions`);
141       const output = prettier.format(text, formatOptions);
142       logger.trace('prettier: output === input', output === text);
143       logger.trace((0, _commonTags.stripIndent)`
144         prettier output:
145
146         ${(0, _indentString.default)(output, 2)}
147       `);
148       return output;
149     } catch (error) {
150       logger.error('prettier formatting failed due to a prettier error');
151       throw error;
152     }
153   };
154 }
155
156 function createEslintFix(eslintConfig, eslintPath) {
157   return function eslintFix(text, filePath) {
158     const cliEngine = (0, _utils.getESLintCLIEngine)(eslintPath, eslintConfig);
159
160     try {
161       logger.trace(`calling cliEngine.executeOnText with the text`);
162       const report = cliEngine.executeOnText(text, filePath, true);
163       logger.trace(`executeOnText returned the following report:`, (0, _prettyFormat.default)(report)); // default the output to text because if there's nothing
164       // to fix, eslint doesn't provide `output`
165
166       const [{
167         output = text
168       }] = report.results;
169       logger.trace('eslint --fix: output === input', output === text); // NOTE: We're ignoring linting errors/warnings here and
170       // defaulting to the given text if there are any
171       // because all we're trying to do is fix what we can.
172       // We don't care about what we can't
173
174       logger.trace((0, _commonTags.stripIndent)`
175         eslint --fix output:
176
177         ${(0, _indentString.default)(output, 2)}
178       `);
179       return output;
180     } catch (error) {
181       logger.error('eslint fix failed due to an eslint error');
182       throw error;
183     }
184   };
185 }
186
187 function getTextFromFilePath(filePath) {
188   try {
189     logger.trace((0, _commonTags.oneLine)`
190         attempting fs.readFileSync to get
191         the text for file at "${filePath}"
192       `);
193     return _fs.default.readFileSync(filePath, 'utf8');
194   } catch (error) {
195     logger.error((0, _commonTags.oneLine)`
196         failed to get the text to format
197         from the given filePath: "${filePath}"
198       `);
199     throw error;
200   }
201 }
202
203 function getESLintConfig(filePath, eslintPath) {
204   const eslintOptions = {};
205
206   if (filePath) {
207     eslintOptions.cwd = _path.default.dirname(filePath);
208   }
209
210   logger.trace((0, _commonTags.oneLine)`
211       creating ESLint CLI Engine to get the config for
212       "${filePath || process.cwd()}"
213     `);
214   const cliEngine = (0, _utils.getESLintCLIEngine)(eslintPath, eslintOptions);
215
216   try {
217     logger.debug(`getting eslint config for file at "${filePath}"`);
218     const config = cliEngine.getConfigForFile(filePath);
219     logger.trace(`eslint config for "${filePath}" received`, (0, _prettyFormat.default)(config));
220     return _objectSpread(_objectSpread({}, eslintOptions), config);
221   } catch (error) {
222     // is this noisy? Try setting options.disableLog to false
223     logger.debug('Unable to find config');
224     return {
225       rules: {}
226     };
227   }
228 }
229
230 function getPrettierConfig(filePath, prettierPath) {
231   const prettier = (0, _utils.requireModule)(prettierPath, 'prettier');
232   return prettier.resolveConfig && prettier.resolveConfig.sync && prettier.resolveConfig.sync(filePath) || {};
233 }
234
235 function getModulePath(filePath = __filename, moduleName) {
236   try {
237     return _requireRelative.default.resolve(moduleName, filePath);
238   } catch (error) {
239     logger.debug((0, _commonTags.oneLine)`
240         There was a problem finding the ${moduleName}
241         module. Using prettier-eslint's version.
242       `, error.message, error.stack);
243     return require.resolve(moduleName);
244   }
245 }
246
247 function getDefaultLogLevel() {
248   return process.env.LOG_LEVEL || 'warn';
249 }