@nx/eslint 20.5.0-canary.20250212-7c5fcf3 → 20.5.0-canary.20250214-ef08108
Sign up to get free protection for your applications and to get access to all the features.
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nx/eslint",
|
3
|
-
"version": "20.5.0-canary.
|
3
|
+
"version": "20.5.0-canary.20250214-ef08108",
|
4
4
|
"private": false,
|
5
5
|
"description": "The ESLint plugin for Nx contains executors, generators and utilities used for linting JavaScript/TypeScript projects within an Nx workspace.",
|
6
6
|
"repository": {
|
@@ -35,8 +35,8 @@
|
|
35
35
|
"eslint": "^8.0.0 || ^9.0.0"
|
36
36
|
},
|
37
37
|
"dependencies": {
|
38
|
-
"@nx/devkit": "20.5.0-canary.
|
39
|
-
"@nx/js": "20.5.0-canary.
|
38
|
+
"@nx/devkit": "20.5.0-canary.20250214-ef08108",
|
39
|
+
"@nx/js": "20.5.0-canary.20250214-ef08108",
|
40
40
|
"semver": "^7.5.3",
|
41
41
|
"tslib": "^2.3.0",
|
42
42
|
"typescript": "~5.7.2"
|
@@ -430,13 +430,26 @@ function addIgnoresToLintConfig(tree, root, ignorePatterns) {
|
|
430
430
|
break;
|
431
431
|
}
|
432
432
|
}
|
433
|
-
|
434
|
-
|
435
|
-
}
|
436
|
-
|
433
|
+
if (!fileName) {
|
434
|
+
return;
|
435
|
+
}
|
436
|
+
let content = tree.read(fileName, 'utf8');
|
437
|
+
if ((0, ast_utils_1.hasFlatConfigIgnoresBlock)(content)) {
|
438
|
+
content = (0, ast_utils_1.addPatternsToFlatConfigIgnoresBlock)(content, ignorePatterns);
|
439
|
+
tree.write(fileName, content);
|
440
|
+
}
|
441
|
+
else {
|
442
|
+
const block = (0, ast_utils_1.generateAst)({
|
443
|
+
ignores: ignorePatterns.map((path) => (0, path_utils_1.mapFilePath)(path)),
|
444
|
+
});
|
445
|
+
tree.write(fileName, (0, ast_utils_1.addBlockToFlatConfigExport)(content, block));
|
446
|
+
}
|
437
447
|
}
|
438
448
|
else {
|
439
449
|
const fileName = (0, devkit_1.joinPathFragments)(root, '.eslintrc.json');
|
450
|
+
if (!tree.exists(fileName)) {
|
451
|
+
return;
|
452
|
+
}
|
440
453
|
(0, devkit_1.updateJson)(tree, fileName, (json) => {
|
441
454
|
const ignoreSet = new Set([
|
442
455
|
...(json.ignorePatterns ?? []),
|
@@ -4,6 +4,8 @@ import * as ts from 'typescript';
|
|
4
4
|
* Remove all overrides from the config file
|
5
5
|
*/
|
6
6
|
export declare function removeOverridesFromLintConfig(content: string): string;
|
7
|
+
export declare function addPatternsToFlatConfigIgnoresBlock(content: string, ignorePatterns: string[]): string;
|
8
|
+
export declare function hasFlatConfigIgnoresBlock(content: string): boolean;
|
7
9
|
export declare function hasOverride(content: string, lookup: (override: Linter.ConfigOverride<Linter.RulesRecord>) => boolean): boolean;
|
8
10
|
/**
|
9
11
|
* Finds an override matching the lookup function and applies the update function to it
|
@@ -1,6 +1,8 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.removeOverridesFromLintConfig = removeOverridesFromLintConfig;
|
4
|
+
exports.addPatternsToFlatConfigIgnoresBlock = addPatternsToFlatConfigIgnoresBlock;
|
5
|
+
exports.hasFlatConfigIgnoresBlock = hasFlatConfigIgnoresBlock;
|
4
6
|
exports.hasOverride = hasOverride;
|
5
7
|
exports.replaceOverride = replaceOverride;
|
6
8
|
exports.addImportToFlatConfig = addImportToFlatConfig;
|
@@ -73,6 +75,55 @@ function findModuleExports(source) {
|
|
73
75
|
}
|
74
76
|
});
|
75
77
|
}
|
78
|
+
function addPatternsToFlatConfigIgnoresBlock(content, ignorePatterns) {
|
79
|
+
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
80
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
81
|
+
const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
82
|
+
if (!exportsArray) {
|
83
|
+
return content;
|
84
|
+
}
|
85
|
+
const changes = [];
|
86
|
+
for (const node of exportsArray) {
|
87
|
+
if (!isFlatConfigIgnoresBlock(node)) {
|
88
|
+
continue;
|
89
|
+
}
|
90
|
+
const start = node.properties.pos + 1; // keep leading line break
|
91
|
+
const data = parseTextToJson(node.getFullText());
|
92
|
+
changes.push({
|
93
|
+
type: devkit_1.ChangeType.Delete,
|
94
|
+
start,
|
95
|
+
length: node.properties.end - start,
|
96
|
+
});
|
97
|
+
data.ignores = Array.from(new Set([...(data.ignores ?? []), ...ignorePatterns]));
|
98
|
+
changes.push({
|
99
|
+
type: devkit_1.ChangeType.Insert,
|
100
|
+
index: start,
|
101
|
+
text: ' ' +
|
102
|
+
JSON.stringify(data, null, 2)
|
103
|
+
.slice(2, -2) // Remove curly braces and start/end line breaks
|
104
|
+
.replaceAll(/\n/g, '\n '), // Maintain indentation
|
105
|
+
});
|
106
|
+
break;
|
107
|
+
}
|
108
|
+
return (0, devkit_1.applyChangesToString)(content, changes);
|
109
|
+
}
|
110
|
+
function hasFlatConfigIgnoresBlock(content) {
|
111
|
+
const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
|
112
|
+
const format = content.includes('export default') ? 'mjs' : 'cjs';
|
113
|
+
const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
|
114
|
+
if (!exportsArray) {
|
115
|
+
return false;
|
116
|
+
}
|
117
|
+
return exportsArray.some(isFlatConfigIgnoresBlock);
|
118
|
+
}
|
119
|
+
function isFlatConfigIgnoresBlock(node) {
|
120
|
+
return (ts.isObjectLiteralExpression(node) &&
|
121
|
+
node.properties.length === 1 &&
|
122
|
+
(node.properties[0].name.getText() === 'ignores' ||
|
123
|
+
node.properties[0].name.getText() === '"ignores"') &&
|
124
|
+
ts.isPropertyAssignment(node.properties[0]) &&
|
125
|
+
ts.isArrayLiteralExpression(node.properties[0].initializer));
|
126
|
+
}
|
76
127
|
function isOverride(node) {
|
77
128
|
return ((ts.isObjectLiteralExpression(node) &&
|
78
129
|
node.properties.some((p) => p.name.getText() === 'files' || p.name.getText() === '"files"')) ||
|
package/src/plugins/plugin.js
CHANGED
@@ -107,7 +107,7 @@ const internalCreateNodes = async (configFilePath, options, context, projectsCac
|
|
107
107
|
projects,
|
108
108
|
};
|
109
109
|
};
|
110
|
-
const internalCreateNodesV2 = async (configFilePath, options, context,
|
110
|
+
const internalCreateNodesV2 = async (configFilePath, options, context, projectRootsByEslintRoots, lintableFilesPerProjectRoot, projectsCache, hashByRoot) => {
|
111
111
|
const configDir = (0, posix_1.dirname)(configFilePath);
|
112
112
|
const ESLint = await (0, resolve_eslint_class_1.resolveESLintClass)({
|
113
113
|
useFlatConfigOverrideVal: (0, config_file_1.isFlatConfig)(configFilePath),
|
@@ -115,12 +115,7 @@ const internalCreateNodesV2 = async (configFilePath, options, context, eslintCon
|
|
115
115
|
const eslintVersion = ESLint.version;
|
116
116
|
const projects = {};
|
117
117
|
await Promise.all(projectRootsByEslintRoots.get(configDir).map(async (projectRoot) => {
|
118
|
-
const
|
119
|
-
const hash = await (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, {
|
120
|
-
configFiles: eslintConfigFiles,
|
121
|
-
nxJsonConfiguration: context.nxJsonConfiguration,
|
122
|
-
workspaceRoot: context.workspaceRoot,
|
123
|
-
}, [...parentConfigs, (0, posix_1.join)(projectRoot, '.eslintignore')]);
|
118
|
+
const hash = hashByRoot.get(projectRoot);
|
124
119
|
if (projectsCache[hash]) {
|
125
120
|
// We can reuse the projects in the cache.
|
126
121
|
Object.assign(projects, projectsCache[hash]);
|
@@ -165,8 +160,13 @@ exports.createNodesV2 = [
|
|
165
160
|
const targetsCache = readTargetsCache(cachePath);
|
166
161
|
const { eslintConfigFiles, projectRoots, projectRootsByEslintRoots } = splitConfigFiles(configFiles);
|
167
162
|
const lintableFilesPerProjectRoot = await collectLintableFilesByProjectRoot(projectRoots, options, context);
|
163
|
+
const hashes = await (0, calculate_hash_for_create_nodes_1.calculateHashesForCreateNodes)(projectRoots, options, context, projectRoots.map((root) => {
|
164
|
+
const parentConfigs = eslintConfigFiles.filter((eslintConfig) => isSubDir(root, (0, posix_1.dirname)(eslintConfig)));
|
165
|
+
return [...parentConfigs, (0, posix_1.join)(root, '.eslintignore')];
|
166
|
+
}));
|
167
|
+
const hashByRoot = new Map(projectRoots.map((r, i) => [r, hashes[i]]));
|
168
168
|
try {
|
169
|
-
return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => internalCreateNodesV2(configFile, options, context,
|
169
|
+
return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => internalCreateNodesV2(configFile, options, context, projectRootsByEslintRoots, lintableFilesPerProjectRoot, targetsCache, hashByRoot), eslintConfigFiles, options, context);
|
170
170
|
}
|
171
171
|
finally {
|
172
172
|
writeTargetsToCache(cachePath, targetsCache);
|