@nx/eslint 0.0.0-pr-30715-a5f5e3b → 0.0.0-pr-31222-862e973

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 +1 -1
  3. package/migrations.json +98 -119
  4. package/package.json +7 -6
  5. package/src/executors/lint/utility/eslint-utils.js +0 -6
  6. package/src/generators/convert-to-flat-config/converters/json-converter.d.ts +1 -1
  7. package/src/generators/convert-to-flat-config/converters/json-converter.js +18 -10
  8. package/src/generators/convert-to-flat-config/generator.js +17 -18
  9. package/src/generators/convert-to-flat-config/schema.d.ts +0 -2
  10. package/src/generators/convert-to-inferred/convert-to-inferred.js +1 -2
  11. package/src/generators/init/global-eslint-config.d.ts +1 -1
  12. package/src/generators/init/global-eslint-config.js +6 -17
  13. package/src/generators/init/init-migration.d.ts +1 -1
  14. package/src/generators/init/init-migration.js +13 -18
  15. package/src/generators/init/init.d.ts +0 -1
  16. package/src/generators/init/init.js +6 -31
  17. package/src/generators/lint-project/lint-project.d.ts +0 -1
  18. package/src/generators/lint-project/lint-project.js +15 -37
  19. package/src/generators/lint-project/setup-root-eslint.d.ts +0 -1
  20. package/src/generators/lint-project/setup-root-eslint.js +1 -2
  21. package/src/generators/utils/eslint-file.d.ts +2 -3
  22. package/src/generators/utils/eslint-file.js +28 -160
  23. package/src/generators/utils/flat-config/ast-utils.d.ts +4 -12
  24. package/src/generators/utils/flat-config/ast-utils.js +63 -412
  25. package/src/generators/utils/linter.d.ts +0 -3
  26. package/src/generators/utils/linter.js +2 -2
  27. package/src/generators/workspace-rule/files/__name__.spec.ts__tmpl__ +2 -11
  28. package/src/generators/workspace-rule/workspace-rule.d.ts +2 -2
  29. package/src/generators/workspace-rule/workspace-rule.js +3 -11
  30. package/src/generators/workspace-rules-project/workspace-rules-project.js +1 -4
  31. package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.d.ts +2 -0
  32. package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.js +9 -0
  33. package/src/migrations/update-16-8-0-add-ignored-files/update-16-8-0-add-ignored-files.d.ts +2 -0
  34. package/src/migrations/update-16-8-0-add-ignored-files/update-16-8-0-add-ignored-files.js +44 -0
  35. package/src/migrations/update-17-0-0-rename-to-eslint/update-17-0-0-rename-to-eslint.d.ts +2 -0
  36. package/src/migrations/update-17-0-0-rename-to-eslint/update-17-0-0-rename-to-eslint.js +47 -0
  37. package/src/migrations/update-17-1-0/update-typescript-eslint.d.ts +2 -0
  38. package/src/migrations/update-17-1-0/update-typescript-eslint.js +74 -0
  39. package/src/migrations/update-17-2-0/simplify-eslint-patterns.d.ts +2 -0
  40. package/src/migrations/update-17-2-0/simplify-eslint-patterns.js +46 -0
  41. package/src/migrations/update-17-2-9/move-options-to-target-defaults.d.ts +2 -0
  42. package/src/migrations/update-17-2-9/move-options-to-target-defaults.js +107 -0
  43. package/src/plugins/plugin.js +10 -21
  44. package/src/utils/config-file.d.ts +1 -3
  45. package/src/utils/config-file.js +2 -5
  46. package/src/utils/flat-config.d.ts +0 -1
  47. package/src/utils/flat-config.js +3 -9
  48. package/src/utils/version-utils.d.ts +0 -1
  49. package/src/utils/version-utils.js +9 -13
  50. package/src/utils/versions.d.ts +2 -3
  51. package/src/utils/versions.js +3 -4
  52. package/src/migrations/update-20-2-0/update-typescript-eslint-v8-13-0.d.ts +0 -2
  53. package/src/migrations/update-20-2-0/update-typescript-eslint-v8-13-0.js +0 -23
  54. package/src/migrations/update-20-3-0/add-file-extensions-to-overrides.d.ts +0 -2
  55. package/src/migrations/update-20-3-0/add-file-extensions-to-overrides.js +0 -49
@@ -1,8 +1,6 @@
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;
6
4
  exports.hasOverride = hasOverride;
7
5
  exports.replaceOverride = replaceOverride;
8
6
  exports.addImportToFlatConfig = addImportToFlatConfig;
@@ -19,7 +17,6 @@ exports.generatePluginExtendsElement = generatePluginExtendsElement;
19
17
  exports.generatePluginExtendsElementWithCompatFixup = generatePluginExtendsElementWithCompatFixup;
20
18
  exports.stringifyNodeList = stringifyNodeList;
21
19
  exports.generateRequire = generateRequire;
22
- exports.generateESMImport = generateESMImport;
23
20
  exports.overrideNeedsCompat = overrideNeedsCompat;
24
21
  exports.generateFlatOverride = generateFlatOverride;
25
22
  exports.generateFlatPredefinedConfig = generateFlatPredefinedConfig;
@@ -38,8 +35,7 @@ const SPREAD_ELEMENTS_REGEXP = /\s*\.\.\.[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*,?\n?/g;
38
35
  */
39
36
  function removeOverridesFromLintConfig(content) {
40
37
  const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
41
- const format = content.includes('export default') ? 'mjs' : 'cjs';
42
- const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
38
+ const exportsArray = findAllBlocks(source);
43
39
  if (!exportsArray) {
44
40
  return content;
45
41
  }
@@ -56,16 +52,7 @@ function removeOverridesFromLintConfig(content) {
56
52
  });
57
53
  return (0, devkit_1.applyChangesToString)(content, changes);
58
54
  }
59
- // TODO Change name
60
- function findExportDefault(source) {
61
- return ts.forEachChild(source, function analyze(node) {
62
- if (ts.isExportAssignment(node) &&
63
- ts.isArrayLiteralExpression(node.expression)) {
64
- return node.expression.elements;
65
- }
66
- });
67
- }
68
- function findModuleExports(source) {
55
+ function findAllBlocks(source) {
69
56
  return ts.forEachChild(source, function analyze(node) {
70
57
  if (ts.isExpressionStatement(node) &&
71
58
  ts.isBinaryExpression(node.expression) &&
@@ -75,58 +62,9 @@ function findModuleExports(source) {
75
62
  }
76
63
  });
77
64
  }
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
- }
127
65
  function isOverride(node) {
128
66
  return ((ts.isObjectLiteralExpression(node) &&
129
- node.properties.some((p) => p.name.getText() === 'files' || p.name.getText() === '"files"')) ||
67
+ node.properties.some((p) => p.name.getText() === 'files')) ||
130
68
  // detect ...compat.config(...).map(...)
131
69
  (ts.isSpreadElement(node) &&
132
70
  ts.isCallExpression(node.expression) &&
@@ -136,8 +74,7 @@ function isOverride(node) {
136
74
  }
137
75
  function hasOverride(content, lookup) {
138
76
  const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
139
- const format = content.includes('export default') ? 'mjs' : 'cjs';
140
- const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
77
+ const exportsArray = findAllBlocks(source);
141
78
  if (!exportsArray) {
142
79
  return false;
143
80
  }
@@ -168,16 +105,14 @@ function parseTextToJson(text) {
168
105
  .replace(/'/g, '"')
169
106
  .replace(/\s([a-zA-Z0-9_]+)\s*:/g, ' "$1": ')
170
107
  // stringify any require calls to avoid JSON parsing errors, turn them into just the string value being required
171
- .replace(/require\(['"]([^'"]+)['"]\)/g, '"$1"')
172
- .replace(/\(?await import\(['"]([^'"]+)['"]\)\)?/g, '"$1"'));
108
+ .replace(/require\(['"]([^'"]+)['"]\)/g, '"$1"'));
173
109
  }
174
110
  /**
175
111
  * Finds an override matching the lookup function and applies the update function to it
176
112
  */
177
113
  function replaceOverride(content, root, lookup, update) {
178
114
  const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
179
- const format = content.includes('export default') ? 'mjs' : 'cjs';
180
- const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
115
+ const exportsArray = findAllBlocks(source);
181
116
  if (!exportsArray) {
182
117
  return content;
183
118
  }
@@ -210,17 +145,15 @@ function replaceOverride(content, root, lookup, update) {
210
145
  let updatedData = update(data);
211
146
  if (updatedData) {
212
147
  updatedData = mapFilePaths(updatedData);
213
- const parserReplacement = format === 'mjs'
214
- ? (parser) => `(await import('${parser}'))`
215
- : (parser) => `require('${parser}')`;
216
148
  changes.push({
217
149
  type: devkit_1.ChangeType.Insert,
218
150
  index: start,
219
- text: ' ' +
220
- JSON.stringify(updatedData, null, 2)
221
- .replace(/"parser": "([^"]+)"/g, (_, parser) => `"parser": ${parserReplacement(parser)}`)
222
- .slice(2, -2) // Remove curly braces and start/end line breaks
223
- .replaceAll(/\n/g, '\n '), // Maintain indentation
151
+ text: JSON.stringify(updatedData, null, 2)
152
+ // restore any parser require calls that were stripped during JSON parsing
153
+ .replace(/"parser": "([^"]+)"/g, (_, parser) => {
154
+ return `"parser": require('${parser}')`;
155
+ })
156
+ .slice(2, -2), // remove curly braces and start/end line breaks since we are injecting just properties
224
157
  });
225
158
  }
226
159
  }
@@ -229,89 +162,11 @@ function replaceOverride(content, root, lookup, update) {
229
162
  return (0, devkit_1.applyChangesToString)(content, changes);
230
163
  }
231
164
  /**
232
- * Adding import statement to the top of the file
233
- * The imports are added based on a few rules:
234
- * 1. If it's a default import and matches the variable, return content unchanged.
235
- * 2. If it's a named import and the variables are not part of the import object, add them.
236
- * 3. If no existing import and variable is a string, add a default import.
237
- * 4. If no existing import and variable is an array, add it as an object import.
165
+ * Adding require statement to the top of the file
238
166
  */
239
167
  function addImportToFlatConfig(content, variable, imp) {
240
168
  const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
241
169
  const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
242
- const format = content.includes('export default') ? 'mjs' : 'cjs';
243
- if (format === 'mjs') {
244
- return addESMImportToFlatConfig(source, printer, content, variable, imp);
245
- }
246
- return addCJSImportToFlatConfig(source, printer, content, variable, imp);
247
- }
248
- function addESMImportToFlatConfig(source, printer, content, variable, imp) {
249
- let existingImport;
250
- ts.forEachChild(source, (node) => {
251
- if (ts.isImportDeclaration(node) &&
252
- ts.isStringLiteral(node.moduleSpecifier) &&
253
- node.moduleSpecifier.text === imp) {
254
- existingImport = node;
255
- }
256
- });
257
- // Rule 1:
258
- if (existingImport &&
259
- typeof variable === 'string' &&
260
- existingImport.importClause?.name?.getText() === variable) {
261
- return content;
262
- }
263
- // Rule 2:
264
- if (existingImport &&
265
- existingImport.importClause?.namedBindings &&
266
- Array.isArray(variable)) {
267
- const namedImports = existingImport.importClause
268
- .namedBindings;
269
- const existingElements = namedImports.elements;
270
- // Filter out variables that are already imported
271
- const newVariables = variable.filter((v) => !existingElements.some((e) => e.name.getText() === v));
272
- if (newVariables.length === 0) {
273
- return content;
274
- }
275
- const newImportSpecifiers = newVariables.map((v) => ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(v)));
276
- const lastElement = existingElements[existingElements.length - 1];
277
- const insertIndex = lastElement
278
- ? lastElement.getEnd()
279
- : namedImports.getEnd();
280
- const insertText = printer.printList(ts.ListFormat.NamedImportsOrExportsElements, ts.factory.createNodeArray(newImportSpecifiers), source);
281
- return (0, devkit_1.applyChangesToString)(content, [
282
- {
283
- type: devkit_1.ChangeType.Insert,
284
- index: insertIndex,
285
- text: `, ${insertText}`,
286
- },
287
- ]);
288
- }
289
- // Rule 3:
290
- if (!existingImport && typeof variable === 'string') {
291
- const defaultImport = ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, ts.factory.createIdentifier(variable), undefined), ts.factory.createStringLiteral(imp));
292
- const insert = printer.printNode(ts.EmitHint.Unspecified, defaultImport, source);
293
- return (0, devkit_1.applyChangesToString)(content, [
294
- {
295
- type: devkit_1.ChangeType.Insert,
296
- index: 0,
297
- text: `${insert}\n`,
298
- },
299
- ]);
300
- }
301
- // Rule 4:
302
- if (!existingImport && Array.isArray(variable)) {
303
- const objectImport = ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports(variable.map((v) => ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(v))))), ts.factory.createStringLiteral(imp));
304
- const insert = printer.printNode(ts.EmitHint.Unspecified, objectImport, source);
305
- return (0, devkit_1.applyChangesToString)(content, [
306
- {
307
- type: devkit_1.ChangeType.Insert,
308
- index: 0,
309
- text: `${insert}\n`,
310
- },
311
- ]);
312
- }
313
- }
314
- function addCJSImportToFlatConfig(source, printer, content, variable, imp) {
315
170
  const foundBindingVars = ts.forEachChild(source, function analyze(node) {
316
171
  // we can only combine object binding patterns
317
172
  if (!Array.isArray(variable)) {
@@ -380,48 +235,11 @@ function addCJSImportToFlatConfig(source, printer, content, variable, imp) {
380
235
  },
381
236
  ]);
382
237
  }
383
- function existsAsNamedOrDefaultImport(node, variable) {
384
- const isNamed = node.importClause.namedBindings &&
385
- ts.isNamedImports(node.importClause.namedBindings);
386
- if (Array.isArray(variable)) {
387
- return isNamed || variable.includes(node.importClause?.name?.getText());
388
- }
389
- return ((node.importClause.namedBindings &&
390
- ts.isNamedImports(node.importClause.namedBindings)) ||
391
- node.importClause?.name?.getText() === variable);
392
- }
393
238
  /**
394
239
  * Remove an import from flat config
395
240
  */
396
241
  function removeImportFromFlatConfig(content, variable, imp) {
397
242
  const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
398
- const format = content.includes('export default') ? 'mjs' : 'cjs';
399
- if (format === 'mjs') {
400
- return removeImportFromFlatConfigESM(source, content, variable, imp);
401
- }
402
- else {
403
- return removeImportFromFlatConfigCJS(source, content, variable, imp);
404
- }
405
- }
406
- function removeImportFromFlatConfigESM(source, content, variable, imp) {
407
- const changes = [];
408
- ts.forEachChild(source, (node) => {
409
- // we can only combine object binding patterns
410
- if (ts.isImportDeclaration(node) &&
411
- ts.isStringLiteral(node.moduleSpecifier) &&
412
- node.moduleSpecifier.text === imp &&
413
- node.importClause &&
414
- existsAsNamedOrDefaultImport(node, variable)) {
415
- changes.push({
416
- type: devkit_1.ChangeType.Delete,
417
- start: node.pos,
418
- length: node.end - node.pos,
419
- });
420
- }
421
- });
422
- return (0, devkit_1.applyChangesToString)(content, changes);
423
- }
424
- function removeImportFromFlatConfigCJS(source, content, variable, imp) {
425
243
  const changes = [];
426
244
  ts.forEachChild(source, (node) => {
427
245
  // we can only combine object binding patterns
@@ -444,44 +262,13 @@ function removeImportFromFlatConfigCJS(source, content, variable, imp) {
444
262
  return (0, devkit_1.applyChangesToString)(content, changes);
445
263
  }
446
264
  /**
447
- * Injects new ts.expression to the end of the module.exports or export default array.
265
+ * Injects new ts.expression to the end of the module.exports array.
448
266
  */
449
267
  function addBlockToFlatConfigExport(content, config, options = {
450
268
  insertAtTheEnd: true,
451
269
  }) {
452
270
  const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
453
271
  const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
454
- const format = content.includes('export default') ? 'mjs' : 'cjs';
455
- // find the export default array statement
456
- if (format === 'mjs') {
457
- return addBlockToFlatConfigExportESM(content, config, source, printer, options);
458
- }
459
- else {
460
- return addBlockToFlatConfigExportCJS(content, config, source, printer, options);
461
- }
462
- }
463
- function addBlockToFlatConfigExportESM(content, config, source, printer, options = {
464
- insertAtTheEnd: true,
465
- }) {
466
- const exportDefaultStatement = source.statements.find((statement) => ts.isExportAssignment(statement) &&
467
- ts.isArrayLiteralExpression(statement.expression));
468
- if (!exportDefaultStatement)
469
- return content;
470
- const exportArrayLiteral = exportDefaultStatement.expression;
471
- const updatedArrayElements = options.insertAtTheEnd
472
- ? [...exportArrayLiteral.elements, config]
473
- : [config, ...exportArrayLiteral.elements];
474
- const updatedExportDefault = ts.factory.createExportAssignment(undefined, false, ts.factory.createArrayLiteralExpression(updatedArrayElements, true));
475
- // update the existing export default array
476
- const updatedStatements = source.statements.map((statement) => statement === exportDefaultStatement ? updatedExportDefault : statement);
477
- const updatedSource = ts.factory.updateSourceFile(source, updatedStatements);
478
- return printer
479
- .printFile(updatedSource)
480
- .replace(/export default/, '\nexport default');
481
- }
482
- function addBlockToFlatConfigExportCJS(content, config, source, printer, options = {
483
- insertAtTheEnd: true,
484
- }) {
485
272
  const exportsArray = ts.forEachChild(source, function analyze(node) {
486
273
  if (ts.isExpressionStatement(node) &&
487
274
  ts.isBinaryExpression(node.expression) &&
@@ -495,10 +282,7 @@ function addBlockToFlatConfigExportCJS(content, config, source, printer, options
495
282
  // base config was not generated by Nx.
496
283
  if (!exportsArray)
497
284
  return content;
498
- const insert = ' ' +
499
- printer
500
- .printNode(ts.EmitHint.Expression, config, source)
501
- .replaceAll(/\n/g, '\n ');
285
+ const insert = printer.printNode(ts.EmitHint.Expression, config, source);
502
286
  if (options.insertAtTheEnd) {
503
287
  const index = exportsArray.length > 0
504
288
  ? exportsArray.at(exportsArray.length - 1).end
@@ -517,54 +301,35 @@ function addBlockToFlatConfigExportCJS(content, config, source, printer, options
517
301
  {
518
302
  type: devkit_1.ChangeType.Insert,
519
303
  index,
520
- text: `\n${insert},\n`,
304
+ text: `\n${insert},`,
521
305
  },
522
306
  ]);
523
307
  }
524
308
  }
525
309
  function removePlugin(content, pluginName, pluginImport) {
526
310
  const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
527
- const format = content.includes('export default') ? 'mjs' : 'cjs';
528
311
  const changes = [];
529
- if (format === 'mjs') {
530
- ts.forEachChild(source, function analyze(node) {
531
- if (ts.isImportDeclaration(node) &&
532
- ts.isStringLiteral(node.moduleSpecifier) &&
533
- node.moduleSpecifier.text === pluginImport) {
534
- const importClause = node.importClause;
535
- if ((importClause && importClause.name) ||
536
- (importClause.namedBindings &&
537
- ts.isNamedImports(importClause.namedBindings))) {
538
- changes.push({
539
- type: devkit_1.ChangeType.Delete,
540
- start: node.pos,
541
- length: node.end - node.pos,
542
- });
543
- }
544
- }
545
- });
546
- }
547
- else {
548
- ts.forEachChild(source, function analyze(node) {
549
- if (ts.isVariableStatement(node) &&
550
- ts.isVariableDeclaration(node.declarationList.declarations[0]) &&
551
- ts.isCallExpression(node.declarationList.declarations[0].initializer) &&
552
- node.declarationList.declarations[0].initializer.arguments.length &&
553
- ts.isStringLiteral(node.declarationList.declarations[0].initializer.arguments[0]) &&
554
- node.declarationList.declarations[0].initializer.arguments[0].text ===
555
- pluginImport) {
556
- changes.push({
557
- type: devkit_1.ChangeType.Delete,
558
- start: node.pos,
559
- length: node.end - node.pos,
560
- });
561
- }
562
- });
563
- }
564
312
  ts.forEachChild(source, function analyze(node) {
565
- if (ts.isExportAssignment(node) &&
566
- ts.isArrayLiteralExpression(node.expression)) {
567
- const blockElements = node.expression.elements;
313
+ if (ts.isVariableStatement(node) &&
314
+ ts.isVariableDeclaration(node.declarationList.declarations[0]) &&
315
+ ts.isCallExpression(node.declarationList.declarations[0].initializer) &&
316
+ node.declarationList.declarations[0].initializer.arguments.length &&
317
+ ts.isStringLiteral(node.declarationList.declarations[0].initializer.arguments[0]) &&
318
+ node.declarationList.declarations[0].initializer.arguments[0].text ===
319
+ pluginImport) {
320
+ changes.push({
321
+ type: devkit_1.ChangeType.Delete,
322
+ start: node.pos,
323
+ length: node.end - node.pos,
324
+ });
325
+ }
326
+ });
327
+ ts.forEachChild(source, function analyze(node) {
328
+ if (ts.isExpressionStatement(node) &&
329
+ ts.isBinaryExpression(node.expression) &&
330
+ node.expression.left.getText() === 'module.exports' &&
331
+ ts.isArrayLiteralExpression(node.expression.right)) {
332
+ const blockElements = node.expression.right.elements;
568
333
  blockElements.forEach((element) => {
569
334
  if (ts.isObjectLiteralExpression(element)) {
570
335
  const pluginsElem = element.properties.find((prop) => prop.name?.getText() === 'plugins');
@@ -654,12 +419,7 @@ function removePlugin(content, pluginName, pluginImport) {
654
419
  function removeCompatExtends(content, compatExtends) {
655
420
  const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
656
421
  const changes = [];
657
- const format = content.includes('export default') ? 'mjs' : 'cjs';
658
- const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
659
- if (!exportsArray) {
660
- return content;
661
- }
662
- exportsArray.forEach((node) => {
422
+ findAllBlocks(source)?.forEach((node) => {
663
423
  if (ts.isSpreadElement(node) &&
664
424
  ts.isCallExpression(node.expression) &&
665
425
  ts.isArrowFunction(node.expression.arguments[0]) &&
@@ -693,14 +453,9 @@ function removeCompatExtends(content, compatExtends) {
693
453
  }
694
454
  function removePredefinedConfigs(content, moduleImport, moduleVariable, configs) {
695
455
  const source = ts.createSourceFile('', content, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
696
- const format = content.includes('export default') ? 'mjs' : 'cjs';
697
456
  const changes = [];
698
457
  let removeImport = true;
699
- const exportsArray = format === 'mjs' ? findExportDefault(source) : findModuleExports(source);
700
- if (!exportsArray) {
701
- return content;
702
- }
703
- exportsArray.forEach((node) => {
458
+ findAllBlocks(source)?.forEach((node) => {
704
459
  if (ts.isSpreadElement(node) &&
705
460
  ts.isElementAccessExpression(node.expression) &&
706
461
  ts.isPropertyAccessExpression(node.expression.expression) &&
@@ -745,22 +500,14 @@ function addPluginsToExportsBlock(content, plugins) {
745
500
  * Adds compat if missing to flat config
746
501
  */
747
502
  function addFlatCompatToFlatConfig(content) {
748
- const result = addImportToFlatConfig(content, 'js', '@eslint/js');
749
- const format = content.includes('export default') ? 'mjs' : 'cjs';
503
+ let result = content;
504
+ result = addImportToFlatConfig(result, 'js', '@eslint/js');
750
505
  if (result.includes('const compat = new FlatCompat')) {
751
506
  return result;
752
507
  }
753
- if (format === 'mjs') {
754
- return addFlatCompatToFlatConfigESM(result);
755
- }
756
- else {
757
- return addFlatCompatToFlatConfigCJS(result);
758
- }
759
- }
760
- function addFlatCompatToFlatConfigCJS(content) {
761
- content = addImportToFlatConfig(content, ['FlatCompat'], '@eslint/eslintrc');
762
- const index = content.indexOf('module.exports');
763
- return (0, devkit_1.applyChangesToString)(content, [
508
+ result = addImportToFlatConfig(result, ['FlatCompat'], '@eslint/eslintrc');
509
+ const index = result.indexOf('module.exports');
510
+ return (0, devkit_1.applyChangesToString)(result, [
764
511
  {
765
512
  type: devkit_1.ChangeType.Insert,
766
513
  index: index - 1,
@@ -773,62 +520,25 @@ const compat = new FlatCompat({
773
520
  },
774
521
  ]);
775
522
  }
776
- function addFlatCompatToFlatConfigESM(content) {
777
- const importsToAdd = [
778
- { variable: 'js', module: '@eslint/js' },
779
- { variable: ['fileURLToPath'], module: 'url' },
780
- { variable: ['dirname'], module: 'path' },
781
- { variable: ['FlatCompat'], module: '@eslint/eslintrc' },
782
- ];
783
- for (const { variable, module } of importsToAdd) {
784
- content = addImportToFlatConfig(content, variable, module);
785
- }
786
- const index = content.indexOf('export default');
787
- return (0, devkit_1.applyChangesToString)(content, [
788
- {
789
- type: devkit_1.ChangeType.Insert,
790
- index: index - 1,
791
- text: `
792
- const compat = new FlatCompat({
793
- baseDirectory: dirname(fileURLToPath(import.meta.url)),
794
- recommendedConfig: js.configs.recommended,
795
- });\n
796
- `,
797
- },
798
- ]);
799
- }
800
523
  /**
801
524
  * Generate node list representing the imports and the exports blocks
802
525
  * Optionally add flat compat initialization
803
526
  */
804
- function createNodeList(importsMap, exportElements, format) {
527
+ function createNodeList(importsMap, exportElements) {
805
528
  const importsList = [];
529
+ // generateRequire(varName, imp, ts.factory);
806
530
  Array.from(importsMap.entries()).forEach(([imp, varName]) => {
807
- if (format === 'mjs') {
808
- importsList.push(generateESMImport(varName, imp));
809
- }
810
- else {
811
- importsList.push(generateRequire(varName, imp));
812
- }
531
+ importsList.push(generateRequire(varName, imp));
813
532
  });
814
- const exports = format === 'mjs'
815
- ? generateESMExport(exportElements)
816
- : generateCJSExport(exportElements);
817
533
  return ts.factory.createNodeArray([
818
534
  // add plugin imports
819
535
  ...importsList,
820
536
  ts.createSourceFile('', '', ts.ScriptTarget.Latest, false, ts.ScriptKind.JS),
821
- exports,
537
+ // creates:
538
+ // module.exports = [ ... ];
539
+ ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('module'), ts.factory.createIdentifier('exports')), ts.factory.createToken(ts.SyntaxKind.EqualsToken), ts.factory.createArrayLiteralExpression(exportElements, true))),
822
540
  ]);
823
541
  }
824
- function generateESMExport(elements) {
825
- // creates: export default = [...]
826
- return ts.factory.createExportAssignment(undefined, false, ts.factory.createArrayLiteralExpression(elements, true));
827
- }
828
- function generateCJSExport(elements) {
829
- // creates: module.exports = [...]
830
- return ts.factory.createExpressionStatement(ts.factory.createBinaryExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier('module'), ts.factory.createIdentifier('exports')), ts.factory.createToken(ts.SyntaxKind.EqualsToken), ts.factory.createArrayLiteralExpression(elements, true)));
831
- }
832
542
  function generateSpreadElement(name) {
833
543
  return ts.factory.createSpreadElement(ts.factory.createIdentifier(name));
834
544
  }
@@ -846,17 +556,12 @@ function generatePluginExtendsElementWithCompatFixup(plugin) {
846
556
  function stringifyNodeList(nodes) {
847
557
  const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
848
558
  const resultFile = ts.createSourceFile('', '', ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
849
- const result = printer
559
+ return (printer
850
560
  .printList(ts.ListFormat.MultiLine, nodes, resultFile)
851
561
  // add new line before compat initialization
852
- .replace(/const compat = new FlatCompat/, '\nconst compat = new FlatCompat');
853
- if (result.includes('export default')) {
854
- return result // add new line before export default = ...
855
- .replace(/export default/, '\nexport default');
856
- }
857
- else {
858
- return result.replace(/module.exports/, '\nmodule.exports');
859
- }
562
+ .replace(/const compat = new FlatCompat/, '\nconst compat = new FlatCompat')
563
+ // add new line before module.exports = ...
564
+ .replace(/module\.exports/, '\nmodule.exports'));
860
565
  }
861
566
  /**
862
567
  * generates AST require statement
@@ -866,26 +571,6 @@ function generateRequire(variableName, imp) {
866
571
  ts.factory.createVariableDeclaration(variableName, undefined, undefined, ts.factory.createCallExpression(ts.factory.createIdentifier('require'), undefined, [ts.factory.createStringLiteral(imp)])),
867
572
  ], ts.NodeFlags.Const));
868
573
  }
869
- // Top level imports
870
- function generateESMImport(variableName, imp) {
871
- let importClause;
872
- if (typeof variableName === 'string') {
873
- // For single variable import e.g import foo from 'module';
874
- importClause = ts.factory.createImportClause(false, ts.factory.createIdentifier(variableName), undefined);
875
- }
876
- else {
877
- // For object binding pattern import e.g import { a, b, c } from 'module';
878
- importClause = ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports(variableName.elements.map((element) => {
879
- const propertyName = element.propertyName
880
- ? ts.isIdentifier(element.propertyName)
881
- ? element.propertyName
882
- : ts.factory.createIdentifier(element.propertyName.getText())
883
- : undefined;
884
- return ts.factory.createImportSpecifier(false, propertyName, element.name);
885
- })));
886
- }
887
- return ts.factory.createImportDeclaration(undefined, importClause, ts.factory.createStringLiteral(imp));
888
- }
889
574
  /**
890
575
  * FROM: https://github.com/eslint/rewrite/blob/e2a7ec809db20e638abbad250d105ddbde88a8d5/packages/migrate-config/src/migrate-config.js#L222
891
576
  *
@@ -911,7 +596,7 @@ function overrideNeedsCompat(override) {
911
596
  * Generates an AST object or spread element representing a modern flat config entry,
912
597
  * based on a given legacy eslintrc JSON override object
913
598
  */
914
- function generateFlatOverride(_override, format) {
599
+ function generateFlatOverride(_override) {
915
600
  const override = mapFilePaths(_override);
916
601
  // We do not need the compat tooling for this override
917
602
  if (!overrideNeedsCompat(override)) {
@@ -967,41 +652,21 @@ function generateFlatOverride(_override, format) {
967
652
  return propertyAssignment;
968
653
  }
969
654
  else {
970
- // Change parser to import statement.
971
- return format === 'mjs'
972
- ? generateESMParserImport(override)
973
- : generateCJSParserImport(override);
655
+ // Change parser to require statement.
656
+ return ts.factory.createPropertyAssignment('parser', ts.factory.createCallExpression(ts.factory.createIdentifier('require'), undefined, [
657
+ ts.factory.createStringLiteral(override['languageOptions']?.['parserOptions']?.parser ??
658
+ override['languageOptions']?.parser ??
659
+ override.parser),
660
+ ]));
974
661
  }
975
662
  },
976
663
  });
977
664
  }
978
665
  // At this point we are applying the flat config compat tooling to the override
979
- let { excludedFiles, parser, parserOptions, rules, files, ...rest } = override;
666
+ const { excludedFiles, parser, parserOptions, rules, files, ...rest } = override;
980
667
  const objectLiteralElements = [
981
668
  ts.factory.createSpreadAssignment(ts.factory.createIdentifier('config')),
982
669
  ];
983
- // If converting the JS rule, then we need to match ESLint default and also include .cjs and .mjs files.
984
- if ((Array.isArray(rest.extends) &&
985
- rest.extends.includes('plugin:@nx/javascript')) ||
986
- rest.extends === 'plugin:@nx/javascript') {
987
- const newFiles = new Set(files);
988
- newFiles.add('**/*.js');
989
- newFiles.add('**/*.jsx');
990
- newFiles.add('**/*.cjs');
991
- newFiles.add('**/*.mjs');
992
- files = Array.from(newFiles);
993
- }
994
- // If converting the TS rule, then we need to match ESLint default and also include .cts and .mts files.
995
- if ((Array.isArray(rest.extends) &&
996
- rest.extends.includes('plugin:@nx/typescript')) ||
997
- rest.extends === 'plugin:@nx/typescript') {
998
- const newFiles = new Set(files);
999
- newFiles.add('**/*.ts');
1000
- newFiles.add('**/*.tsx');
1001
- newFiles.add('**/*.cts');
1002
- newFiles.add('**/*.mts');
1003
- files = Array.from(newFiles);
1004
- }
1005
670
  addTSObjectProperty(objectLiteralElements, 'files', files);
1006
671
  addTSObjectProperty(objectLiteralElements, 'excludedFiles', excludedFiles);
1007
672
  // Apply rules (and spread ...config.rules into it as the first assignment)
@@ -1025,20 +690,6 @@ function generateFlatOverride(_override, format) {
1025
690
  ], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createParenthesizedExpression(ts.factory.createObjectLiteralExpression(objectLiteralElements, true))),
1026
691
  ]));
1027
692
  }
1028
- function generateESMParserImport(override) {
1029
- return ts.factory.createPropertyAssignment('parser', ts.factory.createAwaitExpression(ts.factory.createCallExpression(ts.factory.createIdentifier('import'), undefined, [
1030
- ts.factory.createStringLiteral(override['languageOptions']?.['parserOptions']?.parser ??
1031
- override['languageOptions']?.parser ??
1032
- override.parser),
1033
- ])));
1034
- }
1035
- function generateCJSParserImport(override) {
1036
- return ts.factory.createPropertyAssignment('parser', ts.factory.createCallExpression(ts.factory.createIdentifier('require'), undefined, [
1037
- ts.factory.createStringLiteral(override['languageOptions']?.['parserOptions']?.parser ??
1038
- override['languageOptions']?.parser ??
1039
- override.parser),
1040
- ]));
1041
- }
1042
693
  function generateFlatPredefinedConfig(predefinedConfigName, moduleName = 'nx', spread = true) {
1043
694
  const node = ts.factory.createElementAccessExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(moduleName), ts.factory.createIdentifier('configs')), ts.factory.createStringLiteral(predefinedConfigName));
1044
695
  return spread ? ts.factory.createSpreadElement(node) : node;
@@ -1071,14 +722,14 @@ function addTSObjectProperty(elements, key, value) {
1071
722
  */
1072
723
  function generateAst(input, propertyAssignmentReplacer) {
1073
724
  if (Array.isArray(input)) {
1074
- return ts.factory.createArrayLiteralExpression(input.map((item) => generateAst(item, propertyAssignmentReplacer)), true // Always treat as multiline, using item.length does not work in all cases
725
+ return ts.factory.createArrayLiteralExpression(input.map((item) => generateAst(item, propertyAssignmentReplacer)), input.length > 1 // multiline only if more than one item
1075
726
  );
1076
727
  }
1077
728
  if (input === null) {
1078
729
  return ts.factory.createNull();
1079
730
  }
1080
731
  if (typeof input === 'object') {
1081
- return ts.factory.createObjectLiteralExpression(generatePropertyAssignmentsFromObjectEntries(input, propertyAssignmentReplacer), true // Always treat as multiline, using Object.keys(input).length > 1 does not work in all cases
732
+ return ts.factory.createObjectLiteralExpression(generatePropertyAssignmentsFromObjectEntries(input, propertyAssignmentReplacer), Object.keys(input).length > 1 // multiline only if more than one property
1082
733
  );
1083
734
  }
1084
735
  if (typeof input === 'string') {