@nx/eslint 23.0.0-beta.20 → 23.0.0-beta.22

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.
@@ -3,6 +3,5 @@ export { addImportToFlatConfig } from './src/generators/utils/flat-config/ast-ut
3
3
  export { useFlatConfig } from './src/utils/flat-config';
4
4
  export { javaScriptOverride, typeScriptOverride, } from './src/generators/init/global-eslint-config';
5
5
  export { setupRootEsLint } from './src/generators/lint-project/setup-root-eslint';
6
- export { getInstalledEslintVersion, getTypeScriptEslintVersionToInstall, } from './src/utils/version-utils';
7
- export { eslint9__typescriptESLintVersion } from './src/utils/versions';
6
+ export { getInstalledEslintVersion, typescriptESLintVersion, versions, } from './src/utils/versions';
8
7
  export type { Schema } from './src/executors/lint/schema';
package/dist/internal.js CHANGED
@@ -5,7 +5,7 @@
5
5
  // internal consumers and may change without semver protection. Mirrors
6
6
  // `@nx/devkit/internal`.
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.eslint9__typescriptESLintVersion = exports.getTypeScriptEslintVersionToInstall = exports.getInstalledEslintVersion = exports.setupRootEsLint = exports.typeScriptOverride = exports.javaScriptOverride = exports.useFlatConfig = exports.addImportToFlatConfig = exports.updateRelativePathsInConfig = exports.updateOverrideInLintConfig = exports.replaceOverridesInLintConfig = exports.lintConfigHasOverride = exports.isEslintConfigSupported = exports.findEslintFile = exports.addPredefinedConfigToFlatLintConfig = exports.addPluginsToLintConfig = exports.addOverrideToLintConfig = exports.addIgnoresToLintConfig = exports.addExtendsToLintConfig = void 0;
8
+ exports.versions = exports.typescriptESLintVersion = exports.getInstalledEslintVersion = exports.setupRootEsLint = exports.typeScriptOverride = exports.javaScriptOverride = exports.useFlatConfig = exports.addImportToFlatConfig = exports.updateRelativePathsInConfig = exports.updateOverrideInLintConfig = exports.replaceOverridesInLintConfig = exports.lintConfigHasOverride = exports.isEslintConfigSupported = exports.findEslintFile = exports.addPredefinedConfigToFlatLintConfig = exports.addPluginsToLintConfig = exports.addOverrideToLintConfig = exports.addIgnoresToLintConfig = exports.addExtendsToLintConfig = void 0;
9
9
  var eslint_file_1 = require("./src/generators/utils/eslint-file");
10
10
  Object.defineProperty(exports, "addExtendsToLintConfig", { enumerable: true, get: function () { return eslint_file_1.addExtendsToLintConfig; } });
11
11
  Object.defineProperty(exports, "addIgnoresToLintConfig", { enumerable: true, get: function () { return eslint_file_1.addIgnoresToLintConfig; } });
@@ -27,8 +27,7 @@ Object.defineProperty(exports, "javaScriptOverride", { enumerable: true, get: fu
27
27
  Object.defineProperty(exports, "typeScriptOverride", { enumerable: true, get: function () { return global_eslint_config_1.typeScriptOverride; } });
28
28
  var setup_root_eslint_1 = require("./src/generators/lint-project/setup-root-eslint");
29
29
  Object.defineProperty(exports, "setupRootEsLint", { enumerable: true, get: function () { return setup_root_eslint_1.setupRootEsLint; } });
30
- var version_utils_1 = require("./src/utils/version-utils");
31
- Object.defineProperty(exports, "getInstalledEslintVersion", { enumerable: true, get: function () { return version_utils_1.getInstalledEslintVersion; } });
32
- Object.defineProperty(exports, "getTypeScriptEslintVersionToInstall", { enumerable: true, get: function () { return version_utils_1.getTypeScriptEslintVersionToInstall; } });
33
30
  var versions_1 = require("./src/utils/versions");
34
- Object.defineProperty(exports, "eslint9__typescriptESLintVersion", { enumerable: true, get: function () { return versions_1.eslint9__typescriptESLintVersion; } });
31
+ Object.defineProperty(exports, "getInstalledEslintVersion", { enumerable: true, get: function () { return versions_1.getInstalledEslintVersion; } });
32
+ Object.defineProperty(exports, "typescriptESLintVersion", { enumerable: true, get: function () { return versions_1.typescriptESLintVersion; } });
33
+ Object.defineProperty(exports, "versions", { enumerable: true, get: function () { return versions_1.versions; } });
@@ -2,12 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = run;
4
4
  const devkit_1 = require("@nx/devkit");
5
+ const internal_1 = require("@nx/devkit/internal");
5
6
  const fs_1 = require("fs");
6
7
  const utils_1 = require("nx/src/tasks-runner/utils");
7
8
  const path_1 = require("path");
9
+ const semver_1 = require("semver");
8
10
  const config_file_1 = require("../../utils/config-file");
9
- const eslint_utils_1 = require("./utility/eslint-utils");
10
11
  const deprecation_1 = require("../../utils/deprecation");
12
+ const versions_1 = require("../../utils/versions");
13
+ const eslint_utils_1 = require("./utility/eslint-utils");
11
14
  async function run(options, context) {
12
15
  (0, deprecation_1.warnEslintExecutorDeprecation)();
13
16
  // hasTypeAwareRules is deprecated and no longer used, delete it so it's not passed to ESLint
@@ -44,12 +47,10 @@ async function run(options, context) {
44
47
  ? (0, path_1.resolve)(systemRoot, normalizedOptions.eslintConfig)
45
48
  : undefined;
46
49
  const { eslint, ESLint } = await (0, eslint_utils_1.resolveAndInstantiateESLint)(eslintConfigPath, normalizedOptions, hasFlatConfig);
47
- const version = ESLint.version?.split('.');
48
- if (!version ||
49
- version.length < 2 ||
50
- Number(version[0]) < 7 ||
51
- (Number(version[0]) === 7 && Number(version[1]) < 6)) {
52
- throw new Error('ESLint must be version 7.6 or higher.');
50
+ (0, internal_1.assertSupportedInstalledPackageVersion)('eslint', versions_1.minSupportedEslintVersion);
51
+ const installedEslintVersion = (0, internal_1.getInstalledPackageVersion)('eslint');
52
+ if (installedEslintVersion && (0, semver_1.major)(installedEslintVersion) === 8) {
53
+ (0, deprecation_1.warnEslintV8Deprecation)();
53
54
  }
54
55
  if (printConfig) {
55
56
  try {
@@ -5,9 +5,11 @@ const devkit_1 = require("@nx/devkit");
5
5
  const eslint_file_1 = require("../utils/eslint-file");
6
6
  const plugin_1 = require("../utils/plugin");
7
7
  const path_1 = require("path");
8
+ const assert_supported_eslint_version_1 = require("../../utils/assert-supported-eslint-version");
8
9
  const versions_1 = require("../../utils/versions");
9
10
  const json_converter_1 = require("./converters/json-converter");
10
11
  async function convertToFlatConfigGenerator(tree, options) {
12
+ (0, assert_supported_eslint_version_1.assertSupportedEslintVersion)(tree);
11
13
  const eslintFile = (0, eslint_file_1.findEslintFile)(tree);
12
14
  if (!eslintFile) {
13
15
  throw new Error('Could not find root eslint file');
@@ -230,21 +232,22 @@ function processConvertedConfig(tree, root, source, target, { content, addESLint
230
232
  tree.delete((0, path_1.join)(root, source));
231
233
  // save new
232
234
  tree.write((0, path_1.join)(root, target), content);
233
- // These dependencies are required for flat configs that are generated by subsequent app/lib generators.
235
+ // Once converted to flat config, the workspace is on the v9 ESLint stack
236
+ // install the latest typescript-eslint v8 lane explicitly rather than
237
+ // routing through `versions(tree)` which would pick the legacy lane based
238
+ // on the pre-conversion `eslintrc` workspace state.
234
239
  const devDependencies = {
235
- eslint: versions_1.eslint9__eslintVersion,
240
+ eslint: versions_1.eslintVersion,
236
241
  'eslint-config-prettier': versions_1.eslintConfigPrettierVersion,
237
- 'typescript-eslint': versions_1.eslint9__typescriptESLintVersion,
238
- '@typescript-eslint/eslint-plugin': versions_1.eslint9__typescriptESLintVersion,
239
- '@typescript-eslint/parser': versions_1.eslint9__typescriptESLintVersion,
242
+ 'typescript-eslint': versions_1.typescriptESLintVersion,
243
+ '@typescript-eslint/eslint-plugin': versions_1.typescriptESLintVersion,
244
+ '@typescript-eslint/parser': versions_1.typescriptESLintVersion,
240
245
  };
241
246
  if ((0, devkit_1.getDependencyVersionFromPackageJson)(tree, '@typescript-eslint/utils')) {
242
- devDependencies['@typescript-eslint/utils'] =
243
- versions_1.eslint9__typescriptESLintVersion;
247
+ devDependencies['@typescript-eslint/utils'] = versions_1.typescriptESLintVersion;
244
248
  }
245
249
  if ((0, devkit_1.getDependencyVersionFromPackageJson)(tree, '@typescript-eslint/type-utils')) {
246
- devDependencies['@typescript-eslint/type-utils'] =
247
- versions_1.eslint9__typescriptESLintVersion;
250
+ devDependencies['@typescript-eslint/type-utils'] = versions_1.typescriptESLintVersion;
248
251
  }
249
252
  // add missing packages
250
253
  if (addESLintRC) {
@@ -253,5 +256,7 @@ function processConvertedConfig(tree, root, source, target, { content, addESLint
253
256
  if (addESLintJS) {
254
257
  devDependencies['@eslint/js'] = versions_1.eslintVersion;
255
258
  }
259
+ // Convert-to-flat-config is an opt-in "upgrade" — we intentionally overwrite
260
+ // existing pins to land the workspace on the latest flat-config-ready stack.
256
261
  (0, devkit_1.addDependenciesToPackageJson)(tree, {}, devDependencies);
257
262
  }
@@ -6,9 +6,11 @@ const devkit_1 = require("@nx/devkit");
6
6
  const posix_1 = require("node:path/posix");
7
7
  const utils_1 = require("nx/src/tasks-runner/utils");
8
8
  const plugin_1 = require("../../plugins/plugin");
9
+ const assert_supported_eslint_version_1 = require("../../utils/assert-supported-eslint-version");
9
10
  const config_file_1 = require("../../utils/config-file");
10
11
  const target_options_map_1 = require("./lib/target-options-map");
11
12
  async function convertToInferred(tree, options) {
13
+ (0, assert_supported_eslint_version_1.assertSupportedEslintVersion)(tree);
12
14
  const projectGraph = await (0, devkit_1.createProjectGraphAsync)();
13
15
  const migratedProjects = await (0, internal_1.migrateProjectExecutorsToPlugin)(tree, projectGraph, '@nx/eslint/plugin', plugin_1.createNodesV2, { targetName: 'lint' }, [
14
16
  {
@@ -34,9 +34,10 @@ function migrateConfigToMonorepoStyle(projects, tree, unitTestRunner, eslintConf
34
34
  else {
35
35
  if ((0, flat_config_1.useFlatConfig)(tree)) {
36
36
  // we need this for the compat
37
+ const { eslintVersion } = (0, versions_1.versions)(tree);
37
38
  (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
38
- '@eslint/js': versions_1.eslintVersion,
39
- }, undefined, keepExistingVersions);
39
+ '@eslint/js': eslintVersion,
40
+ }, undefined, keepExistingVersions ?? true);
40
41
  tree.write(tree.exists(`eslint.config.${eslintConfigFormat}`)
41
42
  ? `eslint.base.config.${eslintConfigFormat}`
42
43
  : `eslint.config.${eslintConfigFormat}`, (0, global_eslint_config_1.getGlobalFlatEslintConfiguration)(eslintConfigFormat));
@@ -77,7 +78,7 @@ function migrateConfigToMonorepoStyle(projects, tree, unitTestRunner, eslintConf
77
78
  });
78
79
  return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
79
80
  '@nx/eslint-plugin': versions_1.nxVersion,
80
- });
81
+ }, undefined, keepExistingVersions ?? true);
81
82
  }
82
83
  function findLintTarget(project) {
83
84
  return Object.values(project.targets ?? {}).find((target) => target.executor === '@nx/eslint:lint' ||
@@ -4,6 +4,7 @@ exports.initEsLint = initEsLint;
4
4
  exports.lintInitGenerator = lintInitGenerator;
5
5
  const internal_1 = require("@nx/devkit/internal");
6
6
  const devkit_1 = require("@nx/devkit");
7
+ const assert_supported_eslint_version_1 = require("../../utils/assert-supported-eslint-version");
7
8
  const versions_1 = require("../../utils/versions");
8
9
  const eslint_file_1 = require("../utils/eslint-file");
9
10
  const plugin_1 = require("../../plugins/plugin");
@@ -62,6 +63,7 @@ function updateVsCodeRecommendedExtensions(host) {
62
63
  });
63
64
  }
64
65
  async function initEsLint(tree, options) {
66
+ (0, assert_supported_eslint_version_1.assertSupportedEslintVersion)(tree);
65
67
  const nxJson = (0, devkit_1.readNxJson)(tree);
66
68
  const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
67
69
  nxJson.useInferencePlugins !== false;
@@ -108,11 +110,12 @@ async function initEsLint(tree, options) {
108
110
  }
109
111
  const tasks = [];
110
112
  if (!options.skipPackageJson) {
113
+ const { eslintVersion } = (0, versions_1.versions)(tree);
111
114
  tasks.push((0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@nx/eslint'], []));
112
115
  tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
113
116
  '@nx/eslint': versions_1.nxVersion,
114
- eslint: versions_1.eslintVersion,
115
- }, undefined, options.keepExistingVersions));
117
+ eslint: eslintVersion,
118
+ }, undefined, options.keepExistingVersions ?? true));
116
119
  }
117
120
  return (0, devkit_1.runTasksInSerial)(...tasks);
118
121
  }
@@ -15,7 +15,7 @@
15
15
  "type": "boolean",
16
16
  "x-priority": "internal",
17
17
  "description": "Keep existing dependencies versions",
18
- "default": false
18
+ "default": true
19
19
  },
20
20
  "updatePackageScripts": {
21
21
  "type": "boolean",
@@ -29,24 +29,28 @@ function setUpLegacyRootEslintRc(tree, options) {
29
29
  else {
30
30
  tree.write('.eslintignore', 'node_modules\n');
31
31
  }
32
- return !options.skipPackageJson
33
- ? (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
34
- '@nx/eslint-plugin': versions_1.nxVersion,
35
- '@typescript-eslint/parser': versions_1.typescriptESLintVersion,
36
- '@typescript-eslint/eslint-plugin': versions_1.typescriptESLintVersion,
37
- 'eslint-config-prettier': versions_1.eslintConfigPrettierVersion,
38
- })
39
- : () => { };
32
+ if (options.skipPackageJson) {
33
+ return () => { };
34
+ }
35
+ const { typescriptESLintVersion } = (0, versions_1.versions)(tree);
36
+ return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
37
+ '@nx/eslint-plugin': versions_1.nxVersion,
38
+ '@typescript-eslint/parser': typescriptESLintVersion,
39
+ '@typescript-eslint/eslint-plugin': typescriptESLintVersion,
40
+ 'eslint-config-prettier': versions_1.eslintConfigPrettierVersion,
41
+ }, undefined, true);
40
42
  }
41
43
  function setUpRootFlatConfig(tree, options) {
42
44
  tree.write(`eslint.config.${options.eslintConfigFormat}`, (0, global_eslint_config_1.getGlobalFlatEslintConfiguration)(options.eslintConfigFormat, options.rootProject));
43
- return !options.skipPackageJson
44
- ? (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
45
- '@eslint/js': versions_1.eslint9__eslintVersion,
46
- '@nx/eslint-plugin': versions_1.nxVersion,
47
- eslint: versions_1.eslint9__eslintVersion,
48
- 'eslint-config-prettier': versions_1.eslintConfigPrettierVersion,
49
- 'typescript-eslint': versions_1.eslint9__typescriptESLintVersion,
50
- })
51
- : () => { };
45
+ if (options.skipPackageJson) {
46
+ return () => { };
47
+ }
48
+ const { eslintVersion, typescriptESLintVersion } = (0, versions_1.versions)(tree);
49
+ return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
50
+ '@eslint/js': eslintVersion,
51
+ '@nx/eslint-plugin': versions_1.nxVersion,
52
+ eslint: eslintVersion,
53
+ 'eslint-config-prettier': versions_1.eslintConfigPrettierVersion,
54
+ 'typescript-eslint': typescriptESLintVersion,
55
+ }, undefined, true);
52
56
  }
@@ -14,10 +14,8 @@ exports.addPluginsToLintConfig = addPluginsToLintConfig;
14
14
  exports.addIgnoresToLintConfig = addIgnoresToLintConfig;
15
15
  exports.getPluginImport = getPluginImport;
16
16
  const devkit_1 = require("@nx/devkit");
17
- const semver_1 = require("semver");
18
17
  const config_file_1 = require("../../utils/config-file");
19
18
  const flat_config_1 = require("../../utils/flat-config");
20
- const version_utils_1 = require("../../utils/version-utils");
21
19
  const versions_1 = require("../../utils/versions");
22
20
  const ast_utils_1 = require("./flat-config/ast-utils");
23
21
  const path_utils_1 = require("./flat-config/path-utils");
@@ -312,9 +310,9 @@ function addExtendsToLintConfig(tree, root, plugin, insertAtTheEnd = false) {
312
310
  ? 'cjs'
313
311
  : 'mjs';
314
312
  let shouldImportEslintCompat = false;
315
- // assume eslint version is 9 if not found, as it's what we'd be generating by default
316
- const eslintVersion = (0, version_utils_1.getInstalledEslintVersion)(tree) ?? versions_1.eslint9__eslintVersion;
317
- if ((0, semver_1.gte)(eslintVersion, '9.0.0')) {
313
+ // assume eslint major is 9 if not found, as it's what we'd be generating by default
314
+ const eslintMajor = (0, versions_1.getInstalledEslintMajorVersion)(tree) ?? 9;
315
+ if (eslintMajor >= 9) {
318
316
  // eslint v9 requires the incompatible plugins to be wrapped with a helper from @eslint/compat
319
317
  const plugins = (Array.isArray(plugin) ? plugin : [plugin]).map((p) => typeof p === 'string' ? { name: p, needCompatFixup: false } : p);
320
318
  let compatiblePluginsBatch = [];
@@ -1,4 +1,4 @@
1
- <% if (flatConfig) { %>import { RuleTester } from '@typescript-eslint/rule-tester';
1
+ <% if (useFlatRuleTester) { %>import { RuleTester } from '@typescript-eslint/rule-tester';
2
2
  import type { RuleTesterConfig } from '@typescript-eslint/rule-tester';
3
3
  import { rule, RULE_NAME } from './<%= name %>';
4
4
 
@@ -5,14 +5,26 @@ const tslib_1 = require("tslib");
5
5
  const internal_1 = require("@nx/devkit/internal");
6
6
  const devkit_1 = require("@nx/devkit");
7
7
  const path_1 = require("path");
8
+ const semver_1 = require("semver");
8
9
  const ts = tslib_1.__importStar(require("typescript"));
9
10
  const workspace_lint_rules_1 = require("../../utils/workspace-lint-rules");
10
11
  const workspace_rules_project_1 = require("../workspace-rules-project/workspace-rules-project");
12
+ const assert_supported_eslint_version_1 = require("../../utils/assert-supported-eslint-version");
11
13
  const flat_config_1 = require("../../utils/flat-config");
12
14
  const versions_1 = require("../../utils/versions");
13
15
  async function lintWorkspaceRuleGenerator(tree, options) {
16
+ (0, assert_supported_eslint_version_1.assertSupportedEslintVersion)(tree);
14
17
  const tasks = [];
15
18
  const flatConfig = (0, flat_config_1.useFlatConfig)(tree);
19
+ // ESLint v9 dropped the eslintrc-style `RuleTester` API. typescript-eslint's
20
+ // recommended replacement for any v9 workspace (flat or eslintrc) is the
21
+ // separate `@typescript-eslint/rule-tester` package, which has a flat-style
22
+ // API that works with ESLint v8.57+ and v9 alike. We resolve the effective
23
+ // major from `versions(tree)` to cover both declared workspaces and fresh
24
+ // installs that will be bumped to v9.
25
+ const { eslintVersion, typescriptESLintVersion } = (0, versions_1.versions)(tree);
26
+ const effectiveEslintMajor = (0, semver_1.major)((0, semver_1.coerce)(eslintVersion));
27
+ const useFlatRuleTester = flatConfig || effectiveEslintMajor >= 9;
16
28
  const nxJson = (0, devkit_1.readNxJson)(tree);
17
29
  // Ensure that the workspace rules project has been created
18
30
  tasks.push(await (0, workspace_rules_project_1.lintWorkspaceRulesProjectGenerator)(tree, {
@@ -20,15 +32,15 @@ async function lintWorkspaceRuleGenerator(tree, options) {
20
32
  addPlugin: process.env.NX_ADD_PLUGINS !== 'false' &&
21
33
  nxJson.useInferencePlugins !== false,
22
34
  }));
23
- if (flatConfig) {
24
- tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@typescript-eslint/rule-tester': versions_1.eslint9__typescriptESLintVersion }));
35
+ if (useFlatRuleTester) {
36
+ tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@typescript-eslint/rule-tester': typescriptESLintVersion }, undefined, true));
25
37
  }
26
38
  const ruleDir = (0, devkit_1.joinPathFragments)(workspace_lint_rules_1.workspaceLintPluginDir, options.directory ?? '');
27
39
  // Generate the required files for the new rule
28
40
  (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files'), ruleDir, {
29
41
  tmpl: '',
30
42
  name: options.name,
31
- flatConfig,
43
+ useFlatRuleTester,
32
44
  });
33
45
  const nameCamelCase = (0, internal_1.camelize)(options.name);
34
46
  /**
@@ -6,12 +6,13 @@ const devkit_1 = require("@nx/devkit");
6
6
  const js_1 = require("@nx/js");
7
7
  const internal_1 = require("@nx/js/internal");
8
8
  const path_1 = require("path");
9
+ const assert_supported_eslint_version_1 = require("../../utils/assert-supported-eslint-version");
9
10
  const versions_1 = require("../../utils/versions");
10
- const version_utils_1 = require("../../utils/version-utils");
11
11
  const workspace_lint_rules_1 = require("../../utils/workspace-lint-rules");
12
12
  exports.WORKSPACE_RULES_PROJECT_NAME = 'eslint-rules';
13
13
  exports.WORKSPACE_PLUGIN_DIR = 'tools/eslint-rules';
14
14
  async function lintWorkspaceRulesProjectGenerator(tree, options = {}) {
15
+ (0, assert_supported_eslint_version_1.assertSupportedEslintVersion)(tree);
15
16
  const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/jest', versions_1.nxVersion);
16
17
  const tasks = [];
17
18
  // Noop if the workspace rules project already exists
@@ -56,6 +57,13 @@ async function lintWorkspaceRulesProjectGenerator(tree, options = {}) {
56
57
  (0, devkit_1.updateJson)(tree, (0, path_1.join)(workspace_lint_rules_1.workspaceLintPluginDir, 'tsconfig.spec.json'), (json) => {
57
58
  delete json.compilerOptions?.module;
58
59
  delete json.compilerOptions?.moduleResolution;
60
+ // Inherits `module: node16` from the project's base `tsconfig.json`,
61
+ // which requires `isolatedModules: true` to reliably honor packages'
62
+ // `exports` maps (e.g. `@typescript-eslint/rule-tester`).
63
+ json.compilerOptions = {
64
+ ...json.compilerOptions,
65
+ isolatedModules: true,
66
+ };
59
67
  if (json.include) {
60
68
  json.include = json.include.map((v) => {
61
69
  if (v.startsWith('src/**')) {
@@ -76,10 +84,10 @@ async function lintWorkspaceRulesProjectGenerator(tree, options = {}) {
76
84
  });
77
85
  // Add swc dependencies
78
86
  tasks.push((0, internal_1.addSwcRegisterDependencies)(tree));
79
- const typescriptEslintVersion = (0, version_utils_1.getTypeScriptEslintVersionToInstall)(tree);
87
+ const { typescriptESLintVersion } = (0, versions_1.versions)(tree);
80
88
  tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
81
- '@typescript-eslint/utils': typescriptEslintVersion,
82
- }));
89
+ '@typescript-eslint/utils': typescriptESLintVersion,
90
+ }, undefined, true));
83
91
  if (!options.skipFormat) {
84
92
  await (0, devkit_1.formatFiles)(tree);
85
93
  }
@@ -2,12 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = default_1;
4
4
  const devkit_1 = require("@nx/devkit");
5
+ const internal_1 = require("@nx/devkit/internal");
5
6
  const semver_1 = require("semver");
6
- const version_utils_1 = require("../../utils/version-utils");
7
7
  async function default_1(tree) {
8
8
  const devDependencies = {};
9
+ // `@typescript-eslint/parser >=8.0.0` is enforced at the `requires` gate
10
+ // in `migrations.json`. The per-package `gte('8.0.0') && lt('8.13.0')`
11
+ // check below catches the lockstep-broken case where one of the four
12
+ // typescript-eslint packages is at a different major than the parser.
9
13
  const checkPackageAndMigrate = (pkgName) => {
10
- const pkgVersion = (0, version_utils_1.getInstalledPackageVersion)(pkgName, tree);
14
+ const pkgVersion = (0, internal_1.getDeclaredPackageVersion)(tree, pkgName);
11
15
  if (!!pkgVersion && (0, semver_1.gte)(pkgVersion, '8.0.0') && (0, semver_1.lt)(pkgVersion, '8.13.0')) {
12
16
  devDependencies[pkgName] = '^8.13.0';
13
17
  }
@@ -0,0 +1,2 @@
1
+ import { type Tree } from '@nx/devkit';
2
+ export declare function assertSupportedEslintVersion(tree: Tree): void;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertSupportedEslintVersion = assertSupportedEslintVersion;
4
+ const internal_1 = require("@nx/devkit/internal");
5
+ const deprecation_1 = require("./deprecation");
6
+ const versions_1 = require("./versions");
7
+ function assertSupportedEslintVersion(tree) {
8
+ (0, internal_1.assertSupportedPackageVersion)(tree, 'eslint', versions_1.minSupportedEslintVersion);
9
+ if ((0, versions_1.getInstalledEslintMajorVersion)(tree) === 8) {
10
+ (0, deprecation_1.warnEslintV8Deprecation)();
11
+ }
12
+ }
@@ -1,3 +1,5 @@
1
1
  export declare const ESLINT_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/eslint:lint` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/eslint:convert-to-inferred` to migrate to the `@nx/eslint/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
2
2
  export declare function warnEslintExecutorDeprecation(): void;
3
3
  export declare function warnEslintExecutorGenerating(): void;
4
+ export declare const ESLINT_V8_DEPRECATION_MESSAGE = "Support for ESLint v8 is deprecated and will be removed in Nx v24. Please upgrade to ESLint v9.";
5
+ export declare function warnEslintV8Deprecation(): void;
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ESLINT_EXECUTOR_DEPRECATION_MESSAGE = void 0;
3
+ exports.ESLINT_V8_DEPRECATION_MESSAGE = exports.ESLINT_EXECUTOR_DEPRECATION_MESSAGE = void 0;
4
4
  exports.warnEslintExecutorDeprecation = warnEslintExecutorDeprecation;
5
5
  exports.warnEslintExecutorGenerating = warnEslintExecutorGenerating;
6
+ exports.warnEslintV8Deprecation = warnEslintV8Deprecation;
6
7
  const devkit_1 = require("@nx/devkit");
7
8
  // TODO(v24): Remove the @nx/eslint:lint executor. The inferred plugin
8
9
  // (@nx/eslint/plugin) and the convert-to-inferred generator stay supported.
@@ -13,3 +14,12 @@ function warnEslintExecutorDeprecation() {
13
14
  function warnEslintExecutorGenerating() {
14
15
  devkit_1.logger.warn('Generating a target that uses the deprecated `@nx/eslint:lint` executor. The executor will be removed in Nx v24. Run `nx g @nx/eslint:convert-to-inferred` next to migrate this target to the `@nx/eslint/plugin` inferred plugin and prevent future generators from emitting executor targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.');
15
16
  }
17
+ // TODO(v24): Remove ESLint v8 support. Concrete removals:
18
+ // - Raise `minSupportedEslintVersion` to '9.0.0' in versions.ts.
19
+ // - Delete `versionMap[8]` and the `CompatVersions` type alias.
20
+ // - Delete this constant + `warnEslintV8Deprecation` and their call sites.
21
+ // - Drop the v8 branch in the workspace-rule generator/template.
22
+ exports.ESLINT_V8_DEPRECATION_MESSAGE = 'Support for ESLint v8 is deprecated and will be removed in Nx v24. Please upgrade to ESLint v9.';
23
+ function warnEslintV8Deprecation() {
24
+ devkit_1.logger.warn(exports.ESLINT_V8_DEPRECATION_MESSAGE);
25
+ }
@@ -1,9 +1,17 @@
1
+ import { type Tree } from '@nx/devkit';
1
2
  export declare const nxVersion: any;
2
- export declare const eslintVersion = "~8.57.0";
3
- export declare const eslintrcVersion = "^2.1.1";
3
+ export declare const minSupportedEslintVersion = "8.0.0";
4
4
  export declare const eslintConfigPrettierVersion = "^10.0.0";
5
- export declare const typescriptESLintVersion = "^7.16.0";
5
+ export declare const eslintrcVersion = "^2.1.1";
6
6
  export declare const jsoncEslintParserVersion = "^2.1.0";
7
- export declare const eslint9__typescriptESLintVersion = "^8.40.0";
8
- export declare const eslint9__eslintVersion = "^9.8.0";
9
7
  export declare const eslintCompat = "^1.1.1";
8
+ export declare const eslintVersion = "^9.8.0";
9
+ export declare const typescriptESLintVersion = "^8.40.0";
10
+ type EslintVersions = {
11
+ eslintVersion: string;
12
+ typescriptESLintVersion: string;
13
+ };
14
+ export declare function versions(tree: Tree): EslintVersions;
15
+ export declare function getInstalledEslintVersion(tree?: Tree): string | null;
16
+ export declare function getInstalledEslintMajorVersion(tree?: Tree): number | null;
17
+ export {};
@@ -1,14 +1,49 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.eslintCompat = exports.eslint9__eslintVersion = exports.eslint9__typescriptESLintVersion = exports.jsoncEslintParserVersion = exports.typescriptESLintVersion = exports.eslintConfigPrettierVersion = exports.eslintrcVersion = exports.eslintVersion = exports.nxVersion = void 0;
3
+ exports.typescriptESLintVersion = exports.eslintVersion = exports.eslintCompat = exports.jsoncEslintParserVersion = exports.eslintrcVersion = exports.eslintConfigPrettierVersion = exports.minSupportedEslintVersion = exports.nxVersion = void 0;
4
+ exports.versions = versions;
5
+ exports.getInstalledEslintVersion = getInstalledEslintVersion;
6
+ exports.getInstalledEslintMajorVersion = getInstalledEslintMajorVersion;
7
+ const internal_1 = require("@nx/devkit/internal");
4
8
  const path_1 = require("path");
9
+ const semver_1 = require("semver");
5
10
  exports.nxVersion = require((0, path_1.join)('@nx/eslint', 'package.json')).version;
6
- exports.eslintVersion = '~8.57.0';
7
- exports.eslintrcVersion = '^2.1.1';
11
+ exports.minSupportedEslintVersion = '8.0.0';
8
12
  exports.eslintConfigPrettierVersion = '^10.0.0';
9
- exports.typescriptESLintVersion = '^7.16.0';
13
+ exports.eslintrcVersion = '^2.1.1';
10
14
  exports.jsoncEslintParserVersion = '^2.1.0';
11
- // Updated linting stack for ESLint v9, typescript-eslint v8
12
- exports.eslint9__typescriptESLintVersion = '^8.40.0';
13
- exports.eslint9__eslintVersion = '^9.8.0';
14
15
  exports.eslintCompat = '^1.1.1';
16
+ exports.eslintVersion = '^9.8.0';
17
+ exports.typescriptESLintVersion = '^8.40.0';
18
+ const latestVersions = {
19
+ eslintVersion: exports.eslintVersion,
20
+ typescriptESLintVersion: exports.typescriptESLintVersion,
21
+ };
22
+ const versionMap = {
23
+ 8: {
24
+ eslintVersion: '~8.57.0',
25
+ typescriptESLintVersion: '^8.40.0',
26
+ },
27
+ };
28
+ function versions(tree) {
29
+ const installedEslintVersion = getInstalledEslintVersion(tree);
30
+ if (installedEslintVersion) {
31
+ const eslintMajorVersion = (0, semver_1.major)(installedEslintVersion);
32
+ return versionMap[eslintMajorVersion] ?? latestVersions;
33
+ }
34
+ // No ESLint declared yet — fresh installs always go to the latest supported
35
+ // ESLint stack (v9 + typescript-eslint v8). The eslintrc config shape is
36
+ // still respected at the config-file level when `useFlatConfig(tree)` is
37
+ // false; only the installed package versions move forward.
38
+ return latestVersions;
39
+ }
40
+ function getInstalledEslintVersion(tree) {
41
+ if (!tree) {
42
+ return (0, internal_1.getInstalledPackageVersion)('eslint');
43
+ }
44
+ return (0, internal_1.getDeclaredPackageVersion)(tree, 'eslint');
45
+ }
46
+ function getInstalledEslintMajorVersion(tree) {
47
+ const installedEslintVersion = getInstalledEslintVersion(tree);
48
+ return installedEslintVersion ? (0, semver_1.major)(installedEslintVersion) : null;
49
+ }
package/migrations.json CHANGED
@@ -3,12 +3,20 @@
3
3
  "update-typescript-eslint-v8.13.0": {
4
4
  "version": "20.2.0-beta.5",
5
5
  "description": "Update TypeScript ESLint packages to v8.13.0 if they are already on v8",
6
- "implementation": "./dist/src/migrations/update-20-2-0/update-typescript-eslint-v8-13-0"
6
+ "implementation": "./dist/src/migrations/update-20-2-0/update-typescript-eslint-v8-13-0",
7
+ "requires": {
8
+ "@typescript-eslint/parser": ">=8.0.0"
9
+ },
10
+ "documentation": "./dist/src/migrations/update-20-2-0/update-typescript-eslint-v8-13-0.md"
7
11
  },
8
12
  "add-file-extensions-to-overrides": {
9
13
  "version": "20.3.0-beta.1",
10
14
  "description": "Update ESLint flat config to include .cjs, .mjs, .cts, and .mts files in overrides (if needed)",
11
- "implementation": "./dist/src/migrations/update-20-3-0/add-file-extensions-to-overrides"
15
+ "implementation": "./dist/src/migrations/update-20-3-0/add-file-extensions-to-overrides",
16
+ "requires": {
17
+ "eslint": ">=8.57.0"
18
+ },
19
+ "documentation": "./dist/src/migrations/update-20-3-0/add-file-extensions-to-overrides.md"
12
20
  },
13
21
  "update-executor-lint-inputs": {
14
22
  "version": "22.7.0-beta.12",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/eslint",
3
- "version": "23.0.0-beta.20",
3
+ "version": "23.0.0-beta.22",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "files": [
@@ -73,17 +73,17 @@
73
73
  "peerDependencies": {
74
74
  "@zkochan/js-yaml": "0.0.7",
75
75
  "eslint": "^8.0.0 || ^9.0.0 || ^10.0.0",
76
- "@nx/jest": "23.0.0-beta.20"
76
+ "@nx/jest": "23.0.0-beta.22"
77
77
  },
78
78
  "dependencies": {
79
79
  "semver": "^7.6.3",
80
80
  "tslib": "^2.3.0",
81
81
  "typescript": "~5.9.2",
82
- "@nx/devkit": "23.0.0-beta.20",
83
- "@nx/js": "23.0.0-beta.20"
82
+ "@nx/js": "23.0.0-beta.22",
83
+ "@nx/devkit": "23.0.0-beta.22"
84
84
  },
85
85
  "devDependencies": {
86
- "nx": "23.0.0-beta.20"
86
+ "nx": "23.0.0-beta.22"
87
87
  },
88
88
  "peerDependenciesMeta": {
89
89
  "@nx/jest": {
@@ -1,4 +0,0 @@
1
- import { type Tree } from '@nx/devkit';
2
- export declare function getInstalledPackageVersion(pkgName: string, tree?: Tree): string | null;
3
- export declare function getInstalledEslintVersion(tree?: Tree): string | null;
4
- export declare function getTypeScriptEslintVersionToInstall(tree: Tree): string | null;
@@ -1,49 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getInstalledPackageVersion = getInstalledPackageVersion;
4
- exports.getInstalledEslintVersion = getInstalledEslintVersion;
5
- exports.getTypeScriptEslintVersionToInstall = getTypeScriptEslintVersionToInstall;
6
- const devkit_1 = require("@nx/devkit");
7
- const internal_1 = require("@nx/devkit/internal");
8
- const devkit_internals_1 = require("nx/src/devkit-internals");
9
- const semver_1 = require("semver");
10
- const versions_1 = require("./versions");
11
- function getInstalledPackageVersion(pkgName, tree) {
12
- try {
13
- const packageJson = (0, devkit_internals_1.readModulePackageJson)(pkgName).packageJson;
14
- return packageJson.version;
15
- }
16
- catch { }
17
- // the package is not installed on disk, it could be in the package.json
18
- // but waiting to be installed
19
- let pkgVersionInRootPackageJson;
20
- if (tree) {
21
- pkgVersionInRootPackageJson = (0, devkit_1.getDependencyVersionFromPackageJson)(tree, pkgName);
22
- }
23
- else {
24
- // Use filesystem-based signature for pnpm catalog compatibility
25
- pkgVersionInRootPackageJson = (0, devkit_1.getDependencyVersionFromPackageJson)(pkgName);
26
- }
27
- if (!pkgVersionInRootPackageJson) {
28
- // the package is not installed
29
- return null;
30
- }
31
- try {
32
- // try to parse and return the version
33
- return tree
34
- ? (0, internal_1.checkAndCleanWithSemver)(tree, pkgName, pkgVersionInRootPackageJson)
35
- : (0, internal_1.checkAndCleanWithSemver)(pkgName, pkgVersionInRootPackageJson);
36
- }
37
- catch { }
38
- // we could not resolve the version
39
- return null;
40
- }
41
- function getInstalledEslintVersion(tree) {
42
- return getInstalledPackageVersion('eslint', tree);
43
- }
44
- function getTypeScriptEslintVersionToInstall(tree) {
45
- const eslintVersion = getInstalledEslintVersion(tree);
46
- return eslintVersion && (0, semver_1.lt)(eslintVersion, '9.0.0')
47
- ? versions_1.typescriptESLintVersion
48
- : versions_1.eslint9__typescriptESLintVersion;
49
- }