@nx/eslint 0.0.0-pr-29703-8312c59 → 0.0.0-pr-29720-6055188
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 +3 -3
- package/src/generators/convert-to-flat-config/converters/json-converter.d.ts +1 -1
- package/src/generators/convert-to-flat-config/converters/json-converter.js +6 -6
- package/src/generators/convert-to-flat-config/generator.js +16 -17
- package/src/generators/convert-to-flat-config/schema.d.ts +0 -2
- package/src/generators/convert-to-inferred/convert-to-inferred.js +0 -1
- package/src/generators/init/global-eslint-config.d.ts +1 -1
- package/src/generators/init/global-eslint-config.js +5 -5
- package/src/generators/init/init-migration.d.ts +1 -1
- package/src/generators/init/init-migration.js +5 -15
- package/src/generators/init/init.d.ts +0 -1
- package/src/generators/init/init.js +6 -17
- package/src/generators/lint-project/lint-project.d.ts +0 -1
- package/src/generators/lint-project/lint-project.js +6 -20
- package/src/generators/lint-project/setup-root-eslint.d.ts +0 -1
- package/src/generators/lint-project/setup-root-eslint.js +1 -2
- package/src/generators/utils/eslint-file.d.ts +0 -1
- package/src/generators/utils/eslint-file.js +14 -54
- package/src/generators/utils/flat-config/ast-utils.d.ts +4 -10
- package/src/generators/utils/flat-config/ast-utils.js +59 -328
- package/src/plugins/plugin.js +1 -1
- package/src/utils/config-file.d.ts +1 -2
- package/src/utils/config-file.js +2 -3
- package/src/utils/flat-config.d.ts +0 -1
- package/src/utils/flat-config.js +2 -8
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-29720-6055188",
|
|
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,8 +35,8 @@
|
|
|
35
35
|
"eslint": "^8.0.0 || ^9.0.0"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@nx/devkit": "0.0.0-pr-
|
|
39
|
-
"@nx/js": "0.0.0-pr-
|
|
38
|
+
"@nx/devkit": "0.0.0-pr-29720-6055188",
|
|
39
|
+
"@nx/js": "0.0.0-pr-29720-6055188",
|
|
40
40
|
"semver": "^7.5.3",
|
|
41
41
|
"tslib": "^2.3.0",
|
|
42
42
|
"typescript": "~5.7.2"
|
|
@@ -4,7 +4,7 @@ import { ESLint } from 'eslint';
|
|
|
4
4
|
* Converts an ESLint JSON config to a flat config.
|
|
5
5
|
* Deletes the original file along with .eslintignore if it exists.
|
|
6
6
|
*/
|
|
7
|
-
export declare function convertEslintJsonToFlatConfig(tree: Tree, root: string, config: ESLint.ConfigData, ignorePaths: string[]
|
|
7
|
+
export declare function convertEslintJsonToFlatConfig(tree: Tree, root: string, config: ESLint.ConfigData, ignorePaths: string[]): {
|
|
8
8
|
content: string;
|
|
9
9
|
addESLintRC: boolean;
|
|
10
10
|
addESLintJS: boolean;
|
|
@@ -10,7 +10,7 @@ const path_utils_1 = require("../../utils/flat-config/path-utils");
|
|
|
10
10
|
* Converts an ESLint JSON config to a flat config.
|
|
11
11
|
* Deletes the original file along with .eslintignore if it exists.
|
|
12
12
|
*/
|
|
13
|
-
function convertEslintJsonToFlatConfig(tree, root, config, ignorePaths
|
|
13
|
+
function convertEslintJsonToFlatConfig(tree, root, config, ignorePaths) {
|
|
14
14
|
const importsMap = new Map();
|
|
15
15
|
const exportElements = [];
|
|
16
16
|
let isFlatCompatNeeded = false;
|
|
@@ -22,7 +22,7 @@ function convertEslintJsonToFlatConfig(tree, root, config, ignorePaths, format)
|
|
|
22
22
|
ignores: ['**/dist'],
|
|
23
23
|
}));
|
|
24
24
|
if (config.extends) {
|
|
25
|
-
const extendsResult = addExtends(importsMap, exportElements, config
|
|
25
|
+
const extendsResult = addExtends(importsMap, exportElements, config);
|
|
26
26
|
isFlatCompatNeeded = extendsResult.isFlatCompatNeeded;
|
|
27
27
|
isESLintJSNeeded = extendsResult.isESLintJSNeeded;
|
|
28
28
|
}
|
|
@@ -74,7 +74,7 @@ function convertEslintJsonToFlatConfig(tree, root, config, ignorePaths, format)
|
|
|
74
74
|
override.parser) {
|
|
75
75
|
isFlatCompatNeeded = true;
|
|
76
76
|
}
|
|
77
|
-
exportElements.push((0, ast_utils_1.generateFlatOverride)(override
|
|
77
|
+
exportElements.push((0, ast_utils_1.generateFlatOverride)(override));
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
if (config.ignorePatterns) {
|
|
@@ -100,7 +100,7 @@ function convertEslintJsonToFlatConfig(tree, root, config, ignorePaths, format)
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
// create the node list and print it to new file
|
|
103
|
-
const nodeList = (0, ast_utils_1.createNodeList)(importsMap, exportElements
|
|
103
|
+
const nodeList = (0, ast_utils_1.createNodeList)(importsMap, exportElements);
|
|
104
104
|
let content = (0, ast_utils_1.stringifyNodeList)(nodeList);
|
|
105
105
|
if (isFlatCompatNeeded) {
|
|
106
106
|
content = (0, ast_utils_1.addFlatCompatToFlatConfig)(content);
|
|
@@ -112,7 +112,7 @@ function convertEslintJsonToFlatConfig(tree, root, config, ignorePaths, format)
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
// add parsed extends to export blocks and add import statements
|
|
115
|
-
function addExtends(importsMap, configBlocks, config
|
|
115
|
+
function addExtends(importsMap, configBlocks, config) {
|
|
116
116
|
let isFlatCompatNeeded = false;
|
|
117
117
|
let isESLintJSNeeded = false;
|
|
118
118
|
const extendsConfig = Array.isArray(config.extends)
|
|
@@ -126,7 +126,7 @@ function addExtends(importsMap, configBlocks, config, format) {
|
|
|
126
126
|
if (imp.match(/\.eslintrc(.base)?\.json$/)) {
|
|
127
127
|
const localName = index ? `baseConfig${index}` : 'baseConfig';
|
|
128
128
|
configBlocks.push((0, ast_utils_1.generateSpreadElement)(localName));
|
|
129
|
-
const newImport = imp.replace(/^(.*)\.eslintrc(.base)?\.json$/,
|
|
129
|
+
const newImport = imp.replace(/^(.*)\.eslintrc(.base)?\.json$/, '$1eslint$2.config.cjs');
|
|
130
130
|
importsMap.set(newImport, localName);
|
|
131
131
|
}
|
|
132
132
|
else {
|
|
@@ -14,21 +14,20 @@ async function convertToFlatConfigGenerator(tree, options) {
|
|
|
14
14
|
if (eslintFile.endsWith('.js')) {
|
|
15
15
|
throw new Error('Only json and yaml eslint config files are supported for conversion');
|
|
16
16
|
}
|
|
17
|
-
options.eslintConfigFormat ??= 'mjs';
|
|
18
17
|
const eslintIgnoreFiles = new Set(['.eslintignore']);
|
|
19
|
-
// convert root eslint config to eslint.config.cjs
|
|
20
|
-
convertRootToFlatConfig(tree, eslintFile
|
|
18
|
+
// convert root eslint config to eslint.config.cjs
|
|
19
|
+
convertRootToFlatConfig(tree, eslintFile);
|
|
21
20
|
// convert project eslint files to eslint.config.cjs
|
|
22
21
|
const projects = (0, devkit_1.getProjects)(tree);
|
|
23
22
|
for (const [project, projectConfig] of projects) {
|
|
24
|
-
convertProjectToFlatConfig(tree, project, projectConfig, (0, devkit_1.readNxJson)(tree), eslintIgnoreFiles
|
|
23
|
+
convertProjectToFlatConfig(tree, project, projectConfig, (0, devkit_1.readNxJson)(tree), eslintIgnoreFiles);
|
|
25
24
|
}
|
|
26
25
|
// delete all .eslintignore files
|
|
27
26
|
for (const ignoreFile of eslintIgnoreFiles) {
|
|
28
27
|
tree.delete(ignoreFile);
|
|
29
28
|
}
|
|
30
29
|
// replace references in nx.json
|
|
31
|
-
updateNxJsonConfig(tree
|
|
30
|
+
updateNxJsonConfig(tree);
|
|
32
31
|
// install missing packages
|
|
33
32
|
if (!options.skipFormat) {
|
|
34
33
|
await (0, devkit_1.formatFiles)(tree);
|
|
@@ -36,13 +35,13 @@ async function convertToFlatConfigGenerator(tree, options) {
|
|
|
36
35
|
return () => (0, devkit_1.installPackagesTask)(tree);
|
|
37
36
|
}
|
|
38
37
|
exports.default = convertToFlatConfigGenerator;
|
|
39
|
-
function convertRootToFlatConfig(tree, eslintFile
|
|
38
|
+
function convertRootToFlatConfig(tree, eslintFile) {
|
|
40
39
|
if (/\.base\.(js|json|yml|yaml)$/.test(eslintFile)) {
|
|
41
|
-
convertConfigToFlatConfig(tree, '', eslintFile,
|
|
40
|
+
convertConfigToFlatConfig(tree, '', eslintFile, 'eslint.base.config.cjs');
|
|
42
41
|
}
|
|
43
|
-
convertConfigToFlatConfig(tree, '', eslintFile.replace('.base.', '.'),
|
|
42
|
+
convertConfigToFlatConfig(tree, '', eslintFile.replace('.base.', '.'), 'eslint.config.cjs');
|
|
44
43
|
}
|
|
45
|
-
function convertProjectToFlatConfig(tree, project, projectConfig, nxJson, eslintIgnoreFiles
|
|
44
|
+
function convertProjectToFlatConfig(tree, project, projectConfig, nxJson, eslintIgnoreFiles) {
|
|
46
45
|
const eslintFile = (0, eslint_file_1.findEslintFile)(tree, projectConfig.root);
|
|
47
46
|
if (eslintFile && !eslintFile.endsWith('.js')) {
|
|
48
47
|
if (projectConfig.targets) {
|
|
@@ -68,7 +67,7 @@ function convertProjectToFlatConfig(tree, project, projectConfig, nxJson, eslint
|
|
|
68
67
|
? p === '@nx/eslint/plugin'
|
|
69
68
|
: p.plugin === '@nx/eslint/plugin');
|
|
70
69
|
if (nxHasEsLintTargets || nxHasEsLintPlugin || eslintTargets.length > 0) {
|
|
71
|
-
convertConfigToFlatConfig(tree, projectConfig.root, eslintFile,
|
|
70
|
+
convertConfigToFlatConfig(tree, projectConfig.root, eslintFile, 'eslint.config.cjs', ignorePath);
|
|
72
71
|
eslintIgnoreFiles.add(`${projectConfig.root}/.eslintignore`);
|
|
73
72
|
if (ignorePath) {
|
|
74
73
|
eslintIgnoreFiles.add(ignorePath);
|
|
@@ -79,35 +78,35 @@ function convertProjectToFlatConfig(tree, project, projectConfig, nxJson, eslint
|
|
|
79
78
|
}
|
|
80
79
|
// update names of eslint files in nx.json
|
|
81
80
|
// and remove eslintignore
|
|
82
|
-
function updateNxJsonConfig(tree
|
|
81
|
+
function updateNxJsonConfig(tree) {
|
|
83
82
|
if (tree.exists('nx.json')) {
|
|
84
83
|
(0, devkit_1.updateJson)(tree, 'nx.json', (json) => {
|
|
85
84
|
if (json.targetDefaults?.lint?.inputs) {
|
|
86
85
|
const inputSet = new Set(json.targetDefaults.lint.inputs);
|
|
87
|
-
inputSet.add(
|
|
86
|
+
inputSet.add('{workspaceRoot}/eslint.config.cjs');
|
|
88
87
|
json.targetDefaults.lint.inputs = Array.from(inputSet);
|
|
89
88
|
}
|
|
90
89
|
if (json.targetDefaults?.['@nx/eslint:lint']?.inputs) {
|
|
91
90
|
const inputSet = new Set(json.targetDefaults['@nx/eslint:lint'].inputs);
|
|
92
|
-
inputSet.add(
|
|
91
|
+
inputSet.add('{workspaceRoot}/eslint.config.cjs');
|
|
93
92
|
json.targetDefaults['@nx/eslint:lint'].inputs = Array.from(inputSet);
|
|
94
93
|
}
|
|
95
94
|
if (json.namedInputs?.production) {
|
|
96
95
|
const inputSet = new Set(json.namedInputs.production);
|
|
97
|
-
inputSet.add(
|
|
96
|
+
inputSet.add('!{projectRoot}/eslint.config.cjs');
|
|
98
97
|
json.namedInputs.production = Array.from(inputSet);
|
|
99
98
|
}
|
|
100
99
|
return json;
|
|
101
100
|
});
|
|
102
101
|
}
|
|
103
102
|
}
|
|
104
|
-
function convertConfigToFlatConfig(tree, root, source, target,
|
|
103
|
+
function convertConfigToFlatConfig(tree, root, source, target, ignorePath) {
|
|
105
104
|
const ignorePaths = ignorePath
|
|
106
105
|
? [ignorePath, `${root}/.eslintignore`]
|
|
107
106
|
: [`${root}/.eslintignore`];
|
|
108
107
|
if (source.endsWith('.json')) {
|
|
109
108
|
const config = (0, devkit_1.readJson)(tree, `${root}/${source}`);
|
|
110
|
-
const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths
|
|
109
|
+
const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths);
|
|
111
110
|
return processConvertedConfig(tree, root, source, target, conversionResult);
|
|
112
111
|
}
|
|
113
112
|
if (source.endsWith('.yaml') || source.endsWith('.yml')) {
|
|
@@ -117,7 +116,7 @@ function convertConfigToFlatConfig(tree, root, source, target, format, ignorePat
|
|
|
117
116
|
json: true,
|
|
118
117
|
filename: source,
|
|
119
118
|
});
|
|
120
|
-
const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths
|
|
119
|
+
const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths);
|
|
121
120
|
return processConvertedConfig(tree, root, source, target, conversionResult);
|
|
122
121
|
}
|
|
123
122
|
}
|
|
@@ -34,7 +34,6 @@ function postTargetTransformer(target, tree, projectDetails, inferredTargetConfi
|
|
|
34
34
|
'{workspaceRoot}/.eslintrc.json',
|
|
35
35
|
'{workspaceRoot}/.eslintignore',
|
|
36
36
|
'{workspaceRoot}/eslint.config.cjs',
|
|
37
|
-
'{workspaceRoot}/eslint.config.mjs',
|
|
38
37
|
].includes(input));
|
|
39
38
|
if (inputs.length === 0) {
|
|
40
39
|
delete target.inputs;
|
|
@@ -26,4 +26,4 @@ export declare const javaScriptOverride: {
|
|
|
26
26
|
rules: {};
|
|
27
27
|
};
|
|
28
28
|
export declare const getGlobalEsLintConfiguration: (unitTestRunner?: string, rootProject?: boolean) => Linter.Config;
|
|
29
|
-
export declare const getGlobalFlatEslintConfiguration: (
|
|
29
|
+
export declare const getGlobalFlatEslintConfiguration: (rootProject?: boolean) => string;
|
|
@@ -78,8 +78,8 @@ const getGlobalEsLintConfiguration = (unitTestRunner, rootProject) => {
|
|
|
78
78
|
return config;
|
|
79
79
|
};
|
|
80
80
|
exports.getGlobalEsLintConfiguration = getGlobalEsLintConfiguration;
|
|
81
|
-
const getGlobalFlatEslintConfiguration = (
|
|
82
|
-
const nodeList = (0, ast_utils_1.createNodeList)(new Map(), []
|
|
81
|
+
const getGlobalFlatEslintConfiguration = (rootProject) => {
|
|
82
|
+
const nodeList = (0, ast_utils_1.createNodeList)(new Map(), []);
|
|
83
83
|
let content = (0, ast_utils_1.stringifyNodeList)(nodeList);
|
|
84
84
|
content = (0, ast_utils_1.addImportToFlatConfig)(content, 'nx', '@nx/eslint-plugin');
|
|
85
85
|
content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatPredefinedConfig)('flat/base'), { insertAtTheEnd: false });
|
|
@@ -87,7 +87,7 @@ const getGlobalFlatEslintConfiguration = (format, rootProject) => {
|
|
|
87
87
|
content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatPredefinedConfig)('flat/javascript'));
|
|
88
88
|
content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)({
|
|
89
89
|
ignores: ['**/dist'],
|
|
90
|
-
}
|
|
90
|
+
}));
|
|
91
91
|
if (!rootProject) {
|
|
92
92
|
content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)({
|
|
93
93
|
files: ['*.ts', '*.tsx', '*.js', '*.jsx'],
|
|
@@ -107,7 +107,7 @@ const getGlobalFlatEslintConfiguration = (format, rootProject) => {
|
|
|
107
107
|
},
|
|
108
108
|
],
|
|
109
109
|
},
|
|
110
|
-
}
|
|
110
|
+
}));
|
|
111
111
|
}
|
|
112
112
|
content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, (0, ast_utils_1.generateFlatOverride)({
|
|
113
113
|
files: [
|
|
@@ -119,7 +119,7 @@ const getGlobalFlatEslintConfiguration = (format, rootProject) => {
|
|
|
119
119
|
'**/*.mjs',
|
|
120
120
|
],
|
|
121
121
|
rules: {},
|
|
122
|
-
}
|
|
122
|
+
}));
|
|
123
123
|
return content;
|
|
124
124
|
};
|
|
125
125
|
exports.getGlobalFlatEslintConfiguration = getGlobalFlatEslintConfiguration;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { GeneratorCallback, ProjectConfiguration, TargetConfiguration, Tree } from '@nx/devkit';
|
|
2
|
-
export declare function migrateConfigToMonorepoStyle(projects: ProjectConfiguration[], tree: Tree, unitTestRunner: string,
|
|
2
|
+
export declare function migrateConfigToMonorepoStyle(projects: ProjectConfiguration[], tree: Tree, unitTestRunner: string, keepExistingVersions?: boolean): GeneratorCallback;
|
|
3
3
|
export declare function findLintTarget(project: ProjectConfiguration): TargetConfiguration;
|
|
@@ -11,19 +11,9 @@ const versions_1 = require("../../utils/versions");
|
|
|
11
11
|
const ast_utils_1 = require("../utils/flat-config/ast-utils");
|
|
12
12
|
const plugin_1 = require("../utils/plugin");
|
|
13
13
|
const config_file_1 = require("../../utils/config-file");
|
|
14
|
-
function migrateConfigToMonorepoStyle(projects, tree, unitTestRunner,
|
|
14
|
+
function migrateConfigToMonorepoStyle(projects, tree, unitTestRunner, keepExistingVersions) {
|
|
15
15
|
const rootEslintConfig = (0, eslint_file_1.findEslintFile)(tree);
|
|
16
16
|
let skipCleanup = false;
|
|
17
|
-
if (rootEslintConfig) {
|
|
18
|
-
// We do not want to mix the formats
|
|
19
|
-
const fileExtension = (0, path_1.extname)(rootEslintConfig);
|
|
20
|
-
if (fileExtension === '.mjs' || fileExtension === '.cjs') {
|
|
21
|
-
eslintConfigFormat = fileExtension.slice(1);
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
eslintConfigFormat = (0, eslint_file_1.determineEslintConfigFormat)(tree.read(rootEslintConfig, 'utf-8'));
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
17
|
if (rootEslintConfig?.match(/\.base\./) &&
|
|
28
18
|
!projects.some((p) => p.root === '.')) {
|
|
29
19
|
// if the migration has been run already, we need to rename the base config
|
|
@@ -37,9 +27,9 @@ function migrateConfigToMonorepoStyle(projects, tree, unitTestRunner, eslintConf
|
|
|
37
27
|
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
38
28
|
'@eslint/js': versions_1.eslintVersion,
|
|
39
29
|
}, undefined, keepExistingVersions);
|
|
40
|
-
tree.write(tree.exists(
|
|
41
|
-
?
|
|
42
|
-
:
|
|
30
|
+
tree.write(tree.exists('eslint.config.cjs')
|
|
31
|
+
? 'eslint.base.config.cjs'
|
|
32
|
+
: 'eslint.config.cjs', (0, global_eslint_config_1.getGlobalFlatEslintConfiguration)());
|
|
43
33
|
}
|
|
44
34
|
else {
|
|
45
35
|
const eslintFile = (0, eslint_file_1.findEslintFile)(tree, '.');
|
|
@@ -90,7 +80,7 @@ function migrateEslintFile(projectEslintPath, tree) {
|
|
|
90
80
|
let config = tree.read(projectEslintPath, 'utf-8');
|
|
91
81
|
// remove @nx plugin
|
|
92
82
|
config = (0, ast_utils_1.removePlugin)(config, '@nx', '@nx/eslint-plugin-nx');
|
|
93
|
-
//
|
|
83
|
+
// extend eslint.base.config.cjs
|
|
94
84
|
config = (0, ast_utils_1.addImportToFlatConfig)(config, 'baseConfig', `${(0, devkit_1.offsetFromRoot)((0, path_1.dirname)(projectEslintPath))}${baseFile}`);
|
|
95
85
|
config = (0, ast_utils_1.addBlockToFlatConfigExport)(config, (0, ast_utils_1.generateSpreadElement)('baseConfig'), { insertAtTheEnd: false });
|
|
96
86
|
// cleanup file extends
|
|
@@ -4,7 +4,6 @@ export interface LinterInitOptions {
|
|
|
4
4
|
keepExistingVersions?: boolean;
|
|
5
5
|
updatePackageScripts?: boolean;
|
|
6
6
|
addPlugin?: boolean;
|
|
7
|
-
eslintConfigFormat?: 'mjs' | 'cjs';
|
|
8
7
|
}
|
|
9
8
|
export declare function initEsLint(tree: Tree, options: LinterInitOptions): Promise<GeneratorCallback>;
|
|
10
9
|
export declare function lintInitGenerator(tree: Tree, options: LinterInitOptions): Promise<GeneratorCallback>;
|
|
@@ -8,19 +8,18 @@ const versions_1 = require("../../utils/versions");
|
|
|
8
8
|
const eslint_file_1 = require("../utils/eslint-file");
|
|
9
9
|
const plugin_1 = require("../../plugins/plugin");
|
|
10
10
|
const plugin_2 = require("../utils/plugin");
|
|
11
|
-
|
|
12
|
-
function updateProductionFileset(tree, format = 'mjs') {
|
|
11
|
+
function updateProductionFileset(tree) {
|
|
13
12
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
14
13
|
const productionFileSet = nxJson.namedInputs?.production;
|
|
15
14
|
if (productionFileSet) {
|
|
16
15
|
productionFileSet.push('!{projectRoot}/.eslintrc.json');
|
|
17
|
-
productionFileSet.push(
|
|
16
|
+
productionFileSet.push('!{projectRoot}/eslint.config.cjs');
|
|
18
17
|
// Dedupe and set
|
|
19
18
|
nxJson.namedInputs.production = Array.from(new Set(productionFileSet));
|
|
20
19
|
}
|
|
21
20
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
22
21
|
}
|
|
23
|
-
function addTargetDefaults(tree
|
|
22
|
+
function addTargetDefaults(tree) {
|
|
24
23
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
25
24
|
nxJson.targetDefaults ??= {};
|
|
26
25
|
nxJson.targetDefaults['@nx/eslint:lint'] ??= {};
|
|
@@ -29,7 +28,7 @@ function addTargetDefaults(tree, format) {
|
|
|
29
28
|
'default',
|
|
30
29
|
`{workspaceRoot}/.eslintrc.json`,
|
|
31
30
|
`{workspaceRoot}/.eslintignore`,
|
|
32
|
-
`{workspaceRoot}/eslint.config
|
|
31
|
+
`{workspaceRoot}/eslint.config.cjs`,
|
|
33
32
|
];
|
|
34
33
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
35
34
|
}
|
|
@@ -51,18 +50,8 @@ async function initEsLint(tree, options) {
|
|
|
51
50
|
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
52
51
|
nxJson.useInferencePlugins !== false;
|
|
53
52
|
options.addPlugin ??= addPluginDefault;
|
|
54
|
-
options.eslintConfigFormat ??= 'mjs';
|
|
55
53
|
const hasPlugin = (0, plugin_2.hasEslintPlugin)(tree);
|
|
56
54
|
const rootEslintFile = (0, eslint_file_1.findEslintFile)(tree);
|
|
57
|
-
if (rootEslintFile) {
|
|
58
|
-
const fileExtension = (0, path_1.extname)(rootEslintFile);
|
|
59
|
-
if (fileExtension === '.mjs' || fileExtension === '.cjs') {
|
|
60
|
-
options.eslintConfigFormat = fileExtension.slice(1);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
options.eslintConfigFormat = (0, eslint_file_1.determineEslintConfigFormat)(tree.read(rootEslintFile, 'utf-8'));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
55
|
const graph = await (0, devkit_1.createProjectGraphAsync)();
|
|
67
56
|
const lintTargetNames = [
|
|
68
57
|
'lint',
|
|
@@ -81,7 +70,7 @@ async function initEsLint(tree, options) {
|
|
|
81
70
|
if (rootEslintFile) {
|
|
82
71
|
return () => { };
|
|
83
72
|
}
|
|
84
|
-
updateProductionFileset(tree
|
|
73
|
+
updateProductionFileset(tree);
|
|
85
74
|
updateVsCodeRecommendedExtensions(tree);
|
|
86
75
|
if (options.addPlugin) {
|
|
87
76
|
await (0, add_plugin_1.addPlugin)(tree, graph, '@nx/eslint/plugin', plugin_1.createNodesV2, {
|
|
@@ -89,7 +78,7 @@ async function initEsLint(tree, options) {
|
|
|
89
78
|
}, options.updatePackageScripts);
|
|
90
79
|
}
|
|
91
80
|
else {
|
|
92
|
-
addTargetDefaults(tree
|
|
81
|
+
addTargetDefaults(tree);
|
|
93
82
|
}
|
|
94
83
|
const tasks = [];
|
|
95
84
|
if (!options.skipPackageJson) {
|
|
@@ -18,7 +18,6 @@ function lintProjectGenerator(tree, options) {
|
|
|
18
18
|
}
|
|
19
19
|
async function lintProjectGeneratorInternal(tree, options) {
|
|
20
20
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
21
|
-
options.eslintConfigFormat ??= 'mjs';
|
|
22
21
|
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
23
22
|
nxJson.useInferencePlugins !== false;
|
|
24
23
|
options.addPlugin ??= addPluginDefault;
|
|
@@ -26,14 +25,12 @@ async function lintProjectGeneratorInternal(tree, options) {
|
|
|
26
25
|
const initTask = await (0, init_1.lintInitGenerator)(tree, {
|
|
27
26
|
skipPackageJson: options.skipPackageJson,
|
|
28
27
|
addPlugin: options.addPlugin,
|
|
29
|
-
eslintConfigFormat: options.eslintConfigFormat,
|
|
30
28
|
});
|
|
31
29
|
tasks.push(initTask);
|
|
32
30
|
const rootEsLintTask = (0, setup_root_eslint_1.setupRootEsLint)(tree, {
|
|
33
31
|
unitTestRunner: options.unitTestRunner,
|
|
34
32
|
skipPackageJson: options.skipPackageJson,
|
|
35
33
|
rootProject: options.rootProject,
|
|
36
|
-
eslintConfigFormat: options.eslintConfigFormat,
|
|
37
34
|
});
|
|
38
35
|
tasks.push(rootEsLintTask);
|
|
39
36
|
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
@@ -87,7 +84,7 @@ async function lintProjectGeneratorInternal(tree, options) {
|
|
|
87
84
|
filteredProjects.push(project);
|
|
88
85
|
}
|
|
89
86
|
});
|
|
90
|
-
const migrateTask = (0, init_migration_1.migrateConfigToMonorepoStyle)(filteredProjects, tree, options.unitTestRunner, options.
|
|
87
|
+
const migrateTask = (0, init_migration_1.migrateConfigToMonorepoStyle)(filteredProjects, tree, options.unitTestRunner, options.keepExistingVersions);
|
|
91
88
|
tasks.push(migrateTask);
|
|
92
89
|
}
|
|
93
90
|
}
|
|
@@ -119,18 +116,6 @@ function createEsLintConfiguration(tree, options, projectConfig, setParserOption
|
|
|
119
116
|
const pathToRootConfig = extendedRootConfig
|
|
120
117
|
? `${(0, devkit_1.offsetFromRoot)(projectConfig.root)}${extendedRootConfig}`
|
|
121
118
|
: undefined;
|
|
122
|
-
if (extendedRootConfig) {
|
|
123
|
-
// We do not want to mix the formats
|
|
124
|
-
// if the base file extension is `.mjs` we should use `mjs` for the new file
|
|
125
|
-
// or if base the file extension is `.cjs` then the format should be `cjs`
|
|
126
|
-
const fileExtension = (0, path_1.extname)(extendedRootConfig);
|
|
127
|
-
if (fileExtension === '.mjs' || fileExtension === '.cjs') {
|
|
128
|
-
options.eslintConfigFormat = fileExtension.slice(1);
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
options.eslintConfigFormat = (0, eslint_file_1.determineEslintConfigFormat)(tree.read(extendedRootConfig, 'utf-8'));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
119
|
const addDependencyChecks = options.addPackageJsonDependencyChecks ||
|
|
135
120
|
isBuildableLibraryProject(projectConfig);
|
|
136
121
|
const overrides = (0, flat_config_1.useFlatConfig)(tree)
|
|
@@ -195,11 +180,11 @@ function createEsLintConfiguration(tree, options, projectConfig, setParserOption
|
|
|
195
180
|
nodes.push((0, ast_utils_1.generateSpreadElement)('baseConfig'));
|
|
196
181
|
}
|
|
197
182
|
overrides.forEach((override) => {
|
|
198
|
-
nodes.push((0, ast_utils_1.generateFlatOverride)(override
|
|
183
|
+
nodes.push((0, ast_utils_1.generateFlatOverride)(override));
|
|
199
184
|
});
|
|
200
|
-
const nodeList = (0, ast_utils_1.createNodeList)(importMap, nodes
|
|
185
|
+
const nodeList = (0, ast_utils_1.createNodeList)(importMap, nodes);
|
|
201
186
|
const content = (0, ast_utils_1.stringifyNodeList)(nodeList);
|
|
202
|
-
tree.write((0, path_1.join)(projectConfig.root, `eslint.config
|
|
187
|
+
tree.write((0, path_1.join)(projectConfig.root, `eslint.config.cjs`), content);
|
|
203
188
|
}
|
|
204
189
|
else {
|
|
205
190
|
(0, devkit_1.writeJson)(tree, (0, path_1.join)(projectConfig.root, `.eslintrc.json`), {
|
|
@@ -227,7 +212,8 @@ function isBuildableLibraryProject(projectConfig) {
|
|
|
227
212
|
*/
|
|
228
213
|
function isMigrationToMonorepoNeeded(tree, graph) {
|
|
229
214
|
// the base config is already created, migration has been done
|
|
230
|
-
if (
|
|
215
|
+
if (tree.exists(config_file_1.baseEsLintConfigFile) ||
|
|
216
|
+
tree.exists(config_file_1.baseEsLintFlatConfigFile)) {
|
|
231
217
|
return false;
|
|
232
218
|
}
|
|
233
219
|
const nodes = Object.values(graph.nodes);
|
|
@@ -11,7 +11,6 @@ function setupRootEsLint(tree, options) {
|
|
|
11
11
|
if (rootEslintFile) {
|
|
12
12
|
return () => { };
|
|
13
13
|
}
|
|
14
|
-
options.eslintConfigFormat ??= 'mjs';
|
|
15
14
|
if (!(0, flat_config_1.useFlatConfig)(tree)) {
|
|
16
15
|
return setUpLegacyRootEslintRc(tree, options);
|
|
17
16
|
}
|
|
@@ -39,7 +38,7 @@ function setUpLegacyRootEslintRc(tree, options) {
|
|
|
39
38
|
: () => { };
|
|
40
39
|
}
|
|
41
40
|
function setUpRootFlatConfig(tree, options) {
|
|
42
|
-
tree.write(
|
|
41
|
+
tree.write('eslint.config.cjs', (0, global_eslint_config_1.getGlobalFlatEslintConfiguration)(options.rootProject));
|
|
43
42
|
return !options.skipPackageJson
|
|
44
43
|
? (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
45
44
|
'@eslint/js': versions_1.eslint9__eslintVersion,
|
|
@@ -3,7 +3,6 @@ import type { Linter } from 'eslint';
|
|
|
3
3
|
export declare function findEslintFile(tree: Tree, projectRoot?: string): string | null;
|
|
4
4
|
export declare function isEslintConfigSupported(tree: Tree, projectRoot?: string): boolean;
|
|
5
5
|
export declare function updateRelativePathsInConfig(tree: Tree, sourcePath: string, destinationPath: string): void;
|
|
6
|
-
export declare function determineEslintConfigFormat(content: string): 'mjs' | 'cjs';
|
|
7
6
|
export declare function addOverrideToLintConfig(tree: Tree, root: string, override: Partial<Linter.ConfigOverride<Linter.RulesRecord>>, options?: {
|
|
8
7
|
insertAtTheEnd?: boolean;
|
|
9
8
|
checkBaseConfig?: boolean;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.findEslintFile = findEslintFile;
|
|
4
4
|
exports.isEslintConfigSupported = isEslintConfigSupported;
|
|
5
5
|
exports.updateRelativePathsInConfig = updateRelativePathsInConfig;
|
|
6
|
-
exports.determineEslintConfigFormat = determineEslintConfigFormat;
|
|
7
6
|
exports.addOverrideToLintConfig = addOverrideToLintConfig;
|
|
8
7
|
exports.updateOverrideInLintConfig = updateOverrideInLintConfig;
|
|
9
8
|
exports.lintConfigHasOverride = lintConfigHasOverride;
|
|
@@ -21,18 +20,17 @@ const version_utils_1 = require("../../utils/version-utils");
|
|
|
21
20
|
const versions_1 = require("../../utils/versions");
|
|
22
21
|
const ast_utils_1 = require("./flat-config/ast-utils");
|
|
23
22
|
const path_utils_1 = require("./flat-config/path-utils");
|
|
24
|
-
const ts = require("typescript");
|
|
25
23
|
const posix_1 = require("node:path/posix");
|
|
26
24
|
function findEslintFile(tree, projectRoot) {
|
|
27
|
-
if (projectRoot === undefined) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
if (projectRoot === undefined && tree.exists(config_file_1.baseEsLintConfigFile)) {
|
|
26
|
+
return config_file_1.baseEsLintConfigFile;
|
|
27
|
+
}
|
|
28
|
+
if (projectRoot === undefined && tree.exists(config_file_1.baseEsLintFlatConfigFile)) {
|
|
29
|
+
return config_file_1.baseEsLintFlatConfigFile;
|
|
30
|
+
}
|
|
31
|
+
if (projectRoot === undefined &&
|
|
32
|
+
tree.exists(config_file_1.legacyBaseEsLintFlatConfigFile)) {
|
|
33
|
+
return config_file_1.legacyBaseEsLintFlatConfigFile;
|
|
36
34
|
}
|
|
37
35
|
projectRoot ??= '';
|
|
38
36
|
for (const file of config_file_1.ESLINT_CONFIG_FILENAMES) {
|
|
@@ -49,8 +47,7 @@ function isEslintConfigSupported(tree, projectRoot = '') {
|
|
|
49
47
|
}
|
|
50
48
|
return (eslintFile.endsWith('.json') ||
|
|
51
49
|
eslintFile.endsWith('.config.js') ||
|
|
52
|
-
eslintFile.endsWith('.config.cjs')
|
|
53
|
-
eslintFile.endsWith('.config.mjs'));
|
|
50
|
+
eslintFile.endsWith('.config.cjs'));
|
|
54
51
|
}
|
|
55
52
|
function updateRelativePathsInConfig(tree, sourcePath, destinationPath) {
|
|
56
53
|
if (sourcePath === destinationPath ||
|
|
@@ -94,17 +91,6 @@ function replaceFlatConfigPaths(config, sourceRoot, offset, destinationRoot, tre
|
|
|
94
91
|
`require('${newPath}')` +
|
|
95
92
|
newConfig.slice(match.index + match[0].length);
|
|
96
93
|
}
|
|
97
|
-
// Handle import statements
|
|
98
|
-
const importRegex = RegExp(/import\s+.*?\s+from\s+['"](.*)['"]/g);
|
|
99
|
-
while ((match = importRegex.exec(newConfig)) !== null) {
|
|
100
|
-
const oldPath = match[1];
|
|
101
|
-
const newPath = offsetFilePath(sourceRoot, oldPath, offset, tree);
|
|
102
|
-
// Replace the old path with the updated path
|
|
103
|
-
newConfig =
|
|
104
|
-
newConfig.slice(0, match.index + match[0].indexOf(oldPath)) +
|
|
105
|
-
newPath +
|
|
106
|
-
newConfig.slice(match.index + match[0].indexOf(oldPath) + oldPath.length);
|
|
107
|
-
}
|
|
108
94
|
// replace projects
|
|
109
95
|
const projectRegex = RegExp(/project:\s?\[?['"](.*)['"]\]?/g);
|
|
110
96
|
while ((match = projectRegex.exec(newConfig)) !== null) {
|
|
@@ -130,12 +116,6 @@ function offsetFilePath(projectRoot, pathToFile, offset, tree) {
|
|
|
130
116
|
}
|
|
131
117
|
return (0, devkit_1.joinPathFragments)(offset, projectRoot, pathToFile);
|
|
132
118
|
}
|
|
133
|
-
function determineEslintConfigFormat(content) {
|
|
134
|
-
const sourceFile = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true);
|
|
135
|
-
// Check if there's an `export default` in the AST
|
|
136
|
-
const hasExportDefault = sourceFile.statements.some((statement) => ts.isExportAssignment(statement) && !statement.isExportEquals);
|
|
137
|
-
return hasExportDefault ? 'mjs' : 'cjs';
|
|
138
|
-
}
|
|
139
119
|
function addOverrideToLintConfig(tree, root, override, options = {
|
|
140
120
|
insertAtTheEnd: true,
|
|
141
121
|
}) {
|
|
@@ -143,12 +123,7 @@ function addOverrideToLintConfig(tree, root, override, options = {
|
|
|
143
123
|
if ((0, flat_config_1.useFlatConfig)(tree)) {
|
|
144
124
|
let fileName;
|
|
145
125
|
if (isBase) {
|
|
146
|
-
|
|
147
|
-
if (tree.exists((0, devkit_1.joinPathFragments)(root, file))) {
|
|
148
|
-
fileName = (0, devkit_1.joinPathFragments)(root, file);
|
|
149
|
-
break;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
126
|
+
fileName = (0, devkit_1.joinPathFragments)(root, config_file_1.baseEsLintFlatConfigFile);
|
|
152
127
|
}
|
|
153
128
|
else {
|
|
154
129
|
for (const f of flat_config_1.eslintFlatConfigFilenames) {
|
|
@@ -158,9 +133,8 @@ function addOverrideToLintConfig(tree, root, override, options = {
|
|
|
158
133
|
}
|
|
159
134
|
}
|
|
160
135
|
}
|
|
136
|
+
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override);
|
|
161
137
|
let content = tree.read(fileName, 'utf8');
|
|
162
|
-
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
163
|
-
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override, format);
|
|
164
138
|
// Check if the provided override using legacy eslintrc properties or plugins, if so we need to add compat
|
|
165
139
|
if ((0, ast_utils_1.overrideNeedsCompat)(override)) {
|
|
166
140
|
content = (0, ast_utils_1.addFlatCompatToFlatConfig)(content);
|
|
@@ -239,12 +213,7 @@ function lintConfigHasOverride(tree, rootOrFile, lookup, checkBaseConfig = false
|
|
|
239
213
|
checkBaseConfig &&
|
|
240
214
|
findEslintFile(tree, root).includes('.base');
|
|
241
215
|
if (isBase) {
|
|
242
|
-
|
|
243
|
-
if (tree.exists((0, devkit_1.joinPathFragments)(root, file))) {
|
|
244
|
-
fileName = (0, devkit_1.joinPathFragments)(root, file);
|
|
245
|
-
break;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
216
|
+
fileName = (0, devkit_1.joinPathFragments)(root, config_file_1.baseEsLintFlatConfigFile);
|
|
248
217
|
}
|
|
249
218
|
if ((0, flat_config_1.useFlatConfig)(tree)) {
|
|
250
219
|
if (!fileName) {
|
|
@@ -273,14 +242,13 @@ function replaceOverridesInLintConfig(tree, root, overrides) {
|
|
|
273
242
|
}
|
|
274
243
|
}
|
|
275
244
|
let content = tree.read(fileName, 'utf8');
|
|
276
|
-
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
|
277
245
|
// Check if any of the provided overrides using legacy eslintrc properties or plugins, if so we need to add compat
|
|
278
246
|
if (overrides.some(ast_utils_1.overrideNeedsCompat)) {
|
|
279
247
|
content = (0, ast_utils_1.addFlatCompatToFlatConfig)(content);
|
|
280
248
|
}
|
|
281
249
|
content = (0, ast_utils_1.removeOverridesFromLintConfig)(content);
|
|
282
250
|
overrides.forEach((override) => {
|
|
283
|
-
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override
|
|
251
|
+
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override);
|
|
284
252
|
content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, flatOverride);
|
|
285
253
|
});
|
|
286
254
|
tree.write(fileName, content);
|
|
@@ -303,14 +271,6 @@ function addExtendsToLintConfig(tree, root, plugin, insertAtTheEnd = false) {
|
|
|
303
271
|
break;
|
|
304
272
|
}
|
|
305
273
|
}
|
|
306
|
-
// Check the file extension to determine the format of the config if it is .js we look for the export
|
|
307
|
-
const eslintConfigFormat = fileName.endsWith('.mjs')
|
|
308
|
-
? 'mjs'
|
|
309
|
-
: fileName.endsWith('.cjs')
|
|
310
|
-
? 'cjs'
|
|
311
|
-
: tree.read(fileName, 'utf-8').includes('module.exports')
|
|
312
|
-
? 'cjs'
|
|
313
|
-
: 'mjs';
|
|
314
274
|
let shouldImportEslintCompat = false;
|
|
315
275
|
// assume eslint version is 9 if not found, as it's what we'd be generating by default
|
|
316
276
|
const eslintVersion = (0, version_utils_1.getInstalledEslintVersion)(tree) ?? versions_1.eslint9__eslintVersion;
|