@nx/eslint 17.0.3 → 17.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +9 -4
- package/generators.json +6 -0
- package/migrations.json +68 -0
- package/package.json +9 -8
- package/plugin.d.ts +1 -0
- package/plugin.js +5 -0
- package/src/executors/lint/hasher.js +1 -1
- package/src/executors/lint/lint.impl.js +67 -33
- package/src/executors/lint/schema.d.ts +1 -0
- package/src/executors/lint/schema.json +7 -3
- package/src/executors/lint/utility/eslint-utils.js +5 -1
- package/src/generators/convert-to-flat-config/converters/json-converter.d.ts +6 -1
- package/src/generators/convert-to-flat-config/converters/json-converter.js +28 -33
- package/src/generators/convert-to-flat-config/generator.js +73 -17
- package/src/generators/convert-to-flat-config/schema.json +1 -1
- package/src/generators/init/global-eslint-config.js +9 -5
- package/src/generators/init/init-migration.d.ts +1 -1
- package/src/generators/init/init-migration.js +53 -14
- package/src/generators/init/init.d.ts +5 -5
- package/src/generators/init/init.js +63 -35
- package/src/generators/init/schema.json +28 -0
- package/src/generators/lint-project/lint-project.d.ts +9 -3
- package/src/generators/lint-project/lint-project.js +76 -40
- package/src/generators/lint-project/setup-root-eslint.d.ts +7 -0
- package/src/generators/lint-project/setup-root-eslint.js +33 -0
- package/src/generators/utils/eslint-file.d.ts +2 -5
- package/src/generators/utils/eslint-file.js +37 -30
- package/src/generators/utils/flat-config/ast-utils.d.ts +4 -5
- package/src/generators/utils/flat-config/ast-utils.js +35 -38
- package/src/generators/utils/flat-config/path-utils.d.ts +2 -1
- package/src/generators/utils/flat-config/path-utils.js +9 -12
- package/src/generators/utils/plugin.d.ts +2 -0
- package/src/generators/utils/plugin.js +11 -0
- package/src/generators/workspace-rule/files/__name__.ts__tmpl__ +2 -2
- package/src/generators/workspace-rule/schema.json +1 -1
- package/src/generators/workspace-rule/workspace-rule.js +7 -2
- package/src/generators/workspace-rules-project/files/tsconfig.json__tmpl__ +2 -1
- package/src/generators/workspace-rules-project/schema.json +1 -1
- package/src/generators/workspace-rules-project/workspace-rules-project.d.ts +3 -2
- package/src/generators/workspace-rules-project/workspace-rules-project.js +11 -9
- package/src/migrations/update-15-0-0/add-eslint-inputs.js +2 -2
- package/src/migrations/update-15-7-1/add-eslint-ignore.js +2 -2
- package/src/migrations/update-17-1-0/update-typescript-eslint.d.ts +2 -0
- package/src/migrations/update-17-1-0/update-typescript-eslint.js +74 -0
- package/src/migrations/update-17-2-0/simplify-eslint-patterns.d.ts +2 -0
- package/src/migrations/update-17-2-0/simplify-eslint-patterns.js +46 -0
- package/src/migrations/update-17-2-9/move-options-to-target-defaults.d.ts +2 -0
- package/src/migrations/update-17-2-9/move-options-to-target-defaults.js +107 -0
- package/src/plugins/plugin.d.ts +6 -0
- package/src/plugins/plugin.js +117 -0
- package/src/utils/config-file.d.ts +4 -0
- package/src/utils/config-file.js +18 -0
- package/src/utils/versions.d.ts +2 -2
- package/src/utils/versions.js +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.lintProjectGeneratorInternal = exports.lintProjectGenerator = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const eslint_file_1 = require("../utils/eslint-file");
|
|
6
6
|
const path_1 = require("path");
|
|
@@ -9,34 +9,64 @@ const init_migration_1 = require("../init/init-migration");
|
|
|
9
9
|
const project_configuration_1 = require("nx/src/generators/utils/project-configuration");
|
|
10
10
|
const flat_config_1 = require("../../utils/flat-config");
|
|
11
11
|
const ast_utils_1 = require("../utils/flat-config/ast-utils");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return `${projectRoot}/**/*.${extension}`;
|
|
18
|
-
}
|
|
12
|
+
const config_file_1 = require("../../utils/config-file");
|
|
13
|
+
const plugin_1 = require("../utils/plugin");
|
|
14
|
+
const setup_root_eslint_1 = require("./setup-root-eslint");
|
|
15
|
+
function lintProjectGenerator(tree, options) {
|
|
16
|
+
return lintProjectGeneratorInternal(tree, { addPlugin: false, ...options });
|
|
19
17
|
}
|
|
20
|
-
exports.
|
|
21
|
-
async function
|
|
22
|
-
const
|
|
23
|
-
|
|
18
|
+
exports.lintProjectGenerator = lintProjectGenerator;
|
|
19
|
+
async function lintProjectGeneratorInternal(tree, options) {
|
|
20
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
21
|
+
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
22
|
+
nxJson.useInferencePlugins !== false;
|
|
23
|
+
options.addPlugin ??= addPluginDefault;
|
|
24
|
+
const tasks = [];
|
|
25
|
+
const initTask = await (0, init_1.lintInitGenerator)(tree, {
|
|
26
|
+
skipPackageJson: options.skipPackageJson,
|
|
27
|
+
addPlugin: options.addPlugin,
|
|
28
|
+
});
|
|
29
|
+
tasks.push(initTask);
|
|
30
|
+
const rootEsLintTask = (0, setup_root_eslint_1.setupRootEsLint)(tree, {
|
|
24
31
|
unitTestRunner: options.unitTestRunner,
|
|
25
32
|
skipPackageJson: options.skipPackageJson,
|
|
26
33
|
rootProject: options.rootProject,
|
|
27
34
|
});
|
|
35
|
+
tasks.push(rootEsLintTask);
|
|
28
36
|
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
29
|
-
|
|
30
|
-
if (
|
|
31
|
-
lintFilePatterns
|
|
37
|
+
let lintFilePatterns = options.eslintFilePatterns;
|
|
38
|
+
if (!lintFilePatterns && options.rootProject && projectConfig.root === '.') {
|
|
39
|
+
lintFilePatterns = ['./src'];
|
|
40
|
+
}
|
|
41
|
+
if (lintFilePatterns &&
|
|
42
|
+
lintFilePatterns.length &&
|
|
43
|
+
!lintFilePatterns.includes('{projectRoot}') &&
|
|
44
|
+
isBuildableLibraryProject(projectConfig)) {
|
|
45
|
+
lintFilePatterns.push(`{projectRoot}/package.json`);
|
|
46
|
+
}
|
|
47
|
+
const hasPlugin = (0, plugin_1.hasEslintPlugin)(tree);
|
|
48
|
+
if (hasPlugin && !options.addExplicitTargets) {
|
|
49
|
+
if (lintFilePatterns &&
|
|
50
|
+
lintFilePatterns.length &&
|
|
51
|
+
lintFilePatterns.some((p) => !['./src', '{projectRoot}', projectConfig.root].includes(p))) {
|
|
52
|
+
projectConfig.targets['lint'] = {
|
|
53
|
+
command: `eslint ${lintFilePatterns
|
|
54
|
+
.join(' ')
|
|
55
|
+
.replace('{projectRoot}', projectConfig.root)}`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
projectConfig.targets['lint'] = {
|
|
61
|
+
executor: '@nx/eslint:lint',
|
|
62
|
+
};
|
|
63
|
+
if (lintFilePatterns && lintFilePatterns.length) {
|
|
64
|
+
// only add lintFilePatterns if they are explicitly defined
|
|
65
|
+
projectConfig.targets['lint'].options = {
|
|
66
|
+
lintFilePatterns,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
32
69
|
}
|
|
33
|
-
projectConfig.targets['lint'] = {
|
|
34
|
-
executor: '@nx/eslint:lint',
|
|
35
|
-
outputs: ['{options.outputFile}'],
|
|
36
|
-
options: {
|
|
37
|
-
lintFilePatterns: lintFilePatterns,
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
70
|
// we are adding new project which is not the root project or
|
|
41
71
|
// companion e2e app so we should check if migration to
|
|
42
72
|
// monorepo style is needed
|
|
@@ -51,14 +81,14 @@ async function lintProjectGenerator(tree, options) {
|
|
|
51
81
|
filteredProjects.push(project);
|
|
52
82
|
}
|
|
53
83
|
});
|
|
54
|
-
(0, init_migration_1.migrateConfigToMonorepoStyle)(filteredProjects, tree, options.unitTestRunner);
|
|
84
|
+
(0, init_migration_1.migrateConfigToMonorepoStyle)(filteredProjects, tree, options.unitTestRunner, options.keepExistingVersions);
|
|
55
85
|
}
|
|
56
86
|
}
|
|
57
87
|
// our root `.eslintrc` is already the project config, so we should not override it
|
|
58
88
|
// additionally, the companion e2e app would have `rootProject: true`
|
|
59
89
|
// so we need to check for the root path as well
|
|
60
90
|
if (!options.rootProject || projectConfig.root !== '.') {
|
|
61
|
-
createEsLintConfiguration(tree, projectConfig, options.setParserOptionsProject);
|
|
91
|
+
createEsLintConfiguration(tree, projectConfig, options.setParserOptionsProject, options.rootProject);
|
|
62
92
|
}
|
|
63
93
|
// Buildable libs need source analysis enabled for linting `package.json`.
|
|
64
94
|
if (isBuildableLibraryProject(projectConfig) &&
|
|
@@ -74,13 +104,14 @@ async function lintProjectGenerator(tree, options) {
|
|
|
74
104
|
if (!options.skipFormat) {
|
|
75
105
|
await (0, devkit_1.formatFiles)(tree);
|
|
76
106
|
}
|
|
77
|
-
return
|
|
107
|
+
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
78
108
|
}
|
|
79
|
-
exports.
|
|
80
|
-
function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject) {
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
109
|
+
exports.lintProjectGeneratorInternal = lintProjectGeneratorInternal;
|
|
110
|
+
function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject, rootProject) {
|
|
111
|
+
// we are only extending root for non-standalone projects or their complementary e2e apps
|
|
112
|
+
const extendedRootConfig = rootProject ? undefined : (0, eslint_file_1.findEslintFile)(tree);
|
|
113
|
+
const pathToRootConfig = extendedRootConfig
|
|
114
|
+
? `${(0, devkit_1.offsetFromRoot)(projectConfig.root)}${extendedRootConfig}`
|
|
84
115
|
: undefined;
|
|
85
116
|
const addDependencyChecks = isBuildableLibraryProject(projectConfig);
|
|
86
117
|
const overrides = [
|
|
@@ -132,20 +163,20 @@ function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject)
|
|
|
132
163
|
const isCompatNeeded = addDependencyChecks;
|
|
133
164
|
const nodes = [];
|
|
134
165
|
const importMap = new Map();
|
|
135
|
-
if (
|
|
166
|
+
if (extendedRootConfig) {
|
|
136
167
|
importMap.set(pathToRootConfig, 'baseConfig');
|
|
137
168
|
nodes.push((0, ast_utils_1.generateSpreadElement)('baseConfig'));
|
|
138
169
|
}
|
|
139
170
|
overrides.forEach((override) => {
|
|
140
|
-
nodes.push((0, ast_utils_1.generateFlatOverride)(override
|
|
171
|
+
nodes.push((0, ast_utils_1.generateFlatOverride)(override));
|
|
141
172
|
});
|
|
142
173
|
const nodeList = (0, ast_utils_1.createNodeList)(importMap, nodes, isCompatNeeded);
|
|
143
|
-
const content = (0, ast_utils_1.stringifyNodeList)(nodeList
|
|
174
|
+
const content = (0, ast_utils_1.stringifyNodeList)(nodeList);
|
|
144
175
|
tree.write((0, path_1.join)(projectConfig.root, 'eslint.config.js'), content);
|
|
145
176
|
}
|
|
146
177
|
else {
|
|
147
178
|
(0, devkit_1.writeJson)(tree, (0, path_1.join)(projectConfig.root, `.eslintrc.json`), {
|
|
148
|
-
extends:
|
|
179
|
+
extends: extendedRootConfig ? [pathToRootConfig] : undefined,
|
|
149
180
|
// Include project files to be linted since the global one excludes all files.
|
|
150
181
|
ignorePatterns: ['!**/*'],
|
|
151
182
|
overrides,
|
|
@@ -169,8 +200,8 @@ function isBuildableLibraryProject(projectConfig) {
|
|
|
169
200
|
*/
|
|
170
201
|
function isMigrationToMonorepoNeeded(projects, tree) {
|
|
171
202
|
// the base config is already created, migration has been done
|
|
172
|
-
if (tree.exists(
|
|
173
|
-
tree.exists(
|
|
203
|
+
if (tree.exists(config_file_1.baseEsLintConfigFile) ||
|
|
204
|
+
tree.exists(config_file_1.baseEsLintFlatConfigFile)) {
|
|
174
205
|
return false;
|
|
175
206
|
}
|
|
176
207
|
const configs = Object.values(projects);
|
|
@@ -182,10 +213,15 @@ function isMigrationToMonorepoNeeded(projects, tree) {
|
|
|
182
213
|
if (!rootProject || !rootProject.targets) {
|
|
183
214
|
return false;
|
|
184
215
|
}
|
|
216
|
+
// check if we're inferring lint target from `@nx/eslint/plugin`
|
|
217
|
+
if ((0, plugin_1.hasEslintPlugin)(tree)) {
|
|
218
|
+
for (const f of config_file_1.ESLINT_CONFIG_FILENAMES) {
|
|
219
|
+
if (tree.exists(f)) {
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
185
224
|
// find if root project has lint target
|
|
186
225
|
const lintTarget = (0, init_migration_1.findLintTarget)(rootProject);
|
|
187
|
-
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
190
|
-
return true;
|
|
226
|
+
return !!lintTarget;
|
|
191
227
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type GeneratorCallback, type Tree } from '@nx/devkit';
|
|
2
|
+
export type SetupRootEsLintOptions = {
|
|
3
|
+
unitTestRunner?: string;
|
|
4
|
+
skipPackageJson?: boolean;
|
|
5
|
+
rootProject?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function setupRootEsLint(tree: Tree, options: SetupRootEsLintOptions): GeneratorCallback;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupRootEsLint = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const versions_1 = require("../../utils/versions");
|
|
6
|
+
const global_eslint_config_1 = require("../init/global-eslint-config");
|
|
7
|
+
const eslint_file_1 = require("../utils/eslint-file");
|
|
8
|
+
function setupRootEsLint(tree, options) {
|
|
9
|
+
const rootEslintFile = (0, eslint_file_1.findEslintFile)(tree);
|
|
10
|
+
if (rootEslintFile) {
|
|
11
|
+
return () => { };
|
|
12
|
+
}
|
|
13
|
+
(0, devkit_1.writeJson)(tree, '.eslintrc.json', (0, global_eslint_config_1.getGlobalEsLintConfiguration)(options.unitTestRunner, options.rootProject));
|
|
14
|
+
if (tree.exists('.eslintignore')) {
|
|
15
|
+
let content = tree.read('.eslintignore', 'utf-8');
|
|
16
|
+
if (!/^node_modules$/gm.test(content)) {
|
|
17
|
+
content = `${content}\nnode_modules\n`;
|
|
18
|
+
tree.write('.eslintignore', content);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
tree.write('.eslintignore', 'node_modules\n');
|
|
23
|
+
}
|
|
24
|
+
return !options.skipPackageJson
|
|
25
|
+
? (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
26
|
+
'@nx/eslint-plugin': versions_1.nxVersion,
|
|
27
|
+
'@typescript-eslint/parser': versions_1.typescriptESLintVersion,
|
|
28
|
+
'@typescript-eslint/eslint-plugin': versions_1.typescriptESLintVersion,
|
|
29
|
+
'eslint-config-prettier': versions_1.eslintConfigPrettierVersion,
|
|
30
|
+
})
|
|
31
|
+
: () => { };
|
|
32
|
+
}
|
|
33
|
+
exports.setupRootEsLint = setupRootEsLint;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { Tree } from '@nx/devkit';
|
|
2
|
-
import { Linter } from 'eslint';
|
|
3
|
-
export declare const eslintConfigFileWhitelist: string[];
|
|
4
|
-
export declare const baseEsLintConfigFile = ".eslintrc.base.json";
|
|
5
|
-
export declare const baseEsLintFlatConfigFile = "eslint.base.config.js";
|
|
1
|
+
import type { Tree } from '@nx/devkit';
|
|
2
|
+
import type { Linter } from 'eslint';
|
|
6
3
|
export declare function findEslintFile(tree: Tree, projectRoot?: string): string | null;
|
|
7
4
|
export declare function isEslintConfigSupported(tree: Tree, projectRoot?: string): boolean;
|
|
8
5
|
export declare function updateRelativePathsInConfig(tree: Tree, sourcePath: string, destinationPath: string): void;
|
|
@@ -1,28 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPluginImport = exports.addIgnoresToLintConfig = exports.addPluginsToLintConfig = exports.addExtendsToLintConfig = exports.replaceOverridesInLintConfig = exports.lintConfigHasOverride = exports.updateOverrideInLintConfig = exports.addOverrideToLintConfig = exports.updateRelativePathsInConfig = exports.isEslintConfigSupported = exports.findEslintFile =
|
|
3
|
+
exports.getPluginImport = exports.addIgnoresToLintConfig = exports.addPluginsToLintConfig = exports.addExtendsToLintConfig = exports.replaceOverridesInLintConfig = exports.lintConfigHasOverride = exports.updateOverrideInLintConfig = exports.addOverrideToLintConfig = exports.updateRelativePathsInConfig = exports.isEslintConfigSupported = exports.findEslintFile = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const flat_config_1 = require("../../utils/flat-config");
|
|
6
6
|
const ast_utils_1 = require("./flat-config/ast-utils");
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
'.eslintrc.yml',
|
|
13
|
-
'.eslintrc.json',
|
|
14
|
-
'eslint.config.js',
|
|
15
|
-
];
|
|
16
|
-
exports.baseEsLintConfigFile = '.eslintrc.base.json';
|
|
17
|
-
exports.baseEsLintFlatConfigFile = 'eslint.base.config.js';
|
|
18
|
-
function findEslintFile(tree, projectRoot = '') {
|
|
19
|
-
if (projectRoot === '' && tree.exists(exports.baseEsLintConfigFile)) {
|
|
20
|
-
return exports.baseEsLintConfigFile;
|
|
7
|
+
const path_utils_1 = require("./flat-config/path-utils");
|
|
8
|
+
const config_file_1 = require("../../utils/config-file");
|
|
9
|
+
function findEslintFile(tree, projectRoot) {
|
|
10
|
+
if (projectRoot === undefined && tree.exists(config_file_1.baseEsLintConfigFile)) {
|
|
11
|
+
return config_file_1.baseEsLintConfigFile;
|
|
21
12
|
}
|
|
22
|
-
if (projectRoot ===
|
|
23
|
-
return
|
|
13
|
+
if (projectRoot === undefined && tree.exists(config_file_1.baseEsLintFlatConfigFile)) {
|
|
14
|
+
return config_file_1.baseEsLintFlatConfigFile;
|
|
24
15
|
}
|
|
25
|
-
|
|
16
|
+
projectRoot ??= '';
|
|
17
|
+
for (const file of config_file_1.ESLINT_CONFIG_FILENAMES) {
|
|
26
18
|
if (tree.exists((0, devkit_1.joinPathFragments)(projectRoot, file))) {
|
|
27
19
|
return file;
|
|
28
20
|
}
|
|
@@ -93,7 +85,7 @@ function replaceFlatConfigPaths(config, sourceRoot, offset, destinationRoot, tre
|
|
|
93
85
|
return newConfig;
|
|
94
86
|
}
|
|
95
87
|
function offsetFilePath(projectRoot, pathToFile, offset, tree) {
|
|
96
|
-
if (
|
|
88
|
+
if (config_file_1.ESLINT_CONFIG_FILENAMES.some((eslintFile) => pathToFile.includes(eslintFile))) {
|
|
97
89
|
// if the file is point to base eslint
|
|
98
90
|
const rootEslint = findEslintFile(tree);
|
|
99
91
|
if (rootEslint) {
|
|
@@ -111,8 +103,8 @@ function addOverrideToLintConfig(tree, root, override, options = {
|
|
|
111
103
|
}) {
|
|
112
104
|
const isBase = options.checkBaseConfig && findEslintFile(tree, root).includes('.base');
|
|
113
105
|
if ((0, flat_config_1.useFlatConfig)(tree)) {
|
|
114
|
-
const fileName = (0, devkit_1.joinPathFragments)(root, isBase ?
|
|
115
|
-
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override
|
|
106
|
+
const fileName = (0, devkit_1.joinPathFragments)(root, isBase ? config_file_1.baseEsLintFlatConfigFile : 'eslint.config.js');
|
|
107
|
+
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override);
|
|
116
108
|
let content = tree.read(fileName, 'utf8');
|
|
117
109
|
// we will be using compat here so we need to make sure it's added
|
|
118
110
|
if (overrideNeedsCompat(override)) {
|
|
@@ -121,9 +113,9 @@ function addOverrideToLintConfig(tree, root, override, options = {
|
|
|
121
113
|
tree.write(fileName, (0, ast_utils_1.addBlockToFlatConfigExport)(content, flatOverride, options));
|
|
122
114
|
}
|
|
123
115
|
else {
|
|
124
|
-
const fileName = (0, devkit_1.joinPathFragments)(root, isBase ?
|
|
116
|
+
const fileName = (0, devkit_1.joinPathFragments)(root, isBase ? config_file_1.baseEsLintConfigFile : '.eslintrc.json');
|
|
125
117
|
(0, devkit_1.updateJson)(tree, fileName, (json) => {
|
|
126
|
-
json.overrides
|
|
118
|
+
json.overrides ??= [];
|
|
127
119
|
if (options.insertAtTheEnd) {
|
|
128
120
|
json.overrides.push(override);
|
|
129
121
|
}
|
|
@@ -136,7 +128,7 @@ function addOverrideToLintConfig(tree, root, override, options = {
|
|
|
136
128
|
}
|
|
137
129
|
exports.addOverrideToLintConfig = addOverrideToLintConfig;
|
|
138
130
|
function overrideNeedsCompat(override) {
|
|
139
|
-
return (
|
|
131
|
+
return (override.env || override.extends || override.plugins || override.parser);
|
|
140
132
|
}
|
|
141
133
|
function updateOverrideInLintConfig(tree, root, lookup, update) {
|
|
142
134
|
if ((0, flat_config_1.useFlatConfig)(tree)) {
|
|
@@ -147,10 +139,23 @@ function updateOverrideInLintConfig(tree, root, lookup, update) {
|
|
|
147
139
|
}
|
|
148
140
|
else {
|
|
149
141
|
const fileName = (0, devkit_1.joinPathFragments)(root, '.eslintrc.json');
|
|
142
|
+
if (!tree.exists(fileName)) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const existingJson = (0, devkit_1.readJson)(tree, fileName);
|
|
146
|
+
if (!existingJson.overrides || !existingJson.overrides.some(lookup)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
150
149
|
(0, devkit_1.updateJson)(tree, fileName, (json) => {
|
|
151
150
|
const index = json.overrides.findIndex(lookup);
|
|
152
151
|
if (index !== -1) {
|
|
153
|
-
|
|
152
|
+
const newOverride = update(json.overrides[index]);
|
|
153
|
+
if (newOverride) {
|
|
154
|
+
json.overrides[index] = newOverride;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
json.overrides.splice(index, 1);
|
|
158
|
+
}
|
|
154
159
|
}
|
|
155
160
|
return json;
|
|
156
161
|
});
|
|
@@ -163,12 +168,12 @@ function lintConfigHasOverride(tree, root, lookup, checkBaseConfig = false) {
|
|
|
163
168
|
}
|
|
164
169
|
const isBase = checkBaseConfig && findEslintFile(tree, root).includes('.base');
|
|
165
170
|
if ((0, flat_config_1.useFlatConfig)(tree)) {
|
|
166
|
-
const fileName = (0, devkit_1.joinPathFragments)(root, isBase ?
|
|
171
|
+
const fileName = (0, devkit_1.joinPathFragments)(root, isBase ? config_file_1.baseEsLintFlatConfigFile : 'eslint.config.js');
|
|
167
172
|
const content = tree.read(fileName, 'utf8');
|
|
168
173
|
return (0, ast_utils_1.hasOverride)(content, lookup);
|
|
169
174
|
}
|
|
170
175
|
else {
|
|
171
|
-
const fileName = (0, devkit_1.joinPathFragments)(root, isBase ?
|
|
176
|
+
const fileName = (0, devkit_1.joinPathFragments)(root, isBase ? config_file_1.baseEsLintConfigFile : '.eslintrc.json');
|
|
172
177
|
return (0, devkit_1.readJson)(tree, fileName).overrides?.some(lookup) || false;
|
|
173
178
|
}
|
|
174
179
|
}
|
|
@@ -183,7 +188,7 @@ function replaceOverridesInLintConfig(tree, root, overrides) {
|
|
|
183
188
|
}
|
|
184
189
|
content = (0, ast_utils_1.removeOverridesFromLintConfig)(content);
|
|
185
190
|
overrides.forEach((override) => {
|
|
186
|
-
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override
|
|
191
|
+
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override);
|
|
187
192
|
(0, ast_utils_1.addBlockToFlatConfigExport)(content, flatOverride);
|
|
188
193
|
});
|
|
189
194
|
tree.write(fileName, content);
|
|
@@ -202,7 +207,9 @@ function addExtendsToLintConfig(tree, root, plugin) {
|
|
|
202
207
|
if ((0, flat_config_1.useFlatConfig)(tree)) {
|
|
203
208
|
const fileName = (0, devkit_1.joinPathFragments)(root, 'eslint.config.js');
|
|
204
209
|
const pluginExtends = (0, ast_utils_1.generatePluginExtendsElement)(plugins);
|
|
205
|
-
|
|
210
|
+
let content = tree.read(fileName, 'utf8');
|
|
211
|
+
content = (0, ast_utils_1.addCompatToFlatConfig)(content);
|
|
212
|
+
tree.write(fileName, (0, ast_utils_1.addBlockToFlatConfigExport)(content, pluginExtends));
|
|
206
213
|
}
|
|
207
214
|
else {
|
|
208
215
|
const fileName = (0, devkit_1.joinPathFragments)(root, '.eslintrc.json');
|
|
@@ -247,7 +254,7 @@ function addIgnoresToLintConfig(tree, root, ignorePatterns) {
|
|
|
247
254
|
if ((0, flat_config_1.useFlatConfig)(tree)) {
|
|
248
255
|
const fileName = (0, devkit_1.joinPathFragments)(root, 'eslint.config.js');
|
|
249
256
|
const block = (0, ast_utils_1.generateAst)({
|
|
250
|
-
ignores: ignorePatterns.map((path) => (0,
|
|
257
|
+
ignores: ignorePatterns.map((path) => (0, path_utils_1.mapFilePath)(path)),
|
|
251
258
|
});
|
|
252
259
|
tree.write(fileName, (0, ast_utils_1.addBlockToFlatConfigExport)(tree.read(fileName, 'utf8'), block));
|
|
253
260
|
}
|
|
@@ -8,7 +8,7 @@ export declare function hasOverride(content: string, lookup: (override: Linter.C
|
|
|
8
8
|
/**
|
|
9
9
|
* Finds an override matching the lookup function and applies the update function to it
|
|
10
10
|
*/
|
|
11
|
-
export declare function replaceOverride(content: string, root: string, lookup: (override: Linter.ConfigOverride<Linter.RulesRecord>) => boolean, update
|
|
11
|
+
export declare function replaceOverride(content: string, root: string, lookup: (override: Linter.ConfigOverride<Linter.RulesRecord>) => boolean, update?: (override: Linter.ConfigOverride<Linter.RulesRecord>) => Linter.ConfigOverride<Linter.RulesRecord>): string;
|
|
12
12
|
/**
|
|
13
13
|
* Adding require statement to the top of the file
|
|
14
14
|
*/
|
|
@@ -44,7 +44,7 @@ export declare function generatePluginExtendsElement(plugins: string[]): ts.Spre
|
|
|
44
44
|
/**
|
|
45
45
|
* Stringifies TS nodes to file content string
|
|
46
46
|
*/
|
|
47
|
-
export declare function stringifyNodeList(nodes: ts.NodeArray<ts.VariableStatement | ts.Identifier | ts.ExpressionStatement | ts.SourceFile
|
|
47
|
+
export declare function stringifyNodeList(nodes: ts.NodeArray<ts.VariableStatement | ts.Identifier | ts.ExpressionStatement | ts.SourceFile>): string;
|
|
48
48
|
/**
|
|
49
49
|
* generates AST require statement
|
|
50
50
|
*/
|
|
@@ -52,9 +52,8 @@ export declare function generateRequire(variableName: string | ts.ObjectBindingP
|
|
|
52
52
|
/**
|
|
53
53
|
* Generates AST object or spread element based on JSON override object
|
|
54
54
|
*/
|
|
55
|
-
export declare function generateFlatOverride(override: Linter.ConfigOverride<Linter.RulesRecord
|
|
56
|
-
export declare function mapFilePaths(override: Linter.ConfigOverride<Linter.RulesRecord
|
|
57
|
-
export declare function mapFilePath(filePath: string, root: string): string;
|
|
55
|
+
export declare function generateFlatOverride(override: Linter.ConfigOverride<Linter.RulesRecord>): ts.ObjectLiteralExpression | ts.SpreadElement;
|
|
56
|
+
export declare function mapFilePaths(override: Linter.ConfigOverride<Linter.RulesRecord>): void;
|
|
58
57
|
/**
|
|
59
58
|
* Generates an AST from a JSON-type input
|
|
60
59
|
*/
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateAst = exports.
|
|
3
|
+
exports.generateAst = exports.mapFilePaths = exports.generateFlatOverride = exports.generateRequire = exports.stringifyNodeList = exports.generatePluginExtendsElement = exports.generateSpreadElement = exports.createNodeList = exports.addCompatToFlatConfig = exports.addPluginsToExportsBlock = exports.removeCompatExtends = exports.removePlugin = exports.addBlockToFlatConfigExport = exports.addImportToFlatConfig = exports.replaceOverride = exports.hasOverride = exports.removeOverridesFromLintConfig = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const ts = require("typescript");
|
|
6
|
+
const path_utils_1 = require("./path-utils");
|
|
6
7
|
/**
|
|
7
8
|
* Remove all overrides from the config file
|
|
8
9
|
*/
|
|
@@ -63,7 +64,7 @@ function hasOverride(content, lookup) {
|
|
|
63
64
|
// strip any spread elements
|
|
64
65
|
objSource = fullNodeText.replace(/\s*\.\.\.[a-zA-Z0-9_]+,?\n?/, '');
|
|
65
66
|
}
|
|
66
|
-
const data =
|
|
67
|
+
const data = (0, devkit_1.parseJson)(objSource
|
|
67
68
|
// ensure property names have double quotes so that JSON.parse works
|
|
68
69
|
.replace(/'/g, '"')
|
|
69
70
|
.replace(/\s([a-zA-Z0-9_]+)\s*:/g, ' "$1": '));
|
|
@@ -77,7 +78,7 @@ function hasOverride(content, lookup) {
|
|
|
77
78
|
exports.hasOverride = hasOverride;
|
|
78
79
|
const STRIP_SPREAD_ELEMENTS = /\s*\.\.\.[a-zA-Z0-9_]+,?\n?/g;
|
|
79
80
|
function parseTextToJson(text) {
|
|
80
|
-
return
|
|
81
|
+
return (0, devkit_1.parseJson)(text
|
|
81
82
|
// ensure property names have double quotes so that JSON.parse works
|
|
82
83
|
.replace(/'/g, '"')
|
|
83
84
|
.replace(/\s([a-zA-Z0-9_]+)\s*:/g, ' "$1": '));
|
|
@@ -118,12 +119,14 @@ function replaceOverride(content, root, lookup, update) {
|
|
|
118
119
|
length: end - start,
|
|
119
120
|
});
|
|
120
121
|
const updatedData = update(data);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
if (updatedData) {
|
|
123
|
+
mapFilePaths(updatedData);
|
|
124
|
+
changes.push({
|
|
125
|
+
type: devkit_1.ChangeType.Insert,
|
|
126
|
+
index: start,
|
|
127
|
+
text: JSON.stringify(updatedData, null, 2).slice(2, -2), // remove curly braces and start/end line breaks since we are injecting just properties
|
|
128
|
+
});
|
|
129
|
+
}
|
|
127
130
|
}
|
|
128
131
|
}
|
|
129
132
|
});
|
|
@@ -470,10 +473,15 @@ exports.generatePluginExtendsElement = generatePluginExtendsElement;
|
|
|
470
473
|
/**
|
|
471
474
|
* Stringifies TS nodes to file content string
|
|
472
475
|
*/
|
|
473
|
-
function stringifyNodeList(nodes
|
|
476
|
+
function stringifyNodeList(nodes) {
|
|
474
477
|
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
475
|
-
const resultFile = ts.createSourceFile(
|
|
476
|
-
return printer
|
|
478
|
+
const resultFile = ts.createSourceFile('', '', ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
|
479
|
+
return (printer
|
|
480
|
+
.printList(ts.ListFormat.MultiLine, nodes, resultFile)
|
|
481
|
+
// add new line before compat initialization
|
|
482
|
+
.replace(/const compat = new FlatCompat/, '\nconst compat = new FlatCompat')
|
|
483
|
+
// add new line before module.exports = ...
|
|
484
|
+
.replace(/module\.exports/, '\nmodule.exports'));
|
|
477
485
|
}
|
|
478
486
|
exports.stringifyNodeList = stringifyNodeList;
|
|
479
487
|
/**
|
|
@@ -488,21 +496,30 @@ exports.generateRequire = generateRequire;
|
|
|
488
496
|
/**
|
|
489
497
|
* Generates AST object or spread element based on JSON override object
|
|
490
498
|
*/
|
|
491
|
-
function generateFlatOverride(override
|
|
492
|
-
mapFilePaths(override
|
|
499
|
+
function generateFlatOverride(override) {
|
|
500
|
+
mapFilePaths(override);
|
|
493
501
|
if (!override.env &&
|
|
494
502
|
!override.extends &&
|
|
495
503
|
!override.plugins &&
|
|
496
504
|
!override.parser) {
|
|
505
|
+
if (override.parserOptions) {
|
|
506
|
+
const { parserOptions, ...rest } = override;
|
|
507
|
+
return generateAst({ ...rest, languageSettings: { parserOptions } });
|
|
508
|
+
}
|
|
497
509
|
return generateAst(override);
|
|
498
510
|
}
|
|
499
|
-
const { files, excludedFiles, rules, ...rest } = override;
|
|
511
|
+
const { files, excludedFiles, rules, parserOptions, ...rest } = override;
|
|
500
512
|
const objectLiteralElements = [
|
|
501
513
|
ts.factory.createSpreadAssignment(ts.factory.createIdentifier('config')),
|
|
502
514
|
];
|
|
503
515
|
addTSObjectProperty(objectLiteralElements, 'files', files);
|
|
504
516
|
addTSObjectProperty(objectLiteralElements, 'excludedFiles', excludedFiles);
|
|
505
517
|
addTSObjectProperty(objectLiteralElements, 'rules', rules);
|
|
518
|
+
if (parserOptions) {
|
|
519
|
+
addTSObjectProperty(objectLiteralElements, 'languageSettings', {
|
|
520
|
+
parserOptions,
|
|
521
|
+
});
|
|
522
|
+
}
|
|
506
523
|
return ts.factory.createSpreadElement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('compat'), ts.factory.createIdentifier('config')), undefined, [generateAst(rest)]), ts.factory.createIdentifier('map')), undefined, [
|
|
507
524
|
ts.factory.createArrowFunction(undefined, undefined, [
|
|
508
525
|
ts.factory.createParameterDeclaration(undefined, undefined, 'config'),
|
|
@@ -510,41 +527,21 @@ function generateFlatOverride(override, root) {
|
|
|
510
527
|
]));
|
|
511
528
|
}
|
|
512
529
|
exports.generateFlatOverride = generateFlatOverride;
|
|
513
|
-
function mapFilePaths(override
|
|
530
|
+
function mapFilePaths(override) {
|
|
514
531
|
if (override.files) {
|
|
515
532
|
override.files = Array.isArray(override.files)
|
|
516
533
|
? override.files
|
|
517
534
|
: [override.files];
|
|
518
|
-
override.files = override.files.map((file) =>
|
|
535
|
+
override.files = override.files.map((file) => (0, path_utils_1.mapFilePath)(file));
|
|
519
536
|
}
|
|
520
537
|
if (override.excludedFiles) {
|
|
521
538
|
override.excludedFiles = Array.isArray(override.excludedFiles)
|
|
522
539
|
? override.excludedFiles
|
|
523
540
|
: [override.excludedFiles];
|
|
524
|
-
override.excludedFiles = override.excludedFiles.map((file) =>
|
|
541
|
+
override.excludedFiles = override.excludedFiles.map((file) => (0, path_utils_1.mapFilePath)(file));
|
|
525
542
|
}
|
|
526
543
|
}
|
|
527
544
|
exports.mapFilePaths = mapFilePaths;
|
|
528
|
-
function mapFilePath(filePath, root) {
|
|
529
|
-
if (filePath.startsWith('!')) {
|
|
530
|
-
const fileWithoutBang = filePath.slice(1);
|
|
531
|
-
if (fileWithoutBang.startsWith('*.')) {
|
|
532
|
-
return `!${(0, devkit_1.joinPathFragments)(root, '**', fileWithoutBang)}`;
|
|
533
|
-
}
|
|
534
|
-
else if (!fileWithoutBang.startsWith(root)) {
|
|
535
|
-
return `!${(0, devkit_1.joinPathFragments)(root, fileWithoutBang)}`;
|
|
536
|
-
}
|
|
537
|
-
return filePath;
|
|
538
|
-
}
|
|
539
|
-
if (filePath.startsWith('*.')) {
|
|
540
|
-
return (0, devkit_1.joinPathFragments)(root, '**', filePath);
|
|
541
|
-
}
|
|
542
|
-
else if (!filePath.startsWith(root)) {
|
|
543
|
-
return (0, devkit_1.joinPathFragments)(root, filePath);
|
|
544
|
-
}
|
|
545
|
-
return filePath;
|
|
546
|
-
}
|
|
547
|
-
exports.mapFilePath = mapFilePath;
|
|
548
545
|
function addTSObjectProperty(elements, key, value) {
|
|
549
546
|
if (value) {
|
|
550
547
|
elements.push(ts.factory.createPropertyAssignment(key, generateAst(value)));
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { Linter } from 'eslint';
|
|
2
|
-
export declare function updateFiles(override: Linter.ConfigOverride<Linter.RulesRecord
|
|
2
|
+
export declare function updateFiles(override: Linter.ConfigOverride<Linter.RulesRecord>): Linter.ConfigOverride<Linter.RulesRecord>;
|
|
3
|
+
export declare function mapFilePath(filePath: string): string;
|
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.updateFiles = void 0;
|
|
3
|
+
exports.mapFilePath = exports.updateFiles = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
function updateFiles(override
|
|
5
|
+
function updateFiles(override) {
|
|
6
6
|
if (override.files) {
|
|
7
7
|
override.files = Array.isArray(override.files)
|
|
8
8
|
? override.files
|
|
9
9
|
: [override.files];
|
|
10
|
-
override.files = override.files.map((file) => mapFilePath(file
|
|
10
|
+
override.files = override.files.map((file) => mapFilePath(file));
|
|
11
11
|
}
|
|
12
12
|
return override;
|
|
13
13
|
}
|
|
14
14
|
exports.updateFiles = updateFiles;
|
|
15
|
-
function mapFilePath(filePath
|
|
15
|
+
function mapFilePath(filePath) {
|
|
16
16
|
if (filePath.startsWith('!')) {
|
|
17
17
|
const fileWithoutBang = filePath.slice(1);
|
|
18
18
|
if (fileWithoutBang.startsWith('*.')) {
|
|
19
|
-
return `!${(0, devkit_1.joinPathFragments)(
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
return `!${(0, devkit_1.joinPathFragments)(root, fileWithoutBang)}`;
|
|
19
|
+
return `!${(0, devkit_1.joinPathFragments)('**', fileWithoutBang)}`;
|
|
23
20
|
}
|
|
21
|
+
return filePath;
|
|
24
22
|
}
|
|
25
23
|
if (filePath.startsWith('*.')) {
|
|
26
|
-
return (0, devkit_1.joinPathFragments)(
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
return (0, devkit_1.joinPathFragments)(root, filePath);
|
|
24
|
+
return (0, devkit_1.joinPathFragments)('**', filePath);
|
|
30
25
|
}
|
|
26
|
+
return filePath;
|
|
31
27
|
}
|
|
28
|
+
exports.mapFilePath = mapFilePath;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasEslintPlugin = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
function hasEslintPlugin(tree) {
|
|
6
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
7
|
+
return nxJson.plugins?.some((p) => typeof p === 'string'
|
|
8
|
+
? p === '@nx/eslint/plugin'
|
|
9
|
+
: p.plugin === '@nx/eslint/plugin');
|
|
10
|
+
}
|
|
11
|
+
exports.hasEslintPlugin = hasEslintPlugin;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
18
18
|
|
|
19
|
-
// NOTE: The rule will be available in ESLint configs as "@nx/workspace
|
|
19
|
+
// NOTE: The rule will be available in ESLint configs as "@nx/workspace-<%= name %>"
|
|
20
20
|
export const RULE_NAME = '<%= name %>';
|
|
21
21
|
|
|
22
22
|
export const rule = ESLintUtils.RuleCreator(() => __filename)({
|
|
@@ -25,7 +25,7 @@ export const rule = ESLintUtils.RuleCreator(() => __filename)({
|
|
|
25
25
|
type: 'problem',
|
|
26
26
|
docs: {
|
|
27
27
|
description: ``,
|
|
28
|
-
recommended: '
|
|
28
|
+
recommended: 'recommended',
|
|
29
29
|
},
|
|
30
30
|
schema: [],
|
|
31
31
|
messages: {},
|