@nx/eslint 0.0.0-pr-22179-271588f → 0.0.0-pr-26515-856ef7f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/generators.json +5 -0
- package/migrations.json +17 -12
- package/package.json +12 -10
- package/plugin.d.ts +1 -1
- package/plugin.js +2 -1
- package/src/executors/lint/lint.impl.d.ts +1 -1
- package/src/executors/lint/lint.impl.js +23 -18
- package/src/executors/lint/utility/eslint-utils.js +4 -17
- package/src/generators/convert-to-flat-config/generator.d.ts +2 -2
- package/src/generators/convert-to-flat-config/generator.js +8 -2
- package/src/generators/convert-to-inferred/convert-to-inferred.d.ts +7 -0
- package/src/generators/convert-to-inferred/convert-to-inferred.js +80 -0
- package/src/generators/convert-to-inferred/lib/target-options-map.d.ts +16 -0
- package/src/generators/convert-to-inferred/lib/target-options-map.js +19 -0
- package/src/generators/convert-to-inferred/schema.json +19 -0
- package/src/generators/init/init-migration.js +4 -0
- package/src/generators/init/init.d.ts +1 -1
- package/src/generators/init/init.js +16 -27
- package/src/generators/lint-project/lint-project.d.ts +2 -1
- package/src/generators/lint-project/lint-project.js +16 -20
- package/src/generators/utils/eslint-file.js +4 -2
- package/src/generators/utils/flat-config/ast-utils.js +31 -7
- package/src/plugins/plugin.d.ts +3 -1
- package/src/plugins/plugin.js +162 -55
- package/src/utils/config-file.d.ts +4 -1
- package/src/utils/config-file.js +50 -16
- package/src/utils/resolve-eslint-class.d.ts +2 -0
- package/src/utils/resolve-eslint-class.js +23 -0
- package/src/utils/versions.d.ts +2 -2
- package/src/utils/versions.js +2 -2
- package/src/migrations/update-15-0-0/add-eslint-inputs.d.ts +0 -2
- package/src/migrations/update-15-0-0/add-eslint-inputs.js +0 -27
- package/src/migrations/update-15-7-1/add-eslint-ignore.d.ts +0 -2
- package/src/migrations/update-15-7-1/add-eslint-ignore.js +0 -36
package/LICENSE
CHANGED
package/generators.json
CHANGED
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"factory": "./src/generators/convert-to-flat-config/generator",
|
|
24
24
|
"schema": "./src/generators/convert-to-flat-config/schema.json",
|
|
25
25
|
"description": "Convert an Nx workspace's ESLint configs to use Flat Config."
|
|
26
|
+
},
|
|
27
|
+
"convert-to-inferred": {
|
|
28
|
+
"factory": "./src/generators/convert-to-inferred/convert-to-inferred",
|
|
29
|
+
"schema": "./src/generators/convert-to-inferred/schema.json",
|
|
30
|
+
"description": "Convert existing ESLint project(s) using `@nx/eslint:lint` executor to use `@nx/eslint/plugin`."
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
}
|
package/migrations.json
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generators": {
|
|
3
|
-
"add-eslint-inputs": {
|
|
4
|
-
"cli": "nx",
|
|
5
|
-
"version": "15.0.0-beta.0",
|
|
6
|
-
"description": "Stop hashing eslint config files for build targets and dependent tasks",
|
|
7
|
-
"factory": "./src/migrations/update-15-0-0/add-eslint-inputs"
|
|
8
|
-
},
|
|
9
|
-
"add-eslint-ignore": {
|
|
10
|
-
"cli": "nx",
|
|
11
|
-
"version": "15.7.1-beta.0",
|
|
12
|
-
"description": "Add node_modules to root eslint ignore",
|
|
13
|
-
"factory": "./src/migrations/update-15-7-1/add-eslint-ignore"
|
|
14
|
-
},
|
|
15
3
|
"update-16-0-0-add-nx-packages": {
|
|
16
4
|
"cli": "nx",
|
|
17
5
|
"version": "16.0.0-beta.1",
|
|
@@ -133,6 +121,23 @@
|
|
|
133
121
|
"version": "^6.13.2"
|
|
134
122
|
}
|
|
135
123
|
}
|
|
124
|
+
},
|
|
125
|
+
"18.2.0": {
|
|
126
|
+
"version": "18.2.0-beta.0",
|
|
127
|
+
"packages": {
|
|
128
|
+
"@typescript-eslint/parser": {
|
|
129
|
+
"version": "^7.3.0"
|
|
130
|
+
},
|
|
131
|
+
"@typescript-eslint/eslint-plugin": {
|
|
132
|
+
"version": "^7.3.0"
|
|
133
|
+
},
|
|
134
|
+
"@typescript-eslint/utils": {
|
|
135
|
+
"version": "^7.3.0"
|
|
136
|
+
},
|
|
137
|
+
"eslint": {
|
|
138
|
+
"version": "~8.57.0"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/eslint",
|
|
3
|
-
"version": "0.0.0-pr-
|
|
3
|
+
"version": "0.0.0-pr-26515-856ef7f",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The ESLint plugin for Nx contains executors, generators and utilities used for linting JavaScript/TypeScript projects within an Nx workspace.",
|
|
6
6
|
"repository": {
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"Web",
|
|
14
14
|
"Lint",
|
|
15
15
|
"ESLint",
|
|
16
|
-
"CLI"
|
|
16
|
+
"CLI",
|
|
17
|
+
"Testing"
|
|
17
18
|
],
|
|
18
|
-
"main": "./index
|
|
19
|
+
"main": "./index",
|
|
19
20
|
"typings": "./index.d.ts",
|
|
20
21
|
"author": "Victor Savkin",
|
|
21
22
|
"license": "MIT",
|
|
@@ -30,18 +31,19 @@
|
|
|
30
31
|
"generators": "./generators.json",
|
|
31
32
|
"executors": "./executors.json",
|
|
32
33
|
"peerDependencies": {
|
|
33
|
-
"js-yaml": "
|
|
34
|
+
"@zkochan/js-yaml": "0.0.7",
|
|
35
|
+
"eslint": "^8.0.0 || ^9.0.0"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@nx/devkit": "0.0.0-pr-
|
|
37
|
-
"@nx/js": "0.0.0-pr-
|
|
38
|
-
"
|
|
38
|
+
"@nx/devkit": "0.0.0-pr-26515-856ef7f",
|
|
39
|
+
"@nx/js": "0.0.0-pr-26515-856ef7f",
|
|
40
|
+
"semver": "^7.5.3",
|
|
39
41
|
"tslib": "^2.3.0",
|
|
40
|
-
"typescript": "~5.
|
|
41
|
-
"@nx/linter": "0.0.0-pr-
|
|
42
|
+
"typescript": "~5.4.2",
|
|
43
|
+
"@nx/linter": "0.0.0-pr-26515-856ef7f"
|
|
42
44
|
},
|
|
43
45
|
"peerDependenciesMeta": {
|
|
44
|
-
"js-yaml": {
|
|
46
|
+
"@zkochan/js-yaml": {
|
|
45
47
|
"optional": true
|
|
46
48
|
}
|
|
47
49
|
},
|
package/plugin.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { createNodes, EslintPluginOptions } from './src/plugins/plugin';
|
|
1
|
+
export { createNodes, createNodesV2, EslintPluginOptions, } from './src/plugins/plugin';
|
package/plugin.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createNodes = void 0;
|
|
3
|
+
exports.createNodesV2 = exports.createNodes = void 0;
|
|
4
4
|
var plugin_1 = require("./src/plugins/plugin");
|
|
5
5
|
Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return plugin_1.createNodes; } });
|
|
6
|
+
Object.defineProperty(exports, "createNodesV2", { enumerable: true, get: function () { return plugin_1.createNodesV2; } });
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const devkit_1 = require("@nx/devkit");
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
|
+
const utils_1 = require("nx/src/tasks-runner/utils");
|
|
5
6
|
const path_1 = require("path");
|
|
7
|
+
const config_file_1 = require("../../utils/config-file");
|
|
6
8
|
const eslint_utils_1 = require("./utility/eslint-utils");
|
|
7
|
-
const utils_1 = require("nx/src/tasks-runner/utils");
|
|
8
9
|
async function run(options, context) {
|
|
9
10
|
// this is only used for the hasher
|
|
10
11
|
delete options.hasTypeAwareRules;
|
|
@@ -23,19 +24,14 @@ async function run(options, context) {
|
|
|
23
24
|
? (0, devkit_1.joinPathFragments)(options.cacheLocation, projectName)
|
|
24
25
|
: undefined;
|
|
25
26
|
const { printConfig, errorOnUnmatchedPattern, ...normalizedOptions } = options;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* their root ESLint config to use eslint.config.js
|
|
30
|
-
*/
|
|
31
|
-
const hasFlatConfig = (0, fs_1.existsSync)((0, devkit_1.joinPathFragments)(devkit_1.workspaceRoot, 'eslint.config.js'));
|
|
27
|
+
// locate the flat config file if it exists starting from the project root
|
|
28
|
+
const flatConfigFilePath = (0, config_file_1.findFlatConfigFile)(projectRoot, context.root);
|
|
29
|
+
const hasFlatConfig = flatConfigFilePath !== null;
|
|
32
30
|
// while standard eslint uses by default closest config to the file, if otherwise not specified,
|
|
33
|
-
// the flat config would
|
|
31
|
+
// the flat config would be resolved starting from the cwd, which we changed to the workspace root
|
|
32
|
+
// so we explicitly set the config path to the flat config file path we previously found
|
|
34
33
|
if (hasFlatConfig && !normalizedOptions.eslintConfig) {
|
|
35
|
-
|
|
36
|
-
if ((0, fs_1.existsSync)(eslintConfigPath)) {
|
|
37
|
-
normalizedOptions.eslintConfig = eslintConfigPath;
|
|
38
|
-
}
|
|
34
|
+
normalizedOptions.eslintConfig = path_1.posix.relative(systemRoot, flatConfigFilePath);
|
|
39
35
|
}
|
|
40
36
|
/**
|
|
41
37
|
* We want users to have the option of not specifying the config path, and let
|
|
@@ -81,15 +77,24 @@ async function run(options, context) {
|
|
|
81
77
|
catch (err) {
|
|
82
78
|
if (err.message.includes('You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser')) {
|
|
83
79
|
const ruleName = err.message.match(/rule '([^']+)':/)?.[1];
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
eslintConfigPathForError =
|
|
80
|
+
const reportedFile = err.message.match(/Occurred while linting (.+)$/)?.[1];
|
|
81
|
+
let eslintConfigPathForError = `for the project "${projectName}"`;
|
|
82
|
+
if (eslintConfigPath) {
|
|
83
|
+
eslintConfigPathForError = `"${path_1.posix.relative(context.root, eslintConfigPath)}"`;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const configPathForfile = hasFlatConfig
|
|
87
|
+
? (0, config_file_1.findFlatConfigFile)(projectRoot, context.root)
|
|
88
|
+
: (0, config_file_1.findOldConfigFile)(reportedFile ?? projectRoot, context.root);
|
|
89
|
+
if (configPathForfile) {
|
|
90
|
+
eslintConfigPathForError = `"${path_1.posix.relative(context.root, configPathForfile)}"`;
|
|
91
|
+
}
|
|
88
92
|
}
|
|
89
93
|
console.error(`
|
|
90
|
-
Error: You have attempted to use ${ruleName ? `the lint rule ${ruleName}` : 'a lint rule'} which requires the full TypeScript type-checker to be available, but you do not have
|
|
94
|
+
Error: You have attempted to use ${ruleName ? `the lint rule "${ruleName}"` : 'a lint rule'} which requires the full TypeScript type-checker to be available, but you do not have "parserOptions.project" configured to point at your project tsconfig.json files in the relevant TypeScript file "overrides" block of your ESLint config ${eslintConfigPathForError}
|
|
95
|
+
${reportedFile ? `Occurred while linting ${reportedFile}` : ''}
|
|
91
96
|
|
|
92
|
-
Please see https://nx.dev/
|
|
97
|
+
Please see https://nx.dev/recipes/tips-n-tricks/eslint for full guidance on how to resolve this issue.
|
|
93
98
|
`);
|
|
94
99
|
return {
|
|
95
100
|
success: false,
|
|
@@ -1,26 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resolveAndInstantiateESLint = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (!useFlatConfig) {
|
|
7
|
-
return (await Promise.resolve().then(() => require('eslint'))).ESLint;
|
|
8
|
-
}
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
10
|
-
const { FlatESLint } = require('eslint/use-at-your-own-risk');
|
|
11
|
-
return FlatESLint;
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
throw new Error('Unable to find ESLint. Ensure ESLint is installed.');
|
|
15
|
-
}
|
|
16
|
-
}
|
|
4
|
+
const config_file_1 = require("../../../utils/config-file");
|
|
5
|
+
const resolve_eslint_class_1 = require("../../../utils/resolve-eslint-class");
|
|
17
6
|
async function resolveAndInstantiateESLint(eslintConfigPath, options, useFlatConfig = false) {
|
|
18
|
-
if (useFlatConfig &&
|
|
19
|
-
eslintConfigPath &&
|
|
20
|
-
!eslintConfigPath?.endsWith('eslint.config.js')) {
|
|
7
|
+
if (useFlatConfig && eslintConfigPath && !(0, config_file_1.isFlatConfig)(eslintConfigPath)) {
|
|
21
8
|
throw new Error('When using the new Flat Config with ESLint, all configs must be named eslint.config.js and .eslintrc files may not be used. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
|
|
22
9
|
}
|
|
23
|
-
const ESLint = await resolveESLintClass(useFlatConfig);
|
|
10
|
+
const ESLint = await (0, resolve_eslint_class_1.resolveESLintClass)(useFlatConfig);
|
|
24
11
|
const eslintOptions = {
|
|
25
12
|
overrideConfigFile: eslintConfigPath,
|
|
26
13
|
fix: !!options.fix,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tree } from '@nx/devkit';
|
|
1
|
+
import { GeneratorCallback, Tree } from '@nx/devkit';
|
|
2
2
|
import { ConvertToFlatConfigGeneratorSchema } from './schema';
|
|
3
|
-
export declare function convertToFlatConfigGenerator(tree: Tree, options: ConvertToFlatConfigGeneratorSchema): Promise<void>;
|
|
3
|
+
export declare function convertToFlatConfigGenerator(tree: Tree, options: ConvertToFlatConfigGeneratorSchema): Promise<void | GeneratorCallback>;
|
|
4
4
|
export default convertToFlatConfigGenerator;
|
|
@@ -6,7 +6,7 @@ const eslint_file_1 = require("../utils/eslint-file");
|
|
|
6
6
|
const path_1 = require("path");
|
|
7
7
|
const versions_1 = require("../../utils/versions");
|
|
8
8
|
const json_converter_1 = require("./converters/json-converter");
|
|
9
|
-
|
|
9
|
+
let shouldInstallDeps = false;
|
|
10
10
|
async function convertToFlatConfigGenerator(tree, options) {
|
|
11
11
|
const eslintFile = (0, eslint_file_1.findEslintFile)(tree);
|
|
12
12
|
if (!eslintFile) {
|
|
@@ -33,6 +33,9 @@ async function convertToFlatConfigGenerator(tree, options) {
|
|
|
33
33
|
if (!options.skipFormat) {
|
|
34
34
|
await (0, devkit_1.formatFiles)(tree);
|
|
35
35
|
}
|
|
36
|
+
if (shouldInstallDeps) {
|
|
37
|
+
return () => (0, devkit_1.installPackagesTask)(tree);
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
exports.convertToFlatConfigGenerator = convertToFlatConfigGenerator;
|
|
38
41
|
exports.default = convertToFlatConfigGenerator;
|
|
@@ -112,7 +115,8 @@ function convertConfigToFlatConfig(tree, root, source, target, ignorePath) {
|
|
|
112
115
|
}
|
|
113
116
|
if (source.endsWith('.yaml') || source.endsWith('.yml')) {
|
|
114
117
|
const originalContent = tree.read(`${root}/${source}`, 'utf-8');
|
|
115
|
-
const
|
|
118
|
+
const { load } = require('@zkochan/js-yaml');
|
|
119
|
+
const config = load(originalContent, {
|
|
116
120
|
json: true,
|
|
117
121
|
filename: source,
|
|
118
122
|
});
|
|
@@ -127,11 +131,13 @@ function processConvertedConfig(tree, root, source, target, { content, addESLint
|
|
|
127
131
|
tree.write((0, path_1.join)(root, target), content);
|
|
128
132
|
// add missing packages
|
|
129
133
|
if (addESLintRC) {
|
|
134
|
+
shouldInstallDeps = true;
|
|
130
135
|
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
131
136
|
'@eslint/eslintrc': versions_1.eslintrcVersion,
|
|
132
137
|
});
|
|
133
138
|
}
|
|
134
139
|
if (addESLintJS) {
|
|
140
|
+
shouldInstallDeps = true;
|
|
135
141
|
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
136
142
|
'@eslint/js': versions_1.eslintVersion,
|
|
137
143
|
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertToInferred = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const plugin_1 = require("../../plugins/plugin");
|
|
6
|
+
const executor_to_plugin_migrator_1 = require("@nx/devkit/src/generators/plugin-migrations/executor-to-plugin-migrator");
|
|
7
|
+
const target_options_map_1 = require("./lib/target-options-map");
|
|
8
|
+
const utils_1 = require("nx/src/tasks-runner/utils");
|
|
9
|
+
async function convertToInferred(tree, options) {
|
|
10
|
+
const projectGraph = await (0, devkit_1.createProjectGraphAsync)();
|
|
11
|
+
const migratedProjectsModern = await (0, executor_to_plugin_migrator_1.migrateExecutorToPlugin)(tree, projectGraph, '@nx/eslint:lint', '@nx/eslint/plugin', (targetName) => ({ targetName }), postTargetTransformer, plugin_1.createNodesV2, options.project);
|
|
12
|
+
const migratedProjectsLegacy = await (0, executor_to_plugin_migrator_1.migrateExecutorToPlugin)(tree, projectGraph, '@nrwl/linter:eslint', '@nx/eslint/plugin', (targetName) => ({ targetName }), postTargetTransformer, plugin_1.createNodesV2, options.project);
|
|
13
|
+
const migratedProjects = migratedProjectsModern.size + migratedProjectsLegacy.size;
|
|
14
|
+
if (migratedProjects === 0) {
|
|
15
|
+
throw new Error('Could not find any targets to migrate.');
|
|
16
|
+
}
|
|
17
|
+
if (!options.skipFormat) {
|
|
18
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.convertToInferred = convertToInferred;
|
|
22
|
+
function postTargetTransformer(target, tree, projectDetails) {
|
|
23
|
+
if (target.inputs) {
|
|
24
|
+
const inputs = target.inputs.filter((input) => typeof input === 'string' &&
|
|
25
|
+
![
|
|
26
|
+
'default',
|
|
27
|
+
'{workspaceRoot}/.eslintrc.json',
|
|
28
|
+
'{workspaceRoot}/.eslintignore',
|
|
29
|
+
'{workspaceRoot}/eslint.config.js',
|
|
30
|
+
].includes(input));
|
|
31
|
+
if (inputs.length === 0) {
|
|
32
|
+
delete target.inputs;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (target.options) {
|
|
36
|
+
if ('eslintConfig' in target.options) {
|
|
37
|
+
delete target.options.eslintConfig;
|
|
38
|
+
}
|
|
39
|
+
if ('force' in target.options) {
|
|
40
|
+
delete target.options.force;
|
|
41
|
+
}
|
|
42
|
+
if ('silent' in target.options) {
|
|
43
|
+
delete target.options.silent;
|
|
44
|
+
}
|
|
45
|
+
if ('hasTypeAwareRules' in target.options) {
|
|
46
|
+
delete target.options.hasTypeAwareRules;
|
|
47
|
+
}
|
|
48
|
+
if ('errorOnUnmatchedPattern' in target.options) {
|
|
49
|
+
if (!target.options.errorOnUnmatchedPattern) {
|
|
50
|
+
target.options['no-error-on-unmatched-pattern'] = true;
|
|
51
|
+
}
|
|
52
|
+
delete target.options.errorOnUnmatchedPattern;
|
|
53
|
+
}
|
|
54
|
+
if ('outputFile' in target.options) {
|
|
55
|
+
target.outputs ??= [];
|
|
56
|
+
target.outputs.push(target.options.outputFile);
|
|
57
|
+
}
|
|
58
|
+
for (const key in target_options_map_1.targetOptionsToCliMap) {
|
|
59
|
+
if (target.options[key]) {
|
|
60
|
+
target.options[target_options_map_1.targetOptionsToCliMap[key]] = target.options[key];
|
|
61
|
+
delete target.options[key];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if ('lintFilePatterns' in target.options) {
|
|
65
|
+
const normalizedLintFilePatterns = target.options.lintFilePatterns.map((pattern) => {
|
|
66
|
+
return (0, utils_1.interpolate)(pattern, {
|
|
67
|
+
workspaceRoot: '',
|
|
68
|
+
projectRoot: projectDetails.root,
|
|
69
|
+
projectName: projectDetails.projectName,
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
target.options.args = normalizedLintFilePatterns.map((pattern) => pattern.startsWith(projectDetails.root)
|
|
73
|
+
? pattern.replace(new RegExp(`^${projectDetails.root}/`), './')
|
|
74
|
+
: pattern);
|
|
75
|
+
delete target.options.lintFilePatterns;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return target;
|
|
79
|
+
}
|
|
80
|
+
exports.default = convertToInferred;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const targetOptionsToCliMap: {
|
|
2
|
+
fix: string;
|
|
3
|
+
format: string;
|
|
4
|
+
cache: string;
|
|
5
|
+
cacheLocation: string;
|
|
6
|
+
cacheStrategy: string;
|
|
7
|
+
noEslintrc: string;
|
|
8
|
+
outputFile: string;
|
|
9
|
+
maxWarnings: string;
|
|
10
|
+
quiet: string;
|
|
11
|
+
ignorePath: string;
|
|
12
|
+
rulesdir: string;
|
|
13
|
+
resolvePluginsRelativeTo: string;
|
|
14
|
+
reportUnusedDisableDirectives: string;
|
|
15
|
+
printConfig: string;
|
|
16
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.targetOptionsToCliMap = void 0;
|
|
4
|
+
exports.targetOptionsToCliMap = {
|
|
5
|
+
fix: 'fix',
|
|
6
|
+
format: 'format',
|
|
7
|
+
cache: 'cache',
|
|
8
|
+
cacheLocation: 'cache-location',
|
|
9
|
+
cacheStrategy: 'cache-strategy',
|
|
10
|
+
noEslintrc: 'no-eslintrc',
|
|
11
|
+
outputFile: 'output-file',
|
|
12
|
+
maxWarnings: 'max-warnings',
|
|
13
|
+
quiet: 'quiet',
|
|
14
|
+
ignorePath: 'ignore-path',
|
|
15
|
+
rulesdir: 'rulesdir',
|
|
16
|
+
resolvePluginsRelativeTo: 'resolve-plugins-relative-to',
|
|
17
|
+
reportUnusedDisableDirectives: 'report-unused-disable-directives',
|
|
18
|
+
printConfig: 'print-config',
|
|
19
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"$id": "NxEslintConvertToInferred",
|
|
4
|
+
"description": "Convert existing Eslint project(s) using `@nx/eslint:lint` executor to use `@nx/eslint/plugin`. Defaults to migrating all projects. Pass '--project' to migrate only one target.",
|
|
5
|
+
"title": "Convert Eslint project from executor to plugin",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"project": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "The project to convert from using the `@nx/eslint:lint` executor to use `@nx/eslint/plugin`.",
|
|
11
|
+
"x-priority": "important"
|
|
12
|
+
},
|
|
13
|
+
"skipFormat": {
|
|
14
|
+
"type": "boolean",
|
|
15
|
+
"description": "Whether to format files at the end of the migration.",
|
|
16
|
+
"default": false
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -104,6 +104,10 @@ function migrateEslintFile(projectEslintPath, tree) {
|
|
|
104
104
|
}
|
|
105
105
|
// add extends
|
|
106
106
|
json.extends = json.extends || [];
|
|
107
|
+
// ensure extends is an array
|
|
108
|
+
if (typeof json.extends === 'string') {
|
|
109
|
+
json.extends = [json.extends];
|
|
110
|
+
}
|
|
107
111
|
const pathToRootConfig = `${(0, devkit_1.offsetFromRoot)((0, path_1.dirname)(projectEslintPath))}${baseFile}`;
|
|
108
112
|
if (json.extends.indexOf(pathToRootConfig) === -1) {
|
|
109
113
|
json.extends.push(pathToRootConfig);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.lintInitGenerator = exports.initEsLint = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const
|
|
5
|
+
const add_plugin_1 = require("@nx/devkit/src/utils/add-plugin");
|
|
6
6
|
const versions_1 = require("../../utils/versions");
|
|
7
7
|
const eslint_file_1 = require("../utils/eslint-file");
|
|
8
8
|
const plugin_1 = require("../../plugins/plugin");
|
|
@@ -31,24 +31,6 @@ function addTargetDefaults(tree) {
|
|
|
31
31
|
];
|
|
32
32
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
33
33
|
}
|
|
34
|
-
function addPlugin(tree) {
|
|
35
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
36
|
-
nxJson.plugins ??= [];
|
|
37
|
-
for (const plugin of nxJson.plugins) {
|
|
38
|
-
if (typeof plugin === 'string'
|
|
39
|
-
? plugin === '@nx/eslint/plugin'
|
|
40
|
-
: plugin.plugin === '@nx/eslint/plugin') {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
nxJson.plugins.push({
|
|
45
|
-
plugin: '@nx/eslint/plugin',
|
|
46
|
-
options: {
|
|
47
|
-
targetName: 'lint',
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
51
|
-
}
|
|
52
34
|
async function initEsLint(tree, options) {
|
|
53
35
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
54
36
|
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
@@ -56,11 +38,19 @@ async function initEsLint(tree, options) {
|
|
|
56
38
|
options.addPlugin ??= addPluginDefault;
|
|
57
39
|
const hasPlugin = (0, plugin_2.hasEslintPlugin)(tree);
|
|
58
40
|
const rootEslintFile = (0, eslint_file_1.findEslintFile)(tree);
|
|
41
|
+
const graph = await (0, devkit_1.createProjectGraphAsync)();
|
|
42
|
+
const lintTargetNames = [
|
|
43
|
+
'lint',
|
|
44
|
+
'eslint:lint',
|
|
45
|
+
'eslint-lint',
|
|
46
|
+
'_lint',
|
|
47
|
+
'_eslint:lint',
|
|
48
|
+
'_eslint-lint',
|
|
49
|
+
];
|
|
59
50
|
if (rootEslintFile && options.addPlugin && !hasPlugin) {
|
|
60
|
-
addPlugin(tree
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
51
|
+
await (0, add_plugin_1.addPlugin)(tree, graph, '@nx/eslint/plugin', plugin_1.createNodesV2, {
|
|
52
|
+
targetName: lintTargetNames,
|
|
53
|
+
}, options.updatePackageScripts);
|
|
64
54
|
return () => { };
|
|
65
55
|
}
|
|
66
56
|
if (rootEslintFile) {
|
|
@@ -68,7 +58,9 @@ async function initEsLint(tree, options) {
|
|
|
68
58
|
}
|
|
69
59
|
updateProductionFileset(tree);
|
|
70
60
|
if (options.addPlugin) {
|
|
71
|
-
addPlugin(tree
|
|
61
|
+
await (0, add_plugin_1.addPlugin)(tree, graph, '@nx/eslint/plugin', plugin_1.createNodesV2, {
|
|
62
|
+
targetName: lintTargetNames,
|
|
63
|
+
}, options.updatePackageScripts);
|
|
72
64
|
}
|
|
73
65
|
else {
|
|
74
66
|
addTargetDefaults(tree);
|
|
@@ -81,9 +73,6 @@ async function initEsLint(tree, options) {
|
|
|
81
73
|
eslint: versions_1.eslintVersion,
|
|
82
74
|
}, undefined, options.keepExistingVersions));
|
|
83
75
|
}
|
|
84
|
-
if (options.updatePackageScripts) {
|
|
85
|
-
await (0, update_package_scripts_1.updatePackageScripts)(tree, plugin_1.createNodes);
|
|
86
|
-
}
|
|
87
76
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
88
77
|
}
|
|
89
78
|
exports.initEsLint = initEsLint;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { GeneratorCallback, Tree } from '@nx/devkit';
|
|
2
2
|
import { Linter as LinterEnum } from '../utils/linter';
|
|
3
3
|
interface LintProjectOptions {
|
|
4
4
|
project: string;
|
|
@@ -16,6 +16,7 @@ interface LintProjectOptions {
|
|
|
16
16
|
* @internal
|
|
17
17
|
*/
|
|
18
18
|
addExplicitTargets?: boolean;
|
|
19
|
+
addPackageJsonDependencyChecks?: boolean;
|
|
19
20
|
}
|
|
20
21
|
export declare function lintProjectGenerator(tree: Tree, options: LintProjectOptions): Promise<GeneratorCallback>;
|
|
21
22
|
export declare function lintProjectGeneratorInternal(tree: Tree, options: LintProjectOptions): Promise<GeneratorCallback>;
|
|
@@ -73,7 +73,8 @@ async function lintProjectGeneratorInternal(tree, options) {
|
|
|
73
73
|
if (!options.rootProject) {
|
|
74
74
|
const projects = {};
|
|
75
75
|
(0, project_configuration_1.getProjects)(tree).forEach((v, k) => (projects[k] = v));
|
|
76
|
-
|
|
76
|
+
const graph = await (0, devkit_1.createProjectGraphAsync)();
|
|
77
|
+
if (isMigrationToMonorepoNeeded(tree, graph)) {
|
|
77
78
|
// we only migrate project configurations that have been created
|
|
78
79
|
const filteredProjects = [];
|
|
79
80
|
Object.entries(projects).forEach(([name, project]) => {
|
|
@@ -88,7 +89,7 @@ async function lintProjectGeneratorInternal(tree, options) {
|
|
|
88
89
|
// additionally, the companion e2e app would have `rootProject: true`
|
|
89
90
|
// so we need to check for the root path as well
|
|
90
91
|
if (!options.rootProject || projectConfig.root !== '.') {
|
|
91
|
-
createEsLintConfiguration(tree, projectConfig, options.setParserOptionsProject, options.rootProject);
|
|
92
|
+
createEsLintConfiguration(tree, options, projectConfig, options.setParserOptionsProject, options.rootProject);
|
|
92
93
|
}
|
|
93
94
|
// Buildable libs need source analysis enabled for linting `package.json`.
|
|
94
95
|
if (isBuildableLibraryProject(projectConfig) &&
|
|
@@ -107,7 +108,7 @@ async function lintProjectGeneratorInternal(tree, options) {
|
|
|
107
108
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
108
109
|
}
|
|
109
110
|
exports.lintProjectGeneratorInternal = lintProjectGeneratorInternal;
|
|
110
|
-
function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject, rootProject) {
|
|
111
|
+
function createEsLintConfiguration(tree, options, projectConfig, setParserOptionsProject, rootProject) {
|
|
111
112
|
// we are only extending root for non-standalone projects or their complementary e2e apps
|
|
112
113
|
const extendedRootConfig = rootProject ? undefined : (0, eslint_file_1.findEslintFile)(tree);
|
|
113
114
|
const pathToRootConfig = extendedRootConfig
|
|
@@ -150,7 +151,8 @@ function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject,
|
|
|
150
151
|
rules: {},
|
|
151
152
|
},
|
|
152
153
|
];
|
|
153
|
-
if (
|
|
154
|
+
if (options.addPackageJsonDependencyChecks ||
|
|
155
|
+
isBuildableLibraryProject(projectConfig)) {
|
|
154
156
|
overrides.push({
|
|
155
157
|
files: ['*.json'],
|
|
156
158
|
parser: 'jsonc-eslint-parser',
|
|
@@ -198,30 +200,24 @@ function isBuildableLibraryProject(projectConfig) {
|
|
|
198
200
|
* Detect based on the state of lint target configuration of the root project
|
|
199
201
|
* if we should migrate eslint configs to monorepo style
|
|
200
202
|
*/
|
|
201
|
-
function isMigrationToMonorepoNeeded(
|
|
203
|
+
function isMigrationToMonorepoNeeded(tree, graph) {
|
|
202
204
|
// the base config is already created, migration has been done
|
|
203
205
|
if (tree.exists(config_file_1.baseEsLintConfigFile) ||
|
|
204
206
|
tree.exists(config_file_1.baseEsLintFlatConfigFile)) {
|
|
205
207
|
return false;
|
|
206
208
|
}
|
|
207
|
-
const
|
|
208
|
-
if (configs.length === 1) {
|
|
209
|
-
return false;
|
|
210
|
-
}
|
|
209
|
+
const nodes = Object.values(graph.nodes);
|
|
211
210
|
// get root project
|
|
212
|
-
const rootProject =
|
|
213
|
-
if (!rootProject || !rootProject.targets) {
|
|
211
|
+
const rootProject = nodes.find((p) => p.data.root === '.');
|
|
212
|
+
if (!rootProject || !rootProject.data.targets) {
|
|
214
213
|
return false;
|
|
215
214
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
215
|
+
for (const targetConfig of Object.values(rootProject.data.targets ?? {})) {
|
|
216
|
+
if (['@nx/eslint:lint', '@nrwl/linter:eslint', '@nx/linter:eslint'].includes(targetConfig.executor) ||
|
|
217
|
+
(targetConfig.executor === 'nx:run-commands' &&
|
|
218
|
+
targetConfig.options?.command.startsWith('eslint '))) {
|
|
219
|
+
return true;
|
|
222
220
|
}
|
|
223
221
|
}
|
|
224
|
-
|
|
225
|
-
const lintTarget = (0, init_migration_1.findLintTarget)(rootProject);
|
|
226
|
-
return !!lintTarget;
|
|
222
|
+
return false;
|
|
227
223
|
}
|
|
@@ -189,7 +189,7 @@ function replaceOverridesInLintConfig(tree, root, overrides) {
|
|
|
189
189
|
content = (0, ast_utils_1.removeOverridesFromLintConfig)(content);
|
|
190
190
|
overrides.forEach((override) => {
|
|
191
191
|
const flatOverride = (0, ast_utils_1.generateFlatOverride)(override);
|
|
192
|
-
(0, ast_utils_1.addBlockToFlatConfigExport)(content, flatOverride);
|
|
192
|
+
content = (0, ast_utils_1.addBlockToFlatConfigExport)(content, flatOverride);
|
|
193
193
|
});
|
|
194
194
|
tree.write(fileName, content);
|
|
195
195
|
}
|
|
@@ -209,7 +209,9 @@ function addExtendsToLintConfig(tree, root, plugin) {
|
|
|
209
209
|
const pluginExtends = (0, ast_utils_1.generatePluginExtendsElement)(plugins);
|
|
210
210
|
let content = tree.read(fileName, 'utf8');
|
|
211
211
|
content = (0, ast_utils_1.addCompatToFlatConfig)(content);
|
|
212
|
-
tree.write(fileName, (0, ast_utils_1.addBlockToFlatConfigExport)(content, pluginExtends
|
|
212
|
+
tree.write(fileName, (0, ast_utils_1.addBlockToFlatConfigExport)(content, pluginExtends, {
|
|
213
|
+
insertAtTheEnd: false,
|
|
214
|
+
}));
|
|
213
215
|
}
|
|
214
216
|
else {
|
|
215
217
|
const fileName = (0, devkit_1.joinPathFragments)(root, '.eslintrc.json');
|
|
@@ -4,6 +4,11 @@ exports.generateAst = exports.mapFilePaths = exports.generateFlatOverride = expo
|
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const ts = require("typescript");
|
|
6
6
|
const path_utils_1 = require("./path-utils");
|
|
7
|
+
/**
|
|
8
|
+
* Supports direct identifiers, and those nested within an object (of arbitrary depth)
|
|
9
|
+
* E.g. `...foo` and `...foo.bar.baz.qux` etc
|
|
10
|
+
*/
|
|
11
|
+
const SPREAD_ELEMENTS_REGEXP = /\s*\.\.\.[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*,?\n?/g;
|
|
7
12
|
/**
|
|
8
13
|
* Remove all overrides from the config file
|
|
9
14
|
*/
|
|
@@ -58,11 +63,13 @@ function hasOverride(content, lookup) {
|
|
|
58
63
|
let objSource;
|
|
59
64
|
if (ts.isObjectLiteralExpression(node)) {
|
|
60
65
|
objSource = node.getFullText();
|
|
66
|
+
// strip any spread elements
|
|
67
|
+
objSource = objSource.replace(SPREAD_ELEMENTS_REGEXP, '');
|
|
61
68
|
}
|
|
62
69
|
else {
|
|
63
70
|
const fullNodeText = node['expression'].arguments[0].body.expression.getFullText();
|
|
64
71
|
// strip any spread elements
|
|
65
|
-
objSource = fullNodeText.replace(
|
|
72
|
+
objSource = fullNodeText.replace(SPREAD_ELEMENTS_REGEXP, '');
|
|
66
73
|
}
|
|
67
74
|
const data = (0, devkit_1.parseJson)(objSource
|
|
68
75
|
// ensure property names have double quotes so that JSON.parse works
|
|
@@ -76,7 +83,6 @@ function hasOverride(content, lookup) {
|
|
|
76
83
|
return false;
|
|
77
84
|
}
|
|
78
85
|
exports.hasOverride = hasOverride;
|
|
79
|
-
const STRIP_SPREAD_ELEMENTS = /\s*\.\.\.[a-zA-Z0-9_]+,?\n?/g;
|
|
80
86
|
function parseTextToJson(text) {
|
|
81
87
|
return (0, devkit_1.parseJson)(text
|
|
82
88
|
// ensure property names have double quotes so that JSON.parse works
|
|
@@ -105,7 +111,7 @@ function replaceOverride(content, root, lookup, update) {
|
|
|
105
111
|
else {
|
|
106
112
|
const fullNodeText = node['expression'].arguments[0].body.expression.getFullText();
|
|
107
113
|
// strip any spread elements
|
|
108
|
-
objSource = fullNodeText.replace(
|
|
114
|
+
objSource = fullNodeText.replace(SPREAD_ELEMENTS_REGEXP, '');
|
|
109
115
|
start =
|
|
110
116
|
node['expression'].arguments[0].body.expression.properties.pos +
|
|
111
117
|
(fullNodeText.length - objSource.length);
|
|
@@ -283,7 +289,7 @@ function removePlugin(content, pluginName, pluginImport) {
|
|
|
283
289
|
const pluginsArray = pluginsElem.initializer;
|
|
284
290
|
const plugins = parseTextToJson(pluginsElem.initializer
|
|
285
291
|
.getText()
|
|
286
|
-
.replace(
|
|
292
|
+
.replace(SPREAD_ELEMENTS_REGEXP, ''));
|
|
287
293
|
if (plugins.length > 1) {
|
|
288
294
|
changes.push({
|
|
289
295
|
type: devkit_1.ChangeType.Delete,
|
|
@@ -419,7 +425,7 @@ function addCompatToFlatConfig(content) {
|
|
|
419
425
|
if (result.includes('const compat = new FlatCompat')) {
|
|
420
426
|
return result;
|
|
421
427
|
}
|
|
422
|
-
result = addImportToFlatConfig(result, 'FlatCompat', '@eslint/eslintrc');
|
|
428
|
+
result = addImportToFlatConfig(result, ['FlatCompat'], '@eslint/eslintrc');
|
|
423
429
|
const index = result.indexOf('module.exports');
|
|
424
430
|
return (0, devkit_1.applyChangesToString)(result, [
|
|
425
431
|
{
|
|
@@ -502,15 +508,33 @@ function generateFlatOverride(override) {
|
|
|
502
508
|
!override.extends &&
|
|
503
509
|
!override.plugins &&
|
|
504
510
|
!override.parser) {
|
|
511
|
+
if (override.parserOptions) {
|
|
512
|
+
const { parserOptions, ...rest } = override;
|
|
513
|
+
return generateAst({ ...rest, languageOptions: { parserOptions } });
|
|
514
|
+
}
|
|
505
515
|
return generateAst(override);
|
|
506
516
|
}
|
|
507
|
-
const { files, excludedFiles, rules, ...rest } = override;
|
|
517
|
+
const { files, excludedFiles, rules, parserOptions, ...rest } = override;
|
|
508
518
|
const objectLiteralElements = [
|
|
509
519
|
ts.factory.createSpreadAssignment(ts.factory.createIdentifier('config')),
|
|
510
520
|
];
|
|
511
521
|
addTSObjectProperty(objectLiteralElements, 'files', files);
|
|
512
522
|
addTSObjectProperty(objectLiteralElements, 'excludedFiles', excludedFiles);
|
|
513
|
-
|
|
523
|
+
// Apply rules (and spread ...config.rules into it as the first assignment)
|
|
524
|
+
addTSObjectProperty(objectLiteralElements, 'rules', rules || {});
|
|
525
|
+
const rulesObjectAST = objectLiteralElements.pop();
|
|
526
|
+
const rulesObjectInitializer = rulesObjectAST.initializer;
|
|
527
|
+
const spreadAssignment = ts.factory.createSpreadAssignment(ts.factory.createIdentifier('config.rules'));
|
|
528
|
+
const updatedRulesProperties = [
|
|
529
|
+
spreadAssignment,
|
|
530
|
+
...rulesObjectInitializer.properties,
|
|
531
|
+
];
|
|
532
|
+
objectLiteralElements.push(ts.factory.createPropertyAssignment('rules', ts.factory.createObjectLiteralExpression(updatedRulesProperties, true)));
|
|
533
|
+
if (parserOptions) {
|
|
534
|
+
addTSObjectProperty(objectLiteralElements, 'languageOptions', {
|
|
535
|
+
parserOptions,
|
|
536
|
+
});
|
|
537
|
+
}
|
|
514
538
|
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, [
|
|
515
539
|
ts.factory.createArrowFunction(undefined, undefined, [
|
|
516
540
|
ts.factory.createParameterDeclaration(undefined, undefined, 'config'),
|
package/src/plugins/plugin.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { CreateNodes } from '@nx/devkit';
|
|
1
|
+
import { CreateNodes, CreateNodesV2 } from '@nx/devkit';
|
|
2
2
|
export interface EslintPluginOptions {
|
|
3
3
|
targetName?: string;
|
|
4
|
+
extensions?: string[];
|
|
4
5
|
}
|
|
6
|
+
export declare const createNodesV2: CreateNodesV2<EslintPluginOptions>;
|
|
5
7
|
export declare const createNodes: CreateNodes<EslintPluginOptions>;
|
package/src/plugins/plugin.js
CHANGED
|
@@ -1,85 +1,169 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createNodes = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
3
|
+
exports.createNodes = exports.createNodesV2 = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
6
7
|
const globs_1 = require("nx/src/utils/globs");
|
|
8
|
+
const workspace_context_1 = require("nx/src/utils/workspace-context");
|
|
7
9
|
const config_file_1 = require("../utils/config-file");
|
|
10
|
+
const resolve_eslint_class_1 = require("../utils/resolve-eslint-class");
|
|
11
|
+
const semver_1 = require("semver");
|
|
12
|
+
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
13
|
+
const file_hasher_1 = require("nx/src/hasher/file-hasher");
|
|
14
|
+
const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
|
|
15
|
+
const DEFAULT_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx', 'html', 'vue'];
|
|
16
|
+
const ESLINT_CONFIG_GLOB = (0, globs_1.combineGlobPatterns)([
|
|
17
|
+
...config_file_1.ESLINT_CONFIG_FILENAMES.map((f) => `**/${f}`),
|
|
18
|
+
]);
|
|
19
|
+
function readTargetsCache(cachePath) {
|
|
20
|
+
return (0, node_fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {};
|
|
21
|
+
}
|
|
22
|
+
function writeTargetsToCache(cachePath, results) {
|
|
23
|
+
(0, devkit_1.writeJsonFile)(cachePath, results);
|
|
24
|
+
}
|
|
25
|
+
const internalCreateNodes = async (configFilePath, options, context, projectsCache) => {
|
|
26
|
+
options = normalizeOptions(options);
|
|
27
|
+
const configDir = (0, node_path_1.dirname)(configFilePath);
|
|
28
|
+
// Ensure that configFiles are set, e2e-run fails due to them being undefined in CI (does not occur locally)
|
|
29
|
+
// TODO(JamesHenry): Further troubleshoot this in CI
|
|
30
|
+
context.configFiles = context.configFiles ?? [];
|
|
31
|
+
// Create a Set of all the directories containing eslint configs, and a
|
|
32
|
+
// list of globs to exclude from child projects
|
|
33
|
+
const eslintRoots = new Set();
|
|
34
|
+
const nestedEslintRootPatterns = [];
|
|
35
|
+
for (const configFile of context.configFiles) {
|
|
36
|
+
const eslintRootDir = (0, node_path_1.dirname)(configFile);
|
|
37
|
+
eslintRoots.add(eslintRootDir);
|
|
38
|
+
if (eslintRootDir !== configDir && isSubDir(configDir, eslintRootDir)) {
|
|
39
|
+
nestedEslintRootPatterns.push(`${eslintRootDir}/**/*`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const projectFiles = await (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, ['project.json', 'package.json', '**/project.json', '**/package.json'].map((f) => (0, node_path_1.join)(configDir, f)), nestedEslintRootPatterns.length ? nestedEslintRootPatterns : undefined);
|
|
43
|
+
// dedupe and sort project roots by depth for more efficient traversal
|
|
44
|
+
const dedupedProjectRoots = Array.from(new Set(projectFiles.map((f) => (0, node_path_1.dirname)(f)))).sort((a, b) => (a !== b && isSubDir(a, b) ? -1 : 1));
|
|
45
|
+
const excludePatterns = dedupedProjectRoots.map((root) => `${root}/**/*`);
|
|
46
|
+
const ESLint = await (0, resolve_eslint_class_1.resolveESLintClass)((0, config_file_1.isFlatConfig)(configFilePath));
|
|
47
|
+
const eslintVersion = ESLint.version;
|
|
48
|
+
const childProjectRoots = new Set();
|
|
49
|
+
const projects = {};
|
|
50
|
+
await Promise.all(dedupedProjectRoots.map(async (childProjectRoot, index) => {
|
|
51
|
+
// anything after is either a nested project or a sibling project, can be excluded
|
|
52
|
+
const nestedProjectRootPatterns = excludePatterns.slice(index + 1);
|
|
53
|
+
// Ignore project roots where the project does not contain any lintable files
|
|
54
|
+
const lintableFiles = await (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, [(0, node_path_1.join)(childProjectRoot, `**/*.{${options.extensions.join(',')}}`)],
|
|
55
|
+
// exclude nested eslint roots and nested project roots
|
|
56
|
+
[...nestedEslintRootPatterns, ...nestedProjectRootPatterns]);
|
|
57
|
+
const parentConfigs = context.configFiles.filter((eslintConfig) => isSubDir(childProjectRoot, (0, node_path_1.dirname)(eslintConfig)));
|
|
58
|
+
const hash = await (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(childProjectRoot, options, context, [...parentConfigs, (0, node_path_1.join)(childProjectRoot, '.eslintignore')]);
|
|
59
|
+
if (projectsCache[hash]) {
|
|
60
|
+
// We can reuse the projects in the cache.
|
|
61
|
+
Object.assign(projects, projectsCache[hash]);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const eslint = new ESLint({
|
|
65
|
+
cwd: (0, node_path_1.join)(context.workspaceRoot, childProjectRoot),
|
|
66
|
+
});
|
|
67
|
+
for (const file of lintableFiles) {
|
|
68
|
+
if (!(await eslint.isPathIgnored((0, node_path_1.join)(context.workspaceRoot, file)))) {
|
|
69
|
+
childProjectRoots.add(childProjectRoot);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const uniqueChildProjectRoots = Array.from(childProjectRoots);
|
|
74
|
+
const projectsForRoot = getProjectsUsingESLintConfig(configFilePath, uniqueChildProjectRoots, eslintVersion, options, context);
|
|
75
|
+
if (Object.keys(projectsForRoot).length > 0) {
|
|
76
|
+
Object.assign(projects, projectsForRoot);
|
|
77
|
+
// Store those projects into the cache;
|
|
78
|
+
projectsCache[hash] = projectsForRoot;
|
|
79
|
+
}
|
|
80
|
+
}));
|
|
81
|
+
return {
|
|
82
|
+
projects,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
exports.createNodesV2 = [
|
|
86
|
+
ESLINT_CONFIG_GLOB,
|
|
87
|
+
async (configFiles, options, context) => {
|
|
88
|
+
const optionsHash = (0, file_hasher_1.hashObject)(options);
|
|
89
|
+
const cachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `eslint-${optionsHash}.hash`);
|
|
90
|
+
const targetsCache = readTargetsCache(cachePath);
|
|
91
|
+
try {
|
|
92
|
+
return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => internalCreateNodes(configFile, options, context, targetsCache), configFiles, options, context);
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
writeTargetsToCache(cachePath, targetsCache);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
];
|
|
8
99
|
exports.createNodes = [
|
|
9
|
-
|
|
100
|
+
ESLINT_CONFIG_GLOB,
|
|
10
101
|
(configFilePath, options, context) => {
|
|
11
|
-
|
|
12
|
-
options
|
|
13
|
-
const eslintConfigs = getEslintConfigsForProject(projectRoot, context.workspaceRoot);
|
|
14
|
-
if (!eslintConfigs.length) {
|
|
15
|
-
return {};
|
|
16
|
-
}
|
|
17
|
-
return {
|
|
18
|
-
projects: {
|
|
19
|
-
[projectRoot]: {
|
|
20
|
-
targets: buildEslintTargets(eslintConfigs, projectRoot, options),
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
102
|
+
devkit_1.logger.warn('`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.');
|
|
103
|
+
return internalCreateNodes(configFilePath, options, context, {});
|
|
24
104
|
},
|
|
25
105
|
];
|
|
26
|
-
function
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
106
|
+
function getProjectsUsingESLintConfig(configFilePath, childProjectRoots, eslintVersion, options, context) {
|
|
107
|
+
const projects = {};
|
|
108
|
+
const rootEslintConfig = [
|
|
109
|
+
config_file_1.baseEsLintConfigFile,
|
|
110
|
+
config_file_1.baseEsLintFlatConfigFile,
|
|
111
|
+
...config_file_1.ESLINT_CONFIG_FILENAMES,
|
|
112
|
+
].find((f) => (0, node_fs_1.existsSync)((0, node_path_1.join)(context.workspaceRoot, f)));
|
|
113
|
+
// Add a lint target for each child project without an eslint config, with the root level config as an input
|
|
114
|
+
for (const projectRoot of childProjectRoots) {
|
|
115
|
+
let standaloneSrcPath;
|
|
116
|
+
if (projectRoot === '.' &&
|
|
117
|
+
(0, node_fs_1.existsSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot, 'package.json'))) {
|
|
118
|
+
if ((0, node_fs_1.existsSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot, 'src'))) {
|
|
119
|
+
standaloneSrcPath = 'src';
|
|
120
|
+
}
|
|
121
|
+
else if ((0, node_fs_1.existsSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot, 'lib'))) {
|
|
122
|
+
standaloneSrcPath = 'lib';
|
|
123
|
+
}
|
|
37
124
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (!config) {
|
|
41
|
-
return [];
|
|
125
|
+
if (projectRoot === '.' && !standaloneSrcPath) {
|
|
126
|
+
continue;
|
|
42
127
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
while (projectRoot !== '.') {
|
|
47
|
-
// if it has an eslint config it's lintable
|
|
48
|
-
const config = siblingFiles.find((f) => config_file_1.ESLINT_CONFIG_FILENAMES.includes(f));
|
|
49
|
-
if (config) {
|
|
50
|
-
detectedConfigs.add(`${projectRoot}/${config}`);
|
|
51
|
-
return Array.from(detectedConfigs);
|
|
128
|
+
const eslintConfigs = [configFilePath];
|
|
129
|
+
if (rootEslintConfig && !eslintConfigs.includes(rootEslintConfig)) {
|
|
130
|
+
eslintConfigs.unshift(rootEslintConfig);
|
|
52
131
|
}
|
|
53
|
-
projectRoot =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// check whether the root has an eslint config
|
|
57
|
-
const config = (0, fs_1.readdirSync)(workspaceRoot).find((f) => config_file_1.ESLINT_CONFIG_FILENAMES.includes(f));
|
|
58
|
-
if (config) {
|
|
59
|
-
detectedConfigs.add(config);
|
|
60
|
-
return Array.from(detectedConfigs);
|
|
132
|
+
projects[projectRoot] = {
|
|
133
|
+
targets: buildEslintTargets(eslintConfigs, eslintVersion, projectRoot, context.workspaceRoot, options, standaloneSrcPath),
|
|
134
|
+
};
|
|
61
135
|
}
|
|
62
|
-
return
|
|
136
|
+
return projects;
|
|
63
137
|
}
|
|
64
|
-
function buildEslintTargets(eslintConfigs, projectRoot, options) {
|
|
138
|
+
function buildEslintTargets(eslintConfigs, eslintVersion, projectRoot, workspaceRoot, options, standaloneSrcPath) {
|
|
65
139
|
const isRootProject = projectRoot === '.';
|
|
66
140
|
const targets = {};
|
|
67
141
|
const targetConfig = {
|
|
68
|
-
command: `eslint ${isRootProject ?
|
|
142
|
+
command: `eslint ${isRootProject && standaloneSrcPath ? `./${standaloneSrcPath}` : '.'}`,
|
|
69
143
|
cache: true,
|
|
70
144
|
options: {
|
|
71
145
|
cwd: projectRoot,
|
|
72
146
|
},
|
|
73
147
|
inputs: [
|
|
74
148
|
'default',
|
|
75
|
-
|
|
149
|
+
// Certain lint rules can be impacted by changes to dependencies
|
|
150
|
+
'^default',
|
|
151
|
+
...eslintConfigs.map((config) => `{workspaceRoot}/${config}`.replace(`{workspaceRoot}/${projectRoot}`, isRootProject ? '{projectRoot}/' : '{projectRoot}')),
|
|
152
|
+
...((0, node_fs_1.existsSync)((0, node_path_1.join)(workspaceRoot, projectRoot, '.eslintignore'))
|
|
153
|
+
? ['{projectRoot}/.eslintignore']
|
|
154
|
+
: []),
|
|
76
155
|
'{workspaceRoot}/tools/eslint-rules/**/*',
|
|
77
156
|
{ externalDependencies: ['eslint'] },
|
|
78
157
|
],
|
|
158
|
+
outputs: ['{options.outputFile}'],
|
|
79
159
|
};
|
|
80
|
-
|
|
160
|
+
// Always set the environment variable to ensure that the ESLint CLI can run on eslint v8 and v9
|
|
161
|
+
const useFlatConfig = eslintConfigs.some((config) => (0, config_file_1.isFlatConfig)(config));
|
|
162
|
+
// Flat config is default for 9.0.0+
|
|
163
|
+
const defaultSetting = (0, semver_1.gte)(eslintVersion, '9.0.0');
|
|
164
|
+
if (useFlatConfig !== defaultSetting) {
|
|
81
165
|
targetConfig.options.env = {
|
|
82
|
-
ESLINT_USE_FLAT_CONFIG: 'true',
|
|
166
|
+
ESLINT_USE_FLAT_CONFIG: useFlatConfig ? 'true' : 'false',
|
|
83
167
|
};
|
|
84
168
|
}
|
|
85
169
|
targets[options.targetName] = targetConfig;
|
|
@@ -88,5 +172,28 @@ function buildEslintTargets(eslintConfigs, projectRoot, options) {
|
|
|
88
172
|
function normalizeOptions(options) {
|
|
89
173
|
options ??= {};
|
|
90
174
|
options.targetName ??= 'lint';
|
|
175
|
+
// Normalize user input for extensions (strip leading . characters)
|
|
176
|
+
if (Array.isArray(options.extensions)) {
|
|
177
|
+
options.extensions = options.extensions.map((f) => f.replace(/^\.+/, ''));
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
options.extensions = DEFAULT_EXTENSIONS;
|
|
181
|
+
}
|
|
91
182
|
return options;
|
|
92
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Determines if `child` is a subdirectory of `parent`. This is a simplified
|
|
186
|
+
* version that takes into account that paths are always relative to the
|
|
187
|
+
* workspace root.
|
|
188
|
+
*/
|
|
189
|
+
function isSubDir(parent, child) {
|
|
190
|
+
if (parent === '.') {
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
parent = (0, node_path_1.normalize)(parent);
|
|
194
|
+
child = (0, node_path_1.normalize)(child);
|
|
195
|
+
if (!parent.endsWith(node_path_1.sep)) {
|
|
196
|
+
parent += node_path_1.sep;
|
|
197
|
+
}
|
|
198
|
+
return child.startsWith(parent);
|
|
199
|
+
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
export declare const ESLINT_FLAT_CONFIG_FILENAMES: string[];
|
|
2
|
+
export declare const ESLINT_OLD_CONFIG_FILENAMES: string[];
|
|
1
3
|
export declare const ESLINT_CONFIG_FILENAMES: string[];
|
|
2
4
|
export declare const baseEsLintConfigFile = ".eslintrc.base.json";
|
|
3
5
|
export declare const baseEsLintFlatConfigFile = "eslint.base.config.js";
|
|
4
|
-
export declare function findBaseEslintFile(workspaceRoot?: string): string | null;
|
|
5
6
|
export declare function isFlatConfig(configFilePath: string): boolean;
|
|
7
|
+
export declare function findFlatConfigFile(directory: string, workspaceRoot: string): string | null;
|
|
8
|
+
export declare function findOldConfigFile(filePathOrDirectory: string, workspaceRoot: string): string | null;
|
package/src/utils/config-file.js
CHANGED
|
@@ -1,35 +1,69 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const devkit_1 = require("@nx/devkit");
|
|
3
|
+
exports.findOldConfigFile = exports.findFlatConfigFile = exports.isFlatConfig = exports.baseEsLintFlatConfigFile = exports.baseEsLintConfigFile = exports.ESLINT_CONFIG_FILENAMES = exports.ESLINT_OLD_CONFIG_FILENAMES = exports.ESLINT_FLAT_CONFIG_FILENAMES = void 0;
|
|
5
4
|
const fs_1 = require("fs");
|
|
6
|
-
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
// TODO(leo): add support for eslint.config.mjs and eslint.config.cjs
|
|
7
|
+
exports.ESLINT_FLAT_CONFIG_FILENAMES = ['eslint.config.js'];
|
|
8
|
+
exports.ESLINT_OLD_CONFIG_FILENAMES = [
|
|
7
9
|
'.eslintrc',
|
|
8
10
|
'.eslintrc.js',
|
|
9
11
|
'.eslintrc.cjs',
|
|
10
12
|
'.eslintrc.yaml',
|
|
11
13
|
'.eslintrc.yml',
|
|
12
14
|
'.eslintrc.json',
|
|
13
|
-
|
|
15
|
+
];
|
|
16
|
+
exports.ESLINT_CONFIG_FILENAMES = [
|
|
17
|
+
...exports.ESLINT_OLD_CONFIG_FILENAMES,
|
|
18
|
+
...exports.ESLINT_FLAT_CONFIG_FILENAMES,
|
|
14
19
|
];
|
|
15
20
|
exports.baseEsLintConfigFile = '.eslintrc.base.json';
|
|
16
21
|
exports.baseEsLintFlatConfigFile = 'eslint.base.config.js';
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
function isFlatConfig(configFilePath) {
|
|
23
|
+
const configFileName = (0, path_1.basename)(configFilePath);
|
|
24
|
+
return exports.ESLINT_FLAT_CONFIG_FILENAMES.includes(configFileName);
|
|
25
|
+
}
|
|
26
|
+
exports.isFlatConfig = isFlatConfig;
|
|
27
|
+
// https://eslint.org/docs/latest/use/configure/configuration-files#configuration-file-resolution
|
|
28
|
+
function findFlatConfigFile(directory, workspaceRoot) {
|
|
29
|
+
let currentDir = (0, path_1.resolve)(workspaceRoot, directory);
|
|
30
|
+
while (true) {
|
|
31
|
+
const configFilePath = getConfigFileInDirectory(currentDir, exports.ESLINT_FLAT_CONFIG_FILENAMES);
|
|
32
|
+
if (configFilePath) {
|
|
33
|
+
return configFilePath;
|
|
34
|
+
}
|
|
35
|
+
if (currentDir === workspaceRoot) {
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
currentDir = (0, path_1.dirname)(currentDir);
|
|
20
39
|
}
|
|
21
|
-
|
|
22
|
-
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
exports.findFlatConfigFile = findFlatConfigFile;
|
|
43
|
+
function findOldConfigFile(filePathOrDirectory, workspaceRoot) {
|
|
44
|
+
let currentDir = (0, path_1.resolve)(workspaceRoot, filePathOrDirectory);
|
|
45
|
+
if (!(0, fs_1.statSync)(currentDir).isDirectory()) {
|
|
46
|
+
currentDir = (0, path_1.dirname)(currentDir);
|
|
23
47
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
48
|
+
while (true) {
|
|
49
|
+
const configFilePath = getConfigFileInDirectory(currentDir, exports.ESLINT_OLD_CONFIG_FILENAMES);
|
|
50
|
+
if (configFilePath) {
|
|
51
|
+
return configFilePath;
|
|
27
52
|
}
|
|
53
|
+
if (currentDir === workspaceRoot) {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
currentDir = (0, path_1.dirname)(currentDir);
|
|
28
57
|
}
|
|
29
58
|
return null;
|
|
30
59
|
}
|
|
31
|
-
exports.
|
|
32
|
-
function
|
|
33
|
-
|
|
60
|
+
exports.findOldConfigFile = findOldConfigFile;
|
|
61
|
+
function getConfigFileInDirectory(directory, candidateFileNames) {
|
|
62
|
+
for (const filename of candidateFileNames) {
|
|
63
|
+
const filePath = (0, path_1.join)(directory, filename);
|
|
64
|
+
if ((0, fs_1.existsSync)(filePath)) {
|
|
65
|
+
return filePath;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
34
69
|
}
|
|
35
|
-
exports.isFlatConfig = isFlatConfig;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveESLintClass = void 0;
|
|
4
|
+
async function resolveESLintClass(useFlatConfig = false) {
|
|
5
|
+
try {
|
|
6
|
+
// In eslint 8.57.0 (the final v8 version), a dedicated API was added for resolving the correct ESLint class.
|
|
7
|
+
const eslint = await Promise.resolve().then(() => require('eslint'));
|
|
8
|
+
if (typeof eslint.loadESLint === 'function') {
|
|
9
|
+
return await eslint.loadESLint({ useFlatConfig });
|
|
10
|
+
}
|
|
11
|
+
// If that API is not available (an older version of v8), we need to use the old way of resolving the ESLint class.
|
|
12
|
+
if (!useFlatConfig) {
|
|
13
|
+
return eslint.ESLint;
|
|
14
|
+
}
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
16
|
+
const { FlatESLint } = require('eslint/use-at-your-own-risk');
|
|
17
|
+
return FlatESLint;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
throw new Error('Unable to find ESLint. Ensure ESLint is installed.');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.resolveESLintClass = resolveESLintClass;
|
package/src/utils/versions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const nxVersion: any;
|
|
2
|
-
export declare const eslintVersion = "~8.
|
|
2
|
+
export declare const eslintVersion = "~8.57.0";
|
|
3
3
|
export declare const eslintrcVersion = "^2.1.1";
|
|
4
4
|
export declare const eslintConfigPrettierVersion = "^9.0.0";
|
|
5
|
-
export declare const typescriptESLintVersion = "^
|
|
5
|
+
export declare const typescriptESLintVersion = "^7.3.0";
|
package/src/utils/versions.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.typescriptESLintVersion = exports.eslintConfigPrettierVersion = exports.eslintrcVersion = exports.eslintVersion = exports.nxVersion = void 0;
|
|
4
4
|
exports.nxVersion = require('../../package.json').version;
|
|
5
|
-
exports.eslintVersion = '~8.
|
|
5
|
+
exports.eslintVersion = '~8.57.0';
|
|
6
6
|
exports.eslintrcVersion = '^2.1.1';
|
|
7
7
|
exports.eslintConfigPrettierVersion = '^9.0.0';
|
|
8
|
-
exports.typescriptESLintVersion = '^
|
|
8
|
+
exports.typescriptESLintVersion = '^7.3.0';
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const devkit_1 = require("@nx/devkit");
|
|
4
|
-
const eslint_targets_1 = require("../../generators/utils/eslint-targets");
|
|
5
|
-
const config_file_1 = require("../../utils/config-file");
|
|
6
|
-
async function addEslintInputs(tree) {
|
|
7
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
8
|
-
const globalEslintFile = config_file_1.ESLINT_CONFIG_FILENAMES.find((file) => tree.exists(file));
|
|
9
|
-
if (globalEslintFile && nxJson.namedInputs?.production) {
|
|
10
|
-
const productionFileset = new Set(nxJson.namedInputs.production);
|
|
11
|
-
productionFileset.add(`!{projectRoot}/${globalEslintFile}`);
|
|
12
|
-
nxJson.namedInputs.production = Array.from(productionFileset);
|
|
13
|
-
}
|
|
14
|
-
for (const targetName of (0, eslint_targets_1.getEslintTargets)(tree)) {
|
|
15
|
-
nxJson.targetDefaults ??= {};
|
|
16
|
-
const lintTargetDefaults = (nxJson.targetDefaults[targetName] ??= {});
|
|
17
|
-
lintTargetDefaults.inputs ??= [
|
|
18
|
-
'default',
|
|
19
|
-
...(globalEslintFile
|
|
20
|
-
? [(0, devkit_1.joinPathFragments)('{workspaceRoot}', globalEslintFile)]
|
|
21
|
-
: []),
|
|
22
|
-
];
|
|
23
|
-
}
|
|
24
|
-
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
25
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
26
|
-
}
|
|
27
|
-
exports.default = addEslintInputs;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const devkit_1 = require("@nx/devkit");
|
|
4
|
-
const eslint_targets_1 = require("../../generators/utils/eslint-targets");
|
|
5
|
-
const config_file_1 = require("../../utils/config-file");
|
|
6
|
-
async function addEslintIgnore(tree) {
|
|
7
|
-
const nxJson = (0, devkit_1.readJson)(tree, 'nx.json');
|
|
8
|
-
const globalEslintFile = config_file_1.ESLINT_CONFIG_FILENAMES.find((file) => tree.exists(file));
|
|
9
|
-
if (globalEslintFile) {
|
|
10
|
-
if (tree.exists('.eslintignore')) {
|
|
11
|
-
const content = tree.read('.eslintignore', 'utf-8');
|
|
12
|
-
if (!content.includes('node_modules')) {
|
|
13
|
-
tree.write('.eslintignore', `node_modules\n${content}`);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
tree.write('.eslintignore', 'node_modules\n');
|
|
18
|
-
}
|
|
19
|
-
for (const targetName of (0, eslint_targets_1.getEslintTargets)(tree)) {
|
|
20
|
-
nxJson.targetDefaults ??= {};
|
|
21
|
-
const lintTargetDefaults = (nxJson.targetDefaults[targetName] ??= {});
|
|
22
|
-
const lintIgnorePath = (0, devkit_1.joinPathFragments)('{workspaceRoot}', globalEslintFile);
|
|
23
|
-
if (lintTargetDefaults.inputs) {
|
|
24
|
-
if (!lintTargetDefaults.inputs.includes(lintIgnorePath)) {
|
|
25
|
-
lintTargetDefaults.inputs.push(lintIgnorePath);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
lintTargetDefaults.inputs = ['default', lintIgnorePath];
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
33
|
-
await (0, devkit_1.formatFiles)(tree);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
exports.default = addEslintIgnore;
|