UNPKG

@nx/eslint

Version:

The ESLint plugin for Nx contains executors, generators and utilities used for linting JavaScript/TypeScript projects within an Nx workspace.

139 lines (138 loc) 6.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertToInferred = convertToInferred; const devkit_1 = require("@nx/devkit"); const executor_to_plugin_migrator_1 = require("@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator"); const plugin_migration_utils_1 = require("@nx/devkit/src/generators/plugin-migrations/plugin-migration-utils"); const posix_1 = require("node:path/posix"); const utils_1 = require("nx/src/tasks-runner/utils"); const plugin_1 = require("../../plugins/plugin"); const config_file_1 = require("../../utils/config-file"); const target_options_map_1 = require("./lib/target-options-map"); async function convertToInferred(tree, options) { const projectGraph = await (0, devkit_1.createProjectGraphAsync)(); const migratedProjects = await (0, executor_to_plugin_migrator_1.migrateProjectExecutorsToPlugin)(tree, projectGraph, '@nx/eslint/plugin', plugin_1.createNodesV2, { targetName: 'lint' }, [ { executors: ['@nx/eslint:lint', '@nrwl/linter:eslint'], postTargetTransformer, targetPluginOptionMapper: (targetName) => ({ targetName }), skipTargetFilter, }, ], options.project); if (migratedProjects.size === 0) { throw new executor_to_plugin_migrator_1.NoTargetsToMigrateError(); } if (!options.skipFormat) { await (0, devkit_1.formatFiles)(tree); } } function postTargetTransformer(target, tree, projectDetails, inferredTargetConfiguration) { if (target.inputs) { const inputs = target.inputs.filter((input) => typeof input === 'string' && ![ 'default', '{workspaceRoot}/.eslintrc.json', '{workspaceRoot}/.eslintignore', '{workspaceRoot}/eslint.config.cjs', '{workspaceRoot}/eslint.config.mjs', ].includes(input)); if (inputs.length === 0) { delete target.inputs; } } if (target.options) { handlePropertiesInOptions(target.options, projectDetails, target); } if (target.configurations) { for (const configurationName in target.configurations) { const configuration = target.configurations[configurationName]; handlePropertiesInOptions(configuration, projectDetails, target); } if (Object.keys(target.configurations).length !== 0) { for (const configuration in target.configurations) { if (Object.keys(target.configurations[configuration]).length === 0) { delete target.configurations[configuration]; } } if (Object.keys(target.configurations).length === 0) { delete target.configurations; } } } if (target.outputs) { (0, plugin_migration_utils_1.processTargetOutputs)(target, [], inferredTargetConfiguration, { projectName: projectDetails.projectName, projectRoot: projectDetails.root, }); } return target; } function handlePropertiesInOptions(options, projectDetails, target) { // inferred targets are only identified after known files that ESLint would // pick up, so we can remove the eslintConfig option delete options.eslintConfig; if ('force' in options) { delete options.force; } if ('silent' in options) { delete options.silent; } if ('hasTypeAwareRules' in options) { delete options.hasTypeAwareRules; } if ('errorOnUnmatchedPattern' in options) { if (!options.errorOnUnmatchedPattern) { options['no-error-on-unmatched-pattern'] = true; } delete options.errorOnUnmatchedPattern; } if ('outputFile' in options) { target.outputs ??= []; target.outputs.push(options.outputFile); } for (const key in target_options_map_1.targetOptionsToCliMap) { if (options[key]) { const prevValue = options[key]; delete options[key]; options[target_options_map_1.targetOptionsToCliMap[key]] = prevValue; } } if ('lintFilePatterns' in options) { const normalizedLintFilePatterns = options.lintFilePatterns.map((pattern) => { const interpolatedPattern = (0, utils_1.interpolate)(pattern, { workspaceRoot: '', projectRoot: projectDetails.root, projectName: projectDetails.projectName, }); if (interpolatedPattern === projectDetails.root) { return '.'; } return interpolatedPattern.replace(new RegExp(`^(?:\./)?${projectDetails.root}/`), ''); }); options.args = normalizedLintFilePatterns // the @nx/eslint/plugin automatically infers these, so we don't need to pass them in .filter((p) => projectDetails.root === '.' ? !['.', 'src', './src', 'lib', './lib'].includes(p) : p !== '.'); if (options.args.length === 0) { delete options.args; } delete options.lintFilePatterns; } } exports.default = convertToInferred; function skipTargetFilter(targetOptions, project) { if (targetOptions.eslintConfig) { // check that the eslintConfig option is a default config file known by ESLint if (!config_file_1.ESLINT_CONFIG_FILENAMES.includes((0, posix_1.basename)(targetOptions.eslintConfig))) { return `The "eslintConfig" option value (${targetOptions.eslintConfig}) is not a default config file known by ESLint.`; } // check that it is at the project root or in a parent directory const eslintConfigPath = (0, posix_1.relative)(project.root, targetOptions.eslintConfig); if ((0, posix_1.dirname)(eslintConfigPath) !== '.' && !eslintConfigPath.startsWith('../')) { return `The "eslintConfig" option value (${targetOptions.eslintConfig}) must point to a file in the project root or a parent directory.`; } } return false; }