3 require("core-js/modules/es.array.iterator");
5 Object.defineProperty(exports, "__esModule", {
8 exports.getESLintCLIEngine = getESLintCLIEngine;
9 exports.getOptionsForFormatting = getOptionsForFormatting;
10 exports.requireModule = requireModule;
12 var _commonTags = require("common-tags");
14 var _dlv = _interopRequireDefault(require("dlv"));
16 var _loglevelColoredLevelPrefix = _interopRequireDefault(require("loglevel-colored-level-prefix"));
18 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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; }
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; }
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; }
26 const logger = (0, _loglevelColoredLevelPrefix.default)({
27 prefix: 'prettier-eslint'
29 const RULE_DISABLED = {};
30 const RULE_NOT_CONFIGURED = 'RULE_NOT_CONFIGURED';
32 const ruleValueExists = prettierRuleValue => prettierRuleValue !== RULE_NOT_CONFIGURED && prettierRuleValue !== RULE_DISABLED && typeof prettierRuleValue !== 'undefined';
34 const OPTION_GETTERS = {
36 ruleValue: rules => getRuleValue(rules, 'max-len', 'code'),
37 ruleValueToPrettierOption: getPrintWidth
41 let value = getRuleValue(rules, 'indent');
43 if (value === 'tab') {
44 value = getRuleValue(rules, 'max-len', 'tabWidth');
49 ruleValueToPrettierOption: getTabWidth
52 ruleValue: rules => getRuleValue(rules, 'quotes'),
53 ruleValueToPrettierOption: getSingleQuote
56 ruleValue: rules => getRuleValue(rules, 'comma-dangle', []),
57 ruleValueToPrettierOption: getTrailingComma
60 ruleValue: rules => getRuleValue(rules, 'object-curly-spacing'),
61 ruleValueToPrettierOption: getBracketSpacing
64 ruleValue: rules => getRuleValue(rules, 'semi'),
65 ruleValueToPrettierOption: getSemi
68 ruleValue: rules => getRuleValue(rules, 'indent'),
69 ruleValueToPrettierOption: getUseTabs
72 ruleValue: rules => getRuleValue(rules, 'react/jsx-closing-bracket-location', 'nonEmpty'),
73 ruleValueToPrettierOption: getJsxBracketSameLine
76 ruleValue: rules => getRuleValue(rules, 'arrow-parens'),
77 ruleValueToPrettierOption: getArrowParens
80 /* eslint import/prefer-default-export:0 */
82 function getOptionsForFormatting(eslintConfig, prettierOptions = {}, fallbackPrettierOptions = {}, eslintPath) {
83 const eslint = getRelevantESLintConfig(eslintConfig, eslintPath);
84 const prettier = getPrettierOptionsFromESLintRules(eslintConfig, prettierOptions, fallbackPrettierOptions);
91 function getRelevantESLintConfig(eslintConfig, eslintPath) {
92 const cliEngine = getESLintCLIEngine(eslintPath); // TODO: Actually test this branch
93 // istanbul ignore next
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', {
104 logger.debug('turning off unfixable rules');
105 const relevantRules = Object.entries(rules).reduce((rulesAccumulator, [name, rule]) => {
106 if (loadedRules.has(name)) {
111 } = loadedRules.get(name);
114 logger.trace('turing off rule:', JSON.stringify({
121 rulesAccumulator[name] = rule;
122 return rulesAccumulator;
124 return _objectSpread(_objectSpread({
128 settings: eslintConfig.settings || {}
130 }, eslintConfig), {}, {
132 rules: relevantRules,
138 * This accepts an eslintConfig object and converts
139 * it to the `prettier` options object
143 function getPrettierOptionsFromESLintRules(eslintConfig, prettierOptions, fallbackPrettierOptions) {
147 const prettierPluginOptions = getRuleValue(rules, 'prettier/prettier', []);
149 if (ruleValueExists(prettierPluginOptions)) {
150 prettierOptions = _objectSpread(_objectSpread({}, prettierPluginOptions), prettierOptions);
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.
158 function configureOptions(prettierOptions, fallbackPrettierOptions, key, options, rules) {
159 const givenOption = prettierOptions[key];
160 const optionIsGiven = givenOption !== undefined;
163 options[key] = givenOption;
167 ruleValueToPrettierOption
168 } = OPTION_GETTERS[key];
169 const eslintRuleValue = ruleValue(rules);
170 const option = ruleValueToPrettierOption(eslintRuleValue, fallbackPrettierOptions, rules);
172 if (option !== undefined) {
173 options[key] = option;
180 function getPrintWidth(eslintValue, fallbacks) {
181 return makePrettierOption('printWidth', eslintValue, fallbacks);
184 function getTabWidth(eslintValue, fallbacks) {
185 return makePrettierOption('tabWidth', eslintValue, fallbacks);
188 function getSingleQuote(eslintValue, fallbacks) {
191 if (eslintValue === 'single') {
192 prettierValue = true;
193 } else if (eslintValue === 'double') {
194 prettierValue = false;
195 } else if (eslintValue === 'backtick') {
196 prettierValue = false;
198 prettierValue = eslintValue;
201 return makePrettierOption('singleQuote', prettierValue, fallbacks);
204 function getTrailingComma(eslintValue, fallbacks) {
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);
214 prettierValue = RULE_NOT_CONFIGURED;
217 return makePrettierOption('trailingComma', prettierValue, fallbacks);
220 function getValFromTrailingCommaConfig(objectConfig) {
226 const fns = isAlways(functions);
227 const es5 = [arrays, objects].some(isAlways);
238 function getBracketSpacing(eslintValue, fallbacks) {
241 if (eslintValue === 'never') {
242 prettierValue = false;
243 } else if (eslintValue === 'always') {
244 prettierValue = true;
246 prettierValue = eslintValue;
249 return makePrettierOption('bracketSpacing', prettierValue, fallbacks);
252 function getSemi(eslintValue, fallbacks) {
255 if (eslintValue === 'never') {
256 prettierValue = false;
257 } else if (eslintValue === 'always') {
258 prettierValue = true;
260 prettierValue = eslintValue;
263 return makePrettierOption('semi', prettierValue, fallbacks);
266 function getUseTabs(eslintValue, fallbacks) {
269 if (eslintValue === 'tab') {
270 prettierValue = true;
272 prettierValue = RULE_NOT_CONFIGURED;
275 return makePrettierOption('useTabs', prettierValue, fallbacks);
278 function getJsxBracketSameLine(eslintValue, fallbacks) {
281 if (eslintValue === 'after-props') {
282 prettierValue = true;
283 } else if (eslintValue === 'tag-aligned' || eslintValue === 'line-aligned' || eslintValue === 'props-aligned') {
284 prettierValue = false;
286 prettierValue = eslintValue;
289 return makePrettierOption('jsxBracketSameLine', prettierValue, fallbacks);
292 function getArrowParens(eslintValue, fallbacks) {
295 if (eslintValue === 'as-needed') {
296 prettierValue = 'avoid';
298 prettierValue = eslintValue;
301 return makePrettierOption('arrowParens', prettierValue, fallbacks);
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
309 // istanbul ignore else
311 logger.trace((0, _commonTags.oneLine)`
312 Getting the value from object configuration of ${name}.
313 delving into ${JSON.stringify(value)} with path "${objPath}"
315 return (0, _dlv.default)(value, objPath, RULE_NOT_CONFIGURED);
316 } // istanbul ignore next
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
330 function getRuleValue(rules, name, objPath) {
331 const ruleConfig = rules[name];
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
340 if (ruleSetting === 0 || ruleSetting === 'off') {
341 return RULE_DISABLED;
344 if (typeof value === 'object') {
345 return extractRuleValue(objPath, name, value);
347 logger.trace((0, _commonTags.oneLine)`
348 The ${name} rule is configured with a
349 non-object value of ${value}. Using that value.
355 return RULE_NOT_CONFIGURED;
358 function isAlways(val) {
359 return val.indexOf('always') === 0;
362 function makePrettierOption(prettierRuleName, prettierRuleValue, fallbacks) {
363 if (ruleValueExists(prettierRuleValue)) {
364 return prettierRuleValue;
367 const fallback = fallbacks[prettierRuleName];
369 if (typeof fallback !== 'undefined') {
370 logger.debug((0, _commonTags.oneLine)`
371 The ${prettierRuleName} rule is not configured,
372 using provided fallback of ${fallback}
377 logger.debug((0, _commonTags.oneLine)`
378 The ${prettierRuleName} rule is not configured,
384 function requireModule(modulePath, name) {
386 logger.trace(`requiring "${name}" module at "${modulePath}"`);
387 return require(modulePath);
389 logger.error((0, _commonTags.oneLine)`
390 There was trouble getting "${name}".
391 Is "${modulePath}" a correct path to the "${name}" module?
397 function getESLintCLIEngine(eslintPath, eslintOptions) {
400 } = requireModule(eslintPath, 'eslint');
403 return new CLIEngine(eslintOptions);
405 logger.error(`There was trouble creating the ESLint CLIEngine.`);