@nx/eslint 17.2.0-beta.3 → 17.2.0-beta.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/eslint",
3
- "version": "17.2.0-beta.3",
3
+ "version": "17.2.0-beta.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": {
@@ -30,18 +30,22 @@
30
30
  "executors": "./executors.json",
31
31
  "generators": "./generators.json",
32
32
  "peerDependencies": {
33
- "eslint": "^8.0.0"
33
+ "eslint": "^8.0.0",
34
+ "js-yaml": "4.1.0"
34
35
  },
35
36
  "dependencies": {
36
37
  "tslib": "^2.3.0",
37
- "@nx/devkit": "17.2.0-beta.3",
38
- "@nx/js": "17.2.0-beta.3",
38
+ "@nx/devkit": "17.2.0-beta.4",
39
+ "@nx/js": "17.2.0-beta.4",
39
40
  "typescript": "~5.2.2",
40
- "@nx/linter": "17.2.0-beta.3"
41
+ "@nx/linter": "17.2.0-beta.4"
41
42
  },
42
43
  "peerDependenciesMeta": {
43
44
  "eslint": {
44
45
  "optional": true
46
+ },
47
+ "js-yaml": {
48
+ "optional": true
45
49
  }
46
50
  },
47
51
  "publishConfig": {
@@ -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, ignorePaths: 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,24 @@
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");
10
8
  /**
11
9
  * Converts an ESLint JSON config to a flat config.
12
10
  * Deletes the original file along with .eslintignore if it exists.
13
11
  */
14
- function convertEslintJsonToFlatConfig(tree, root, sourceFile, destinationFile, ignorePaths) {
12
+ function convertEslintJsonToFlatConfig(tree, root, config, ignorePaths) {
15
13
  const importsMap = new Map();
16
14
  const exportElements = [];
17
15
  let isFlatCompatNeeded = false;
16
+ let isESLintJSNeeded = false;
18
17
  let combinedConfig = [];
19
18
  let languageOptions = [];
20
- // read original config
21
- const config = (0, devkit_1.readJson)(tree, `${root}/${sourceFile}`);
22
19
  if (config.extends) {
23
- isFlatCompatNeeded = addExtends(importsMap, exportElements, config, tree);
20
+ const extendsResult = addExtends(importsMap, exportElements, config);
21
+ isFlatCompatNeeded = extendsResult.isFlatCompatNeeded;
22
+ isESLintJSNeeded = extendsResult.isESLintJSNeeded;
24
23
  }
25
24
  if (config.plugins) {
26
25
  addPlugins(importsMap, exportElements, config);
@@ -95,21 +94,19 @@ function convertEslintJsonToFlatConfig(tree, root, sourceFile, destinationFile,
95
94
  }
96
95
  }
97
96
  }
98
- tree.delete((0, path_1.join)(root, sourceFile));
99
97
  // create the node list and print it to new file
100
98
  const nodeList = (0, ast_utils_1.createNodeList)(importsMap, exportElements, isFlatCompatNeeded);
101
- const content = (0, ast_utils_1.stringifyNodeList)(nodeList, root, destinationFile);
102
- tree.write((0, path_1.join)(root, destinationFile), content);
103
- if (isFlatCompatNeeded) {
104
- (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
105
- '@eslint/eslintrc': versions_1.eslintrcVersion,
106
- });
107
- }
99
+ return {
100
+ content: (0, ast_utils_1.stringifyNodeList)(nodeList, root),
101
+ addESLintRC: isFlatCompatNeeded,
102
+ addESLintJS: isESLintJSNeeded,
103
+ };
108
104
  }
109
105
  exports.convertEslintJsonToFlatConfig = convertEslintJsonToFlatConfig;
110
106
  // add parsed extends to export blocks and add import statements
111
- function addExtends(importsMap, configBlocks, config, tree) {
107
+ function addExtends(importsMap, configBlocks, config) {
112
108
  let isFlatCompatNeeded = false;
109
+ let isESLintJSNeeded = false;
113
110
  const extendsConfig = Array.isArray(config.extends)
114
111
  ? config.extends
115
112
  : [config.extends];
@@ -138,9 +135,7 @@ function addExtends(importsMap, configBlocks, config, tree) {
138
135
  }
139
136
  });
140
137
  if (eslintPluginExtends.length) {
141
- (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
142
- '@eslint/js': versions_1.eslintVersion,
143
- });
138
+ isESLintJSNeeded = true;
144
139
  importsMap.set('@eslint/js', 'js');
145
140
  eslintPluginExtends.forEach((plugin) => {
146
141
  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
@@ -150,12 +145,10 @@ function addExtends(importsMap, configBlocks, config, tree) {
150
145
  }
151
146
  if (eslintrcConfigs.length) {
152
147
  isFlatCompatNeeded = true;
153
- (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
154
- '@eslint/js': versions_1.eslintVersion,
155
- });
148
+ isESLintJSNeeded = true;
156
149
  configBlocks.push((0, ast_utils_1.generatePluginExtendsElement)(eslintrcConfigs));
157
150
  }
158
- return isFlatCompatNeeded;
151
+ return { isFlatCompatNeeded, isESLintJSNeeded };
159
152
  }
160
153
  function addPlugins(importsMap, configBlocks, config) {
161
154
  const mappedPlugins = [];
@@ -3,14 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertToFlatConfigGenerator = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
5
  const eslint_file_1 = require("../utils/eslint-file");
6
+ const path_1 = require("path");
7
+ const versions_1 = require("../../utils/versions");
6
8
  const json_converter_1 = require("./converters/json-converter");
9
+ const js_yaml_1 = require("js-yaml");
7
10
  async function convertToFlatConfigGenerator(tree, options) {
8
11
  const eslintFile = (0, eslint_file_1.findEslintFile)(tree);
9
12
  if (!eslintFile) {
10
13
  throw new Error('Could not find root eslint file');
11
14
  }
12
- if (!eslintFile.endsWith('.json')) {
13
- throw new Error('Only json eslint config files are supported for conversion');
15
+ if (eslintFile.endsWith('.js')) {
16
+ throw new Error('Only json and yaml eslint config files are supported for conversion');
14
17
  }
15
18
  const eslintIgnoreFiles = new Set(['.eslintignore']);
16
19
  // convert root eslint config to eslint.config.js
@@ -34,13 +37,14 @@ async function convertToFlatConfigGenerator(tree, options) {
34
37
  exports.convertToFlatConfigGenerator = convertToFlatConfigGenerator;
35
38
  exports.default = convertToFlatConfigGenerator;
36
39
  function convertRootToFlatConfig(tree, eslintFile) {
37
- if (eslintFile.endsWith('.base.json')) {
38
- convertConfigToFlatConfig(tree, '', '.eslintrc.base.json', 'eslint.base.config.js');
40
+ if (/\.base\.(js|json|yml|yaml)$/.test(eslintFile)) {
41
+ convertConfigToFlatConfig(tree, '', eslintFile, 'eslint.base.config.js');
39
42
  }
40
- convertConfigToFlatConfig(tree, '', '.eslintrc.json', 'eslint.config.js');
43
+ convertConfigToFlatConfig(tree, '', eslintFile.replace('.base.', '.'), 'eslint.config.js');
41
44
  }
42
45
  function convertProjectToFlatConfig(tree, project, projectConfig, nxJson, eslintIgnoreFiles) {
43
- if (tree.exists(`${projectConfig.root}/.eslintrc.json`)) {
46
+ const eslintFile = (0, eslint_file_1.findEslintFile)(tree, projectConfig.root);
47
+ if (eslintFile && !eslintFile.endsWith('.js')) {
44
48
  if (projectConfig.targets) {
45
49
  const eslintTargets = Object.keys(projectConfig.targets || {}).filter((t) => projectConfig.targets[t].executor === '@nx/eslint:lint');
46
50
  let ignorePath;
@@ -59,7 +63,7 @@ function convertProjectToFlatConfig(tree, project, projectConfig, nxJson, eslint
59
63
  nxJson.targetDefaults[t].executor === '@nx/eslint:lint') &&
60
64
  projectConfig.targets?.[t]);
61
65
  if (nxHasLintTargets || eslintTargets.length > 0) {
62
- convertConfigToFlatConfig(tree, projectConfig.root, '.eslintrc.json', 'eslint.config.js', ignorePath);
66
+ convertConfigToFlatConfig(tree, projectConfig.root, eslintFile, 'eslint.config.js', ignorePath);
63
67
  eslintIgnoreFiles.add(`${projectConfig.root}/.eslintignore`);
64
68
  if (ignorePath) {
65
69
  eslintIgnoreFiles.add(ignorePath);
@@ -96,5 +100,35 @@ function convertConfigToFlatConfig(tree, root, source, target, ignorePath) {
96
100
  const ignorePaths = ignorePath
97
101
  ? [ignorePath, `${root}/.eslintignore`]
98
102
  : [`${root}/.eslintignore`];
99
- (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, source, target, ignorePaths);
103
+ if (source.endsWith('.json')) {
104
+ const config = (0, devkit_1.readJson)(tree, `${root}/${source}`);
105
+ const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths);
106
+ return processConvertedConfig(tree, root, source, target, conversionResult);
107
+ }
108
+ if (source.endsWith('.yaml') || source.endsWith('.yml')) {
109
+ const originalContent = tree.read(`${root}/${source}`, 'utf-8');
110
+ const config = (0, js_yaml_1.load)(originalContent, {
111
+ json: true,
112
+ filename: source,
113
+ });
114
+ const conversionResult = (0, json_converter_1.convertEslintJsonToFlatConfig)(tree, root, config, ignorePaths);
115
+ return processConvertedConfig(tree, root, source, target, conversionResult);
116
+ }
117
+ }
118
+ function processConvertedConfig(tree, root, source, target, { content, addESLintRC, addESLintJS, }) {
119
+ // remove original config file
120
+ tree.delete((0, path_1.join)(root, source));
121
+ // save new
122
+ tree.write((0, path_1.join)(root, target), content);
123
+ // add missing packages
124
+ if (addESLintRC) {
125
+ (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
126
+ '@eslint/eslintrc': versions_1.eslintrcVersion,
127
+ });
128
+ }
129
+ if (addESLintJS) {
130
+ (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
131
+ '@eslint/js': versions_1.eslintVersion,
132
+ });
133
+ }
100
134
  }
@@ -80,7 +80,7 @@ const getGlobalEsLintConfiguration = (unitTestRunner, rootProject) => {
80
80
  exports.getGlobalEsLintConfiguration = getGlobalEsLintConfiguration;
81
81
  const getGlobalFlatEslintConfiguration = (unitTestRunner, rootProject) => {
82
82
  const nodeList = (0, ast_utils_1.createNodeList)(new Map(), [], true);
83
- let content = (0, ast_utils_1.stringifyNodeList)(nodeList, '', 'eslint.config.js');
83
+ let content = (0, ast_utils_1.stringifyNodeList)(nodeList, '');
84
84
  content = (0, ast_utils_1.addImportToFlatConfig)(content, 'nxPlugin', '@nx/eslint-plugin');
85
85
  content = (0, ast_utils_1.addPluginsToExportsBlock)(content, [
86
86
  { name: '@nx', varName: 'nxPlugin', imp: '@nx/eslint-plugin' },
@@ -140,7 +140,7 @@ function createEsLintConfiguration(tree, projectConfig, setParserOptionsProject)
140
140
  nodes.push((0, ast_utils_1.generateFlatOverride)(override, projectConfig.root));
141
141
  });
142
142
  const nodeList = (0, ast_utils_1.createNodeList)(importMap, nodes, isCompatNeeded);
143
- const content = (0, ast_utils_1.stringifyNodeList)(nodeList, projectConfig.root, 'eslint.config.js');
143
+ const content = (0, ast_utils_1.stringifyNodeList)(nodeList, projectConfig.root);
144
144
  tree.write((0, path_1.join)(projectConfig.root, 'eslint.config.js'), content);
145
145
  }
146
146
  else {
@@ -44,7 +44,7 @@ export declare function generatePluginExtendsElement(plugins: string[]): ts.Spre
44
44
  /**
45
45
  * Stringifies TS nodes to file content string
46
46
  */
47
- export declare function stringifyNodeList(nodes: ts.NodeArray<ts.VariableStatement | ts.Identifier | ts.ExpressionStatement | ts.SourceFile>, root: string, fileName: string): string;
47
+ export declare function stringifyNodeList(nodes: ts.NodeArray<ts.VariableStatement | ts.Identifier | ts.ExpressionStatement | ts.SourceFile>, root: string): string;
48
48
  /**
49
49
  * generates AST require statement
50
50
  */
@@ -470,10 +470,15 @@ exports.generatePluginExtendsElement = generatePluginExtendsElement;
470
470
  /**
471
471
  * Stringifies TS nodes to file content string
472
472
  */
473
- function stringifyNodeList(nodes, root, fileName) {
473
+ function stringifyNodeList(nodes, root) {
474
474
  const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
475
- const resultFile = ts.createSourceFile((0, devkit_1.joinPathFragments)(root, fileName), '', ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
476
- return printer.printList(ts.ListFormat.MultiLine, nodes, resultFile);
475
+ const resultFile = ts.createSourceFile((0, devkit_1.joinPathFragments)(root, ''), '', ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
476
+ return (printer
477
+ .printList(ts.ListFormat.MultiLine, nodes, resultFile)
478
+ // add new line before compat initialization
479
+ .replace(/const compat = new FlatCompat/, '\nconst compat = new FlatCompat')
480
+ // add new line before module.exports = ...
481
+ .replace(/module\.exports/, '\nmodule.exports'));
477
482
  }
478
483
  exports.stringifyNodeList = stringifyNodeList;
479
484
  /**