.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / prettier-eslint / dist / utils.js
1 "use strict";
2
3 require("core-js/modules/es.array.iterator");
4
5 Object.defineProperty(exports, "__esModule", {
6   value: true
7 });
8 exports.getESLintCLIEngine = getESLintCLIEngine;
9 exports.getOptionsForFormatting = getOptionsForFormatting;
10 exports.requireModule = requireModule;
11
12 var _commonTags = require("common-tags");
13
14 var _dlv = _interopRequireDefault(require("dlv"));
15
16 var _loglevelColoredLevelPrefix = _interopRequireDefault(require("loglevel-colored-level-prefix"));
17
18 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
20 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; }
21
22 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; }
23
24 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; }
25
26 const logger = (0, _loglevelColoredLevelPrefix.default)({
27   prefix: 'prettier-eslint'
28 });
29 const RULE_DISABLED = {};
30 const RULE_NOT_CONFIGURED = 'RULE_NOT_CONFIGURED';
31
32 const ruleValueExists = prettierRuleValue => prettierRuleValue !== RULE_NOT_CONFIGURED && prettierRuleValue !== RULE_DISABLED && typeof prettierRuleValue !== 'undefined';
33
34 const OPTION_GETTERS = {
35   printWidth: {
36     ruleValue: rules => getRuleValue(rules, 'max-len', 'code'),
37     ruleValueToPrettierOption: getPrintWidth
38   },
39   tabWidth: {
40     ruleValue: rules => {
41       let value = getRuleValue(rules, 'indent');
42
43       if (value === 'tab') {
44         value = getRuleValue(rules, 'max-len', 'tabWidth');
45       }
46
47       return value;
48     },
49     ruleValueToPrettierOption: getTabWidth
50   },
51   singleQuote: {
52     ruleValue: rules => getRuleValue(rules, 'quotes'),
53     ruleValueToPrettierOption: getSingleQuote
54   },
55   trailingComma: {
56     ruleValue: rules => getRuleValue(rules, 'comma-dangle', []),
57     ruleValueToPrettierOption: getTrailingComma
58   },
59   bracketSpacing: {
60     ruleValue: rules => getRuleValue(rules, 'object-curly-spacing'),
61     ruleValueToPrettierOption: getBracketSpacing
62   },
63   semi: {
64     ruleValue: rules => getRuleValue(rules, 'semi'),
65     ruleValueToPrettierOption: getSemi
66   },
67   useTabs: {
68     ruleValue: rules => getRuleValue(rules, 'indent'),
69     ruleValueToPrettierOption: getUseTabs
70   },
71   jsxBracketSameLine: {
72     ruleValue: rules => getRuleValue(rules, 'react/jsx-closing-bracket-location', 'nonEmpty'),
73     ruleValueToPrettierOption: getJsxBracketSameLine
74   },
75   arrowParens: {
76     ruleValue: rules => getRuleValue(rules, 'arrow-parens'),
77     ruleValueToPrettierOption: getArrowParens
78   }
79 };
80 /* eslint import/prefer-default-export:0 */
81
82 function getOptionsForFormatting(eslintConfig, prettierOptions = {}, fallbackPrettierOptions = {}, eslintPath) {
83   const eslint = getRelevantESLintConfig(eslintConfig, eslintPath);
84   const prettier = getPrettierOptionsFromESLintRules(eslintConfig, prettierOptions, fallbackPrettierOptions);
85   return {
86     eslint,
87     prettier
88   };
89 }
90
91 function getRelevantESLintConfig(eslintConfig, eslintPath) {
92   const cliEngine = getESLintCLIEngine(eslintPath); // TODO: Actually test this branch
93   // istanbul ignore next
94
95   const loadedRules = cliEngine.getRules && cliEngine.getRules() || // XXX: Fallback list of unfixable rules, when using and old version of eslint
96   new Map([['global-require', {
97     meta: {}
98   }], ['no-with', {
99     meta: {}
100   }]]);
101   const {
102     rules
103   } = eslintConfig;
104   logger.debug('turning off unfixable rules');
105   const relevantRules = Object.entries(rules).reduce((rulesAccumulator, [name, rule]) => {
106     if (loadedRules.has(name)) {
107       const {
108         meta: {
109           fixable
110         }
111       } = loadedRules.get(name);
112
113       if (!fixable) {
114         logger.trace('turing off rule:', JSON.stringify({
115           [name]: rule
116         }));
117         rule = ['off'];
118       }
119     }
120
121     rulesAccumulator[name] = rule;
122     return rulesAccumulator;
123   }, {});
124   return _objectSpread(_objectSpread({
125     // defaults
126     useEslintrc: false,
127     baseConfig: {
128       settings: eslintConfig.settings || {}
129     }
130   }, eslintConfig), {}, {
131     // overrides
132     rules: relevantRules,
133     fix: true,
134     globals: []
135   });
136 }
137 /**
138  * This accepts an eslintConfig object and converts
139  * it to the `prettier` options object
140  */
141
142
143 function getPrettierOptionsFromESLintRules(eslintConfig, prettierOptions, fallbackPrettierOptions) {
144   const {
145     rules
146   } = eslintConfig;
147   const prettierPluginOptions = getRuleValue(rules, 'prettier/prettier', []);
148
149   if (ruleValueExists(prettierPluginOptions)) {
150     prettierOptions = _objectSpread(_objectSpread({}, prettierPluginOptions), prettierOptions);
151   }
152
153   return Object.keys(OPTION_GETTERS).reduce((options, key) => configureOptions(prettierOptions, fallbackPrettierOptions, key, options, rules), prettierOptions);
154 } // If an ESLint rule that prettier can be configured with is enabled create a
155 // prettier configuration object that reflects the ESLint rule configuration.
156
157
158 function configureOptions(prettierOptions, fallbackPrettierOptions, key, options, rules) {
159   const givenOption = prettierOptions[key];
160   const optionIsGiven = givenOption !== undefined;
161
162   if (optionIsGiven) {
163     options[key] = givenOption;
164   } else {
165     const {
166       ruleValue,
167       ruleValueToPrettierOption
168     } = OPTION_GETTERS[key];
169     const eslintRuleValue = ruleValue(rules);
170     const option = ruleValueToPrettierOption(eslintRuleValue, fallbackPrettierOptions, rules);
171
172     if (option !== undefined) {
173       options[key] = option;
174     }
175   }
176
177   return options;
178 }
179
180 function getPrintWidth(eslintValue, fallbacks) {
181   return makePrettierOption('printWidth', eslintValue, fallbacks);
182 }
183
184 function getTabWidth(eslintValue, fallbacks) {
185   return makePrettierOption('tabWidth', eslintValue, fallbacks);
186 }
187
188 function getSingleQuote(eslintValue, fallbacks) {
189   let prettierValue;
190
191   if (eslintValue === 'single') {
192     prettierValue = true;
193   } else if (eslintValue === 'double') {
194     prettierValue = false;
195   } else if (eslintValue === 'backtick') {
196     prettierValue = false;
197   } else {
198     prettierValue = eslintValue;
199   }
200
201   return makePrettierOption('singleQuote', prettierValue, fallbacks);
202 }
203
204 function getTrailingComma(eslintValue, fallbacks) {
205   let prettierValue;
206
207   if (eslintValue === 'never') {
208     prettierValue = 'none';
209   } else if (typeof eslintValue === 'string' && eslintValue.indexOf('always') === 0) {
210     prettierValue = 'es5';
211   } else if (typeof eslintValue === 'object') {
212     prettierValue = getValFromTrailingCommaConfig(eslintValue);
213   } else {
214     prettierValue = RULE_NOT_CONFIGURED;
215   }
216
217   return makePrettierOption('trailingComma', prettierValue, fallbacks);
218 }
219
220 function getValFromTrailingCommaConfig(objectConfig) {
221   const {
222     arrays = '',
223     objects = '',
224     functions = ''
225   } = objectConfig;
226   const fns = isAlways(functions);
227   const es5 = [arrays, objects].some(isAlways);
228
229   if (fns) {
230     return 'all';
231   } else if (es5) {
232     return 'es5';
233   } else {
234     return 'none';
235   }
236 }
237
238 function getBracketSpacing(eslintValue, fallbacks) {
239   let prettierValue;
240
241   if (eslintValue === 'never') {
242     prettierValue = false;
243   } else if (eslintValue === 'always') {
244     prettierValue = true;
245   } else {
246     prettierValue = eslintValue;
247   }
248
249   return makePrettierOption('bracketSpacing', prettierValue, fallbacks);
250 }
251
252 function getSemi(eslintValue, fallbacks) {
253   let prettierValue;
254
255   if (eslintValue === 'never') {
256     prettierValue = false;
257   } else if (eslintValue === 'always') {
258     prettierValue = true;
259   } else {
260     prettierValue = eslintValue;
261   }
262
263   return makePrettierOption('semi', prettierValue, fallbacks);
264 }
265
266 function getUseTabs(eslintValue, fallbacks) {
267   let prettierValue;
268
269   if (eslintValue === 'tab') {
270     prettierValue = true;
271   } else {
272     prettierValue = RULE_NOT_CONFIGURED;
273   }
274
275   return makePrettierOption('useTabs', prettierValue, fallbacks);
276 }
277
278 function getJsxBracketSameLine(eslintValue, fallbacks) {
279   let prettierValue;
280
281   if (eslintValue === 'after-props') {
282     prettierValue = true;
283   } else if (eslintValue === 'tag-aligned' || eslintValue === 'line-aligned' || eslintValue === 'props-aligned') {
284     prettierValue = false;
285   } else {
286     prettierValue = eslintValue;
287   }
288
289   return makePrettierOption('jsxBracketSameLine', prettierValue, fallbacks);
290 }
291
292 function getArrowParens(eslintValue, fallbacks) {
293   let prettierValue;
294
295   if (eslintValue === 'as-needed') {
296     prettierValue = 'avoid';
297   } else {
298     prettierValue = eslintValue;
299   }
300
301   return makePrettierOption('arrowParens', prettierValue, fallbacks);
302 }
303
304 function extractRuleValue(objPath, name, value) {
305   // XXX: Ignore code coverage for the following else case
306   // There are currently no eslint rules which we can infer prettier
307   // options from, that have an object option which we don't know how
308   // to infer from.
309   // istanbul ignore else
310   if (objPath) {
311     logger.trace((0, _commonTags.oneLine)`
312         Getting the value from object configuration of ${name}.
313         delving into ${JSON.stringify(value)} with path "${objPath}"
314       `);
315     return (0, _dlv.default)(value, objPath, RULE_NOT_CONFIGURED);
316   } // istanbul ignore next
317
318
319   logger.debug((0, _commonTags.oneLine)`
320       The ${name} rule is using an object configuration
321       of ${JSON.stringify(value)} but prettier-eslint is
322       not currently capable of getting the prettier value
323       based on an object configuration for ${name}.
324       Please file an issue (and make a pull request?)
325     `); // istanbul ignore next
326
327   return undefined;
328 }
329
330 function getRuleValue(rules, name, objPath) {
331   const ruleConfig = rules[name];
332
333   if (Array.isArray(ruleConfig)) {
334     const [ruleSetting, value] = ruleConfig; // If `ruleSetting` is set to disable the ESLint rule don't use `value` as
335     // it might be a value provided by an overriden config package e.g. airbnb
336     // overriden by config-prettier. The airbnb values are provided even though
337     // config-prettier disables the rule. Instead use fallback or prettier
338     // default.
339
340     if (ruleSetting === 0 || ruleSetting === 'off') {
341       return RULE_DISABLED;
342     }
343
344     if (typeof value === 'object') {
345       return extractRuleValue(objPath, name, value);
346     } else {
347       logger.trace((0, _commonTags.oneLine)`
348           The ${name} rule is configured with a
349           non-object value of ${value}. Using that value.
350         `);
351       return value;
352     }
353   }
354
355   return RULE_NOT_CONFIGURED;
356 }
357
358 function isAlways(val) {
359   return val.indexOf('always') === 0;
360 }
361
362 function makePrettierOption(prettierRuleName, prettierRuleValue, fallbacks) {
363   if (ruleValueExists(prettierRuleValue)) {
364     return prettierRuleValue;
365   }
366
367   const fallback = fallbacks[prettierRuleName];
368
369   if (typeof fallback !== 'undefined') {
370     logger.debug((0, _commonTags.oneLine)`
371         The ${prettierRuleName} rule is not configured,
372         using provided fallback of ${fallback}
373       `);
374     return fallback;
375   }
376
377   logger.debug((0, _commonTags.oneLine)`
378       The ${prettierRuleName} rule is not configured,
379       let prettier decide
380     `);
381   return undefined;
382 }
383
384 function requireModule(modulePath, name) {
385   try {
386     logger.trace(`requiring "${name}" module at "${modulePath}"`);
387     return require(modulePath);
388   } catch (error) {
389     logger.error((0, _commonTags.oneLine)`
390       There was trouble getting "${name}".
391       Is "${modulePath}" a correct path to the "${name}" module?
392     `);
393     throw error;
394   }
395 }
396
397 function getESLintCLIEngine(eslintPath, eslintOptions) {
398   const {
399     CLIEngine
400   } = requireModule(eslintPath, 'eslint');
401
402   try {
403     return new CLIEngine(eslintOptions);
404   } catch (error) {
405     logger.error(`There was trouble creating the ESLint CLIEngine.`);
406     throw error;
407   }
408 }