@nx/eslint 17.0.2 → 17.0.4

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.
Files changed (55) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +9 -4
  3. package/generators.json +6 -0
  4. package/migrations.json +68 -0
  5. package/package.json +9 -8
  6. package/plugin.d.ts +1 -0
  7. package/plugin.js +5 -0
  8. package/src/executors/lint/hasher.js +1 -1
  9. package/src/executors/lint/lint.impl.js +67 -33
  10. package/src/executors/lint/schema.d.ts +1 -0
  11. package/src/executors/lint/schema.json +7 -3
  12. package/src/executors/lint/utility/eslint-utils.js +5 -1
  13. package/src/generators/convert-to-flat-config/converters/json-converter.d.ts +6 -1
  14. package/src/generators/convert-to-flat-config/converters/json-converter.js +28 -33
  15. package/src/generators/convert-to-flat-config/generator.js +73 -17
  16. package/src/generators/convert-to-flat-config/schema.json +1 -1
  17. package/src/generators/init/global-eslint-config.js +9 -5
  18. package/src/generators/init/init-migration.d.ts +1 -1
  19. package/src/generators/init/init-migration.js +53 -15
  20. package/src/generators/init/init.d.ts +5 -5
  21. package/src/generators/init/init.js +63 -35
  22. package/src/generators/init/schema.json +28 -0
  23. package/src/generators/lint-project/lint-project.d.ts +9 -3
  24. package/src/generators/lint-project/lint-project.js +76 -40
  25. package/src/generators/lint-project/setup-root-eslint.d.ts +7 -0
  26. package/src/generators/lint-project/setup-root-eslint.js +33 -0
  27. package/src/generators/utils/eslint-file.d.ts +2 -5
  28. package/src/generators/utils/eslint-file.js +37 -30
  29. package/src/generators/utils/flat-config/ast-utils.d.ts +4 -5
  30. package/src/generators/utils/flat-config/ast-utils.js +41 -40
  31. package/src/generators/utils/flat-config/path-utils.d.ts +2 -1
  32. package/src/generators/utils/flat-config/path-utils.js +9 -12
  33. package/src/generators/utils/plugin.d.ts +2 -0
  34. package/src/generators/utils/plugin.js +11 -0
  35. package/src/generators/workspace-rule/files/__name__.ts__tmpl__ +2 -2
  36. package/src/generators/workspace-rule/schema.json +1 -1
  37. package/src/generators/workspace-rule/workspace-rule.js +7 -2
  38. package/src/generators/workspace-rules-project/files/tsconfig.json__tmpl__ +2 -1
  39. package/src/generators/workspace-rules-project/schema.json +1 -1
  40. package/src/generators/workspace-rules-project/workspace-rules-project.d.ts +3 -2
  41. package/src/generators/workspace-rules-project/workspace-rules-project.js +11 -9
  42. package/src/migrations/update-15-0-0/add-eslint-inputs.js +2 -2
  43. package/src/migrations/update-15-7-1/add-eslint-ignore.js +2 -2
  44. package/src/migrations/update-17-1-0/update-typescript-eslint.d.ts +2 -0
  45. package/src/migrations/update-17-1-0/update-typescript-eslint.js +74 -0
  46. package/src/migrations/update-17-2-0/simplify-eslint-patterns.d.ts +2 -0
  47. package/src/migrations/update-17-2-0/simplify-eslint-patterns.js +46 -0
  48. package/src/migrations/update-17-2-9/move-options-to-target-defaults.d.ts +2 -0
  49. package/src/migrations/update-17-2-9/move-options-to-target-defaults.js +107 -0
  50. package/src/plugins/plugin.d.ts +6 -0
  51. package/src/plugins/plugin.js +117 -0
  52. package/src/utils/config-file.d.ts +4 -0
  53. package/src/utils/config-file.js +18 -0
  54. package/src/utils/versions.d.ts +2 -2
  55. package/src/utils/versions.js +2 -2
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2017-2023 Narwhal Technologies Inc.
3
+ Copyright (c) 2017-2024 Narwhal Technologies Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
package/README.md CHANGED
@@ -1,4 +1,9 @@
1
- <p style="text-align: center;"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx.png" width="600" alt="Nx - Smart, Fast and Extensible Build System"></p>
1
+ <p style="text-align: center;">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
4
+ <img alt="Nx - Smart Monorepos · Fast CI" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
5
+ </picture>
6
+ </p>
2
7
 
3
8
  <div style="text-align: center;">
4
9
 
@@ -15,9 +20,9 @@
15
20
 
16
21
  <hr>
17
22
 
18
- # Nx: Smart, Fast and Extensible Build System
23
+ # Nx: Smart Monorepos · Fast CI
19
24
 
20
- Nx is a next generation build system with first class monorepo support and powerful integrations.
25
+ Nx is a build system with built-in tooling and advanced CI capabilities. It helps you maintain and scale monorepos, both locally and on CI.
21
26
 
22
27
  ## Getting Started
23
28
 
@@ -57,5 +62,5 @@ npx nx@latest init
57
62
  - [Blog Posts About Nx](https://blog.nrwl.io/nx/home)
58
63
 
59
64
  <p style="text-align: center;"><a href="https://nx.dev/#learning-materials" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-courses-and-videos.svg"
60
- width="100%" alt="Nx - Smart, Fast and Extensible Build System"></a></p>
65
+ width="100%" alt="Nx - Smart Monorepos · Fast CI"></a></p>
61
66
 
package/generators.json CHANGED
@@ -2,6 +2,12 @@
2
2
  "name": "nx/eslint",
3
3
  "version": "0.1",
4
4
  "generators": {
5
+ "init": {
6
+ "factory": "./src/generators/init/init#initEsLint",
7
+ "schema": "./src/generators/init/schema.json",
8
+ "description": "Set up the ESLint plugin.",
9
+ "hidden": true
10
+ },
5
11
  "workspace-rules-project": {
6
12
  "factory": "./src/generators/workspace-rules-project/workspace-rules-project#lintWorkspaceRulesProjectGenerator",
7
13
  "schema": "./src/generators/workspace-rules-project/schema.json",
package/migrations.json CHANGED
@@ -27,6 +27,21 @@
27
27
  "version": "17.0.0-beta.7",
28
28
  "description": "update-17-0-0-rename-to-eslint",
29
29
  "implementation": "./src/migrations/update-17-0-0-rename-to-eslint/update-17-0-0-rename-to-eslint"
30
+ },
31
+ "update-typescript-eslint": {
32
+ "version": "17.1.0-beta.1",
33
+ "description": "Updates for @typescript-utils/utils v6.9.1+",
34
+ "implementation": "./src/migrations/update-17-1-0/update-typescript-eslint"
35
+ },
36
+ "simplify-eslint-patterns": {
37
+ "version": "17.2.0-beta.0",
38
+ "description": "Simplify eslintFilePatterns",
39
+ "implementation": "./src/migrations/update-17-2-0/simplify-eslint-patterns"
40
+ },
41
+ "move-options-to-target-defaults": {
42
+ "version": "17.2.9",
43
+ "description": "Move executor options to target defaults",
44
+ "implementation": "./src/migrations/update-17-2-9/move-options-to-target-defaults"
30
45
  }
31
46
  },
32
47
  "packageJsonUpdates": {
@@ -82,6 +97,59 @@
82
97
  "version": "^9.0.0"
83
98
  }
84
99
  }
100
+ },
101
+ "17.1.0": {
102
+ "version": "17.1.0-beta.1",
103
+ "packages": {
104
+ "@typescript-eslint/parser": {
105
+ "version": "^6.9.1"
106
+ },
107
+ "@typescript-eslint/eslint-plugin": {
108
+ "version": "^6.9.1"
109
+ },
110
+ "@typescript-eslint/utils": {
111
+ "version": "^6.9.1"
112
+ }
113
+ }
114
+ },
115
+ "17.2.0": {
116
+ "version": "17.2.0-beta.2",
117
+ "packages": {
118
+ "eslint": {
119
+ "version": "~8.48.0"
120
+ }
121
+ }
122
+ },
123
+ "17.3.0": {
124
+ "version": "17.3.0-beta.0",
125
+ "packages": {
126
+ "@typescript-eslint/parser": {
127
+ "version": "^6.13.2"
128
+ },
129
+ "@typescript-eslint/eslint-plugin": {
130
+ "version": "^6.13.2"
131
+ },
132
+ "@typescript-eslint/utils": {
133
+ "version": "^6.13.2"
134
+ }
135
+ }
136
+ },
137
+ "18.2.0": {
138
+ "version": "18.2.0-beta.0",
139
+ "packages": {
140
+ "@typescript-eslint/parser": {
141
+ "version": "^7.3.0"
142
+ },
143
+ "@typescript-eslint/eslint-plugin": {
144
+ "version": "^7.3.0"
145
+ },
146
+ "@typescript-eslint/utils": {
147
+ "version": "^7.3.0"
148
+ },
149
+ "eslint": {
150
+ "version": "~8.57.0"
151
+ }
152
+ }
85
153
  }
86
154
  }
87
155
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/eslint",
3
- "version": "17.0.2",
3
+ "version": "17.0.4",
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": {
@@ -27,20 +27,21 @@
27
27
  "requirements": {},
28
28
  "migrations": "./migrations.json"
29
29
  },
30
- "executors": "./executors.json",
31
30
  "generators": "./generators.json",
31
+ "executors": "./executors.json",
32
32
  "peerDependencies": {
33
- "eslint": "^8.0.0"
33
+ "js-yaml": "4.1.0"
34
34
  },
35
35
  "dependencies": {
36
+ "@nx/devkit": "17.0.4",
37
+ "@nx/js": "17.0.4",
38
+ "eslint": "^8.0.0",
36
39
  "tslib": "^2.3.0",
37
- "@nx/devkit": "17.0.2",
38
- "@nx/js": "17.0.2",
39
- "typescript": "~5.1.3",
40
- "@nx/linter": "17.0.2"
40
+ "typescript": "~5.4.2",
41
+ "@nx/linter": "17.0.4"
41
42
  },
42
43
  "peerDependenciesMeta": {
43
- "eslint": {
44
+ "js-yaml": {
44
45
  "optional": true
45
46
  }
46
47
  },
package/plugin.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createNodes, EslintPluginOptions } from './src/plugins/plugin';
package/plugin.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodes = void 0;
4
+ var plugin_1 = require("./src/plugins/plugin");
5
+ Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return plugin_1.createNodes; } });
@@ -17,7 +17,7 @@ async function run(task, context) {
17
17
  }
18
18
  const nodes = {};
19
19
  const hashes = [];
20
- for (const d of Object.keys(res.details.nodes)) {
20
+ for (const d of Object.keys(res.details.nodes).sort()) {
21
21
  if (d.indexOf('$fileset') === -1) {
22
22
  nodes[d] = res.details.nodes[d];
23
23
  hashes.push(res.details.nodes[d]);
@@ -4,6 +4,7 @@ const devkit_1 = require("@nx/devkit");
4
4
  const fs_1 = require("fs");
5
5
  const path_1 = require("path");
6
6
  const eslint_utils_1 = require("./utility/eslint-utils");
7
+ const utils_1 = require("nx/src/tasks-runner/utils");
7
8
  async function run(options, context) {
8
9
  // this is only used for the hasher
9
10
  delete options.hasTypeAwareRules;
@@ -13,31 +14,36 @@ async function run(options, context) {
13
14
  // root to be able to run the lint executor from any subfolder.
14
15
  process.chdir(systemRoot);
15
16
  const projectName = context.projectName || '<???>';
17
+ const projectRoot = context.projectsConfigurations.projects[context.projectName].root;
16
18
  const printInfo = options.format && !options.silent;
17
19
  if (printInfo) {
18
20
  console.info(`\nLinting ${JSON.stringify(projectName)}...`);
19
21
  }
20
- /**
21
- * We want users to have the option of not specifying the config path, and let
22
- * eslint automatically resolve the `.eslintrc.json` files in each folder.
23
- */
24
- let eslintConfigPath = options.eslintConfig
25
- ? (0, path_1.resolve)(systemRoot, options.eslintConfig)
26
- : undefined;
27
22
  options.cacheLocation = options.cacheLocation
28
23
  ? (0, devkit_1.joinPathFragments)(options.cacheLocation, projectName)
29
24
  : undefined;
30
- const { printConfig, ...normalizedOptions } = options;
25
+ const { printConfig, errorOnUnmatchedPattern, ...normalizedOptions } = options;
31
26
  /**
32
27
  * Until ESLint v9 is released and the new so called flat config is the default
33
28
  * we only want to support it if the user has explicitly opted into it by converting
34
29
  * their root ESLint config to use eslint.config.js
35
30
  */
36
31
  const hasFlatConfig = (0, fs_1.existsSync)((0, devkit_1.joinPathFragments)(devkit_1.workspaceRoot, 'eslint.config.js'));
37
- if (!eslintConfigPath && hasFlatConfig) {
38
- const projectRoot = context.projectsConfigurations.projects[context.projectName].root;
39
- eslintConfigPath = (0, devkit_1.joinPathFragments)(projectRoot, 'eslint.config.js');
32
+ // while standard eslint uses by default closest config to the file, if otherwise not specified,
33
+ // the flat config would always use the root config, so we need to explicitly set it to the local one
34
+ if (hasFlatConfig && !normalizedOptions.eslintConfig) {
35
+ const eslintConfigPath = (0, devkit_1.joinPathFragments)(projectRoot, 'eslint.config.js');
36
+ if ((0, fs_1.existsSync)(eslintConfigPath)) {
37
+ normalizedOptions.eslintConfig = eslintConfigPath;
38
+ }
40
39
  }
40
+ /**
41
+ * We want users to have the option of not specifying the config path, and let
42
+ * eslint automatically resolve the `.eslintrc.json` files in each folder.
43
+ */
44
+ let eslintConfigPath = normalizedOptions.eslintConfig
45
+ ? (0, path_1.resolve)(systemRoot, normalizedOptions.eslintConfig)
46
+ : undefined;
41
47
  const { eslint, ESLint } = await (0, eslint_utils_1.resolveAndInstantiateESLint)(eslintConfigPath, normalizedOptions, hasFlatConfig);
42
48
  const version = ESLint.version?.split('.');
43
49
  if (!version ||
@@ -62,18 +68,26 @@ async function run(options, context) {
62
68
  }
63
69
  }
64
70
  let lintResults = [];
71
+ const normalizedLintFilePatterns = normalizedOptions.lintFilePatterns.map((pattern) => {
72
+ return (0, utils_1.interpolate)(pattern, {
73
+ workspaceRoot: '',
74
+ projectRoot,
75
+ projectName: context.projectName,
76
+ });
77
+ });
65
78
  try {
66
- lintResults = await eslint.lintFiles(normalizedOptions.lintFilePatterns);
79
+ lintResults = await eslint.lintFiles(normalizedLintFilePatterns);
67
80
  }
68
81
  catch (err) {
69
82
  if (err.message.includes('You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser')) {
83
+ const ruleName = err.message.match(/rule '([^']+)':/)?.[1];
70
84
  let eslintConfigPathForError = `for ${projectName}`;
71
85
  if (context.projectsConfigurations?.projects?.[projectName]?.root) {
72
86
  const { root } = context.projectsConfigurations.projects[projectName];
73
87
  eslintConfigPathForError = `\`${root}/.eslintrc.json\``;
74
88
  }
75
89
  console.error(`
76
- Error: You have attempted to use a lint rule which requires the full TypeScript type-checker to be available, but you do not have \`parserOptions.project\` configured to point at your project tsconfig.json files in the relevant TypeScript file "overrides" block of your project ESLint config ${eslintConfigPath || eslintConfigPathForError}
90
+ Error: You have attempted to use ${ruleName ? `the lint rule ${ruleName}` : 'a lint rule'} which requires the full TypeScript type-checker to be available, but you do not have \`parserOptions.project\` configured to point at your project tsconfig.json files in the relevant TypeScript file "overrides" block of your project ESLint config ${eslintConfigPath || eslintConfigPathForError}
77
91
 
78
92
  Please see https://nx.dev/guides/eslint for full guidance on how to resolve this issue.
79
93
  `);
@@ -84,8 +98,8 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
84
98
  // If some unexpected error, rethrow
85
99
  throw err;
86
100
  }
87
- if (lintResults.length === 0) {
88
- const ignoredPatterns = (await Promise.all(normalizedOptions.lintFilePatterns.map(async (pattern) => (await eslint.isPathIgnored(pattern)) ? pattern : null)))
101
+ if (lintResults.length === 0 && errorOnUnmatchedPattern) {
102
+ const ignoredPatterns = (await Promise.all(normalizedLintFilePatterns.map(async (pattern) => (await eslint.isPathIgnored(pattern)) ? pattern : null)))
89
103
  .filter((pattern) => !!pattern)
90
104
  .map((pattern) => `- '${pattern}'`);
91
105
  if (ignoredPatterns.length) {
@@ -104,14 +118,6 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
104
118
  lintResults = ESLint.getErrorResults(lintResults);
105
119
  }
106
120
  const formatter = await eslint.loadFormatter(normalizedOptions.format);
107
- let totalErrors = 0;
108
- let totalWarnings = 0;
109
- for (const result of lintResults) {
110
- if (result.errorCount || result.warningCount) {
111
- totalErrors += result.errorCount;
112
- totalWarnings += result.warningCount;
113
- }
114
- }
115
121
  const formattedResults = await formatter.format(lintResults);
116
122
  if (normalizedOptions.outputFile) {
117
123
  const pathToOutputFile = (0, devkit_1.joinPathFragments)(context.root, normalizedOptions.outputFile);
@@ -121,20 +127,48 @@ Please see https://nx.dev/guides/eslint for full guidance on how to resolve this
121
127
  else {
122
128
  console.info(formattedResults);
123
129
  }
124
- if (totalWarnings > 0 && printInfo) {
125
- console.warn('Lint warnings found in the listed files.\n');
126
- }
127
- if (totalErrors > 0 && printInfo) {
128
- console.error('Lint errors found in the listed files.\n');
129
- }
130
- if (totalWarnings === 0 && totalErrors === 0 && printInfo) {
131
- console.info('All files pass linting.\n');
130
+ const totals = getTotals(lintResults);
131
+ if (printInfo) {
132
+ outputPrintInfo(totals);
132
133
  }
133
134
  return {
134
135
  success: normalizedOptions.force ||
135
- (totalErrors === 0 &&
136
+ (totals.errors === 0 &&
136
137
  (normalizedOptions.maxWarnings === -1 ||
137
- totalWarnings <= normalizedOptions.maxWarnings)),
138
+ totals.warnings <= normalizedOptions.maxWarnings)),
138
139
  };
139
140
  }
140
141
  exports.default = run;
142
+ function getTotals(lintResults) {
143
+ let errors = 0;
144
+ let warnings = 0;
145
+ let fixableErrors = 0;
146
+ let fixableWarnings = 0;
147
+ for (const result of lintResults) {
148
+ errors += result.errorCount || 0;
149
+ warnings += result.warningCount || 0;
150
+ fixableErrors += result.fixableErrorCount || 0;
151
+ fixableWarnings += result.fixableWarningCount || 0;
152
+ }
153
+ return {
154
+ errors,
155
+ warnings,
156
+ fixableErrors,
157
+ fixableWarnings,
158
+ };
159
+ }
160
+ function pluralizedOutput(word, count) {
161
+ return `${count} ${word}${count === 1 ? '' : 's'}`;
162
+ }
163
+ function outputPrintInfo({ errors, warnings, fixableErrors, fixableWarnings, }) {
164
+ const total = warnings + errors;
165
+ const totalFixable = fixableErrors + fixableWarnings;
166
+ if (total <= 0) {
167
+ console.info('\u2714 All files pass linting\n');
168
+ return;
169
+ }
170
+ console.info(`\u2716 ${pluralizedOutput('problem', total)} (${pluralizedOutput('error', errors)}, ${pluralizedOutput('warning', warnings)})\n`);
171
+ if (totalFixable <= 0)
172
+ return;
173
+ console.info(` ${pluralizedOutput('error', fixableErrors)} and ${pluralizedOutput('warning', fixableWarnings)} are potentially fixable with the \`--fix\` option.\n`);
174
+ }
@@ -21,6 +21,7 @@ export interface Schema extends JsonObject {
21
21
  resolvePluginsRelativeTo: string | null;
22
22
  reportUnusedDisableDirectives: Linter.StringSeverity | null;
23
23
  printConfig?: string | null;
24
+ errorOnUnmatchedPattern?: boolean;
24
25
  }
25
26
 
26
27
  type Formatter =
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 2,
3
3
  "outputCapture": "direct-nodejs",
4
- "$schema": "http://json-schema.org/schema",
4
+ "$schema": "https://json-schema.org/schema",
5
5
  "title": "ESLint Lint Target",
6
6
  "description": "ESLint Lint Target.",
7
7
  "cli": "nx",
@@ -17,7 +17,7 @@
17
17
  "lintFilePatterns": {
18
18
  "type": "array",
19
19
  "description": "One or more files/dirs/globs to pass directly to ESLint's `lintFiles()` method.",
20
- "default": [],
20
+ "default": ["{projectRoot}"],
21
21
  "items": {
22
22
  "type": "string"
23
23
  }
@@ -137,8 +137,12 @@
137
137
  "type": "string",
138
138
  "description": "The equivalent of the `--print-config` flag on the ESLint CLI.",
139
139
  "x-completion-type": "file"
140
+ },
141
+ "errorOnUnmatchedPattern": {
142
+ "type": "boolean",
143
+ "description": "When set to false, equivalent of the `--no-error-on-unmatched-pattern` flag on the ESLint CLI.",
144
+ "default": true
140
145
  }
141
146
  },
142
- "required": ["lintFilePatterns"],
143
147
  "examplesFile": "../../../docs/eslint-examples.md"
144
148
  }
@@ -38,7 +38,6 @@ async function resolveAndInstantiateESLint(eslintConfigPath, options, useFlatCon
38
38
  * not be any html files in the project, so keeping it true would break linting every time
39
39
  */
40
40
  errorOnUnmatchedPattern: false,
41
- reportUnusedDisableDirectives: options.reportUnusedDisableDirectives || undefined,
42
41
  };
43
42
  if (useFlatConfig) {
44
43
  if (typeof options.useEslintrc !== 'undefined') {
@@ -50,6 +49,9 @@ async function resolveAndInstantiateESLint(eslintConfigPath, options, useFlatCon
50
49
  if (options.ignorePath !== undefined) {
51
50
  throw new Error('For Flat Config, ESLint removed `ignorePath` and so it is not supported as an option. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
52
51
  }
52
+ if (options.reportUnusedDisableDirectives) {
53
+ throw new Error('For Flat Config, ESLint removed `reportedUnusedDisableDirectives` and so it is not supported as an option. See https://eslint.org/docs/latest/use/configure/configuration-files-new');
54
+ }
53
55
  }
54
56
  else {
55
57
  eslintOptions.rulePaths = options.rulesdir || [];
@@ -61,6 +63,8 @@ async function resolveAndInstantiateESLint(eslintConfigPath, options, useFlatCon
61
63
  * merge the provided config with others it finds automatically.
62
64
  */
63
65
  eslintOptions.useEslintrc = !options.noEslintrc;
66
+ eslintOptions.reportUnusedDisableDirectives =
67
+ options.reportUnusedDisableDirectives || undefined;
64
68
  }
65
69
  const eslint = new ESLint(eslintOptions);
66
70
  return {
@@ -1,6 +1,11 @@
1
1
  import { Tree } from '@nx/devkit';
2
+ import { ESLint } from 'eslint';
2
3
  /**
3
4
  * Converts an ESLint JSON config to a flat config.
4
5
  * Deletes the original file along with .eslintignore if it exists.
5
6
  */
6
- export declare function convertEslintJsonToFlatConfig(tree: Tree, root: string, sourceFile: string, destinationFile: string): void;
7
+ export declare function convertEslintJsonToFlatConfig(tree: Tree, root: string, config: ESLint.ConfigData, ignorePaths: string[]): {
8
+ content: string;
9
+ addESLintRC: boolean;
10
+ addESLintJS: boolean;
11
+ };
@@ -2,25 +2,25 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertEslintJsonToFlatConfig = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
- const path_1 = require("path");
6
5
  const ts = require("typescript");
7
- const versions_1 = require("../../../utils/versions");
8
6
  const ast_utils_1 = require("../../utils/flat-config/ast-utils");
9
7
  const eslint_file_1 = require("../../utils/eslint-file");
8
+ const path_utils_1 = require("../../utils/flat-config/path-utils");
10
9
  /**
11
10
  * Converts an ESLint JSON config to a flat config.
12
11
  * Deletes the original file along with .eslintignore if it exists.
13
12
  */
14
- function convertEslintJsonToFlatConfig(tree, root, sourceFile, destinationFile) {
13
+ function convertEslintJsonToFlatConfig(tree, root, config, ignorePaths) {
15
14
  const importsMap = new Map();
16
15
  const exportElements = [];
17
16
  let isFlatCompatNeeded = false;
17
+ let isESLintJSNeeded = false;
18
18
  let combinedConfig = [];
19
19
  let languageOptions = [];
20
- // read original config
21
- const config = (0, devkit_1.readJson)(tree, `${root}/${sourceFile}`);
22
20
  if (config.extends) {
23
- isFlatCompatNeeded = addExtends(importsMap, exportElements, config, tree);
21
+ const extendsResult = addExtends(importsMap, exportElements, config);
22
+ isFlatCompatNeeded = extendsResult.isFlatCompatNeeded;
23
+ isESLintJSNeeded = extendsResult.isESLintJSNeeded;
24
24
  }
25
25
  if (config.plugins) {
26
26
  addPlugins(importsMap, exportElements, config);
@@ -70,7 +70,7 @@ function convertEslintJsonToFlatConfig(tree, root, sourceFile, destinationFile)
70
70
  override.parser) {
71
71
  isFlatCompatNeeded = true;
72
72
  }
73
- exportElements.push((0, ast_utils_1.generateFlatOverride)(override, root));
73
+ exportElements.push((0, ast_utils_1.generateFlatOverride)(override));
74
74
  });
75
75
  }
76
76
  if (config.ignorePatterns) {
@@ -79,36 +79,35 @@ function convertEslintJsonToFlatConfig(tree, root, sourceFile, destinationFile)
79
79
  : [config.ignorePatterns]).filter((pattern) => !['**/*', '!**/*', 'node_modules'].includes(pattern)); // these are useless in a flat config
80
80
  if (patterns.length > 0) {
81
81
  exportElements.push((0, ast_utils_1.generateAst)({
82
- ignores: patterns.map((path) => (0, ast_utils_1.mapFilePath)(path, root)),
82
+ ignores: patterns.map((path) => (0, path_utils_1.mapFilePath)(path)),
83
83
  }));
84
84
  }
85
85
  }
86
- if (tree.exists(`${root}/.eslintignore`)) {
87
- const patterns = tree
88
- .read(`${root}/.eslintignore`, 'utf-8')
89
- .split('\n')
90
- .filter((line) => line.length > 0 && line !== 'node_modules')
91
- .map((path) => (0, ast_utils_1.mapFilePath)(path, root));
92
- if (patterns.length > 0) {
93
- exportElements.push((0, ast_utils_1.generateAst)({ ignores: patterns }));
86
+ for (const ignorePath of ignorePaths) {
87
+ if (tree.exists(ignorePath)) {
88
+ const patterns = tree
89
+ .read(ignorePath, 'utf-8')
90
+ .split('\n')
91
+ .filter((line) => line.length > 0 && line !== 'node_modules')
92
+ .map((path) => (0, path_utils_1.mapFilePath)(path));
93
+ if (patterns.length > 0) {
94
+ exportElements.push((0, ast_utils_1.generateAst)({ ignores: patterns }));
95
+ }
94
96
  }
95
97
  }
96
- tree.delete((0, path_1.join)(root, sourceFile));
97
- tree.delete((0, path_1.join)(root, '.eslintignore'));
98
98
  // create the node list and print it to new file
99
99
  const nodeList = (0, ast_utils_1.createNodeList)(importsMap, exportElements, isFlatCompatNeeded);
100
- const content = (0, ast_utils_1.stringifyNodeList)(nodeList, root, destinationFile);
101
- tree.write((0, path_1.join)(root, destinationFile), content);
102
- if (isFlatCompatNeeded) {
103
- (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
104
- '@eslint/eslintrc': versions_1.eslintrcVersion,
105
- });
106
- }
100
+ return {
101
+ content: (0, ast_utils_1.stringifyNodeList)(nodeList),
102
+ addESLintRC: isFlatCompatNeeded,
103
+ addESLintJS: isESLintJSNeeded,
104
+ };
107
105
  }
108
106
  exports.convertEslintJsonToFlatConfig = convertEslintJsonToFlatConfig;
109
107
  // add parsed extends to export blocks and add import statements
110
- function addExtends(importsMap, configBlocks, config, tree) {
108
+ function addExtends(importsMap, configBlocks, config) {
111
109
  let isFlatCompatNeeded = false;
110
+ let isESLintJSNeeded = false;
112
111
  const extendsConfig = Array.isArray(config.extends)
113
112
  ? config.extends
114
113
  : [config.extends];
@@ -137,9 +136,7 @@ function addExtends(importsMap, configBlocks, config, tree) {
137
136
  }
138
137
  });
139
138
  if (eslintPluginExtends.length) {
140
- (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
141
- '@eslint/js': versions_1.eslintVersion,
142
- });
139
+ isESLintJSNeeded = true;
143
140
  importsMap.set('@eslint/js', 'js');
144
141
  eslintPluginExtends.forEach((plugin) => {
145
142
  configBlocks.push(ts.factory.createPropertyAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('js'), ts.factory.createIdentifier('configs')), ts.factory.createIdentifier(plugin.slice(7)) // strip 'eslint:' prefix
@@ -149,12 +146,10 @@ function addExtends(importsMap, configBlocks, config, tree) {
149
146
  }
150
147
  if (eslintrcConfigs.length) {
151
148
  isFlatCompatNeeded = true;
152
- (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
153
- '@eslint/js': versions_1.eslintVersion,
154
- });
149
+ isESLintJSNeeded = true;
155
150
  configBlocks.push((0, ast_utils_1.generatePluginExtendsElement)(eslintrcConfigs));
156
151
  }
157
- return isFlatCompatNeeded;
152
+ return { isFlatCompatNeeded, isESLintJSNeeded };
158
153
  }
159
154
  function addPlugins(importsMap, configBlocks, config) {
160
155
  const mappedPlugins = [];