@nx/eslint 21.0.0-beta.0 → 21.0.0-beta.2

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/migrations.json CHANGED
@@ -104,6 +104,18 @@
104
104
  },
105
105
  "@typescript-eslint/utils": {
106
106
  "version": "^7.16.0"
107
+ },
108
+ "@typescript-eslint/rule-tester": {
109
+ "version": "^7.16.0",
110
+ "alwaysAddToPackageJson": false
111
+ },
112
+ "@typescript-eslint/scope-manager": {
113
+ "version": "^7.16.0",
114
+ "alwaysAddToPackageJson": false
115
+ },
116
+ "@typescript-eslint/typescript-estree": {
117
+ "version": "^7.16.0",
118
+ "alwaysAddToPackageJson": false
107
119
  }
108
120
  }
109
121
  },
@@ -116,14 +128,26 @@
116
128
  "typescript-eslint": {
117
129
  "version": "^8.19.0"
118
130
  },
119
- "@typescript-eslint/parser": {
131
+ "@typescript-eslint/eslint-plugin": {
120
132
  "version": "^8.19.0"
121
133
  },
122
- "@typescript-eslint/eslint-plugin": {
134
+ "@typescript-eslint/parser": {
123
135
  "version": "^8.19.0"
124
136
  },
125
137
  "@typescript-eslint/utils": {
126
138
  "version": "^8.19.0"
139
+ },
140
+ "@typescript-eslint/rule-tester": {
141
+ "version": "^8.19.0",
142
+ "alwaysAddToPackageJson": false
143
+ },
144
+ "@typescript-eslint/scope-manager": {
145
+ "version": "^8.19.0",
146
+ "alwaysAddToPackageJson": false
147
+ },
148
+ "@typescript-eslint/typescript-estree": {
149
+ "version": "^8.19.0",
150
+ "alwaysAddToPackageJson": false
127
151
  }
128
152
  }
129
153
  },
@@ -136,14 +160,34 @@
136
160
  "typescript-eslint": {
137
161
  "version": "^8.19.0"
138
162
  },
139
- "@typescript-eslint/parser": {
163
+ "@typescript-eslint/eslint-plugin": {
140
164
  "version": "^8.19.0"
141
165
  },
142
- "@typescript-eslint/eslint-plugin": {
166
+ "@typescript-eslint/parser": {
143
167
  "version": "^8.19.0"
144
168
  },
145
169
  "@typescript-eslint/utils": {
146
170
  "version": "^8.19.0"
171
+ },
172
+ "@typescript-eslint/rule-tester": {
173
+ "version": "^8.19.0",
174
+ "alwaysAddToPackageJson": false
175
+ },
176
+ "@typescript-eslint/scope-manager": {
177
+ "version": "^8.19.0",
178
+ "alwaysAddToPackageJson": false
179
+ },
180
+ "@typescript-eslint/typescript-estree": {
181
+ "version": "^8.19.0",
182
+ "alwaysAddToPackageJson": false
183
+ }
184
+ }
185
+ },
186
+ "20.7.0": {
187
+ "version": "20.7.0-beta.4",
188
+ "packages": {
189
+ "eslint-config-prettier": {
190
+ "version": "^10.0.0"
147
191
  }
148
192
  }
149
193
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/eslint",
3
- "version": "21.0.0-beta.0",
3
+ "version": "21.0.0-beta.2",
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": "21.0.0-beta.0",
39
- "@nx/js": "21.0.0-beta.0",
38
+ "@nx/devkit": "21.0.0-beta.2",
39
+ "@nx/js": "21.0.0-beta.2",
40
40
  "semver": "^7.5.3",
41
41
  "tslib": "^2.3.0",
42
42
  "typescript": "~5.7.2"
@@ -12,6 +12,7 @@ const flat_config_1 = require("../../utils/flat-config");
12
12
  const ast_utils_1 = require("../utils/flat-config/ast-utils");
13
13
  const config_file_1 = require("../../utils/config-file");
14
14
  const plugin_1 = require("../utils/plugin");
15
+ const versions_1 = require("../../utils/versions");
15
16
  const setup_root_eslint_1 = require("./setup-root-eslint");
16
17
  const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
17
18
  function lintProjectGenerator(tree, options) {
@@ -96,7 +97,12 @@ async function lintProjectGeneratorInternal(tree, options) {
96
97
  // additionally, the companion e2e app would have `rootProject: true`
97
98
  // so we need to check for the root path as well
98
99
  if (!options.rootProject || projectConfig.root !== '.') {
99
- createEsLintConfiguration(tree, options, projectConfig, options.setParserOptionsProject, options.rootProject);
100
+ const addDependencyChecks = options.addPackageJsonDependencyChecks ||
101
+ isBuildableLibraryProject(tree, projectConfig);
102
+ createEsLintConfiguration(tree, options, projectConfig, options.setParserOptionsProject, options.rootProject, addDependencyChecks);
103
+ if (addDependencyChecks) {
104
+ tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, { 'jsonc-eslint-parser': versions_1.jsoncEslintParserVersion }, undefined, true));
105
+ }
100
106
  }
101
107
  // Buildable libs need source analysis enabled for linting `package.json`.
102
108
  if (isBuildableLibraryProject(tree, projectConfig) &&
@@ -114,7 +120,7 @@ async function lintProjectGeneratorInternal(tree, options) {
114
120
  }
115
121
  return (0, devkit_1.runTasksInSerial)(...tasks);
116
122
  }
117
- function createEsLintConfiguration(tree, options, projectConfig, setParserOptionsProject, rootProject) {
123
+ function createEsLintConfiguration(tree, options, projectConfig, setParserOptionsProject, rootProject, addDependencyChecks) {
118
124
  // we are only extending root for non-standalone projects or their complementary e2e apps
119
125
  const extendedRootConfig = rootProject ? undefined : (0, eslint_file_1.findEslintFile)(tree);
120
126
  const pathToRootConfig = extendedRootConfig
@@ -132,8 +138,6 @@ function createEsLintConfiguration(tree, options, projectConfig, setParserOption
132
138
  options.eslintConfigFormat = (0, eslint_file_1.determineEslintConfigFormat)(tree.read(extendedRootConfig, 'utf-8'));
133
139
  }
134
140
  }
135
- const addDependencyChecks = options.addPackageJsonDependencyChecks ||
136
- isBuildableLibraryProject(tree, projectConfig);
137
141
  const overrides = (0, flat_config_1.useFlatConfig)(tree)
138
142
  ? // For flat configs, we don't need to generate different overrides for each file. Users should add their own overrides as needed.
139
143
  []
@@ -357,9 +357,9 @@ function addExtendsToLintConfig(tree, root, plugin, insertAtTheEnd = false) {
357
357
  }
358
358
  tree.write(fileName, content);
359
359
  if (shouldImportEslintCompat) {
360
- return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@eslint/compat': versions_1.eslintCompat }, undefined, true);
360
+ return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@eslint/compat': versions_1.eslintCompat, '@eslint/eslintrc': versions_1.eslintrcVersion }, undefined, true);
361
361
  }
362
- return () => { };
362
+ return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@eslint/eslintrc': versions_1.eslintrcVersion }, undefined, true);
363
363
  }
364
364
  else {
365
365
  const plugins = (Array.isArray(plugin) ? plugin : [plugin]).map((p) => typeof p === 'string' ? p : p.name);
@@ -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);
@@ -1,8 +1,9 @@
1
1
  export declare const nxVersion: any;
2
2
  export declare const eslintVersion = "~8.57.0";
3
3
  export declare const eslintrcVersion = "^2.1.1";
4
- export declare const eslintConfigPrettierVersion = "^9.0.0";
4
+ export declare const eslintConfigPrettierVersion = "^10.0.0";
5
5
  export declare const typescriptESLintVersion = "^7.16.0";
6
+ export declare const jsoncEslintParserVersion = "^2.1.0";
6
7
  export declare const eslint9__typescriptESLintVersion = "^8.19.0";
7
8
  export declare const eslint9__eslintVersion = "^9.8.0";
8
9
  export declare const eslintCompat = "^1.1.1";
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.eslintCompat = exports.eslint9__eslintVersion = exports.eslint9__typescriptESLintVersion = exports.typescriptESLintVersion = exports.eslintConfigPrettierVersion = exports.eslintrcVersion = exports.eslintVersion = exports.nxVersion = void 0;
3
+ exports.eslintCompat = exports.eslint9__eslintVersion = exports.eslint9__typescriptESLintVersion = exports.jsoncEslintParserVersion = exports.typescriptESLintVersion = exports.eslintConfigPrettierVersion = exports.eslintrcVersion = exports.eslintVersion = exports.nxVersion = void 0;
4
4
  exports.nxVersion = require('../../package.json').version;
5
5
  exports.eslintVersion = '~8.57.0';
6
6
  exports.eslintrcVersion = '^2.1.1';
7
- exports.eslintConfigPrettierVersion = '^9.0.0';
7
+ exports.eslintConfigPrettierVersion = '^10.0.0';
8
8
  exports.typescriptESLintVersion = '^7.16.0';
9
+ exports.jsoncEslintParserVersion = '^2.1.0';
9
10
  // Updated linting stack for ESLint v9, typescript-eslint v8
10
11
  exports.eslint9__typescriptESLintVersion = '^8.19.0';
11
12
  exports.eslint9__eslintVersion = '^9.8.0';