@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
|
@@ -8,8 +8,13 @@ const ts = require("typescript");
|
|
|
8
8
|
const workspace_lint_rules_1 = require("../../utils/workspace-lint-rules");
|
|
9
9
|
const workspace_rules_project_1 = require("../workspace-rules-project/workspace-rules-project");
|
|
10
10
|
async function lintWorkspaceRuleGenerator(tree, options) {
|
|
11
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
11
12
|
// Ensure that the workspace rules project has been created
|
|
12
|
-
const projectGeneratorCallback = await (0, workspace_rules_project_1.lintWorkspaceRulesProjectGenerator)(tree, {
|
|
13
|
+
const projectGeneratorCallback = await (0, workspace_rules_project_1.lintWorkspaceRulesProjectGenerator)(tree, {
|
|
14
|
+
skipFormat: true,
|
|
15
|
+
addPlugin: process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
16
|
+
nxJson.useInferencePlugins !== false,
|
|
17
|
+
});
|
|
13
18
|
const ruleDir = (0, devkit_1.joinPathFragments)(workspace_lint_rules_1.workspaceLintPluginDir, options.directory ?? '');
|
|
14
19
|
// Generate the required files for the new rule
|
|
15
20
|
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files'), ruleDir, {
|
|
@@ -65,7 +70,7 @@ async function lintWorkspaceRuleGenerator(tree, options) {
|
|
|
65
70
|
devkit_1.logger.info(`NX Reminder: Once you have finished writing your rule logic, you need to actually enable the rule within an appropriate ESLint config in your workspace, for example:
|
|
66
71
|
|
|
67
72
|
"rules": {
|
|
68
|
-
"@nx/workspace
|
|
73
|
+
"@nx/workspace-${options.name}": "error"
|
|
69
74
|
}
|
|
70
75
|
`);
|
|
71
76
|
return projectGeneratorCallback;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Tree } from '@nx/devkit';
|
|
1
|
+
import { GeneratorCallback, Tree } from '@nx/devkit';
|
|
2
2
|
export declare const WORKSPACE_RULES_PROJECT_NAME = "eslint-rules";
|
|
3
3
|
export declare const WORKSPACE_PLUGIN_DIR = "tools/eslint-rules";
|
|
4
4
|
export interface LintWorkspaceRulesProjectGeneratorOptions {
|
|
5
5
|
skipFormat?: boolean;
|
|
6
|
+
addPlugin?: boolean;
|
|
6
7
|
}
|
|
7
|
-
export declare function lintWorkspaceRulesProjectGenerator(tree: Tree, options?: LintWorkspaceRulesProjectGeneratorOptions): Promise<
|
|
8
|
+
export declare function lintWorkspaceRulesProjectGenerator(tree: Tree, options?: LintWorkspaceRulesProjectGeneratorOptions): Promise<GeneratorCallback>;
|
|
@@ -10,7 +10,8 @@ const workspace_lint_rules_1 = require("../../utils/workspace-lint-rules");
|
|
|
10
10
|
exports.WORKSPACE_RULES_PROJECT_NAME = 'eslint-rules';
|
|
11
11
|
exports.WORKSPACE_PLUGIN_DIR = 'tools/eslint-rules';
|
|
12
12
|
async function lintWorkspaceRulesProjectGenerator(tree, options = {}) {
|
|
13
|
-
const {
|
|
13
|
+
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/jest', versions_1.nxVersion);
|
|
14
|
+
const tasks = [];
|
|
14
15
|
// Noop if the workspace rules project already exists
|
|
15
16
|
try {
|
|
16
17
|
(0, devkit_1.readProjectConfiguration)(tree, exports.WORKSPACE_RULES_PROJECT_NAME);
|
|
@@ -39,15 +40,17 @@ async function lintWorkspaceRulesProjectGenerator(tree, options = {}) {
|
|
|
39
40
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
40
41
|
}
|
|
41
42
|
// Add jest to the project and return installation task
|
|
42
|
-
|
|
43
|
+
tasks.push(await configurationGenerator(tree, {
|
|
44
|
+
...options,
|
|
43
45
|
project: exports.WORKSPACE_RULES_PROJECT_NAME,
|
|
44
46
|
supportTsx: false,
|
|
45
47
|
skipSerializers: true,
|
|
46
48
|
setupFile: 'none',
|
|
47
49
|
compiler: 'tsc',
|
|
48
50
|
skipFormat: true,
|
|
49
|
-
});
|
|
51
|
+
}));
|
|
50
52
|
(0, devkit_1.updateJson)(tree, (0, path_1.join)(workspace_lint_rules_1.workspaceLintPluginDir, 'tsconfig.spec.json'), (json) => {
|
|
53
|
+
delete json.compilerOptions?.module;
|
|
51
54
|
if (json.include) {
|
|
52
55
|
json.include = json.include.map((v) => {
|
|
53
56
|
if (v.startsWith('src/**')) {
|
|
@@ -67,14 +70,13 @@ async function lintWorkspaceRulesProjectGenerator(tree, options = {}) {
|
|
|
67
70
|
return json;
|
|
68
71
|
});
|
|
69
72
|
// Add swc dependencies
|
|
70
|
-
(0, add_swc_dependencies_1.addSwcRegisterDependencies)(tree);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
});
|
|
73
|
+
tasks.push((0, add_swc_dependencies_1.addSwcRegisterDependencies)(tree));
|
|
74
|
+
tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
75
|
+
'@typescript-eslint/utils': versions_1.typescriptESLintVersion,
|
|
76
|
+
}));
|
|
75
77
|
if (!options.skipFormat) {
|
|
76
78
|
await (0, devkit_1.formatFiles)(tree);
|
|
77
79
|
}
|
|
78
|
-
return
|
|
80
|
+
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
79
81
|
}
|
|
80
82
|
exports.lintWorkspaceRulesProjectGenerator = lintWorkspaceRulesProjectGenerator;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const devkit_1 = require("@nx/devkit");
|
|
4
|
-
const eslint_file_1 = require("../../generators/utils/eslint-file");
|
|
5
4
|
const eslint_targets_1 = require("../../generators/utils/eslint-targets");
|
|
5
|
+
const config_file_1 = require("../../utils/config-file");
|
|
6
6
|
async function addEslintInputs(tree) {
|
|
7
7
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
8
|
-
const globalEslintFile =
|
|
8
|
+
const globalEslintFile = config_file_1.ESLINT_CONFIG_FILENAMES.find((file) => tree.exists(file));
|
|
9
9
|
if (globalEslintFile && nxJson.namedInputs?.production) {
|
|
10
10
|
const productionFileset = new Set(nxJson.namedInputs.production);
|
|
11
11
|
productionFileset.add(`!{projectRoot}/${globalEslintFile}`);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const devkit_1 = require("@nx/devkit");
|
|
4
|
-
const eslint_file_1 = require("../../generators/utils/eslint-file");
|
|
5
4
|
const eslint_targets_1 = require("../../generators/utils/eslint-targets");
|
|
5
|
+
const config_file_1 = require("../../utils/config-file");
|
|
6
6
|
async function addEslintIgnore(tree) {
|
|
7
7
|
const nxJson = (0, devkit_1.readJson)(tree, 'nx.json');
|
|
8
|
-
const globalEslintFile =
|
|
8
|
+
const globalEslintFile = config_file_1.ESLINT_CONFIG_FILENAMES.find((file) => tree.exists(file));
|
|
9
9
|
if (globalEslintFile) {
|
|
10
10
|
if (tree.exists('.eslintignore')) {
|
|
11
11
|
const content = tree.read('.eslintignore', 'utf-8');
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const devkit_1 = require("@nx/devkit");
|
|
4
|
+
const versions_1 = require("../../utils/versions");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const typescript_1 = require("typescript");
|
|
7
|
+
function updateJestConfig(tree) {
|
|
8
|
+
const jestConfigPath = 'tools/eslint-rules/jest.config.ts';
|
|
9
|
+
if (tree.exists(jestConfigPath)) {
|
|
10
|
+
const { removePropertyFromJestConfig } = (0, devkit_1.ensurePackage)('@nx/jest', versions_1.nxVersion);
|
|
11
|
+
removePropertyFromJestConfig(tree, jestConfigPath, [
|
|
12
|
+
'moduleNameMapper',
|
|
13
|
+
'@eslint/eslintrc',
|
|
14
|
+
]);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function updateTsConfigs(tree) {
|
|
18
|
+
const tsConfigPath = 'tools/eslint-rules/tsconfig.json';
|
|
19
|
+
if (tree.exists(tsConfigPath)) {
|
|
20
|
+
(0, devkit_1.updateJson)(tree, tsConfigPath, (tsConfig) => {
|
|
21
|
+
tsConfig.compilerOptions ??= {};
|
|
22
|
+
tsConfig.compilerOptions.moduleResolution = 'node16';
|
|
23
|
+
tsConfig.compilerOptions.module = 'node16';
|
|
24
|
+
return tsConfig;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const tsConfigSpec = 'tools/eslint-rules/tsconfig.spec.json';
|
|
28
|
+
if (tree.exists(tsConfigSpec)) {
|
|
29
|
+
(0, devkit_1.updateJson)(tree, tsConfigSpec, (tsConfigSpec) => {
|
|
30
|
+
delete tsConfigSpec.compilerOptions?.module;
|
|
31
|
+
delete tsConfigSpec.compilerOptions?.moduleResolution;
|
|
32
|
+
return tsConfigSpec;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function updateRecommended(tree) {
|
|
37
|
+
(0, devkit_1.visitNotIgnoredFiles)(tree, 'tools/eslint-rules', (path) => {
|
|
38
|
+
if ((0, path_1.extname)(path) !== '.ts') {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const contents = tree.read(path, 'utf-8');
|
|
42
|
+
const sourceFile = (0, typescript_1.createSourceFile)(path, contents, typescript_1.ScriptTarget.ESNext, true);
|
|
43
|
+
const changes = [];
|
|
44
|
+
const visit = (node) => {
|
|
45
|
+
if ((0, typescript_1.isPropertyAssignment)(node) &&
|
|
46
|
+
(0, typescript_1.isIdentifier)(node.name) &&
|
|
47
|
+
node.name.text === 'recommended' &&
|
|
48
|
+
(0, typescript_1.isStringLiteral)(node.initializer)) {
|
|
49
|
+
changes.push({
|
|
50
|
+
type: devkit_1.ChangeType.Delete,
|
|
51
|
+
start: node.initializer.getStart(sourceFile),
|
|
52
|
+
length: node.initializer.getWidth(sourceFile),
|
|
53
|
+
});
|
|
54
|
+
changes.push({
|
|
55
|
+
type: devkit_1.ChangeType.Insert,
|
|
56
|
+
index: node.initializer.getStart(sourceFile),
|
|
57
|
+
text: "'recommended'",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
(0, typescript_1.forEachChild)(node, visit);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
(0, typescript_1.forEachChild)(sourceFile, visit);
|
|
65
|
+
tree.write(path, (0, devkit_1.applyChangesToString)(contents, changes));
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
async function update(tree) {
|
|
69
|
+
updateJestConfig(tree);
|
|
70
|
+
updateTsConfigs(tree);
|
|
71
|
+
updateRecommended(tree);
|
|
72
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
73
|
+
}
|
|
74
|
+
exports.default = update;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const devkit_1 = require("@nx/devkit");
|
|
4
|
+
async function update(tree) {
|
|
5
|
+
const projects = (0, devkit_1.getProjects)(tree);
|
|
6
|
+
for (const [projectName, projectConfiguration] of projects) {
|
|
7
|
+
let needsUpdate = false;
|
|
8
|
+
for (const [targetName, targetConfig] of Object.entries(projectConfiguration.targets ?? {})) {
|
|
9
|
+
if (targetConfig.executor !== '@nx/eslint:lint') {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
needsUpdate = true;
|
|
13
|
+
if (projectConfiguration.targets[targetName].options?.lintFilePatterns) {
|
|
14
|
+
const rootPattern = getLintRoot(projectConfiguration);
|
|
15
|
+
const nonRootPatterns = projectConfiguration.targets[targetName].options.lintFilePatterns.filter((p) => !p.startsWith(rootPattern) && !p.startsWith('{projectRoot}'));
|
|
16
|
+
if (nonRootPatterns.length === 0 &&
|
|
17
|
+
rootPattern === projectConfiguration.root) {
|
|
18
|
+
// delete the lintFilePatterns option if it's the only option and matches the root of the project
|
|
19
|
+
delete projectConfiguration.targets[targetName].options
|
|
20
|
+
.lintFilePatterns;
|
|
21
|
+
if (Object.keys(projectConfiguration.targets[targetName].options)
|
|
22
|
+
.length === 0) {
|
|
23
|
+
delete projectConfiguration.targets[targetName].options;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
projectConfiguration.targets[targetName].options.lintFilePatterns = [
|
|
28
|
+
rootPattern,
|
|
29
|
+
...nonRootPatterns,
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (needsUpdate) {
|
|
35
|
+
(0, devkit_1.updateProjectConfiguration)(tree, projectName, projectConfiguration);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
39
|
+
}
|
|
40
|
+
exports.default = update;
|
|
41
|
+
function getLintRoot({ root, sourceRoot }) {
|
|
42
|
+
if (root === '' || root === '.') {
|
|
43
|
+
return sourceRoot || './src';
|
|
44
|
+
}
|
|
45
|
+
return root;
|
|
46
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const devkit_1 = require("@nx/devkit");
|
|
4
|
+
const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
|
|
5
|
+
const eslint_file_1 = require("../../generators/utils/eslint-file");
|
|
6
|
+
const project_configuration_utils_1 = require("nx/src/project-graph/utils/project-configuration-utils");
|
|
7
|
+
async function update(tree) {
|
|
8
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
9
|
+
// Don't override anything if there are already target defaults for eslint
|
|
10
|
+
if (nxJson.targetDefaults?.['@nx/eslint:lint']) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
nxJson.targetDefaults ??= {};
|
|
14
|
+
const graph = await (0, devkit_1.createProjectGraphAsync)();
|
|
15
|
+
const lintTargets = new Set();
|
|
16
|
+
(0, executor_options_utils_1.forEachExecutorOptionsInGraph)(graph, '@nx/eslint:lint', (value, proj, targetName) => {
|
|
17
|
+
lintTargets.add(targetName);
|
|
18
|
+
});
|
|
19
|
+
// Workspace does not use eslint?
|
|
20
|
+
if (lintTargets.size === 0) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const lintDefaults = (nxJson.targetDefaults['@nx/eslint:lint'] = {});
|
|
24
|
+
// All eslint targets have the same name
|
|
25
|
+
if (lintTargets.size === 1) {
|
|
26
|
+
const targetName = Array.from(lintTargets)[0];
|
|
27
|
+
if (nxJson.targetDefaults[targetName]) {
|
|
28
|
+
Object.assign(lintDefaults, nxJson.targetDefaults[targetName]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
lintDefaults.cache ??= true;
|
|
32
|
+
if (!lintDefaults.inputs) {
|
|
33
|
+
const eslintConfig = (0, eslint_file_1.findEslintFile)(tree);
|
|
34
|
+
lintDefaults.inputs = [
|
|
35
|
+
'default',
|
|
36
|
+
...(eslintConfig ? [`{workspaceRoot}/${eslintConfig}`] : []),
|
|
37
|
+
'{workspaceRoot}/tools/eslint-rules/**/*',
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
// Cleanup old target defaults
|
|
41
|
+
const projects = graph.nodes;
|
|
42
|
+
const projectMap = (0, devkit_1.getProjects)(tree);
|
|
43
|
+
for (const [targetDefaultKey, targetDefault] of Object.entries(nxJson.targetDefaults)) {
|
|
44
|
+
if (!isTargetDefaultUsed(targetDefault, nxJson.targetDefaults, projects, projectMap)) {
|
|
45
|
+
delete nxJson.targetDefaults[targetDefaultKey];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
let addOutputs = false;
|
|
49
|
+
(0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nx/eslint:lint', (options, proj, targetName, configuration) => {
|
|
50
|
+
const projConfig = projectMap.get(proj);
|
|
51
|
+
// modify lint file patterns
|
|
52
|
+
if (options.lintFilePatterns) {
|
|
53
|
+
const projectRootRegex = new RegExp(`^${projConfig.root}/`);
|
|
54
|
+
projConfig.targets[targetName].options.lintFilePatterns =
|
|
55
|
+
options.lintFilePatterns
|
|
56
|
+
.filter((filePattern) => filePattern !== '{projectRoot}' &&
|
|
57
|
+
filePattern !== projConfig.root)
|
|
58
|
+
.map((filePattern) => filePattern.replace(projectRootRegex, '{projectRoot}/'));
|
|
59
|
+
// remove lintFilePatterns if empty
|
|
60
|
+
if (projConfig.targets[targetName].options.lintFilePatterns.length === 0) {
|
|
61
|
+
delete projConfig.targets[targetName].options.lintFilePatterns;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// remove inputs if they are not bringing any new inputs
|
|
65
|
+
if (projConfig.targets[targetName].inputs &&
|
|
66
|
+
projConfig.targets[targetName].inputs.every((i) => lintDefaults.inputs.includes(i))) {
|
|
67
|
+
delete projConfig.targets[targetName].inputs;
|
|
68
|
+
}
|
|
69
|
+
// remove obsolete eslint config definition, unless it's a custom one
|
|
70
|
+
const projectEslintConfig = (0, eslint_file_1.findEslintFile)(tree, projConfig.root);
|
|
71
|
+
if (options.eslintConfig === `${projConfig.root}/${projectEslintConfig}` ||
|
|
72
|
+
options.eslintConfig === `{projectRoot}/${projectEslintConfig}`) {
|
|
73
|
+
delete projConfig.targets[targetName].options.eslintConfig;
|
|
74
|
+
}
|
|
75
|
+
// remove options if empty
|
|
76
|
+
if (Object.keys(projConfig.targets[targetName]?.options ?? {}).length === 0) {
|
|
77
|
+
delete projConfig.targets[targetName].options;
|
|
78
|
+
}
|
|
79
|
+
// track output
|
|
80
|
+
if (options.outputFile) {
|
|
81
|
+
addOutputs = true;
|
|
82
|
+
}
|
|
83
|
+
if (projConfig.targets[targetName].outputs?.length === 1 &&
|
|
84
|
+
projConfig.targets[targetName].outputs[0] === '{options.outputFile}') {
|
|
85
|
+
delete projConfig.targets[targetName].outputs;
|
|
86
|
+
}
|
|
87
|
+
(0, devkit_1.updateProjectConfiguration)(tree, proj, projConfig);
|
|
88
|
+
});
|
|
89
|
+
if (addOutputs) {
|
|
90
|
+
lintDefaults.outputs = ['{options.outputFile}'];
|
|
91
|
+
}
|
|
92
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
93
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
94
|
+
}
|
|
95
|
+
exports.default = update;
|
|
96
|
+
function isTargetDefaultUsed(targetDefault, targetDefaults, projects, projectMap) {
|
|
97
|
+
for (const p of Object.values(projects)) {
|
|
98
|
+
for (const targetName in p.data?.targets ?? {}) {
|
|
99
|
+
if ((0, project_configuration_utils_1.readTargetDefaultsForTarget)(targetName, targetDefaults,
|
|
100
|
+
// It might seem like we should use the graph here too but we don't want to pass an executor which was processed in the graph
|
|
101
|
+
projectMap.get(p.name)?.targets?.[targetName]?.executor) === targetDefault) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNodes = void 0;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const globs_1 = require("nx/src/utils/globs");
|
|
7
|
+
const workspace_context_1 = require("nx/src/utils/workspace-context");
|
|
8
|
+
const config_file_1 = require("../utils/config-file");
|
|
9
|
+
const DEFAULT_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx', 'html', 'vue'];
|
|
10
|
+
exports.createNodes = [
|
|
11
|
+
(0, globs_1.combineGlobPatterns)([
|
|
12
|
+
...config_file_1.ESLINT_CONFIG_FILENAMES.map((f) => `**/${f}`),
|
|
13
|
+
config_file_1.baseEsLintConfigFile,
|
|
14
|
+
config_file_1.baseEsLintFlatConfigFile,
|
|
15
|
+
]),
|
|
16
|
+
(configFilePath, options, context) => {
|
|
17
|
+
options = normalizeOptions(options);
|
|
18
|
+
// Ensure that configFiles are set, e2e-run fails due to them being undefined in CI (does not occur locally)
|
|
19
|
+
// TODO(JamesHenry): Further troubleshoot this in CI
|
|
20
|
+
context.configFiles = context.configFiles ?? [];
|
|
21
|
+
// Create a Set of all the directories containing eslint configs
|
|
22
|
+
const eslintRoots = new Set(context.configFiles.map(node_path_1.dirname));
|
|
23
|
+
const configDir = (0, node_path_1.dirname)(configFilePath);
|
|
24
|
+
const childProjectRoots = (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, [
|
|
25
|
+
'project.json',
|
|
26
|
+
'package.json',
|
|
27
|
+
'**/project.json',
|
|
28
|
+
'**/package.json',
|
|
29
|
+
].map((f) => (0, node_path_1.join)(configDir, f)))
|
|
30
|
+
.map((f) => (0, node_path_1.dirname)(f))
|
|
31
|
+
.filter((childProjectRoot) => {
|
|
32
|
+
// Filter out projects under other eslint configs
|
|
33
|
+
let root = childProjectRoot;
|
|
34
|
+
// Traverse up from the childProjectRoot to either the workspaceRoot or the dir of this config file
|
|
35
|
+
while (root !== (0, node_path_1.dirname)(root) && root !== (0, node_path_1.dirname)(configFilePath)) {
|
|
36
|
+
if (eslintRoots.has(root)) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
root = (0, node_path_1.dirname)(root);
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
})
|
|
43
|
+
.filter((dir) => {
|
|
44
|
+
// Ignore project roots where the project does not contain any lintable files
|
|
45
|
+
const lintableFiles = (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, [
|
|
46
|
+
(0, node_path_1.join)(dir, `**/*.{${options.extensions.join(',')}}`),
|
|
47
|
+
]);
|
|
48
|
+
return lintableFiles.length > 0;
|
|
49
|
+
});
|
|
50
|
+
const uniqueChildProjectRoots = Array.from(new Set(childProjectRoots));
|
|
51
|
+
return {
|
|
52
|
+
projects: getProjectsUsingESLintConfig(configFilePath, uniqueChildProjectRoots, options, context),
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
function getProjectsUsingESLintConfig(configFilePath, childProjectRoots, options, context) {
|
|
57
|
+
const projects = {};
|
|
58
|
+
const rootEslintConfig = context.configFiles.find((f) => f === config_file_1.baseEsLintConfigFile ||
|
|
59
|
+
f === config_file_1.baseEsLintFlatConfigFile ||
|
|
60
|
+
config_file_1.ESLINT_CONFIG_FILENAMES.includes(f));
|
|
61
|
+
// Add a lint target for each child project without an eslint config, with the root level config as an input
|
|
62
|
+
for (const projectRoot of childProjectRoots) {
|
|
63
|
+
// If there's no src folder, it's not a standalone project, do not add the target at all
|
|
64
|
+
const isStandaloneWorkspace = projectRoot === '.' &&
|
|
65
|
+
(0, node_fs_1.existsSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot, 'src')) &&
|
|
66
|
+
(0, node_fs_1.existsSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot, 'package.json'));
|
|
67
|
+
if (projectRoot === '.' && !isStandaloneWorkspace) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const eslintConfigs = [configFilePath];
|
|
71
|
+
if (rootEslintConfig && !eslintConfigs.includes(rootEslintConfig)) {
|
|
72
|
+
eslintConfigs.unshift(rootEslintConfig);
|
|
73
|
+
}
|
|
74
|
+
projects[projectRoot] = {
|
|
75
|
+
targets: buildEslintTargets(eslintConfigs, projectRoot, options, isStandaloneWorkspace),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return projects;
|
|
79
|
+
}
|
|
80
|
+
function buildEslintTargets(eslintConfigs, projectRoot, options, isStandaloneWorkspace = false) {
|
|
81
|
+
const isRootProject = projectRoot === '.';
|
|
82
|
+
const targets = {};
|
|
83
|
+
const targetConfig = {
|
|
84
|
+
command: `eslint ${isRootProject && isStandaloneWorkspace ? './src' : '.'}`,
|
|
85
|
+
cache: true,
|
|
86
|
+
options: {
|
|
87
|
+
cwd: projectRoot,
|
|
88
|
+
},
|
|
89
|
+
inputs: [
|
|
90
|
+
'default',
|
|
91
|
+
// Certain lint rules can be impacted by changes to dependencies
|
|
92
|
+
'^default',
|
|
93
|
+
...eslintConfigs.map((config) => `{workspaceRoot}/${config}`.replace(`{workspaceRoot}/${projectRoot}`, isRootProject ? '{projectRoot}/' : '{projectRoot}')),
|
|
94
|
+
'{workspaceRoot}/tools/eslint-rules/**/*',
|
|
95
|
+
{ externalDependencies: ['eslint'] },
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
if (eslintConfigs.some((config) => (0, config_file_1.isFlatConfig)(config))) {
|
|
99
|
+
targetConfig.options.env = {
|
|
100
|
+
ESLINT_USE_FLAT_CONFIG: 'true',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
targets[options.targetName] = targetConfig;
|
|
104
|
+
return targets;
|
|
105
|
+
}
|
|
106
|
+
function normalizeOptions(options) {
|
|
107
|
+
options ??= {};
|
|
108
|
+
options.targetName ??= 'lint';
|
|
109
|
+
// Normalize user input for extensions (strip leading . characters)
|
|
110
|
+
if (Array.isArray(options.extensions)) {
|
|
111
|
+
options.extensions = options.extensions.map((f) => f.replace(/^\.+/, ''));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
options.extensions = DEFAULT_EXTENSIONS;
|
|
115
|
+
}
|
|
116
|
+
return options;
|
|
117
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isFlatConfig = exports.baseEsLintFlatConfigFile = exports.baseEsLintConfigFile = exports.ESLINT_CONFIG_FILENAMES = void 0;
|
|
4
|
+
exports.ESLINT_CONFIG_FILENAMES = [
|
|
5
|
+
'.eslintrc',
|
|
6
|
+
'.eslintrc.js',
|
|
7
|
+
'.eslintrc.cjs',
|
|
8
|
+
'.eslintrc.yaml',
|
|
9
|
+
'.eslintrc.yml',
|
|
10
|
+
'.eslintrc.json',
|
|
11
|
+
'eslint.config.js',
|
|
12
|
+
];
|
|
13
|
+
exports.baseEsLintConfigFile = '.eslintrc.base.json';
|
|
14
|
+
exports.baseEsLintFlatConfigFile = 'eslint.base.config.js';
|
|
15
|
+
function isFlatConfig(configFilePath) {
|
|
16
|
+
return configFilePath.endsWith('.config.js');
|
|
17
|
+
}
|
|
18
|
+
exports.isFlatConfig = isFlatConfig;
|
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';
|