@nx/eslint 22.6.0-rc.2 → 22.7.0-beta.0
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/package.json +4 -4
- package/src/generators/convert-to-flat-config/converters/json-converter.d.ts.map +1 -1
- package/src/generators/convert-to-flat-config/converters/json-converter.js +80 -3
- package/src/generators/convert-to-flat-config/generator.d.ts.map +1 -1
- package/src/generators/convert-to-flat-config/generator.js +39 -30
- package/src/plugins/plugin.d.ts.map +1 -1
- package/src/plugins/plugin.js +7 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/eslint",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.7.0-beta.0",
|
|
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": {
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"eslint": "^8.0.0 || ^9.0.0 || ^10.0.0"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@nx/devkit": "22.
|
|
39
|
-
"@nx/js": "22.
|
|
38
|
+
"@nx/devkit": "22.7.0-beta.0",
|
|
39
|
+
"@nx/js": "22.7.0-beta.0",
|
|
40
40
|
"semver": "^7.6.3",
|
|
41
41
|
"tslib": "^2.3.0",
|
|
42
42
|
"typescript": "~5.9.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"nx": "22.
|
|
45
|
+
"nx": "22.7.0-beta.0"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
48
48
|
"@zkochan/js-yaml": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-converter.d.ts","sourceRoot":"","sources":["../../../../../../../packages/eslint/src/generators/convert-to-flat-config/converters/json-converter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAS,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"json-converter.d.ts","sourceRoot":"","sources":["../../../../../../../packages/eslint/src/generators/convert-to-flat-config/converters/json-converter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAS,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAehC;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,UAAU,EACzB,WAAW,EAAE,MAAM,EAAE,EACrB,MAAM,EAAE,KAAK,GAAG,KAAK,GACpB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CA8OjE"}
|
|
@@ -68,6 +68,47 @@ function convertEslintJsonToFlatConfig(tree, root, config, ignorePaths, format)
|
|
|
68
68
|
}
|
|
69
69
|
if (config.overrides) {
|
|
70
70
|
config.overrides.forEach((override) => {
|
|
71
|
+
if (override.extends) {
|
|
72
|
+
const extendsArr = Array.isArray(override.extends)
|
|
73
|
+
? override.extends
|
|
74
|
+
: [override.extends];
|
|
75
|
+
const mapped = extendsArr.map((e) => ({
|
|
76
|
+
original: e,
|
|
77
|
+
flatConfig: mapNxPluginToFlatConfig(e),
|
|
78
|
+
}));
|
|
79
|
+
const nxExtends = mapped.filter((m) => m.flatConfig);
|
|
80
|
+
const nonNxExtends = mapped
|
|
81
|
+
.filter((m) => !m.flatConfig)
|
|
82
|
+
.map((m) => m.original);
|
|
83
|
+
if (nxExtends.length > 0) {
|
|
84
|
+
const nxVar = importsMap.get('@nx/eslint-plugin') ?? 'nx';
|
|
85
|
+
importsMap.set('@nx/eslint-plugin', nxVar);
|
|
86
|
+
nxExtends.forEach((ext) => {
|
|
87
|
+
exportElements.push((0, ast_utils_1.generateFlatPredefinedConfig)(ext.flatConfig, nxVar, true));
|
|
88
|
+
});
|
|
89
|
+
// Build remaining override without Nx extends
|
|
90
|
+
const remainingOverride = { ...override };
|
|
91
|
+
if (nonNxExtends.length > 0) {
|
|
92
|
+
remainingOverride.extends = nonNxExtends;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
delete remainingOverride.extends;
|
|
96
|
+
}
|
|
97
|
+
// Emit remaining override if it has content beyond files and empty rules
|
|
98
|
+
const { files: _files, rules: remainingRules, ...remainingRest } = remainingOverride;
|
|
99
|
+
const hasNonEmptyRules = remainingRules && Object.keys(remainingRules).length > 0;
|
|
100
|
+
if (Object.keys(remainingRest).length > 0 || hasNonEmptyRules) {
|
|
101
|
+
if (remainingOverride.env ||
|
|
102
|
+
remainingOverride.extends ||
|
|
103
|
+
remainingOverride.plugins ||
|
|
104
|
+
remainingOverride.parser) {
|
|
105
|
+
isFlatCompatNeeded = true;
|
|
106
|
+
}
|
|
107
|
+
exportElements.push((0, ast_utils_1.generateFlatOverride)(remainingOverride, format));
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
71
112
|
if (override.env ||
|
|
72
113
|
override.extends ||
|
|
73
114
|
override.plugins ||
|
|
@@ -138,7 +179,16 @@ function addExtends(importsMap, configBlocks, config, format) {
|
|
|
138
179
|
if (pluginExtends.length) {
|
|
139
180
|
const eslintPluginExtends = pluginExtends.filter((imp) => imp.startsWith('eslint:'));
|
|
140
181
|
pluginExtends.forEach((imp) => {
|
|
141
|
-
if (
|
|
182
|
+
if (imp.startsWith('eslint:')) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const nxFlatConfig = mapNxPluginToFlatConfig(imp);
|
|
186
|
+
if (nxFlatConfig) {
|
|
187
|
+
const nxVar = importsMap.get('@nx/eslint-plugin') ?? 'nx';
|
|
188
|
+
importsMap.set('@nx/eslint-plugin', nxVar);
|
|
189
|
+
configBlocks.push((0, ast_utils_1.generateFlatPredefinedConfig)(nxFlatConfig, nxVar, true));
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
142
192
|
eslintrcConfigs.push(imp);
|
|
143
193
|
}
|
|
144
194
|
});
|
|
@@ -159,10 +209,22 @@ function addExtends(importsMap, configBlocks, config, format) {
|
|
|
159
209
|
return { isFlatCompatNeeded, isESLintJSNeeded };
|
|
160
210
|
}
|
|
161
211
|
function addPlugins(importsMap, configBlocks, config) {
|
|
212
|
+
// Replace @nx plugin with flat/base predefined config to match fresh generation.
|
|
213
|
+
// flat/base registers the @nx plugin and ignores .nx directory.
|
|
214
|
+
// This runs before overrides are processed, so we set the import name here
|
|
215
|
+
// for Nx extends that may appear in overrides later.
|
|
216
|
+
if (config.plugins.includes('@nx')) {
|
|
217
|
+
importsMap.set('@nx/eslint-plugin', 'nx');
|
|
218
|
+
configBlocks.push((0, ast_utils_1.generateFlatPredefinedConfig)('flat/base', 'nx', true));
|
|
219
|
+
}
|
|
220
|
+
const remainingPlugins = config.plugins.filter((name) => name !== '@nx');
|
|
221
|
+
if (remainingPlugins.length === 0) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
162
224
|
const mappedPlugins = [];
|
|
163
|
-
|
|
225
|
+
remainingPlugins.forEach((name) => {
|
|
164
226
|
const imp = (0, eslint_file_1.getPluginImport)(name);
|
|
165
|
-
const varName = (0, devkit_1.names)(imp).propertyName;
|
|
227
|
+
const varName = importsMap.get(imp) ?? (0, devkit_1.names)(imp).propertyName;
|
|
166
228
|
mappedPlugins.push({ name, varName, imp });
|
|
167
229
|
});
|
|
168
230
|
mappedPlugins.forEach(({ varName, imp }) => {
|
|
@@ -180,3 +242,18 @@ function addPlugins(importsMap, configBlocks, config) {
|
|
|
180
242
|
], false);
|
|
181
243
|
configBlocks.push(pluginsAst);
|
|
182
244
|
}
|
|
245
|
+
const nxPluginToFlatConfigMap = {
|
|
246
|
+
'plugin:@nx/typescript': 'flat/typescript',
|
|
247
|
+
'plugin:@nx/javascript': 'flat/javascript',
|
|
248
|
+
'plugin:@nx/react': 'flat/react',
|
|
249
|
+
'plugin:@nx/react-base': 'flat/react-base',
|
|
250
|
+
'plugin:@nx/react-typescript': 'flat/react-typescript',
|
|
251
|
+
'plugin:@nx/react-jsx': 'flat/react-jsx',
|
|
252
|
+
'plugin:@nx/angular': 'flat/angular',
|
|
253
|
+
'plugin:@nx/angular-template': 'flat/angular-template',
|
|
254
|
+
'plugin:@nrwl/nx/typescript': 'flat/typescript',
|
|
255
|
+
'plugin:@nrwl/nx/javascript': 'flat/javascript',
|
|
256
|
+
};
|
|
257
|
+
function mapNxPluginToFlatConfig(pluginExtend) {
|
|
258
|
+
return nxPluginToFlatConfigMap[pluginExtend];
|
|
259
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../../../../packages/eslint/src/generators/convert-to-flat-config/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../../../../packages/eslint/src/generators/convert-to-flat-config/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,EASjB,IAAI,EAGL,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kCAAkC,EAAE,MAAM,UAAU,CAAC;AAc9D,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,kCAAkC,GAC1C,OAAO,CAAC,IAAI,GAAG,iBAAiB,CAAC,CA6CnC;AAED,eAAe,4BAA4B,CAAC"}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.convertToFlatConfigGenerator = convertToFlatConfigGenerator;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const eslint_file_1 = require("../utils/eslint-file");
|
|
6
|
+
const plugin_1 = require("../utils/plugin");
|
|
6
7
|
const path_1 = require("path");
|
|
7
8
|
const versions_1 = require("../../utils/versions");
|
|
8
9
|
const json_converter_1 = require("./converters/json-converter");
|
|
@@ -42,39 +43,47 @@ function convertRootToFlatConfig(tree, eslintFile, format) {
|
|
|
42
43
|
}
|
|
43
44
|
convertConfigToFlatConfig(tree, '', eslintFile.replace('.base.', '.'), `eslint.config.${format}`, format);
|
|
44
45
|
}
|
|
46
|
+
const ESLINT_LINT_EXECUTOR = '@nx/eslint:lint';
|
|
47
|
+
function isEslintTarget(target) {
|
|
48
|
+
return (target.executor === ESLINT_LINT_EXECUTOR ||
|
|
49
|
+
target.command?.includes('eslint'));
|
|
50
|
+
}
|
|
45
51
|
function convertProjectToFlatConfig(tree, project, projectConfig, nxJson, eslintIgnoreFiles, format) {
|
|
46
52
|
const eslintFile = (0, eslint_file_1.findEslintFile)(tree, projectConfig.root);
|
|
47
|
-
if (eslintFile
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
ignorePath = projectConfig.targets[target].options.ignorePath;
|
|
59
|
-
delete projectConfig.targets[target].options.ignorePath;
|
|
60
|
-
}
|
|
61
|
-
(0, devkit_1.updateProjectConfiguration)(tree, project, projectConfig);
|
|
62
|
-
}
|
|
63
|
-
const nxHasEsLintTargets = Object.keys(nxJson.targetDefaults || {}).some((t) => (t === '@nx/eslint:lint' ||
|
|
64
|
-
nxJson.targetDefaults[t].executor === '@nx/eslint:lint' ||
|
|
65
|
-
nxJson.targetDefaults[t].command?.includes('eslint')) &&
|
|
66
|
-
projectConfig.targets?.[t]);
|
|
67
|
-
const nxHasEsLintPlugin = (nxJson.plugins || []).some((p) => typeof p === 'string'
|
|
68
|
-
? p === '@nx/eslint/plugin'
|
|
69
|
-
: p.plugin === '@nx/eslint/plugin');
|
|
70
|
-
if (nxHasEsLintTargets || nxHasEsLintPlugin || eslintTargets.length > 0) {
|
|
71
|
-
convertConfigToFlatConfig(tree, projectConfig.root, eslintFile, `eslint.config.${format}`, format, ignorePath);
|
|
72
|
-
eslintIgnoreFiles.add(`${projectConfig.root}/.eslintignore`);
|
|
73
|
-
if (ignorePath) {
|
|
74
|
-
eslintIgnoreFiles.add(ignorePath);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
53
|
+
if (!eslintFile || eslintFile.endsWith('.js')) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// Clean up obsolete target options and detect explicit ESLint targets
|
|
57
|
+
let ignorePath;
|
|
58
|
+
const eslintTargets = projectConfig.targets
|
|
59
|
+
? Object.keys(projectConfig.targets).filter((t) => isEslintTarget(projectConfig.targets[t]))
|
|
60
|
+
: [];
|
|
61
|
+
for (const target of eslintTargets) {
|
|
62
|
+
if (projectConfig.targets[target].options?.eslintConfig) {
|
|
63
|
+
delete projectConfig.targets[target].options.eslintConfig;
|
|
77
64
|
}
|
|
65
|
+
if (projectConfig.targets[target].options?.ignorePath) {
|
|
66
|
+
ignorePath = projectConfig.targets[target].options.ignorePath;
|
|
67
|
+
delete projectConfig.targets[target].options.ignorePath;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (eslintTargets.length > 0) {
|
|
71
|
+
(0, devkit_1.updateProjectConfiguration)(tree, project, projectConfig);
|
|
72
|
+
}
|
|
73
|
+
const hasEslintTargetDefaults = projectConfig.targets &&
|
|
74
|
+
Object.keys(nxJson.targetDefaults || {}).some((t) => (t === ESLINT_LINT_EXECUTOR ||
|
|
75
|
+
isEslintTarget(nxJson.targetDefaults[t])) &&
|
|
76
|
+
projectConfig.targets[t]);
|
|
77
|
+
if (eslintTargets.length === 0 &&
|
|
78
|
+
!hasEslintTargetDefaults &&
|
|
79
|
+
!(0, plugin_1.hasEslintPlugin)(tree)) {
|
|
80
|
+
devkit_1.logger.warn(`Skipping "${project}": found ${eslintFile} but no ESLint lint target detected. Convert manually if needed.`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
convertConfigToFlatConfig(tree, projectConfig.root, eslintFile, `eslint.config.${format}`, format, ignorePath);
|
|
84
|
+
eslintIgnoreFiles.add(`${projectConfig.root}/.eslintignore`);
|
|
85
|
+
if (ignorePath) {
|
|
86
|
+
eslintIgnoreFiles.add(ignorePath);
|
|
78
87
|
}
|
|
79
88
|
}
|
|
80
89
|
// update names of eslint files in nx.json
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../packages/eslint/src/plugins/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,aAAa,EAMd,MAAM,YAAY,CAAC;AAqBpB,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAmHD,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../packages/eslint/src/plugins/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,aAAa,EAMd,MAAM,YAAY,CAAC;AAqBpB,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAmHD,eAAO,MAAM,WAAW,EAAE,aAAa,CAAC,mBAAmB,CAsE1D,CAAC;AAEF,eAAO,MAAM,aAAa,oCAAc,CAAC"}
|
package/src/plugins/plugin.js
CHANGED
|
@@ -112,8 +112,14 @@ exports.createNodes = [
|
|
|
112
112
|
if (eslintConfigFiles.length === 0) {
|
|
113
113
|
return [];
|
|
114
114
|
}
|
|
115
|
+
// Determine flat vs legacy from root config, matching ESLint's own
|
|
116
|
+
// behavior (find-up from cwd). Nested .eslintrc.* files are irrelevant
|
|
117
|
+
// when a root flat config exists. Prefer flat config at root when both
|
|
118
|
+
// flat and legacy root configs coexist (e.g., mid-migration).
|
|
119
|
+
const rootConfigs = eslintConfigFiles.filter((f) => (0, posix_1.dirname)(f) === '.');
|
|
120
|
+
const rootConfig = rootConfigs.find(config_file_1.isFlatConfig) ?? rootConfigs[0];
|
|
115
121
|
const ESLint = await (0, resolve_eslint_class_1.resolveESLintClass)({
|
|
116
|
-
useFlatConfigOverrideVal: (0, config_file_1.isFlatConfig)(eslintConfigFiles[0]),
|
|
122
|
+
useFlatConfigOverrideVal: (0, config_file_1.isFlatConfig)(rootConfig ?? eslintConfigFiles[0]),
|
|
117
123
|
});
|
|
118
124
|
return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => internalCreateNodesV2(ESLint, configFile, options, context, projectRootsByEslintRoots, lintableFilesPerProjectRoot, targetsCache, hashByRoot), eslintConfigFiles, options, context);
|
|
119
125
|
}
|