@nx/eslint 24.0.0-beta.2 → 24.0.0-beta.4
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/dist/internal.d.ts +0 -1
- package/dist/src/generators/init/init-migration.d.ts +1 -2
- package/dist/src/generators/init/init-migration.js +2 -13
- package/dist/src/generators/init/init.d.ts +0 -1
- package/dist/src/generators/init/init.js +5 -42
- package/dist/src/generators/lint-project/lint-project.d.ts +0 -2
- package/dist/src/generators/lint-project/lint-project.js +10 -33
- package/dist/src/generators/workspace-rule/workspace-rule.js +0 -3
- package/dist/src/generators/workspace-rules-project/workspace-rules-project.d.ts +0 -1
- package/dist/src/migrations/update-23-1-0/convert-to-flat-config.md +9 -9
- package/dist/src/migrations/update-24-0-0/finish-inferred-conversion.md +12 -0
- package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.d.ts +6 -0
- package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.js +10 -0
- package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.md +38 -0
- package/dist/src/utils/config-file.d.ts +0 -2
- package/dist/src/utils/config-file.js +0 -44
- package/executors.json +1 -7
- package/migrations.json +7 -0
- package/package.json +6 -6
- package/dist/src/executors/lint/lint.impl.d.ts +0 -5
- package/dist/src/executors/lint/lint.impl.js +0 -190
- package/dist/src/executors/lint/schema.d.ts +0 -32
- package/dist/src/executors/lint/schema.json +0 -154
- package/dist/src/executors/lint/utility/eslint-utils.d.ts +0 -6
- package/dist/src/executors/lint/utility/eslint-utils.js +0 -106
- package/dist/src/generators/utils/eslint-targets.d.ts +0 -2
- package/dist/src/generators/utils/eslint-targets.js +0 -17
- package/dist/src/utils/deprecation.d.ts +0 -3
- package/dist/src/utils/deprecation.js +0 -15
package/dist/internal.d.ts
CHANGED
|
@@ -4,4 +4,3 @@ export { useFlatConfig } from './src/utils/flat-config';
|
|
|
4
4
|
export { javaScriptOverride, typeScriptOverride, } from './src/generators/init/global-eslint-config';
|
|
5
5
|
export { setupRootEsLint } from './src/generators/lint-project/setup-root-eslint';
|
|
6
6
|
export { getInstalledEslintVersion, typescriptESLintVersion, versions, } from './src/utils/versions';
|
|
7
|
-
export type { Schema } from './src/executors/lint/schema';
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { GeneratorCallback, ProjectConfiguration,
|
|
1
|
+
import { GeneratorCallback, ProjectConfiguration, Tree } from '@nx/devkit';
|
|
2
2
|
export declare function migrateConfigToMonorepoStyle(projects: ProjectConfiguration[], tree: Tree, unitTestRunner: string, eslintConfigFormat: 'mjs' | 'cjs', keepExistingVersions?: boolean): GeneratorCallback;
|
|
3
|
-
export declare function findLintTarget(project: ProjectConfiguration): TargetConfiguration;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.migrateConfigToMonorepoStyle = migrateConfigToMonorepoStyle;
|
|
4
|
-
exports.findLintTarget = findLintTarget;
|
|
5
4
|
const devkit_1 = require("@nx/devkit");
|
|
6
5
|
const path_1 = require("path");
|
|
7
6
|
const eslint_file_1 = require("../utils/eslint-file");
|
|
@@ -50,14 +49,8 @@ function migrateConfigToMonorepoStyle(projects, tree, unitTestRunner, eslintConf
|
|
|
50
49
|
// update extends in all projects' eslint configs
|
|
51
50
|
projects.forEach((project) => {
|
|
52
51
|
let eslintFile;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// If target is configured in project.json, read file from target options.
|
|
56
|
-
eslintFile =
|
|
57
|
-
lintTarget.options?.eslintConfig || (0, eslint_file_1.findEslintFile)(tree, project.root);
|
|
58
|
-
}
|
|
59
|
-
else if ((0, plugin_1.hasEslintPlugin)(tree)) {
|
|
60
|
-
// Otherwise, if `@nx/eslint/plugin` is used, match any of the known config files.
|
|
52
|
+
if ((0, plugin_1.hasEslintPlugin)(tree)) {
|
|
53
|
+
// If `@nx/eslint/plugin` is used, match any of the known config files.
|
|
61
54
|
for (const f of config_file_1.ESLINT_CONFIG_FILENAMES) {
|
|
62
55
|
if (tree.exists((0, devkit_1.joinPathFragments)(project.root, f))) {
|
|
63
56
|
eslintFile = f;
|
|
@@ -80,10 +73,6 @@ function migrateConfigToMonorepoStyle(projects, tree, unitTestRunner, eslintConf
|
|
|
80
73
|
'@nx/eslint-plugin': versions_1.nxVersion,
|
|
81
74
|
}, undefined, keepExistingVersions ?? true);
|
|
82
75
|
}
|
|
83
|
-
function findLintTarget(project) {
|
|
84
|
-
return Object.values(project.targets ?? {}).find((target) => target.executor === '@nx/eslint:lint' ||
|
|
85
|
-
target.executor === '@nx/linter:eslint');
|
|
86
|
-
}
|
|
87
76
|
function migrateEslintFile(projectEslintPath, tree) {
|
|
88
77
|
const baseFile = (0, eslint_file_1.findEslintFile)(tree);
|
|
89
78
|
if ((0, eslint_file_1.isEslintConfigSupported)(tree)) {
|
|
@@ -3,7 +3,6 @@ export interface LinterInitOptions {
|
|
|
3
3
|
skipPackageJson?: boolean;
|
|
4
4
|
keepExistingVersions?: boolean;
|
|
5
5
|
updatePackageScripts?: boolean;
|
|
6
|
-
addPlugin?: boolean;
|
|
7
6
|
eslintConfigFormat?: 'mjs' | 'cjs';
|
|
8
7
|
}
|
|
9
8
|
export declare function initEsLint(tree: Tree, options: LinterInitOptions): Promise<GeneratorCallback>;
|
|
@@ -21,34 +21,6 @@ function updateProductionFileset(tree, format = 'mjs') {
|
|
|
21
21
|
}
|
|
22
22
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
23
23
|
}
|
|
24
|
-
function addTargetDefaults(tree, format) {
|
|
25
|
-
const nxJson = (0, devkit_1.readNxJson)(tree) ?? {};
|
|
26
|
-
// `@nx/eslint:lint` is an executor identifier — match defaults keyed on
|
|
27
|
-
// the executor, not on a target named that string.
|
|
28
|
-
const existing = (0, internal_1.findTargetDefault)(nxJson.targetDefaults, {
|
|
29
|
-
executor: '@nx/eslint:lint',
|
|
30
|
-
});
|
|
31
|
-
const patch = {};
|
|
32
|
-
if (existing?.cache === undefined)
|
|
33
|
-
patch.cache = true;
|
|
34
|
-
if (existing?.inputs === undefined) {
|
|
35
|
-
patch.inputs = [
|
|
36
|
-
'default',
|
|
37
|
-
'^default',
|
|
38
|
-
`{workspaceRoot}/.eslintrc.json`,
|
|
39
|
-
`{workspaceRoot}/.eslintignore`,
|
|
40
|
-
`{workspaceRoot}/eslint.config.${format}`,
|
|
41
|
-
'{workspaceRoot}/tools/eslint-rules/**/*',
|
|
42
|
-
];
|
|
43
|
-
}
|
|
44
|
-
if (Object.keys(patch).length > 0) {
|
|
45
|
-
(0, internal_1.upsertTargetDefault)(tree, nxJson, {
|
|
46
|
-
executor: '@nx/eslint:lint',
|
|
47
|
-
...patch,
|
|
48
|
-
});
|
|
49
|
-
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
24
|
function updateVsCodeRecommendedExtensions(host) {
|
|
53
25
|
if (!host.exists('.vscode/extensions.json')) {
|
|
54
26
|
return;
|
|
@@ -64,10 +36,6 @@ function updateVsCodeRecommendedExtensions(host) {
|
|
|
64
36
|
}
|
|
65
37
|
async function initEsLint(tree, options) {
|
|
66
38
|
(0, assert_supported_eslint_version_1.assertSupportedEslintVersion)(tree);
|
|
67
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
68
|
-
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
69
|
-
nxJson.useInferencePlugins !== false;
|
|
70
|
-
options.addPlugin ??= addPluginDefault;
|
|
71
39
|
options.eslintConfigFormat ??= 'mjs';
|
|
72
40
|
const hasPlugin = (0, plugin_2.hasEslintPlugin)(tree);
|
|
73
41
|
const rootEslintFile = (0, eslint_file_1.findEslintFile)(tree);
|
|
@@ -89,7 +57,7 @@ async function initEsLint(tree, options) {
|
|
|
89
57
|
'_eslint:lint',
|
|
90
58
|
'_eslint-lint',
|
|
91
59
|
];
|
|
92
|
-
if (rootEslintFile &&
|
|
60
|
+
if (rootEslintFile && !hasPlugin) {
|
|
93
61
|
await (0, internal_1.addPlugin)(tree, graph, '@nx/eslint/plugin', plugin_1.createNodes, {
|
|
94
62
|
targetName: lintTargetNames,
|
|
95
63
|
}, options.updatePackageScripts);
|
|
@@ -100,14 +68,9 @@ async function initEsLint(tree, options) {
|
|
|
100
68
|
}
|
|
101
69
|
updateProductionFileset(tree, options.eslintConfigFormat);
|
|
102
70
|
updateVsCodeRecommendedExtensions(tree);
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}, options.updatePackageScripts);
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
addTargetDefaults(tree, options.eslintConfigFormat);
|
|
110
|
-
}
|
|
71
|
+
await (0, internal_1.addPlugin)(tree, graph, '@nx/eslint/plugin', plugin_1.createNodes, {
|
|
72
|
+
targetName: lintTargetNames,
|
|
73
|
+
}, options.updatePackageScripts);
|
|
111
74
|
const tasks = [];
|
|
112
75
|
if (!options.skipPackageJson) {
|
|
113
76
|
const { eslintVersion } = (0, versions_1.versions)(tree);
|
|
@@ -120,5 +83,5 @@ async function initEsLint(tree, options) {
|
|
|
120
83
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
121
84
|
}
|
|
122
85
|
async function lintInitGenerator(tree, options) {
|
|
123
|
-
return await initEsLint(tree,
|
|
86
|
+
return await initEsLint(tree, options);
|
|
124
87
|
}
|
|
@@ -15,12 +15,10 @@ interface LintProjectOptions {
|
|
|
15
15
|
unitTestRunner?: string;
|
|
16
16
|
rootProject?: boolean;
|
|
17
17
|
keepExistingVersions?: boolean;
|
|
18
|
-
addPlugin?: boolean;
|
|
19
18
|
eslintConfigFormat?: 'mjs' | 'cjs';
|
|
20
19
|
/**
|
|
21
20
|
* @internal
|
|
22
21
|
*/
|
|
23
|
-
addExplicitTargets?: boolean;
|
|
24
22
|
addPackageJsonDependencyChecks?: boolean;
|
|
25
23
|
}
|
|
26
24
|
export declare function lintProjectGenerator(tree: Tree, options: LintProjectOptions): Promise<GeneratorCallback>;
|
|
@@ -6,7 +6,6 @@ const devkit_1 = require("@nx/devkit");
|
|
|
6
6
|
const eslint_file_1 = require("../utils/eslint-file");
|
|
7
7
|
const path_1 = require("path");
|
|
8
8
|
const init_1 = require("../init/init");
|
|
9
|
-
const deprecation_1 = require("../../utils/deprecation");
|
|
10
9
|
const init_migration_1 = require("../init/init-migration");
|
|
11
10
|
const flat_config_1 = require("../../utils/flat-config");
|
|
12
11
|
const ast_utils_1 = require("../utils/flat-config/ast-utils");
|
|
@@ -16,18 +15,13 @@ const versions_1 = require("../../utils/versions");
|
|
|
16
15
|
const setup_root_eslint_1 = require("./setup-root-eslint");
|
|
17
16
|
const internal_1 = require("@nx/js/internal");
|
|
18
17
|
function lintProjectGenerator(tree, options) {
|
|
19
|
-
return lintProjectGeneratorInternal(tree,
|
|
18
|
+
return lintProjectGeneratorInternal(tree, options);
|
|
20
19
|
}
|
|
21
20
|
async function lintProjectGeneratorInternal(tree, options) {
|
|
22
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
23
21
|
options.eslintConfigFormat ??= 'mjs';
|
|
24
|
-
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
25
|
-
nxJson.useInferencePlugins !== false;
|
|
26
|
-
options.addPlugin ??= addPluginDefault;
|
|
27
22
|
const tasks = [];
|
|
28
23
|
const initTask = await (0, init_1.lintInitGenerator)(tree, {
|
|
29
24
|
skipPackageJson: options.skipPackageJson,
|
|
30
|
-
addPlugin: options.addPlugin,
|
|
31
25
|
eslintConfigFormat: options.eslintConfigFormat,
|
|
32
26
|
});
|
|
33
27
|
tasks.push(initTask);
|
|
@@ -49,31 +43,15 @@ async function lintProjectGeneratorInternal(tree, options) {
|
|
|
49
43
|
isBuildableLibraryProject(tree, projectConfig)) {
|
|
50
44
|
lintFilePatterns.push(`{projectRoot}/package.json`);
|
|
51
45
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
lintFilePatterns.length &&
|
|
56
|
-
lintFilePatterns.some((p) => !['./src', '{projectRoot}', projectConfig.root].includes(p))) {
|
|
57
|
-
projectConfig.targets ??= {};
|
|
58
|
-
projectConfig.targets['lint'] = {
|
|
59
|
-
command: `eslint ${lintFilePatterns
|
|
60
|
-
.join(' ')
|
|
61
|
-
.replace('{projectRoot}', projectConfig.root)}`,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
(0, deprecation_1.warnEslintExecutorGenerating)();
|
|
46
|
+
if (lintFilePatterns &&
|
|
47
|
+
lintFilePatterns.length &&
|
|
48
|
+
lintFilePatterns.some((p) => !['./src', '{projectRoot}', projectConfig.root].includes(p))) {
|
|
67
49
|
projectConfig.targets ??= {};
|
|
68
50
|
projectConfig.targets['lint'] = {
|
|
69
|
-
|
|
51
|
+
command: `eslint ${lintFilePatterns
|
|
52
|
+
.join(' ')
|
|
53
|
+
.replace('{projectRoot}', projectConfig.root)}`,
|
|
70
54
|
};
|
|
71
|
-
if (lintFilePatterns && lintFilePatterns.length) {
|
|
72
|
-
// only add lintFilePatterns if they are explicitly defined
|
|
73
|
-
projectConfig.targets['lint'].options = {
|
|
74
|
-
lintFilePatterns,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
55
|
}
|
|
78
56
|
// we are adding new project which is not the root project or
|
|
79
57
|
// companion e2e app so we should check if migration to
|
|
@@ -274,10 +252,9 @@ function rootHasEslintLintTarget(targets) {
|
|
|
274
252
|
return false;
|
|
275
253
|
}
|
|
276
254
|
for (const targetConfig of Object.values(targets)) {
|
|
277
|
-
if (
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
targetConfig.options?.command.startsWith('eslint '))) {
|
|
255
|
+
if (targetConfig.executor === 'nx:run-commands' &&
|
|
256
|
+
targetConfig.options?.command &&
|
|
257
|
+
targetConfig.options?.command.startsWith('eslint ')) {
|
|
281
258
|
return true;
|
|
282
259
|
}
|
|
283
260
|
}
|
|
@@ -17,12 +17,9 @@ async function lintWorkspaceRuleGenerator(tree, options) {
|
|
|
17
17
|
// recommended replacement is the separate `@typescript-eslint/rule-tester`
|
|
18
18
|
// package, whose flat-style API works for both flat and eslintrc workspaces.
|
|
19
19
|
const { typescriptESLintVersion } = (0, versions_1.versions)(tree);
|
|
20
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
21
20
|
// Ensure that the workspace rules project has been created
|
|
22
21
|
tasks.push(await (0, workspace_rules_project_1.lintWorkspaceRulesProjectGenerator)(tree, {
|
|
23
22
|
skipFormat: true,
|
|
24
|
-
addPlugin: process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
25
|
-
nxJson.useInferencePlugins !== false,
|
|
26
23
|
}));
|
|
27
24
|
tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@typescript-eslint/rule-tester': typescriptESLintVersion }, undefined, true));
|
|
28
25
|
const ruleDir = (0, devkit_1.joinPathFragments)(workspace_lint_rules_1.workspaceLintPluginDir, options.directory ?? '');
|
|
@@ -3,6 +3,5 @@ export declare const WORKSPACE_RULES_PROJECT_NAME = "eslint-rules";
|
|
|
3
3
|
export declare const WORKSPACE_PLUGIN_DIR = "tools/eslint-rules";
|
|
4
4
|
export interface LintWorkspaceRulesProjectGeneratorOptions {
|
|
5
5
|
skipFormat?: boolean;
|
|
6
|
-
addPlugin?: boolean;
|
|
7
6
|
}
|
|
8
7
|
export declare function lintWorkspaceRulesProjectGenerator(tree: Tree, options?: LintWorkspaceRulesProjectGeneratorOptions): Promise<GeneratorCallback>;
|
|
@@ -34,17 +34,17 @@ The pre-pass does NOT:
|
|
|
34
34
|
- Decide whether a generated `FlatCompat` shim should become flat-native config.
|
|
35
35
|
- Make the workspace pass lint after ESLint v9 changed which rules its preset defaults enable.
|
|
36
36
|
|
|
37
|
-
Everything the pre-pass could not finish is forwarded to you in
|
|
37
|
+
Everything the pre-pass could not finish is forwarded to you in `impl.agentContext`.
|
|
38
38
|
|
|
39
|
-
How to read the
|
|
39
|
+
How to read the `impl` fields of the step's `nx_migrate_prompt` block:
|
|
40
40
|
|
|
41
|
-
-
|
|
42
|
-
-
|
|
41
|
+
- `impl.changes` lists files the pre-pass wrote. Verify the new shape is in place; do not re-apply the same edit. It is empty when the pre-pass made no changes (for example a workspace that was already on flat config).
|
|
42
|
+
- `impl.agentContext` lists detections the pre-pass forwarded because it could not safely complete them. Every entry is pending work. Address each one in the relevant section below.
|
|
43
43
|
|
|
44
44
|
</pre_pass_summary>
|
|
45
45
|
|
|
46
46
|
<handoff_guidance>
|
|
47
|
-
In your handoff `summary` (1 to 3 sentences per the
|
|
47
|
+
In your handoff `summary` (1 to 3 sentences, per the handoff format), name the sections you applied and explicitly call out any you skipped because they did not apply (for example "no JavaScript-based configs and no removed formatters in this workspace").
|
|
48
48
|
</handoff_guidance>
|
|
49
49
|
|
|
50
50
|
## Pre-Migration Checklist
|
|
@@ -87,7 +87,7 @@ If the workspace already uses `eslint.config.*` at the root and in every project
|
|
|
87
87
|
|
|
88
88
|
## 2. Convert JavaScript-based ESLint configs the pre-pass skipped
|
|
89
89
|
|
|
90
|
-
**Search pattern**: `.eslintrc.js` and `.eslintrc.cjs` files (forwarded in
|
|
90
|
+
**Search pattern**: `.eslintrc.js` and `.eslintrc.cjs` files (forwarded in `impl.agentContext`).
|
|
91
91
|
|
|
92
92
|
**What changed**: the pre-pass only converts JSON and YAML eslintrc files. JavaScript-based configs run arbitrary code, so they need manual conversion.
|
|
93
93
|
|
|
@@ -126,7 +126,7 @@ export default [
|
|
|
126
126
|
|
|
127
127
|
## 3. Convert FlatCompat shims to flat-native config where low-risk
|
|
128
128
|
|
|
129
|
-
**Search pattern**: `FlatCompat`, `@eslint/eslintrc`, `compat.extends(`, `compat.config(` in the generated `eslint.config.*` files (listed in
|
|
129
|
+
**Search pattern**: `FlatCompat`, `@eslint/eslintrc`, `compat.extends(`, `compat.config(` in the generated `eslint.config.*` files (listed in `impl.changes`).
|
|
130
130
|
|
|
131
131
|
**What changed**: `FlatCompat` is a runtime shim that adapts eslintrc-style `extends` into flat config. Many plugins now ship native flat presets, which are clearer and avoid the shim.
|
|
132
132
|
|
|
@@ -169,7 +169,7 @@ This is the core requirement of the migration: the workspace must lint cleanly w
|
|
|
169
169
|
|
|
170
170
|
ESLint v9 and typescript-eslint v8 changed which rules their recommended sets enable. A rule the user never configured may now report errors. Disable those rules; do not edit source files to satisfy them.
|
|
171
171
|
|
|
172
|
-
The set of rules the user explicitly configured before the migration is in
|
|
172
|
+
The set of rules the user explicitly configured before the migration is in `impl.agentContext` (the entry that starts with "Passing-state requirement").
|
|
173
173
|
|
|
174
174
|
**Procedure**:
|
|
175
175
|
|
|
@@ -213,7 +213,7 @@ You cannot make lint pass without either editing source files or disabling a rul
|
|
|
213
213
|
|
|
214
214
|
## 5. Fix removed output formatters
|
|
215
215
|
|
|
216
|
-
**Search pattern**: the `format` option on lint targets (forwarded in
|
|
216
|
+
**Search pattern**: the `format` option on lint targets (forwarded in `impl.agentContext`).
|
|
217
217
|
|
|
218
218
|
**What changed**: ESLint v9 removed several built-in output formatters. The built-ins that remain are `stylish`, `html`, `json`, and `json-with-metadata`. Removed: `compact`, `codeframe`, `unix`, `visualstudio`, `table`, `checkstyle`, `jslint-xml`, `junit`, `tap`.
|
|
219
219
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Replace removed @nx/eslint executors with inferred tasks
|
|
2
|
+
|
|
3
|
+
Nx 24 removed `@nx/eslint:lint` (including the old `@nrwl/linter:eslint` name).
|
|
4
|
+
|
|
5
|
+
Before changing anything, check for leftover work: a project target, a package.json target or a `targetDefaults` entry still uses a removed executor, or the advisory context reports a conversion error. If none applies, make no changes and stop. Treat each advisory-context item as pending work.
|
|
6
|
+
|
|
7
|
+
1. Inspect all affected projects and workspace defaults. Repair config-loading errors first. Do not restore executor registrations or install older Nx packages.
|
|
8
|
+
2. Ensure flat ESLint configs load and preserve file patterns, exclusions, rules and output flags. Do not weaken rules to make validation pass.
|
|
9
|
+
3. Register `@nx/eslint/plugin` with options/includes that preserve custom target names and mixed inferred/explicit projects. Replace remaining removed-executor targets, including those in package.json and filtered targetDefaults. Transfer their behavior before removing obsolete defaults. Preserve configurations, dependencies, cache inputs/outputs and environment behavior. Do not silently delete unsupported options or unrelated targets. Migrate old @nrwl aliases too.
|
|
10
|
+
4. Run project graph creation with the daemon and graph cache disabled (`NX_DAEMON=false NX_CACHE_PROJECT_GRAPH=false`), using the workspace package manager. Inspect resolved project targets and verify each migrated entrypoint exists and is inferred (a thin alias to an inferred target is acceptable). Resolve graph errors before completing this migration, even if task validation was skipped. Configs must load for subsequent migrations.
|
|
11
|
+
5. By default run relevant real builds/tests with task cache disabled, including alternate configurations. Honor an existing preference to skip expensive task validation; otherwise offer that option when validation is slow. Skipping expensive tasks never skips conversion or the graph check. Report each skipped task as unverified. Never weaken assertions or change application behavior to make checks pass.
|
|
12
|
+
6. Report converted projects, graph validation, task results and any skipped checks. Unconverted targets or a broken graph mean the migration is incomplete. Investigate task failures and distinguish missing environment prerequisites from conversion regressions; do not claim a working workspace with unresolved regressions.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = update;
|
|
4
|
+
const internal_1 = require("@nx/devkit/internal");
|
|
5
|
+
function update(tree) {
|
|
6
|
+
return (0, internal_1.migrateRemovedExecutors)(tree, ['@nx/eslint:lint', '@nrwl/linter:eslint'], async (tree, options) => {
|
|
7
|
+
const { convertToInferred } = require('../../generators/convert-to-inferred/convert-to-inferred');
|
|
8
|
+
return convertToInferred(tree, options);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#### Convert `@nx/eslint:lint` targets to inferred tasks
|
|
2
|
+
|
|
3
|
+
Nx 24 removes the `@nx/eslint:lint` executor and its `@nrwl/linter:eslint` alias. The migration registers `@nx/eslint/plugin` in `nx.json` and converts the targets that use those executors to inferred tasks. Options the plugin does not infer stay on the target. A target with nothing left to override is removed from project configuration. When several projects share the same remaining options, those options move to a `targetDefaults` entry scoped to the plugin. `targetDefaults` entries keyed by a removed executor are removed once no target uses that executor.
|
|
4
|
+
|
|
5
|
+
The migration lists the targets the converter cannot convert safely. In agentic runs, an AI prompt finishes them and validates the project graph.
|
|
6
|
+
|
|
7
|
+
#### Sample code changes
|
|
8
|
+
|
|
9
|
+
##### Before
|
|
10
|
+
|
|
11
|
+
```json title="myapp/project.json"
|
|
12
|
+
{
|
|
13
|
+
"name": "myapp",
|
|
14
|
+
"targets": {
|
|
15
|
+
"lint": {
|
|
16
|
+
"executor": "@nx/eslint:lint",
|
|
17
|
+
"options": {
|
|
18
|
+
"eslintConfig": "myapp/.eslintrc.json"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
##### After
|
|
26
|
+
|
|
27
|
+
```json title="nx.json"
|
|
28
|
+
{
|
|
29
|
+
"plugins": [
|
|
30
|
+
{
|
|
31
|
+
"plugin": "@nx/eslint/plugin",
|
|
32
|
+
"options": {
|
|
33
|
+
"targetName": "lint"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
```
|
|
@@ -6,5 +6,3 @@ export declare const baseEsLintConfigFile = ".eslintrc.base.json";
|
|
|
6
6
|
export declare const baseEsLintFlatConfigFile = "eslint.base.config.mjs";
|
|
7
7
|
export declare const legacyBaseEsLintFlatConfigFile = "eslint.base.config.js";
|
|
8
8
|
export declare function isFlatConfig(configFilePath: string): boolean;
|
|
9
|
-
export declare function findFlatConfigFile(directory: string, workspaceRoot: string): string | null;
|
|
10
|
-
export declare function findOldConfigFile(filePathOrDirectory: string, workspaceRoot: string): string | null;
|
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.legacyBaseEsLintFlatConfigFile = exports.baseEsLintFlatConfigFile = exports.baseEsLintConfigFile = exports.BASE_ESLINT_CONFIG_FILENAMES = exports.ESLINT_CONFIG_FILENAMES = exports.ESLINT_OLD_CONFIG_FILENAMES = exports.ESLINT_FLAT_CONFIG_FILENAMES = void 0;
|
|
4
4
|
exports.isFlatConfig = isFlatConfig;
|
|
5
|
-
exports.findFlatConfigFile = findFlatConfigFile;
|
|
6
|
-
exports.findOldConfigFile = findOldConfigFile;
|
|
7
|
-
const fs_1 = require("fs");
|
|
8
5
|
const path_1 = require("path");
|
|
9
6
|
const flat_config_1 = require("./flat-config");
|
|
10
7
|
exports.ESLINT_FLAT_CONFIG_FILENAMES = flat_config_1.eslintFlatConfigFilenames;
|
|
@@ -22,44 +19,3 @@ function isFlatConfig(configFilePath) {
|
|
|
22
19
|
const configFileName = (0, path_1.basename)(configFilePath);
|
|
23
20
|
return exports.ESLINT_FLAT_CONFIG_FILENAMES.includes(configFileName);
|
|
24
21
|
}
|
|
25
|
-
// https://eslint.org/docs/latest/use/configure/configuration-files#configuration-file-resolution
|
|
26
|
-
function findFlatConfigFile(directory, workspaceRoot) {
|
|
27
|
-
let currentDir = (0, path_1.resolve)(workspaceRoot, directory);
|
|
28
|
-
while (true) {
|
|
29
|
-
const configFilePath = getConfigFileInDirectory(currentDir, exports.ESLINT_FLAT_CONFIG_FILENAMES);
|
|
30
|
-
if (configFilePath) {
|
|
31
|
-
return configFilePath;
|
|
32
|
-
}
|
|
33
|
-
if (currentDir === workspaceRoot) {
|
|
34
|
-
break;
|
|
35
|
-
}
|
|
36
|
-
currentDir = (0, path_1.dirname)(currentDir);
|
|
37
|
-
}
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
function findOldConfigFile(filePathOrDirectory, workspaceRoot) {
|
|
41
|
-
let currentDir = (0, path_1.resolve)(workspaceRoot, filePathOrDirectory);
|
|
42
|
-
if (!(0, fs_1.statSync)(currentDir).isDirectory()) {
|
|
43
|
-
currentDir = (0, path_1.dirname)(currentDir);
|
|
44
|
-
}
|
|
45
|
-
while (true) {
|
|
46
|
-
const configFilePath = getConfigFileInDirectory(currentDir, exports.ESLINT_OLD_CONFIG_FILENAMES);
|
|
47
|
-
if (configFilePath) {
|
|
48
|
-
return configFilePath;
|
|
49
|
-
}
|
|
50
|
-
if (currentDir === workspaceRoot) {
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
currentDir = (0, path_1.dirname)(currentDir);
|
|
54
|
-
}
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
function getConfigFileInDirectory(directory, candidateFileNames) {
|
|
58
|
-
for (const filename of candidateFileNames) {
|
|
59
|
-
const filePath = (0, path_1.join)(directory, filename);
|
|
60
|
-
if ((0, fs_1.existsSync)(filePath)) {
|
|
61
|
-
return filePath;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return null;
|
|
65
|
-
}
|
package/executors.json
CHANGED
package/migrations.json
CHANGED
|
@@ -34,6 +34,13 @@
|
|
|
34
34
|
"version": "23.1.0-beta.5",
|
|
35
35
|
"description": "Migrate the removed @typescript-eslint/ban-types rule to its v8 successors (no-empty-object-type, no-unsafe-function-type, no-wrapper-object-types), whose options do not map 1:1 - so it is driven by an AI prompt rather than a deterministic codemod.",
|
|
36
36
|
"prompt": "./dist/src/migrations/update-23-1-0/migrate-ban-types-rule.md"
|
|
37
|
+
},
|
|
38
|
+
"remove-deprecated-executors": {
|
|
39
|
+
"version": "24.0.0-beta.3",
|
|
40
|
+
"description": "Converts targets using the removed `@nx/eslint` executors to inferred tasks; an AI prompt finishes the targets the converter cannot convert safely and validates the project graph.",
|
|
41
|
+
"implementation": "./dist/src/migrations/update-24-0-0/remove-deprecated-executors",
|
|
42
|
+
"prompt": "./dist/src/migrations/update-24-0-0/finish-inferred-conversion.md",
|
|
43
|
+
"documentation": "./dist/src/migrations/update-24-0-0/remove-deprecated-executors.md"
|
|
37
44
|
}
|
|
38
45
|
},
|
|
39
46
|
"packageJsonUpdates": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/eslint",
|
|
3
|
-
"version": "24.0.0-beta.
|
|
3
|
+
"version": "24.0.0-beta.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"files": [
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"executors.json",
|
|
11
11
|
"generators.json"
|
|
12
12
|
],
|
|
13
|
-
"description": "The ESLint plugin for Nx
|
|
13
|
+
"description": "The ESLint plugin for Nx infers tasks and provides generators and utilities used for linting JavaScript/TypeScript projects within an Nx workspace.",
|
|
14
14
|
"repository": {
|
|
15
15
|
"type": "git",
|
|
16
16
|
"url": "https://github.com/nrwl/nx.git",
|
|
@@ -71,19 +71,19 @@
|
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
|
-
"@nx/jest": "24.0.0-beta.
|
|
74
|
+
"@nx/jest": "24.0.0-beta.4",
|
|
75
75
|
"@zkochan/js-yaml": "0.0.7",
|
|
76
76
|
"eslint": "^9.0.0 || ^10.0.0"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@nx/devkit": "24.0.0-beta.
|
|
80
|
-
"@nx/js": "24.0.0-beta.
|
|
79
|
+
"@nx/devkit": "24.0.0-beta.4",
|
|
80
|
+
"@nx/js": "24.0.0-beta.4",
|
|
81
81
|
"semver": "^7.6.3",
|
|
82
82
|
"tslib": "^2.3.0",
|
|
83
83
|
"typescript": "~6.0.3"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
|
-
"nx": "24.0.0-beta.
|
|
86
|
+
"nx": "24.0.0-beta.4"
|
|
87
87
|
},
|
|
88
88
|
"peerDependenciesMeta": {
|
|
89
89
|
"@nx/jest": {
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = run;
|
|
4
|
-
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const internal_1 = require("@nx/devkit/internal");
|
|
6
|
-
const fs_1 = require("fs");
|
|
7
|
-
const path_1 = require("path");
|
|
8
|
-
const config_file_1 = require("../../utils/config-file");
|
|
9
|
-
const deprecation_1 = require("../../utils/deprecation");
|
|
10
|
-
const versions_1 = require("../../utils/versions");
|
|
11
|
-
const eslint_utils_1 = require("./utility/eslint-utils");
|
|
12
|
-
async function run(options, context) {
|
|
13
|
-
(0, deprecation_1.warnEslintExecutorDeprecation)();
|
|
14
|
-
// hasTypeAwareRules is deprecated and no longer used, delete it so it's not passed to ESLint
|
|
15
|
-
delete options.hasTypeAwareRules;
|
|
16
|
-
const systemRoot = context.root;
|
|
17
|
-
// eslint resolves files relative to the current working directory.
|
|
18
|
-
// We want these paths to always be resolved relative to the workspace
|
|
19
|
-
// root to be able to run the lint executor from any subfolder.
|
|
20
|
-
process.chdir(systemRoot);
|
|
21
|
-
const projectName = context.projectName || '<???>';
|
|
22
|
-
const projectRoot = context.projectsConfigurations.projects[context.projectName].root;
|
|
23
|
-
const printInfo = options.format && !options.silent;
|
|
24
|
-
if (printInfo) {
|
|
25
|
-
console.info(`\nLinting ${JSON.stringify(projectName)}...`);
|
|
26
|
-
}
|
|
27
|
-
options.cacheLocation = options.cacheLocation
|
|
28
|
-
? (0, devkit_1.joinPathFragments)(options.cacheLocation, projectName)
|
|
29
|
-
: undefined;
|
|
30
|
-
const { printConfig, errorOnUnmatchedPattern, ...normalizedOptions } = options;
|
|
31
|
-
// locate the flat config file if it exists starting from the project root
|
|
32
|
-
const flatConfigFilePath = (0, config_file_1.findFlatConfigFile)(projectRoot, context.root);
|
|
33
|
-
const hasFlatConfig = flatConfigFilePath !== null;
|
|
34
|
-
// while standard eslint uses by default closest config to the file, if otherwise not specified,
|
|
35
|
-
// the flat config would be resolved starting from the cwd, which we changed to the workspace root
|
|
36
|
-
// so we explicitly set the config path to the flat config file path we previously found
|
|
37
|
-
if (hasFlatConfig && !normalizedOptions.eslintConfig) {
|
|
38
|
-
normalizedOptions.eslintConfig = (0, path_1.relative)(systemRoot, flatConfigFilePath);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* We want users to have the option of not specifying the config path, and let
|
|
42
|
-
* eslint automatically resolve the `.eslintrc.json` files in each folder.
|
|
43
|
-
*/
|
|
44
|
-
let eslintConfigPath = normalizedOptions.eslintConfig
|
|
45
|
-
? (0, path_1.resolve)(systemRoot, normalizedOptions.eslintConfig)
|
|
46
|
-
: undefined;
|
|
47
|
-
const { eslint, ESLint } = await (0, eslint_utils_1.resolveAndInstantiateESLint)(eslintConfigPath, normalizedOptions, hasFlatConfig);
|
|
48
|
-
(0, internal_1.assertSupportedInstalledPackageVersion)('eslint', versions_1.minSupportedEslintVersion);
|
|
49
|
-
if (printConfig) {
|
|
50
|
-
try {
|
|
51
|
-
const fileConfig = await eslint.calculateConfigForFile(printConfig);
|
|
52
|
-
console.log(JSON.stringify(fileConfig, null, ' '));
|
|
53
|
-
return {
|
|
54
|
-
success: true,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
catch (err) {
|
|
58
|
-
console.error(err);
|
|
59
|
-
return {
|
|
60
|
-
success: false,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
let lintResults = [];
|
|
65
|
-
const normalizedLintFilePatterns = normalizedOptions.lintFilePatterns.map((pattern) => {
|
|
66
|
-
return (0, internal_1.interpolate)(pattern, {
|
|
67
|
-
workspaceRoot: '',
|
|
68
|
-
projectRoot,
|
|
69
|
-
projectName: context.projectName,
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
try {
|
|
73
|
-
lintResults = await eslint.lintFiles(normalizedLintFilePatterns);
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
if (err.message.includes('You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser')) {
|
|
77
|
-
const ruleName = err.message.match(/rule '([^']+)':/)?.[1];
|
|
78
|
-
const reportedFile = err.message.match(/Occurred while linting (.+)$/)?.[1];
|
|
79
|
-
let eslintConfigPathForError = `for the project "${projectName}"`;
|
|
80
|
-
if (eslintConfigPath) {
|
|
81
|
-
eslintConfigPathForError = `"${path_1.posix.relative(context.root, eslintConfigPath)}"`;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
const configPathForfile = hasFlatConfig
|
|
85
|
-
? (0, config_file_1.findFlatConfigFile)(projectRoot, context.root)
|
|
86
|
-
: (0, config_file_1.findOldConfigFile)(reportedFile ?? projectRoot, context.root);
|
|
87
|
-
if (configPathForfile) {
|
|
88
|
-
eslintConfigPathForError = `"${path_1.posix.relative(context.root, configPathForfile)}"`;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
console.error(`
|
|
92
|
-
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}
|
|
93
|
-
${reportedFile ? `Occurred while linting ${reportedFile}` : ''}
|
|
94
|
-
|
|
95
|
-
Please see https://nx.dev/recipes/tips-n-tricks/eslint for full guidance on how to resolve this issue.
|
|
96
|
-
`);
|
|
97
|
-
return {
|
|
98
|
-
success: false,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
// log unexpected errors
|
|
102
|
-
const lines = (err.message ? err.message : err.toString()).split('\n');
|
|
103
|
-
const bodyLines = lines.slice(1);
|
|
104
|
-
if (err.stack) {
|
|
105
|
-
bodyLines.push(...err.stack.split('\n'));
|
|
106
|
-
}
|
|
107
|
-
devkit_1.output.error({
|
|
108
|
-
title: lines[0],
|
|
109
|
-
bodyLines,
|
|
110
|
-
});
|
|
111
|
-
return {
|
|
112
|
-
success: false,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
if (lintResults.length === 0 && errorOnUnmatchedPattern) {
|
|
116
|
-
const ignoredPatterns = (await Promise.all(normalizedLintFilePatterns.map(async (pattern) => (await eslint.isPathIgnored(pattern)) ? pattern : null)))
|
|
117
|
-
.filter((pattern) => !!pattern)
|
|
118
|
-
.map((pattern) => `- '${pattern}'`);
|
|
119
|
-
if (ignoredPatterns.length) {
|
|
120
|
-
const ignoreSection = hasFlatConfig
|
|
121
|
-
? `'ignores' configuration`
|
|
122
|
-
: `'.eslintignore' file`;
|
|
123
|
-
throw new Error(`All files matching the following patterns are ignored:\n${ignoredPatterns.join('\n')}\n\nPlease check your ${ignoreSection}.`);
|
|
124
|
-
}
|
|
125
|
-
throw new Error('Invalid lint configuration. Nothing to lint. Please check your lint target pattern(s).');
|
|
126
|
-
}
|
|
127
|
-
// output fixes to disk, if applicable based on the options
|
|
128
|
-
await ESLint.outputFixes(lintResults);
|
|
129
|
-
// if quiet, only show errors
|
|
130
|
-
if (normalizedOptions.quiet) {
|
|
131
|
-
console.debug('Quiet mode enabled - filtering out warnings\n');
|
|
132
|
-
lintResults = ESLint.getErrorResults(lintResults);
|
|
133
|
-
}
|
|
134
|
-
const formatter = await eslint.loadFormatter(normalizedOptions.format);
|
|
135
|
-
const formattedResults = await formatter.format(lintResults);
|
|
136
|
-
if (normalizedOptions.outputFile) {
|
|
137
|
-
const pathToOutputFile = (0, devkit_1.joinPathFragments)(context.root, normalizedOptions.outputFile);
|
|
138
|
-
(0, fs_1.mkdirSync)((0, path_1.dirname)(pathToOutputFile), { recursive: true });
|
|
139
|
-
(0, fs_1.writeFileSync)(pathToOutputFile, formattedResults);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
console.info(formattedResults);
|
|
143
|
-
}
|
|
144
|
-
const totals = getTotals(lintResults);
|
|
145
|
-
if (printInfo) {
|
|
146
|
-
outputPrintInfo(totals);
|
|
147
|
-
}
|
|
148
|
-
if (options.maxWarnings >= 0 && totals.warnings > options.maxWarnings) {
|
|
149
|
-
console.info(`ESLint found too many warnings (maximum: ${options.maxWarnings}).`);
|
|
150
|
-
}
|
|
151
|
-
return {
|
|
152
|
-
success: normalizedOptions.force ||
|
|
153
|
-
(totals.errors === 0 &&
|
|
154
|
-
(normalizedOptions.maxWarnings === -1 ||
|
|
155
|
-
totals.warnings <= normalizedOptions.maxWarnings)),
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function getTotals(lintResults) {
|
|
159
|
-
let errors = 0;
|
|
160
|
-
let warnings = 0;
|
|
161
|
-
let fixableErrors = 0;
|
|
162
|
-
let fixableWarnings = 0;
|
|
163
|
-
for (const result of lintResults) {
|
|
164
|
-
errors += result.errorCount || 0;
|
|
165
|
-
warnings += result.warningCount || 0;
|
|
166
|
-
fixableErrors += result.fixableErrorCount || 0;
|
|
167
|
-
fixableWarnings += result.fixableWarningCount || 0;
|
|
168
|
-
}
|
|
169
|
-
return {
|
|
170
|
-
errors,
|
|
171
|
-
warnings,
|
|
172
|
-
fixableErrors,
|
|
173
|
-
fixableWarnings,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
function pluralizedOutput(word, count) {
|
|
177
|
-
return `${count} ${word}${count === 1 ? '' : 's'}`;
|
|
178
|
-
}
|
|
179
|
-
function outputPrintInfo({ errors, warnings, fixableErrors, fixableWarnings, }) {
|
|
180
|
-
const total = warnings + errors;
|
|
181
|
-
const totalFixable = fixableErrors + fixableWarnings;
|
|
182
|
-
if (total <= 0) {
|
|
183
|
-
console.info('\u2714 All files pass linting\n');
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
console.info(`\u2716 ${pluralizedOutput('problem', total)} (${pluralizedOutput('error', errors)}, ${pluralizedOutput('warning', warnings)})\n`);
|
|
187
|
-
if (totalFixable <= 0)
|
|
188
|
-
return;
|
|
189
|
-
console.info(` ${pluralizedOutput('error', fixableErrors)} and ${pluralizedOutput('warning', fixableWarnings)} are potentially fixable with the \`--fix\` option.\n`);
|
|
190
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { JsonObject } from '@angular-devkit/core';
|
|
2
|
-
import type { Linter } from 'eslint';
|
|
3
|
-
|
|
4
|
-
export interface Schema extends JsonObject {
|
|
5
|
-
eslintConfig: string | null;
|
|
6
|
-
lintFilePatterns: string[];
|
|
7
|
-
format: Formatter;
|
|
8
|
-
force: boolean;
|
|
9
|
-
silent: boolean;
|
|
10
|
-
fix: boolean;
|
|
11
|
-
cache: boolean;
|
|
12
|
-
noEslintrc: boolean;
|
|
13
|
-
outputFile: string | null;
|
|
14
|
-
cacheLocation: string | null;
|
|
15
|
-
maxWarnings: number;
|
|
16
|
-
quiet: boolean;
|
|
17
|
-
ignorePath: string | null;
|
|
18
|
-
|
|
19
|
-
/** @deprecated No longer has any effect. Will be removed in Nx v23. */
|
|
20
|
-
hasTypeAwareRules?: boolean;
|
|
21
|
-
cacheStrategy: 'content' | 'metadata' | null;
|
|
22
|
-
rulesdir: string[];
|
|
23
|
-
resolvePluginsRelativeTo: string | null;
|
|
24
|
-
reportUnusedDisableDirectives: Linter.StringSeverity | null;
|
|
25
|
-
printConfig?: string | null;
|
|
26
|
-
errorOnUnmatchedPattern?: boolean;
|
|
27
|
-
suppressAll?: boolean;
|
|
28
|
-
suppressRule?: string[];
|
|
29
|
-
suppressionsLocation?: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
type Formatter = 'stylish' | 'html' | 'json' | 'json-with-metadata';
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 2,
|
|
3
|
-
"outputCapture": "direct-nodejs",
|
|
4
|
-
"$schema": "https://json-schema.org/schema",
|
|
5
|
-
"title": "ESLint Lint Target",
|
|
6
|
-
"description": "ESLint Lint Target.",
|
|
7
|
-
"cli": "nx",
|
|
8
|
-
"type": "object",
|
|
9
|
-
"x-deprecated": "The `@nx/eslint:lint` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/eslint:convert-to-inferred` to migrate to the `@nx/eslint/plugin` inferred plugin. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.",
|
|
10
|
-
"properties": {
|
|
11
|
-
"eslintConfig": {
|
|
12
|
-
"type": "string",
|
|
13
|
-
"description": "The name of the ESLint configuration file.",
|
|
14
|
-
"x-completion-type": "file",
|
|
15
|
-
"x-completion-glob": ".eslintrc?(.json)",
|
|
16
|
-
"x-priority": "important"
|
|
17
|
-
},
|
|
18
|
-
"lintFilePatterns": {
|
|
19
|
-
"type": "array",
|
|
20
|
-
"description": "One or more files/dirs/globs to pass directly to ESLint's `lintFiles()` method.",
|
|
21
|
-
"default": ["{projectRoot}"],
|
|
22
|
-
"items": {
|
|
23
|
-
"type": "string"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"format": {
|
|
27
|
-
"type": "string",
|
|
28
|
-
"description": "ESLint Output formatter (https://eslint.org/docs/user-guide/formatters).",
|
|
29
|
-
"default": "stylish",
|
|
30
|
-
"anyOf": [
|
|
31
|
-
{
|
|
32
|
-
"enum": ["stylish", "html", "json", "json-with-metadata"]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"minLength": 1
|
|
36
|
-
}
|
|
37
|
-
],
|
|
38
|
-
"x-priority": "important"
|
|
39
|
-
},
|
|
40
|
-
"force": {
|
|
41
|
-
"type": "boolean",
|
|
42
|
-
"description": "Succeeds even if there was linting errors.",
|
|
43
|
-
"default": false
|
|
44
|
-
},
|
|
45
|
-
"silent": {
|
|
46
|
-
"type": "boolean",
|
|
47
|
-
"description": "Hide output text.",
|
|
48
|
-
"default": false
|
|
49
|
-
},
|
|
50
|
-
"fix": {
|
|
51
|
-
"type": "boolean",
|
|
52
|
-
"description": "Fixes linting errors (may overwrite linted files).",
|
|
53
|
-
"default": false,
|
|
54
|
-
"x-priority": "important"
|
|
55
|
-
},
|
|
56
|
-
"cache": {
|
|
57
|
-
"type": "boolean",
|
|
58
|
-
"description": "Only check changed files.",
|
|
59
|
-
"default": false
|
|
60
|
-
},
|
|
61
|
-
"cacheLocation": {
|
|
62
|
-
"type": "string",
|
|
63
|
-
"description": "Path to the cache file or directory.",
|
|
64
|
-
"x-completion-type": "directory",
|
|
65
|
-
"x-completion-glob": "tsconfig.*.json"
|
|
66
|
-
},
|
|
67
|
-
"outputFile": {
|
|
68
|
-
"type": "string",
|
|
69
|
-
"description": "File to write report to.",
|
|
70
|
-
"x-completion-type": "file"
|
|
71
|
-
},
|
|
72
|
-
"maxWarnings": {
|
|
73
|
-
"type": "number",
|
|
74
|
-
"description": "Number of warnings to trigger nonzero exit code - default: `-1`.",
|
|
75
|
-
"default": -1
|
|
76
|
-
},
|
|
77
|
-
"quiet": {
|
|
78
|
-
"type": "boolean",
|
|
79
|
-
"description": "Report errors only - default: `false`.",
|
|
80
|
-
"default": false,
|
|
81
|
-
"x-priority": "important"
|
|
82
|
-
},
|
|
83
|
-
"ignorePath": {
|
|
84
|
-
"type": "string",
|
|
85
|
-
"description": "The path of the `.eslintignore` file. Not supported for Flat Config.",
|
|
86
|
-
"x-completion-type": "file",
|
|
87
|
-
"x-completion-glob": ".eslintignore"
|
|
88
|
-
},
|
|
89
|
-
"noEslintrc": {
|
|
90
|
-
"type": "boolean",
|
|
91
|
-
"description": "The equivalent of the `--no-eslintrc` flag on the ESLint CLI, it is `false` by default.",
|
|
92
|
-
"default": false
|
|
93
|
-
},
|
|
94
|
-
"hasTypeAwareRules": {
|
|
95
|
-
"type": "boolean",
|
|
96
|
-
"description": "Deprecated. No longer has any effect.",
|
|
97
|
-
"x-deprecated": "No longer has any effect. Will be removed in Nx v23."
|
|
98
|
-
},
|
|
99
|
-
"cacheStrategy": {
|
|
100
|
-
"type": "string",
|
|
101
|
-
"description": "Strategy to use for detecting changed files in the cache.",
|
|
102
|
-
"default": "metadata",
|
|
103
|
-
"enum": ["metadata", "content"]
|
|
104
|
-
},
|
|
105
|
-
"rulesdir": {
|
|
106
|
-
"type": "array",
|
|
107
|
-
"description": "The equivalent of the `--rulesdir` flag on the ESLint CLI.",
|
|
108
|
-
"default": [],
|
|
109
|
-
"items": {
|
|
110
|
-
"type": "string",
|
|
111
|
-
"x-completion-type": "directory"
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
"resolvePluginsRelativeTo": {
|
|
115
|
-
"type": "string",
|
|
116
|
-
"description": "The equivalent of the `--resolve-plugins-relative-to` flag on the ESLint CLI. Not supported for Flat Config.",
|
|
117
|
-
"x-completion-type": "directory"
|
|
118
|
-
},
|
|
119
|
-
"reportUnusedDisableDirectives": {
|
|
120
|
-
"type": "string",
|
|
121
|
-
"enum": ["off", "warn", "error"],
|
|
122
|
-
"description": "The equivalent of the `--report-unused-disable-directives` flag on the ESLint CLI."
|
|
123
|
-
},
|
|
124
|
-
"printConfig": {
|
|
125
|
-
"type": "string",
|
|
126
|
-
"description": "The equivalent of the `--print-config` flag on the ESLint CLI.",
|
|
127
|
-
"x-completion-type": "file"
|
|
128
|
-
},
|
|
129
|
-
"errorOnUnmatchedPattern": {
|
|
130
|
-
"type": "boolean",
|
|
131
|
-
"description": "When set to false, equivalent of the `--no-error-on-unmatched-pattern` flag on the ESLint CLI.",
|
|
132
|
-
"default": true
|
|
133
|
-
},
|
|
134
|
-
"suppressAll": {
|
|
135
|
-
"type": "boolean",
|
|
136
|
-
"description": "Suppress all existing violations. This is equivalent to the `--suppress-all` flag on the ESLint CLI. Requires ESLint v9.24.0 or higher.",
|
|
137
|
-
"default": false
|
|
138
|
-
},
|
|
139
|
-
"suppressRule": {
|
|
140
|
-
"type": "array",
|
|
141
|
-
"description": "Suppress violations for specific rules. This is equivalent to the `--suppress-rule` flag on the ESLint CLI. Requires ESLint v9.24.0 or higher.",
|
|
142
|
-
"default": [],
|
|
143
|
-
"items": {
|
|
144
|
-
"type": "string"
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
"suppressionsLocation": {
|
|
148
|
-
"type": "string",
|
|
149
|
-
"description": "Specify the location of the suppressions file. This is equivalent to the `--suppressions-location` flag on the ESLint CLI. Defaults to 'eslint-suppressions.json' in the project root. Requires ESLint v9.24.0 or higher.",
|
|
150
|
-
"x-completion-type": "file"
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
"examplesFile": "../../../docs/eslint-examples.md"
|
|
154
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { ESLint } from 'eslint';
|
|
2
|
-
import type { Schema } from '../schema';
|
|
3
|
-
export declare function resolveAndInstantiateESLint(eslintConfigPath: string | undefined, options: Schema, useFlatConfig?: boolean): Promise<{
|
|
4
|
-
ESLint: typeof import("eslint").ESLint;
|
|
5
|
-
eslint: ESLint;
|
|
6
|
-
}>;
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveAndInstantiateESLint = resolveAndInstantiateESLint;
|
|
4
|
-
const semver_1 = require("semver");
|
|
5
|
-
const config_file_1 = require("../../../utils/config-file");
|
|
6
|
-
const resolve_eslint_class_1 = require("../../../utils/resolve-eslint-class");
|
|
7
|
-
async function resolveAndInstantiateESLint(eslintConfigPath, options, useFlatConfig = false) {
|
|
8
|
-
if (useFlatConfig && eslintConfigPath && !(0, config_file_1.isFlatConfig)(eslintConfigPath)) {
|
|
9
|
-
throw new Error('When using the new Flat Config with ESLint, all configs must be named eslint.config.js or eslint.config.cjs and .eslintrc files may not be used. See https://eslint.org/docs/latest/use/configure/configuration-files');
|
|
10
|
-
}
|
|
11
|
-
const ESLint = await (0, resolve_eslint_class_1.resolveESLintClass)({
|
|
12
|
-
useFlatConfigOverrideVal: useFlatConfig,
|
|
13
|
-
});
|
|
14
|
-
// Use the broader legacy (eslintrc) options shape so the legacy-only fields
|
|
15
|
-
// assigned below type-check. The flat-only fields (ruleFilter, suppress*) are
|
|
16
|
-
// intersected in and set conditionally below, since LegacyESLint rejects
|
|
17
|
-
// unknown options.
|
|
18
|
-
const eslintOptions = {
|
|
19
|
-
overrideConfigFile: eslintConfigPath,
|
|
20
|
-
fix: !!options.fix &&
|
|
21
|
-
(options.quiet ? (message) => message.severity === 2 : true),
|
|
22
|
-
cache: !!options.cache,
|
|
23
|
-
cacheLocation: options.cacheLocation || undefined,
|
|
24
|
-
cacheStrategy: options.cacheStrategy || undefined,
|
|
25
|
-
/**
|
|
26
|
-
* Default is `true` and if not overridden the eslint.lintFiles() method will throw an error
|
|
27
|
-
* when no target files are found.
|
|
28
|
-
*
|
|
29
|
-
* We don't want ESLint to throw an error if a user has only just created
|
|
30
|
-
* a project and therefore doesn't necessarily have matching files, for example.
|
|
31
|
-
*
|
|
32
|
-
* Also, the angular generator creates a lint pattern for `html` files, but there may
|
|
33
|
-
* not be any html files in the project, so keeping it true would break linting every time
|
|
34
|
-
*/
|
|
35
|
-
errorOnUnmatchedPattern: false,
|
|
36
|
-
};
|
|
37
|
-
if (useFlatConfig) {
|
|
38
|
-
if (typeof options.useEslintrc !== 'undefined') {
|
|
39
|
-
throw new Error('For Flat Config, the `useEslintrc` option is not applicable. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
40
|
-
}
|
|
41
|
-
if (options.resolvePluginsRelativeTo !== undefined) {
|
|
42
|
-
throw new Error('For Flat Config, ESLint removed `resolvePluginsRelativeTo` and so it is not supported as an option. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
43
|
-
}
|
|
44
|
-
if (options.ignorePath !== undefined) {
|
|
45
|
-
throw new Error('For Flat Config, ESLint removed `ignorePath` and so it is not supported as an option. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
46
|
-
}
|
|
47
|
-
if (options.reportUnusedDisableDirectives) {
|
|
48
|
-
throw new Error('For Flat Config, ESLint removed `reportedUnusedDisableDirectives` and so it is not supported as an option. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
eslintOptions.rulePaths = options.rulesdir || [];
|
|
53
|
-
eslintOptions.resolvePluginsRelativeTo =
|
|
54
|
-
options.resolvePluginsRelativeTo || undefined;
|
|
55
|
-
eslintOptions.ignorePath = options.ignorePath || undefined;
|
|
56
|
-
/**
|
|
57
|
-
* If "noEslintrc" is set to `true` (and therefore here "useEslintrc" will be `false`), then ESLint will not
|
|
58
|
-
* merge the provided config with others it finds automatically.
|
|
59
|
-
*/
|
|
60
|
-
eslintOptions.useEslintrc = !options.noEslintrc;
|
|
61
|
-
eslintOptions.reportUnusedDisableDirectives =
|
|
62
|
-
options.reportUnusedDisableDirectives || undefined;
|
|
63
|
-
}
|
|
64
|
-
// `ruleFilter` is flat-config only; LegacyESLint (eslintrc) throws on unknown
|
|
65
|
-
// options, so only set it for flat config.
|
|
66
|
-
if (options.quiet && useFlatConfig) {
|
|
67
|
-
eslintOptions.ruleFilter = (rule) => rule.severity === 2;
|
|
68
|
-
}
|
|
69
|
-
// Handle bulk suppression options (ESLint v9.24.0+)
|
|
70
|
-
try {
|
|
71
|
-
if (ESLint.version && (0, semver_1.gte)(ESLint.version, '9.24.0')) {
|
|
72
|
-
if (options.suppressAll) {
|
|
73
|
-
eslintOptions.suppressAll = true;
|
|
74
|
-
}
|
|
75
|
-
if (options.suppressRule && options.suppressRule.length > 0) {
|
|
76
|
-
eslintOptions.suppressRule = options.suppressRule;
|
|
77
|
-
}
|
|
78
|
-
if (options.suppressionsLocation) {
|
|
79
|
-
eslintOptions.suppressionsLocation = options.suppressionsLocation;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else if (options.suppressAll ||
|
|
83
|
-
(options.suppressRule && options.suppressRule.length > 0) ||
|
|
84
|
-
options.suppressionsLocation) {
|
|
85
|
-
throw new Error('Bulk suppression options (suppressAll, suppressRule, suppressionsLocation) require ESLint v9.24.0 or higher. Current version: ' +
|
|
86
|
-
(ESLint.version || 'unknown'));
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
// If version checking fails (e.g., in tests), skip suppression options
|
|
91
|
-
if (options.suppressAll ||
|
|
92
|
-
(options.suppressRule && options.suppressRule.length > 0) ||
|
|
93
|
-
options.suppressionsLocation) {
|
|
94
|
-
// In test environment, just skip the suppression options
|
|
95
|
-
console.warn('Bulk suppression options skipped due to version check failure');
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// Runtime ESLint class may be the flat or legacy implementation; the built
|
|
99
|
-
// options object is compatible with either at runtime, but the two Options
|
|
100
|
-
// shapes diverge in v9 types so cast at the boundary.
|
|
101
|
-
const eslint = new ESLint(eslintOptions);
|
|
102
|
-
return {
|
|
103
|
-
ESLint,
|
|
104
|
-
eslint,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getEslintTargets = getEslintTargets;
|
|
4
|
-
const internal_1 = require("@nx/devkit/internal");
|
|
5
|
-
function getEslintTargets(tree) {
|
|
6
|
-
const eslintTargetNames = new Set();
|
|
7
|
-
(0, internal_1.forEachExecutorOptions)(tree, '@nx/eslint:lint', (_, __, target) => {
|
|
8
|
-
eslintTargetNames.add(target);
|
|
9
|
-
});
|
|
10
|
-
(0, internal_1.forEachExecutorOptions)(tree, '@nx/linter:eslint', (_, __, target) => {
|
|
11
|
-
eslintTargetNames.add(target);
|
|
12
|
-
});
|
|
13
|
-
(0, internal_1.forEachExecutorOptions)(tree, '@nrwl/linter:eslint', (_, __, target) => {
|
|
14
|
-
eslintTargetNames.add(target);
|
|
15
|
-
});
|
|
16
|
-
return eslintTargetNames;
|
|
17
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export declare const ESLINT_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/eslint:lint` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/eslint:convert-to-inferred` to migrate to the `@nx/eslint/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
|
|
2
|
-
export declare function warnEslintExecutorDeprecation(): void;
|
|
3
|
-
export declare function warnEslintExecutorGenerating(): void;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ESLINT_EXECUTOR_DEPRECATION_MESSAGE = void 0;
|
|
4
|
-
exports.warnEslintExecutorDeprecation = warnEslintExecutorDeprecation;
|
|
5
|
-
exports.warnEslintExecutorGenerating = warnEslintExecutorGenerating;
|
|
6
|
-
const devkit_1 = require("@nx/devkit");
|
|
7
|
-
// TODO(v24): Remove the @nx/eslint:lint executor. The inferred plugin
|
|
8
|
-
// (@nx/eslint/plugin) and the convert-to-inferred generator stay supported.
|
|
9
|
-
exports.ESLINT_EXECUTOR_DEPRECATION_MESSAGE = 'The `@nx/eslint:lint` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/eslint:convert-to-inferred` to migrate to the `@nx/eslint/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.';
|
|
10
|
-
function warnEslintExecutorDeprecation() {
|
|
11
|
-
devkit_1.logger.warn(exports.ESLINT_EXECUTOR_DEPRECATION_MESSAGE);
|
|
12
|
-
}
|
|
13
|
-
function warnEslintExecutorGenerating() {
|
|
14
|
-
devkit_1.logger.warn('Generating a target that uses the deprecated `@nx/eslint:lint` executor. The executor will be removed in Nx v24. Run `nx g @nx/eslint:convert-to-inferred` next to migrate this target to the `@nx/eslint/plugin` inferred plugin and prevent future generators from emitting executor targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.');
|
|
15
|
-
}
|