@nx/eslint 20.5.0-canary.20250213-b8ee838 → 20.5.0-canary.20250214-ef08108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/eslint",
3
- "version": "20.5.0-canary.20250213-b8ee838",
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.20250213-b8ee838",
39
- "@nx/js": "20.5.0-canary.20250213-b8ee838",
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
- const block = (0, ast_utils_1.generateAst)({
434
- ignores: ignorePatterns.map((path) => (0, path_utils_1.mapFilePath)(path)),
435
- });
436
- tree.write(fileName, (0, ast_utils_1.addBlockToFlatConfigExport)(tree.read(fileName, 'utf8'), block));
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"')) ||
@@ -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, eslintConfigFiles, projectRootsByEslintRoots, lintableFilesPerProjectRoot, projectsCache) => {
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 parentConfigs = eslintConfigFiles.filter((eslintConfig) => isSubDir(projectRoot, (0, posix_1.dirname)(eslintConfig)));
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, eslintConfigFiles, projectRootsByEslintRoots, lintableFilesPerProjectRoot, targetsCache), eslintConfigFiles, 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);