Installing dependencies.

This commit is contained in:
2025-11-11 06:53:11 -05:00
parent 2c36c04da6
commit 0d2fea3c88
14371 changed files with 2770923 additions and 25 deletions
+287
View File
@@ -0,0 +1,287 @@
"use strict";
var _fs = _interopRequireDefault(require("fs"));
var _path = _interopRequireDefault(require("path"));
var _requireRelative = _interopRequireDefault(require("require-relative"));
var _prettyFormat = _interopRequireDefault(require("pretty-format"));
var _commonTags = require("common-tags");
var _indentString = _interopRequireDefault(require("indent-string"));
var _loglevelColoredLevelPrefix = _interopRequireDefault(require("loglevel-colored-level-prefix"));
var _lodash = _interopRequireDefault(require("lodash.merge"));
var _utils = require("./utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint no-console:0, global-require:0, import/no-dynamic-require:0 */
/* eslint complexity: [1, 13] */
const logger = (0, _loglevelColoredLevelPrefix.default)({
prefix: 'prettier-eslint'
}); // CommonJS + ES6 modules... is it worth it? Probably not...
module.exports = format;
/**
* Formats the text with prettier and then eslint based on the given options
* @param {String} options.filePath - the path of the file being formatted
* can be used in leu of `eslintConfig` (eslint will be used to find the
* relevant config for the file). Will also be used to load the `text` if
* `text` is not provided.
* @param {String} options.text - the text (JavaScript code) to format
* @param {String} options.eslintPath - the path to the eslint module to use.
* Will default to require.resolve('eslint')
* @param {String} options.prettierPath - the path to the prettier module.
* Will default to require.resovlve('prettier')
* @param {Object} options.eslintConfig - the config to use for formatting
* with ESLint.
* @param {Object} options.prettierOptions - the options to pass for
* formatting with `prettier`. If not provided, prettier-eslint will attempt
* to create the options based on the eslintConfig
* @param {Object} options.fallbackPrettierOptions - the options to pass for
* formatting with `prettier` if the given option is not inferrable from the
* eslintConfig.
* @param {String} options.logLevel - the level for the logs
* (error, warn, info, debug, trace)
* @param {Boolean} options.prettierLast - Run Prettier Last
* @return {Promise<String>} - the formatted string
*/
async function format(options) {
const {
logLevel = getDefaultLogLevel()
} = options;
logger.setLevel(logLevel);
logger.trace('called format with options:', (0, _prettyFormat.default)(options));
const {
filePath,
text = getTextFromFilePath(filePath),
eslintPath = getModulePath(filePath, 'eslint'),
prettierPath = getModulePath(filePath, 'prettier'),
prettierLast,
fallbackPrettierOptions
} = options;
const eslintConfig = (0, _lodash.default)({}, options.eslintConfig, await getESLintConfig(filePath, eslintPath, options.eslintConfig || {}));
const prettierOptions = (0, _lodash.default)({}, filePath && {
filepath: filePath
}, getPrettierConfig(filePath, prettierPath), options.prettierOptions);
const formattingOptions = (0, _utils.getOptionsForFormatting)(eslintConfig, prettierOptions, fallbackPrettierOptions, eslintPath);
logger.debug('inferred options:', (0, _prettyFormat.default)({
filePath,
text,
eslintPath,
prettierPath,
eslintConfig: formattingOptions.eslint,
prettierOptions: formattingOptions.prettier,
logLevel,
prettierLast
}));
const eslintExtensions = eslintConfig.extensions || ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.vue'];
const fileExtension = _path.default.extname(filePath || ''); // If we don't get filePath run eslint on text, otherwise only run eslint
// if it's a configured extension or fall back to a "supported" file type.
const onlyPrettier = filePath ? !eslintExtensions.includes(fileExtension) : false;
const prettify = createPrettify(formattingOptions.prettier, prettierPath);
if (onlyPrettier) {
return prettify(text);
}
if (['.ts', '.tsx'].includes(fileExtension)) {
formattingOptions.eslint.parser = formattingOptions.eslint.parser || require.resolve('@typescript-eslint/parser');
}
if (['.vue'].includes(fileExtension)) {
formattingOptions.eslint.parser = formattingOptions.eslint.parser || require.resolve('vue-eslint-parser');
}
const eslintFix = await createEslintFix(formattingOptions.eslint, eslintPath);
if (prettierLast) {
const eslintFixed = await eslintFix(text, filePath);
return prettify(eslintFixed);
}
return eslintFix(prettify(text), filePath);
}
function createPrettify(formatOptions, prettierPath) {
return function prettify(text) {
logger.debug('calling prettier on text');
logger.trace((0, _commonTags.stripIndent)`
prettier input:
${(0, _indentString.default)(text, 2)}
`);
const prettier = (0, _utils.requireModule)(prettierPath, 'prettier');
try {
logger.trace('calling prettier.format with the text and prettierOptions');
const output = prettier.format(text, formatOptions);
logger.trace('prettier: output === input', output === text);
logger.trace((0, _commonTags.stripIndent)`
prettier output:
${(0, _indentString.default)(output, 2)}
`);
return output;
} catch (error) {
logger.error('prettier formatting failed due to a prettier error');
throw error;
}
};
}
function createEslintFix(eslintConfig, eslintPath) {
return async function eslintFix(text, filePath) {
if (Array.isArray(eslintConfig.globals)) {
const tempGlobals = {};
eslintConfig.globals.forEach(g => {
const [key, value] = g.split(':');
tempGlobals[key] = value;
});
eslintConfig.globals = tempGlobals;
}
eslintConfig.overrideConfig = {
rules: eslintConfig.rules,
parser: eslintConfig.parser,
globals: eslintConfig.globals,
parserOptions: eslintConfig.parserOptions,
ignorePatterns: eslintConfig.ignorePatterns || eslintConfig.ignorePattern,
plugins: eslintConfig.plugins,
env: eslintConfig.env,
settings: eslintConfig.settings,
noInlineConfig: eslintConfig.noInlineConfig,
...eslintConfig.overrideConfig
};
delete eslintConfig.rules;
delete eslintConfig.parser;
delete eslintConfig.parserOptions;
delete eslintConfig.globals;
delete eslintConfig.ignorePatterns;
delete eslintConfig.ignorePattern;
delete eslintConfig.plugins;
delete eslintConfig.env;
delete eslintConfig.noInlineConfig;
delete eslintConfig.settings;
const eslint = (0, _utils.getESLint)(eslintPath, eslintConfig);
try {
logger.trace('calling cliEngine.executeOnText with the text');
const report = await eslint.lintText(text, {
filePath,
warnIgnored: true
});
logger.trace('executeOnText returned the following report:', (0, _prettyFormat.default)(report)); // default the output to text because if there's nothing
// to fix, eslint doesn't provide `output`
const [{
output = text
}] = await report;
logger.trace('eslint --fix: output === input', output === text); // NOTE: We're ignoring linting errors/warnings here and
// defaulting to the given text if there are any
// because all we're trying to do is fix what we can.
// We don't care about what we can't
logger.trace((0, _commonTags.stripIndent)`
eslint --fix output:
${(0, _indentString.default)(output, 2)}
`);
return output;
} catch (error) {
logger.error('eslint fix failed due to an eslint error');
throw error;
}
};
}
function getTextFromFilePath(filePath) {
try {
logger.trace((0, _commonTags.oneLine)`
attempting fs.readFileSync to get
the text for file at "${filePath}"
`);
return _fs.default.readFileSync(filePath, 'utf8');
} catch (error) {
logger.error((0, _commonTags.oneLine)`
failed to get the text to format
from the given filePath: "${filePath}"
`);
throw error;
}
}
function getESLintApiOptions(eslintConfig) {
// https://eslint.org/docs/developer-guide/nodejs-api
// these options affect what calculateConfigForFile produces
return {
ignore: eslintConfig.ignore || true,
ignorePath: eslintConfig.ignorePath || null,
allowInlineConfig: eslintConfig.allowInlineConfig || true,
baseConfig: eslintConfig.baseConfig || null,
overrideConfig: eslintConfig.overrideConfig || null,
overrideConfigFile: eslintConfig.overrideConfigFile || null,
plugins: eslintConfig.plugins || null,
resolvePluginsRelativeTo: eslintConfig.resolvePluginsRelativeTo || null,
rulePaths: eslintConfig.rulePaths || [],
useEslintrc: eslintConfig.useEslintrc || true
};
}
async function getESLintConfig(filePath, eslintPath, eslintOptions) {
if (filePath) {
eslintOptions.cwd = _path.default.dirname(filePath);
}
logger.trace((0, _commonTags.oneLine)`
creating ESLint CLI Engine to get the config for
"${filePath || process.cwd()}"
`);
const eslint = (0, _utils.getESLint)(eslintPath, getESLintApiOptions(eslintOptions));
try {
logger.debug(`getting eslint config for file at "${filePath}"`);
const config = await eslint.calculateConfigForFile(filePath);
logger.trace(`eslint config for "${filePath}" received`, (0, _prettyFormat.default)(config));
return { ...eslintOptions,
...config
};
} catch (error) {
// is this noisy? Try setting options.disableLog to false
logger.debug('Unable to find config');
return {
rules: {}
};
}
}
function getPrettierConfig(filePath, prettierPath) {
const prettier = (0, _utils.requireModule)(prettierPath, 'prettier');
return prettier.resolveConfig && prettier.resolveConfig.sync && prettier.resolveConfig.sync(filePath) || {};
}
function getModulePath(filePath = __filename, moduleName) {
try {
return _requireRelative.default.resolve(moduleName, filePath);
} catch (error) {
logger.debug((0, _commonTags.oneLine)`
There was a problem finding the ${moduleName}
module. Using prettier-eslint's version.
`, error.message, error.stack);
return require.resolve(moduleName);
}
}
function getDefaultLogLevel() {
return process.env.LOG_LEVEL || 'warn';
}
+391
View File
@@ -0,0 +1,391 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getESLint = getESLint;
exports.getOptionsForFormatting = getOptionsForFormatting;
exports.requireModule = requireModule;
var _commonTags = require("common-tags");
var _dlv = _interopRequireDefault(require("dlv"));
var _loglevelColoredLevelPrefix = _interopRequireDefault(require("loglevel-colored-level-prefix"));
var _eslint = require("eslint");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* eslint import/no-dynamic-require:0 */
const logger = (0, _loglevelColoredLevelPrefix.default)({
prefix: 'prettier-eslint'
});
const RULE_DISABLED = {};
const RULE_NOT_CONFIGURED = 'RULE_NOT_CONFIGURED';
const ruleValueExists = prettierRuleValue => prettierRuleValue !== RULE_NOT_CONFIGURED && prettierRuleValue !== RULE_DISABLED && typeof prettierRuleValue !== 'undefined';
const OPTION_GETTERS = {
printWidth: {
ruleValue: rules => getRuleValue(rules, 'max-len', 'code'),
ruleValueToPrettierOption: getPrintWidth
},
tabWidth: {
ruleValue: rules => {
let value = getRuleValue(rules, 'indent');
if (value === 'tab') {
value = getRuleValue(rules, 'max-len', 'tabWidth');
}
return value;
},
ruleValueToPrettierOption: getTabWidth
},
singleQuote: {
ruleValue: rules => getRuleValue(rules, 'quotes'),
ruleValueToPrettierOption: getSingleQuote
},
trailingComma: {
ruleValue: rules => getRuleValue(rules, 'comma-dangle', []),
ruleValueToPrettierOption: getTrailingComma
},
bracketSpacing: {
ruleValue: rules => getRuleValue(rules, 'object-curly-spacing'),
ruleValueToPrettierOption: getBracketSpacing
},
semi: {
ruleValue: rules => getRuleValue(rules, 'semi'),
ruleValueToPrettierOption: getSemi
},
useTabs: {
ruleValue: rules => getRuleValue(rules, 'indent'),
ruleValueToPrettierOption: getUseTabs
},
bracketSameLine: {
ruleValue: rules => getRuleValue(rules, 'react/jsx-closing-bracket-location', 'nonEmpty'),
ruleValueToPrettierOption: getBracketSameLine
},
arrowParens: {
ruleValue: rules => getRuleValue(rules, 'arrow-parens'),
ruleValueToPrettierOption: getArrowParens
}
};
/* eslint import/prefer-default-export:0 */
function getOptionsForFormatting(eslintConfig, prettierOptions = {}, fallbackPrettierOptions = {}) {
const eslint = getRelevantESLintConfig(eslintConfig);
const prettier = getPrettierOptionsFromESLintRules(eslintConfig, prettierOptions, fallbackPrettierOptions);
return {
eslint,
prettier
};
}
function getRelevantESLintConfig(eslintConfig) {
const linter = new _eslint.Linter();
const rules = linter.getRules();
logger.debug('turning off unfixable rules');
const relevantRules = {};
rules.forEach((rule, name) => {
const {
meta: {
fixable
}
} = rule;
if (!fixable) {
logger.trace('turning off rule:', JSON.stringify({
[name]: rule
}));
rule = ['off'];
relevantRules[name] = rule;
}
}, {});
return {
// defaults
useEslintrc: false,
...eslintConfig,
// overrides
rules: { ...eslintConfig.rules,
...relevantRules
},
fix: true,
globals: eslintConfig.globals || {}
};
}
/**
* This accepts an eslintConfig object and converts
* it to the `prettier` options object
*/
function getPrettierOptionsFromESLintRules(eslintConfig, prettierOptions, fallbackPrettierOptions) {
const {
rules
} = eslintConfig;
const prettierPluginOptions = getRuleValue(rules, 'prettier/prettier', []);
if (ruleValueExists(prettierPluginOptions)) {
prettierOptions = { ...prettierPluginOptions,
...prettierOptions
};
}
return Object.keys(OPTION_GETTERS).reduce((options, key) => configureOptions(prettierOptions, fallbackPrettierOptions, key, options, rules), prettierOptions);
} // If an ESLint rule that prettier can be configured with is enabled create a
// prettier configuration object that reflects the ESLint rule configuration.
function configureOptions(prettierOptions, fallbackPrettierOptions, key, options, rules) {
const givenOption = prettierOptions[key];
const optionIsGiven = givenOption !== undefined;
if (optionIsGiven) {
options[key] = givenOption;
} else {
const {
ruleValue,
ruleValueToPrettierOption
} = OPTION_GETTERS[key];
const eslintRuleValue = ruleValue(rules);
const option = ruleValueToPrettierOption(eslintRuleValue, fallbackPrettierOptions, rules);
if (option !== undefined) {
options[key] = option;
}
}
return options;
}
function getPrintWidth(eslintValue, fallbacks) {
return makePrettierOption('printWidth', eslintValue, fallbacks);
}
function getTabWidth(eslintValue, fallbacks) {
return makePrettierOption('tabWidth', eslintValue, fallbacks);
}
function getSingleQuote(eslintValue, fallbacks) {
let prettierValue;
if (eslintValue === 'single') {
prettierValue = true;
} else if (eslintValue === 'double') {
prettierValue = false;
} else if (eslintValue === 'backtick') {
prettierValue = false;
} else {
prettierValue = eslintValue;
}
return makePrettierOption('singleQuote', prettierValue, fallbacks);
}
function getTrailingComma(eslintValue, fallbacks) {
let prettierValue;
if (eslintValue === 'never') {
prettierValue = 'none';
} else if (typeof eslintValue === 'string' && eslintValue.indexOf('always') === 0) {
prettierValue = 'es5';
} else if (typeof eslintValue === 'object') {
prettierValue = getValFromTrailingCommaConfig(eslintValue);
} else {
prettierValue = RULE_NOT_CONFIGURED;
}
return makePrettierOption('trailingComma', prettierValue, fallbacks);
}
function getValFromTrailingCommaConfig(objectConfig) {
const {
arrays = '',
objects = '',
functions = ''
} = objectConfig;
const fns = isAlways(functions);
const es5 = [arrays, objects].some(isAlways);
if (fns) {
return 'all';
} else if (es5) {
return 'es5';
} else {
return 'none';
}
}
function getBracketSpacing(eslintValue, fallbacks) {
let prettierValue;
if (eslintValue === 'never') {
prettierValue = false;
} else if (eslintValue === 'always') {
prettierValue = true;
} else {
prettierValue = eslintValue;
}
return makePrettierOption('bracketSpacing', prettierValue, fallbacks);
}
function getSemi(eslintValue, fallbacks) {
let prettierValue;
if (eslintValue === 'never') {
prettierValue = false;
} else if (eslintValue === 'always') {
prettierValue = true;
} else {
prettierValue = eslintValue;
}
return makePrettierOption('semi', prettierValue, fallbacks);
}
function getUseTabs(eslintValue, fallbacks) {
let prettierValue;
if (eslintValue === 'tab') {
prettierValue = true;
} else {
prettierValue = RULE_NOT_CONFIGURED;
}
return makePrettierOption('useTabs', prettierValue, fallbacks);
}
function getBracketSameLine(eslintValue, fallbacks) {
let prettierValue;
if (eslintValue === 'after-props') {
prettierValue = true;
} else if (eslintValue === 'tag-aligned' || eslintValue === 'line-aligned' || eslintValue === 'props-aligned') {
prettierValue = false;
} else {
prettierValue = eslintValue;
}
return makePrettierOption('bracketSameLine', prettierValue, fallbacks);
}
function getArrowParens(eslintValue, fallbacks) {
let prettierValue;
if (eslintValue === 'as-needed') {
prettierValue = 'avoid';
} else {
prettierValue = eslintValue;
}
return makePrettierOption('arrowParens', prettierValue, fallbacks);
}
function extractRuleValue(objPath, name, value) {
// XXX: Ignore code coverage for the following else case
// There are currently no eslint rules which we can infer prettier
// options from, that have an object option which we don't know how
// to infer from.
// istanbul ignore else
if (objPath) {
logger.trace((0, _commonTags.oneLine)`
Getting the value from object configuration of ${name}.
delving into ${JSON.stringify(value)} with path "${objPath}"
`);
return (0, _dlv.default)(value, objPath, RULE_NOT_CONFIGURED);
} // istanbul ignore next
logger.debug((0, _commonTags.oneLine)`
The ${name} rule is using an object configuration
of ${JSON.stringify(value)} but prettier-eslint is
not currently capable of getting the prettier value
based on an object configuration for ${name}.
Please file an issue (and make a pull request?)
`); // istanbul ignore next
return undefined;
}
function getRuleValue(rules, name, objPath) {
const ruleConfig = rules[name];
if (Array.isArray(ruleConfig)) {
const [ruleSetting, value] = ruleConfig; // If `ruleSetting` is set to disable the ESLint rule don't use `value` as
// it might be a value provided by an overriden config package e.g. airbnb
// overriden by config-prettier. The airbnb values are provided even though
// config-prettier disables the rule. Instead use fallback or prettier
// default.
if (ruleSetting === 0 || ruleSetting === 'off') {
return RULE_DISABLED;
}
if (typeof value === 'object') {
return extractRuleValue(objPath, name, value);
} else {
logger.trace((0, _commonTags.oneLine)`
The ${name} rule is configured with a
non-object value of ${value}. Using that value.
`);
return value;
}
}
return RULE_NOT_CONFIGURED;
}
function isAlways(val) {
return val.indexOf('always') === 0;
}
function makePrettierOption(prettierRuleName, prettierRuleValue, fallbacks) {
if (ruleValueExists(prettierRuleValue)) {
return prettierRuleValue;
}
const fallback = fallbacks[prettierRuleName];
if (typeof fallback !== 'undefined') {
logger.debug((0, _commonTags.oneLine)`
The ${prettierRuleName} rule is not configured,
using provided fallback of ${fallback}
`);
return fallback;
}
logger.debug((0, _commonTags.oneLine)`
The ${prettierRuleName} rule is not configured,
let prettier decide
`);
return undefined;
}
function requireModule(modulePath, name) {
try {
logger.trace(`requiring "${name}" module at "${modulePath}"`);
return require(modulePath);
} catch (error) {
logger.error((0, _commonTags.oneLine)`
There was trouble getting "${name}".
Is "${modulePath}" a correct path to the "${name}" module?
`);
throw error;
}
}
function getESLint(eslintPath, eslintOptions) {
const {
ESLint
} = requireModule(eslintPath, 'eslint');
try {
return new ESLint(eslintOptions);
} catch (error) {
logger.error('There was trouble creating the ESLint CLIEngine.');
throw error;
}
}