@nx/eslint 0.0.0-pr-22179-271588f → 0.0.0-pr-26482-ebe2dba
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/generators.json +5 -0
- package/migrations.json +17 -12
- package/package.json +12 -10
- package/plugin.d.ts +1 -1
- package/plugin.js +2 -1
- package/src/executors/lint/lint.impl.d.ts +1 -1
- package/src/executors/lint/lint.impl.js +23 -18
- package/src/executors/lint/utility/eslint-utils.js +4 -17
- package/src/generators/convert-to-flat-config/generator.d.ts +2 -2
- package/src/generators/convert-to-flat-config/generator.js +8 -2
- package/src/generators/convert-to-inferred/convert-to-inferred.d.ts +7 -0
- package/src/generators/convert-to-inferred/convert-to-inferred.js +80 -0
- package/src/generators/convert-to-inferred/lib/target-options-map.d.ts +16 -0
- package/src/generators/convert-to-inferred/lib/target-options-map.js +19 -0
- package/src/generators/convert-to-inferred/schema.json +19 -0
- package/src/generators/init/init-migration.js +4 -0
- package/src/generators/init/init.d.ts +1 -1
- package/src/generators/init/init.js +16 -27
- package/src/generators/lint-project/lint-project.d.ts +2 -1
- package/src/generators/lint-project/lint-project.js +16 -20
- package/src/generators/utils/eslint-file.js +4 -2
- package/src/generators/utils/flat-config/ast-utils.js +31 -7
- package/src/plugins/plugin.d.ts +3 -1
- package/src/plugins/plugin.js +285 -58
- package/src/utils/config-file.d.ts +4 -1
- package/src/utils/config-file.js +50 -16
- package/src/utils/resolve-eslint-class.d.ts +2 -0
- package/src/utils/resolve-eslint-class.js +23 -0
- package/src/utils/versions.d.ts +2 -2
- package/src/utils/versions.js +2 -2
- package/src/migrations/update-15-0-0/add-eslint-inputs.d.ts +0 -2
- package/src/migrations/update-15-0-0/add-eslint-inputs.js +0 -27
- package/src/migrations/update-15-7-1/add-eslint-ignore.d.ts +0 -2
- package/src/migrations/update-15-7-1/add-eslint-ignore.js +0 -36
package/LICENSE
CHANGED
package/generators.json
CHANGED
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"factory": "./src/generators/convert-to-flat-config/generator",
|
|
24
24
|
"schema": "./src/generators/convert-to-flat-config/schema.json",
|
|
25
25
|
"description": "Convert an Nx workspace's ESLint configs to use Flat Config."
|
|
26
|
+
},
|
|
27
|
+
"convert-to-inferred": {
|
|
28
|
+
"factory": "./src/generators/convert-to-inferred/convert-to-inferred",
|
|
29
|
+
"schema": "./src/generators/convert-to-inferred/schema.json",
|
|
30
|
+
"description": "Convert existing ESLint project(s) using `@nx/eslint:lint` executor to use `@nx/eslint/plugin`."
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
}
|
package/migrations.json
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generators": {
|
|
3
|
-
"add-eslint-inputs": {
|
|
4
|
-
"cli": "nx",
|
|
5
|
-
"version": "15.0.0-beta.0",
|
|
6
|
-
"description": "Stop hashing eslint config files for build targets and dependent tasks",
|
|
7
|
-
"factory": "./src/migrations/update-15-0-0/add-eslint-inputs"
|
|
8
|
-
},
|
|
9
|
-
"add-eslint-ignore": {
|
|
10
|
-
"cli": "nx",
|
|
11
|
-
"version": "15.7.1-beta.0",
|
|
12
|
-
"description": "Add node_modules to root eslint ignore",
|
|
13
|
-
"factory": "./src/migrations/update-15-7-1/add-eslint-ignore"
|
|
14
|
-
},
|
|
15
3
|
"update-16-0-0-add-nx-packages": {
|
|
16
4
|
"cli": "nx",
|
|
17
5
|
"version": "16.0.0-beta.1",
|
|
@@ -133,6 +121,23 @@
|
|
|
133
121
|
"version": "^6.13.2"
|
|
134
122
|
}
|
|
135
123
|
}
|
|
124
|
+
},
|
|
125
|
+
"18.2.0": {
|
|
126
|
+
"version": "18.2.0-beta.0",
|
|
127
|
+
"packages": {
|
|
128
|
+
"@typescript-eslint/parser": {
|
|
129
|
+
"version": "^7.3.0"
|
|
130
|
+
},
|
|
131
|
+
"@typescript-eslint/eslint-plugin": {
|
|
132
|
+
"version": "^7.3.0"
|
|
133
|
+
},
|
|
134
|
+
"@typescript-eslint/utils": {
|
|
135
|
+
"version": "^7.3.0"
|
|
136
|
+
},
|
|
137
|
+
"eslint": {
|
|
138
|
+
"version": "~8.57.0"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/eslint",
|
|
3
|
-
"version": "0.0.0-pr-
|
|
3
|
+
"version": "0.0.0-pr-26482-ebe2dba",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The ESLint plugin for Nx contains executors, generators and utilities used for linting JavaScript/TypeScript projects within an Nx workspace.",
|
|
6
6
|
"repository": {
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"Web",
|
|
14
14
|
"Lint",
|
|
15
15
|
"ESLint",
|
|
16
|
-
"CLI"
|
|
16
|
+
"CLI",
|
|
17
|
+
"Testing"
|
|
17
18
|
],
|
|
18
|
-
"main": "./index
|
|
19
|
+
"main": "./index",
|
|
19
20
|
"typings": "./index.d.ts",
|
|
20
21
|
"author": "Victor Savkin",
|
|
21
22
|
"license": "MIT",
|
|
@@ -30,18 +31,19 @@
|
|
|
30
31
|
"generators": "./generators.json",
|
|
31
32
|
"executors": "./executors.json",
|
|
32
33
|
"peerDependencies": {
|
|
33
|
-
"js-yaml": "
|
|
34
|
+
"@zkochan/js-yaml": "0.0.7",
|
|
35
|
+
"eslint": "^8.0.0 || ^9.0.0"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@nx/devkit": "0.0.0-pr-
|
|
37
|
-
"@nx/js": "0.0.0-pr-
|
|
38
|
-
"
|
|
38
|
+
"@nx/devkit": "0.0.0-pr-26482-ebe2dba",
|
|
39
|
+
"@nx/js": "0.0.0-pr-26482-ebe2dba",
|
|
40
|
+
"semver": "^7.5.3",
|
|
39
41
|
"tslib": "^2.3.0",
|
|
40
|
-
"typescript": "~5.
|
|
41
|
-
"@nx/linter": "0.0.0-pr-
|
|
42
|
+
"typescript": "~5.4.2",
|
|
43
|
+
"@nx/linter": "0.0.0-pr-26482-ebe2dba"
|
|
42
44
|
},
|
|
43
45
|
"peerDependenciesMeta": {
|
|
44
|
-
"js-yaml": {
|
|
46
|
+
"@zkochan/js-yaml": {
|
|
45
47
|
"optional": true
|
|
46
48
|
}
|
|
47
49
|
},
|
package/plugin.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { createNodes, EslintPluginOptions } from './src/plugins/plugin';
|
|
1
|
+
export { createNodes, createNodesV2, EslintPluginOptions, } from './src/plugins/plugin';
|
package/plugin.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createNodes = void 0;
|
|
3
|
+
exports.createNodesV2 = exports.createNodes = void 0;
|
|
4
4
|
var plugin_1 = require("./src/plugins/plugin");
|
|
5
5
|
Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return plugin_1.createNodes; } });
|
|
6
|
+
Object.defineProperty(exports, "createNodesV2", { enumerable: true, get: function () { return plugin_1.createNodesV2; } });
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const devkit_1 = require("@nx/devkit");
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
|
+
const utils_1 = require("nx/src/tasks-runner/utils");
|
|
5
6
|
const path_1 = require("path");
|
|
7
|
+
const config_file_1 = require("../../utils/config-file");
|
|
6
8
|
const eslint_utils_1 = require("./utility/eslint-utils");
|
|
7
|
-
const utils_1 = require("nx/src/tasks-runner/utils");
|
|
8
9
|
async function run(options, context) {
|
|
9
10
|
// this is only used for the hasher
|
|
10
11
|
delete options.hasTypeAwareRules;
|
|
@@ -23,19 +24,14 @@ async function run(options, context) {
|
|
|
23
24
|
? (0, devkit_1.joinPathFragments)(options.cacheLocation, projectName)
|
|
24
25
|
: undefined;
|
|
25
26
|
const { printConfig, errorOnUnmatchedPattern, ...normalizedOptions } = options;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* their root ESLint config to use eslint.config.js
|
|
30
|
-
*/
|
|
31
|
-
const hasFlatConfig = (0, fs_1.existsSync)((0, devkit_1.joinPathFragments)(devkit_1.workspaceRoot, 'eslint.config.js'));
|
|
27
|
+
// locate the flat config file if it exists starting from the project root
|
|
28
|
+
const flatConfigFilePath = (0, config_file_1.findFlatConfigFile)(projectRoot, context.root);
|
|
29
|
+
const hasFlatConfig = flatConfigFilePath !== null;
|
|
32
30
|
// while standard eslint uses by default closest config to the file, if otherwise not specified,
|
|
33
|
-
// the flat config would
|
|
31
|
+
// the flat config would be resolved starting from the cwd, which we changed to the workspace root
|
|
32
|
+
// so we explicitly set the config path to the flat config file path we previously found
|
|
34
33
|
if (hasFlatConfig && !normalizedOptions.eslintConfig) {
|
|
35
|
-
|
|
36
|
-
if ((0, fs_1.existsSync)(eslintConfigPath)) {
|
|
37
|
-
normalizedOptions.eslintConfig = eslintConfigPath;
|
|
38
|
-
}
|
|
34
|
+
normalizedOptions.eslintConfig = path_1.posix.relative(systemRoot, flatConfigFilePath);
|
|
39
35
|
}
|
|
40
36
|
/**
|
|
41
37
|
* We want users to have the option of not specifying the config path, and let
|
|
@@ -81,15 +77,24 @@ async function run(options, context) {
|
|
|
81
77
|
catch (err) {
|
|
82
78
|
if (err.message.includes('You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser')) {
|
|
83
79
|
const ruleName = err.message.match(/rule '([^']+)':/)?.[1];
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
eslintConfigPathForError =
|
|
80
|
+
const reportedFile = err.message.match(/Occurred while linting (.+)$/)?.[1];
|
|
81
|
+
let eslintConfigPathForError = `for the project "${projectName}"`;
|
|
82
|
+
if (eslintConfigPath) {
|
|
83
|
+
eslintConfigPathForError = `"${path_1.posix.relative(context.root, eslintConfigPath)}"`;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const configPathForfile = hasFlatConfig
|
|
87
|
+
? (0, config_file_1.findFlatConfigFile)(projectRoot, context.root)
|
|
88
|
+
: (0, config_file_1.findOldConfigFile)(reportedFile ?? projectRoot, context.root);
|
|
89
|
+
if (configPathForfile) {
|
|
90
|
+
eslintConfigPathForError = `"${path_1.posix.relative(context.root, configPathForfile)}"`;
|
|
91
|
+
}
|
|
88
92
|
}
|
|
89
93
|
console.error(`
|
|
90
|
-
Error: You have attempted to use ${ruleName ? `the lint rule ${ruleName}` : 'a lint rule'} which requires the full TypeScript type-checker to be available, but you do not have
|
|
94
|
+
Error: You have attempted to use ${ruleName ? `the lint rule "${ruleName}"` : 'a lint rule'} which requires the full TypeScript type-checker to be available, but you do not have "parserOptions.project" configured to point at your project tsconfig.json files in the relevant TypeScript file "overrides" block of your ESLint config ${eslintConfigPathForError}
|
|
95
|
+
${reportedFile ? `Occurred while linting ${reportedFile}` : ''}
|
|
91
96
|
|
|
92
|
-
Please see https://nx.dev/
|
|
97
|
+
Please see https://nx.dev/recipes/tips-n-tricks/eslint for full guidance on how to resolve this issue.
|
|
93
98
|
`);
|
|
94
99
|
return {
|
|
95
100
|
success: false,
|
|
@@ -1,26 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resolveAndInstantiateESLint = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (!useFlatConfig) {
|
|
7
|
-
return (await Promise.resolve().then(() => require('eslint'))).ESLint;
|
|
8
|
-
}
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
10
|
-
const { FlatESLint } = require('eslint/use-at-your-own-risk');
|
|
11
|
-
return FlatESLint;
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
throw new Error('Unable to find ESLint. Ensure ESLint is installed.');
|
|
15
|
-
}
|
|
16
|
-
}
|
|
4
|
+
const config_file_1 = require("../../../utils/config-file");
|
|
5
|
+
const resolve_eslint_class_1 = require("../../../utils/resolve-eslint-class");
|
|
17
6
|
async function resolveAndInstantiateESLint(eslintConfigPath, options, useFlatConfig = false) {
|
|
18
|
-
if (useFlatConfig &&
|
|
19
|
-
eslintConfigPath &&
|
|
20
|
-
!eslintConfigPath?.endsWith('eslint.config.js')) {
|
|
7
|
+
if (useFlatConfig && eslintConfigPath && !(0, config_file_1.isFlatConfig)(eslintConfigPath)) {
|
|
21
8
|
throw new Error('When using the new Flat Config with ESLint, all configs must be named eslint.config.js and .eslintrc files may not be used. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
22
9
|
}
|
|
23
|
-
const ESLint = await resolveESLintClass(useFlatConfig);
|
|
10
|
+
const ESLint = await (0, resolve_eslint_class_1.resolveESLintClass)(useFlatConfig);
|
|
24
11
|
const eslintOptions = {
|
|
25
12
|
overrideConfigFile: eslintConfigPath,
|
|
26
13
|
fix: !!options.fix,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tree } from '@nx/devkit';
|
|
1
|
+
import { GeneratorCallback, Tree } from '@nx/devkit';
|
|
2
2
|
import { ConvertToFlatConfigGeneratorSchema } from './schema';
|
|
3
|
-
export declare function convertToFlatConfigGenerator(tree: Tree, options: ConvertToFlatConfigGeneratorSchema): Promise<void>;
|
|
3
|
+
export declare function convertToFlatConfigGenerator(tree: Tree, options: ConvertToFlatConfigGeneratorSchema): Promise<void | GeneratorCallback>;
|
|
4
4
|
export default convertToFlatConfigGenerator;
|
|
@@ -6,7 +6,7 @@ const eslint_file_1 = require("../utils/eslint-file");
|
|
|
6
6
|
const path_1 = require("path");
|
|
7
7
|
const versions_1 = require("../../utils/versions");
|
|
8
8
|
const json_converter_1 = require("./converters/json-converter");
|
|
9
|
-
|
|
9
|
+
let shouldInstallDeps = false;
|
|
10
10
|
async function convertToFlatConfigGenerator(tree, options) {
|
|
11
11
|
const eslintFile = (0, eslint_file_1.findEslintFile)(tree);
|
|
12
12
|
if (!eslintFile) {
|
|
@@ -33,6 +33,9 @@ async function convertToFlatConfigGenerator(tree, options) {
|
|
|
33
33
|
if (!options.skipFormat) {
|
|
34
34
|
await (0, devkit_1.formatFiles)(tree);
|
|
35
35
|
}
|
|
36
|
+
if (shouldInstallDeps) {
|
|
37
|
+
return () => (0, devkit_1.installPackagesTask)(tree);
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
exports.convertToFlatConfigGenerator = convertToFlatConfigGenerator;
|
|
38
41
|
exports.default = convertToFlatConfigGenerator;
|
|
@@ -112,7 +115,8 @@ function convertConfigToFlatConfig(tree, root, source, target, ignorePath) {
|
|
|
112
115
|
}
|
|
113
116
|
if (source.endsWith('.yaml') || source.endsWith('.yml')) {
|
|
114
117
|
const originalContent = tree.read(`${root}/${source}`, 'utf-8');
|
|
115
|
-
const
|
|
118
|
+
const { load } = require('@zkochan/js-yaml');
|
|
119
|
+
const config = load(originalContent, {
|
|
116
120
|
json: true,
|
|
117
121
|
filename: source,
|
|
118
122
|
});
|
|
@@ -127,11 +131,13 @@ function processConvertedConfig(tree, root, source, target, { content, addESLint
|
|
|
127
131
|
tree.write((0, path_1.join)(root, target), content);
|
|
128
132
|
// add missing packages
|
|
129
133
|
if (addESLintRC) {
|
|
134
|
+
shouldInstallDeps = true;
|
|
130
135
|
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
131
136
|
'@eslint/eslintrc': versions_1.eslintrcVersion,
|
|
132
137
|
});
|
|
133
138
|
}
|
|
134
139
|
if (addESLintJS) {
|
|
140
|
+
shouldInstallDeps = true;
|
|
135
141
|
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
136
142
|
'@eslint/js': versions_1.eslintVersion,
|
|
137
143
|
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertToInferred = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const plugin_1 = require("../../plugins/plugin");
|
|
6
|
+
const executor_to_plugin_migrator_1 = require("@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator");
|
|
7
|
+
const target_options_map_1 = require("./lib/target-options-map");
|
|
8
|
+
const utils_1 = require("nx/src/tasks-runner/utils");
|
|
9
|
+
async function convertToInferred(tree, options) {
|
|
10
|
+
const projectGraph = await (0, devkit_1.createProjectGraphAsync)();
|
|
11
|
+
const migratedProjectsModern = await (0, executor_to_plugin_migrator_1.migrateExecutorToPlugin)(tree, projectGraph, '@nx/eslint:lint', '@nx/eslint/plugin', (targetName) => ({ targetName }), postTargetTransformer, plugin_1.createNodesV2, options.project);
|
|
12
|
+
const migratedProjectsLegacy = await (0, executor_to_plugin_migrator_1.migrateExecutorToPlugin)(tree, projectGraph, '@nrwl/linter:eslint', '@nx/eslint/plugin', (targetName) => ({ targetName }), postTargetTransformer, plugin_1.createNodesV2, options.project);
|
|
13
|
+
const migratedProjects = migratedProjectsModern.size + migratedProjectsLegacy.size;
|
|
14
|
+
if (migratedProjects === 0) {
|
|
15
|
+
throw new Error('Could not find any targets to migrate.');
|
|
16
|
+
}
|
|
17
|
+
if (!options.skipFormat) {
|
|
18
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.convertToInferred = convertToInferred;
|
|
22
|
+
function postTargetTransformer(target, tree, projectDetails) {
|
|
23
|
+
if (target.inputs) {
|
|
24
|
+
const inputs = target.inputs.filter((input) => typeof input === 'string' &&
|
|
25
|
+
![
|
|
26
|
+
'default',
|
|
27
|
+
'{workspaceRoot}/.eslintrc.json',
|
|
28
|
+
'{workspaceRoot}/.eslintignore',
|
|
29
|
+
'{workspaceRoot}/eslint.config.js',
|
|
30
|
+
].includes(input));
|
|
31
|
+
if (inputs.length === 0) {
|
|
32
|
+
delete target.inputs;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (target.options) {
|
|
36
|
+
if ('eslintConfig' in target.options) {
|
|
37
|
+
delete target.options.eslintConfig;
|
|
38
|
+
}
|
|
39
|
+
if ('force' in target.options) {
|
|
40
|
+
delete target.options.force;
|
|
41
|
+
}
|
|
42
|
+
if ('silent' in target.options) {
|
|
43
|
+
delete target.options.silent;
|
|
44
|
+
}
|
|
45
|
+
if ('hasTypeAwareRules' in target.options) {
|
|
46
|
+
delete target.options.hasTypeAwareRules;
|
|
47
|
+
}
|
|
48
|
+
if ('errorOnUnmatchedPattern' in target.options) {
|
|
49
|
+
if (!target.options.errorOnUnmatchedPattern) {
|
|
50
|
+
target.options['no-error-on-unmatched-pattern'] = true;
|
|
51
|
+
}
|
|
52
|
+
delete target.options.errorOnUnmatchedPattern;
|
|
53
|
+
}
|
|
54
|
+
if ('outputFile' in target.options) {
|
|
55
|
+
target.outputs ??= [];
|
|
56
|
+
target.outputs.push(target.options.outputFile);
|
|
57
|
+
}
|
|
58
|
+
for (const key in target_options_map_1.targetOptionsToCliMap) {
|
|
59
|
+
if (target.options[key]) {
|
|
60
|
+
target.options[target_options_map_1.targetOptionsToCliMap[key]] = target.options[key];
|
|
61
|
+
delete target.options[key];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if ('lintFilePatterns' in target.options) {
|
|
65
|
+
const normalizedLintFilePatterns = target.options.lintFilePatterns.map((pattern) => {
|
|
66
|
+
return (0, utils_1.interpolate)(pattern, {
|
|
67
|
+
workspaceRoot: '',
|
|
68
|
+
projectRoot: projectDetails.root,
|
|
69
|
+
projectName: projectDetails.projectName,
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
target.options.args = normalizedLintFilePatterns.map((pattern) => pattern.startsWith(projectDetails.root)
|
|
73
|
+
? pattern.replace(new RegExp(`^${projectDetails.root}/`), './')
|
|
74
|
+
: pattern);
|
|
75
|
+
delete target.options.lintFilePatterns;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return target;
|
|
79
|
+
}
|
|
80
|
+
exports.default = convertToInferred;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const targetOptionsToCliMap: {
|
|
2
|
+
fix: string;
|
|
3
|
+
format: string;
|
|
4
|
+
cache: string;
|
|
5
|
+
cacheLocation: string;
|
|
6
|
+
cacheStrategy: string;
|
|
7
|
+
noEslintrc: string;
|
|
8
|
+
outputFile: string;
|
|
9
|
+
maxWarnings: string;
|
|
10
|
+
quiet: string;
|
|
11
|
+
ignorePath: string;
|
|
12
|
+
rulesdir: string;
|
|
13
|
+
resolvePluginsRelativeTo: string;
|
|
14
|
+
reportUnusedDisableDirectives: string;
|
|
15
|
+
printConfig: string;
|
|
16
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.targetOptionsToCliMap = void 0;
|
|
4
|
+
exports.targetOptionsToCliMap = {
|
|
5
|
+
fix: 'fix',
|
|
6
|
+
format: 'format',
|
|
7
|
+
cache: 'cache',
|
|
8
|
+
cacheLocation: 'cache-location',
|
|
9
|
+
cacheStrategy: 'cache-strategy',
|
|
10
|
+
noEslintrc: 'no-eslintrc',
|
|
11
|
+
outputFile: 'output-file',
|
|
12
|
+
maxWarnings: 'max-warnings',
|
|
13
|
+
quiet: 'quiet',
|
|
14
|
+
ignorePath: 'ignore-path',
|
|
15
|
+
rulesdir: 'rulesdir',
|
|
16
|
+
resolvePluginsRelativeTo: 'resolve-plugins-relative-to',
|
|
17
|
+
reportUnusedDisableDirectives: 'report-unused-disable-directives',
|
|
18
|
+
printConfig: 'print-config',
|
|
19
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"$id": "NxEslintConvertToInferred",
|
|
4
|
+
"description": "Convert existing Eslint project(s) using `@nx/eslint:lint` executor to use `@nx/eslint/plugin`. Defaults to migrating all projects. Pass '--project' to migrate only one target.",
|
|
5
|
+
"title": "Convert Eslint project from executor to plugin",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"project": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "The project to convert from using the `@nx/eslint:lint` executor to use `@nx/eslint/plugin`.",
|
|
11
|
+
"x-priority": "important"
|
|
12
|
+
},
|
|
13
|
+
"skipFormat": {
|
|
14
|
+
"type": "boolean",
|
|
15
|
+
"description": "Whether to format files at the end of the migration.",
|
|
16
|
+
"default": false
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -104,6 +104,10 @@ function migrateEslintFile(projectEslintPath, tree) {
|
|
|
104
104
|
}
|
|
105
105
|
// add extends
|
|
106
106
|
json.extends = json.extends || [];
|
|
107
|
+
// ensure extends is an array
|
|
108
|
+
if (typeof json.extends === 'string') {
|
|
109
|
+
json.extends = [json.extends];
|
|
110
|
+
}
|
|
107
111
|
const pathToRootConfig = `${(0, devkit_1.offsetFromRoot)((0, path_1.dirname)(projectEslintPath))}${baseFile}`;
|
|
108
112
|
if (json.extends.indexOf(pathToRootConfig) === -1) {
|
|
109
113
|
json.extends.push(pathToRootConfig);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.lintInitGenerator = exports.initEsLint = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const
|
|
5
|
+
const add_plugin_1 = require("@nx/devkit/src/utils/add-plugin");
|
|
6
6
|
const versions_1 = require("../../utils/versions");
|
|
7
7
|
const eslint_file_1 = require("../utils/eslint-file");
|
|
8
8
|
const plugin_1 = require("../../plugins/plugin");
|
|
@@ -31,24 +31,6 @@ function addTargetDefaults(tree) {
|
|
|
31
31
|
];
|
|
32
32
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
33
33
|
}
|
|
34
|
-
function addPlugin(tree) {
|
|
35
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
36
|
-
nxJson.plugins ??= [];
|
|
37
|
-
for (const plugin of nxJson.plugins) {
|
|
38
|
-
if (typeof plugin === 'string'
|
|
39
|
-
? plugin === '@nx/eslint/plugin'
|
|
40
|
-
: plugin.plugin === '@nx/eslint/plugin') {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
nxJson.plugins.push({
|
|
45
|
-
plugin: '@nx/eslint/plugin',
|
|
46
|
-
options: {
|
|
47
|
-
targetName: 'lint',
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
51
|
-
}
|
|
52
34
|
async function initEsLint(tree, options) {
|
|
53
35
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
54
36
|
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
@@ -56,11 +38,19 @@ async function initEsLint(tree, options) {
|
|
|
56
38
|
options.addPlugin ??= addPluginDefault;
|
|
57
39
|
const hasPlugin = (0, plugin_2.hasEslintPlugin)(tree);
|
|
58
40
|
const rootEslintFile = (0, eslint_file_1.findEslintFile)(tree);
|
|
41
|
+
const graph = await (0, devkit_1.createProjectGraphAsync)();
|
|
42
|
+
const lintTargetNames = [
|
|
43
|
+
'lint',
|
|
44
|
+
'eslint:lint',
|
|
45
|
+
'eslint-lint',
|
|
46
|
+
'_lint',
|
|
47
|
+
'_eslint:lint',
|
|
48
|
+
'_eslint-lint',
|
|
49
|
+
];
|
|
59
50
|
if (rootEslintFile && options.addPlugin && !hasPlugin) {
|
|
60
|
-
addPlugin(tree
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
51
|
+
await (0, add_plugin_1.addPlugin)(tree, graph, '@nx/eslint/plugin', plugin_1.createNodesV2, {
|
|
52
|
+
targetName: lintTargetNames,
|
|
53
|
+
}, options.updatePackageScripts);
|
|
64
54
|
return () => { };
|
|
65
55
|
}
|
|
66
56
|
if (rootEslintFile) {
|
|
@@ -68,7 +58,9 @@ async function initEsLint(tree, options) {
|
|
|
68
58
|
}
|
|
69
59
|
updateProductionFileset(tree);
|
|
70
60
|
if (options.addPlugin) {
|
|
71
|
-
addPlugin(tree
|
|
61
|
+
await (0, add_plugin_1.addPlugin)(tree, graph, '@nx/eslint/plugin', plugin_1.createNodesV2, {
|
|
62
|
+
targetName: lintTargetNames,
|
|
63
|
+
}, options.updatePackageScripts);
|
|
72
64
|
}
|
|
73
65
|
else {
|
|
74
66
|
addTargetDefaults(tree);
|
|
@@ -81,9 +73,6 @@ async function initEsLint(tree, options) {
|
|
|
81
73
|
eslint: versions_1.eslintVersion,
|
|
82
74
|
}, undefined, options.keepExistingVersions));
|
|
83
75
|
}
|
|
84
|
-
if (options.updatePackageScripts) {
|
|
85
|
-
await (0, update_package_scripts_1.updatePackageScripts)(tree, plugin_1.createNodes);
|
|
86
|
-
}
|
|
87
76
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
88
77
|
}
|
|
89
78
|
exports.initEsLint = initEsLint;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { GeneratorCallback, Tree } from '@nx/devkit';
|
|
2
2
|
import { Linter as LinterEnum } from '../utils/linter';
|
|
3
3
|
interface LintProjectOptions {
|
|
4
4
|
project: string;
|
|
@@ -16,6 +16,7 @@ interface LintProjectOptions {
|
|
|
16
16
|
* @internal
|
|
17
17
|
*/
|
|
18
18
|
addExplicitTargets?: boolean;
|
|
19
|
+
addPackageJsonDependencyChecks?: boolean;
|
|
19
20
|
}
|
|
20
21
|
export declare function lintProjectGenerator(tree: Tree, options: LintProjectOptions): Promise<GeneratorCallback>;
|
|
21
22
|
export declare function lintProjectGeneratorInternal(tree: Tree, options: LintProjectOptions): Promise<GeneratorCallback>;
|
|
@@ -73,7 +73,8 @@ async function lintProjectGeneratorInternal(tree, options) {
|
|
|
73
73
|
if (!options.rootProject) {
|
|
74
74
|
const projects = {};
|
|
75
75
|
(0, project_configuration_1.getProjects)(tree).forEach((v, k) => (projects[k] = v));
|
|
76
|
-
|
|
76
|
+
const graph = await (0, devkit_1.createProjectGraphAsync)();
|
|
77
|
+
if (isMigrationToMonorepoNeeded(tree, graph)) {
|
|
77
78
|
// we only migrate project configurations that have been created
|
|
78
79
|
const filteredProjects = [];
|
|
79
80
|
Object.entries(projects).forEach(([name, project]) => {
|
|
@@ -88,7 +89,7 @@ async function lintProjectGeneratorInternal(tree, options) {
|
|
|
88
89
|
// additionally, the companion e2e app would have `rootProject: true`
|
|
89
90
|
// so we need to check for the root path as well
|
|
90
91
|
if (!options.rootProject || projectConfig.root !== '.') {
|
|
91
|
-
createEsLintConfiguration(tree, projectConfig, options.setParserOptionsProject, options.rootProject);
|
|
92
|
+
createEsLintConfiguration(tree, options, projectConfig, options.setParserOptionsProject, options.rootProject);
|
|
92
93
|
}
|
|
93
94
|
// Buildable libs need source analysis enabled for linting `package.json`.
|
|
94
95
|
if (isBuildableLibraryProject(projectConfig) &&
|
|
@@ -107,7 +108,7 @@ async function lintProjectGeneratorInternal(tree, options) {
|
|
|
107
108
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
108
109
|
}
|
|
109
110
|
exports.lintProjectGeneratorInternal = lintProjectGeneratorInternal;
|
|
110
|
-
function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject, rootProject) {
|
|
111
|
+
function createEsLintConfiguration(tree, options, projectConfig, setParserOptionsProject, rootProject) {
|
|
111
112
|
// we are only extending root for non-standalone projects or their complementary e2e apps
|
|
112
113
|
const extendedRootConfig = rootProject ? undefined : (0, eslint_file_1.findEslintFile)(tree);
|
|
113
114
|
const pathToRootConfig = extendedRootConfig
|
|
@@ -150,7 +151,8 @@ function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject,
|
|
|
150
151
|
rules: {},
|
|
151
152
|
},
|
|
152
153
|
];
|
|
153
|
-
if (
|
|
154
|
+
if (options.addPackageJsonDependencyChecks ||
|
|
155
|
+
isBuildableLibraryProject(projectConfig)) {
|
|
154
156
|
overrides.push({
|
|
155
157
|
files: ['*.json'],
|
|
156
158
|
parser: 'jsonc-eslint-parser',
|
|
@@ -198,30 +200,24 @@ function isBuildableLibraryProject(projectConfig) {
|
|
|
198
200
|
* Detect based on the state of lint target configuration of the root project
|
|
199
201
|
* if we should migrate eslint configs to monorepo style
|
|
200
202
|
*/
|
|
201
|
-
function isMigrationToMonorepoNeeded(
|
|
203
|
+
function isMigrationToMonorepoNeeded(tree, graph) {
|
|
202
204
|
// the base config is already created, migration has been done
|
|
203
205
|
if (tree.exists(config_file_1.baseEsLintConfigFile) ||
|
|
204
206
|
tree.exists(config_file_1.baseEsLintFlatConfigFile)) {
|
|
205
207
|
return false;
|
|
206
208
|
}
|
|
207
|
-
const
|
|
208
|
-
if (configs.length === 1) {
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
209
|
+
const nodes = Object.values(graph.nodes);
|
|
211
210
|
// get root project
|
|
212
|
-
const rootProject =
|
|
213
|
-
if (!rootProject || !rootProject.targets) {
|
|
211
|
+
const rootProject = nodes.find((p) => p.data.root === '.');
|
|
212
|
+
if (!rootProject || !rootProject.data.targets) {
|
|
214
213
|
return false;
|
|
215
214
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
215
|
+
for (const targetConfig of Object.values(rootProject.data.targets ?? {})) {
|
|
216
|
+
if (['@nx/eslint:lint', '@nrwl/linter:eslint', '@nx/linter:eslint'].includes(targetConfig.executor) ||
|
|
217
|
+
(targetConfig.executor === 'nx:run-commands' &&
|
|
218
|
+
targetConfig.options?.command.startsWith('eslint '))) {
|
|
219
|
+
return true;
|
|
222
220
|
}
|
|
223
221
|
}
|
|
224
|
-
|
|
225
|
-
const lintTarget = (0, init_migration_1.findLintTarget)(rootProject);
|
|
226
|
-
return !!lintTarget;
|
|
222
|
+
return false;
|
|
227
223
|
}
|
|
@@ -189,7 +189,7 @@ function replaceOverridesInLintConfig(tree, root, overrides) {
|
|
|
189
189
|
content = (0, ast_utils_1.removeOverridesFromLintConfig)(content);
|
|
190
190
|
overrides.forEach((override) => {
|
|
191
191
|
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override);
|
|
192
|
-
(0, ast_utils_1.addBlockToFlatConfigExport)(content, flatOverride);
|
|
192
|
+
content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, flatOverride);
|
|
193
193
|
});
|
|
194
194
|
tree.write(fileName, content);
|
|
195
195
|
}
|
|
@@ -209,7 +209,9 @@ function addExtendsToLintConfig(tree, root, plugin) {
|
|
|
209
209
|
const pluginExtends = (0, ast_utils_1.generatePluginExtendsElement)(plugins);
|
|
210
210
|
let content = tree.read(fileName, 'utf8');
|
|
211
211
|
content = (0, ast_utils_1.addCompatToFlatConfig)(content);
|
|
212
|
-
tree.write(fileName, (0, ast_utils_1.addBlockToFlatConfigExport)(content, pluginExtends
|
|
212
|
+
tree.write(fileName, (0, ast_utils_1.addBlockToFlatConfigExport)(content, pluginExtends, {
|
|
213
|
+
insertAtTheEnd: false,
|
|
214
|
+
}));
|
|
213
215
|
}
|
|
214
216
|
else {
|
|
215
217
|
const fileName = (0, devkit_1.joinPathFragments)(root, '.eslintrc.json');
|