@oxlint/migrate 1.50.0 → 1.52.0

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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @oxlint/migrate
2
2
 
3
3
  ![test](https://github.com/oxc-project/oxlint-migrate/actions/workflows/test.yml/badge.svg)
4
- [![NPM Version](https://img.shields.io/npm/v/%40oxlint%2Fmigrate)](https://www.npmjs.com/package/@oxlint/migrate)
5
- [![NPM Downloads](https://img.shields.io/npm/dm/%40oxlint%2Fmigrate)](https://www.npmjs.com/package/@oxlint/migrate)
4
+ [![NPM Version](https://img.shields.io/npm/v/%40oxlint%2Fmigrate)](https://npmx.dev/package/@oxlint/migrate)
5
+ [![NPM Downloads](https://img.shields.io/npm/dm/%40oxlint%2Fmigrate)](https://npmx.dev/package/@oxlint/migrate)
6
6
 
7
7
  Generates a `.oxlintrc.json` from an existing ESLint flat config.
8
8
 
@@ -18,15 +18,15 @@ When no config file is provided, the script searches for the default ESLint conf
18
18
 
19
19
  ### Options
20
20
 
21
- | Options | Description |
22
- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
23
- | `--merge` | \* merge ESLint configuration with an existing .oxlintrc.json configuration |
24
- | `--type-aware` | Include type aware rules, which are supported with `oxlint --type-aware` and [oxlint-tsgolint](https://github.com/oxc-project/tsgolint) |
25
- | `--with-nursery` | Include oxlint rules which are currently under development |
26
- | `--js-plugins` | \*\* Include ESLint plugins via `jsPlugins` key. |
27
- | `--details` | List rules that could not be migrated to oxlint |
28
- | `--output-file <file>` | The oxlint configuration file where ESLint v9 rules will be written to, default: `.oxlintrc.json` |
29
- | `--replace-eslint-comments` | Search in the project files for ESLint comments and replaces them with oxlint. Some ESLint comments are not supported and will be reported. |
21
+ | Options | Description |
22
+ | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23
+ | `--merge` | \* merge ESLint configuration with an existing .oxlintrc.json configuration |
24
+ | `--type-aware` | Include type aware rules. These rules are supported with `oxlint --type-aware` and [oxlint-tsgolint](https://github.com/oxc-project/tsgolint). This will also enable the `typeAware` option in the generated configuration. |
25
+ | `--with-nursery` | Include oxlint rules which are currently under development |
26
+ | `--js-plugins [bool]` | \*\* Include ESLint plugins via `jsPlugins` key (enabled by default). Use `--js-plugins=false` to disable. |
27
+ | `--details` | List rules that could not be migrated to oxlint |
28
+ | `--output-file <file>` | The oxlint configuration file where ESLint v9 rules will be written to, default: `.oxlintrc.json` |
29
+ | `--replace-eslint-comments` | Search in the project files for ESLint comments and replaces them with oxlint. Some ESLint comments are not supported and will be reported. |
30
30
 
31
31
  \* WARNING: When some `categories` are enabled, this tools will enable more rules with the combination of `plugins`.
32
32
  Else we need to disable each rule `plugin/categories` combination, which is not covered by your ESLint configuration.
@@ -49,7 +49,7 @@ TypeScript configuration files, like `eslint.config.mts`, are supported in the f
49
49
  - **Deno and Bun**: TypeScript configuration files are natively supported.
50
50
  - **Node.js >=22.18.0**: TypeScript configuration files are supported natively with built-in type-stripping enabled by default.
51
51
  - **Node.js >=22.6.0**: TypeScript configuration files can be used by setting `NODE_OPTIONS=--experimental-strip-types`.
52
- - **Node.js <22.6.0**: TypeScript configuration files can be used by setting `NODE_OPTIONS=--import @oxc-node/core/register` and installing [@oxc-node/core](https://www.npmjs.com/package/@oxc-node/core) as a dev dependency.
52
+ - **Node.js <22.6.0**: TypeScript configuration files can be used by setting `NODE_OPTIONS=--import @oxc-node/core/register` and installing [@oxc-node/core](https://npmx.dev/package/@oxc-node/core) as a dev dependency.
53
53
 
54
54
  If you attempt to use a TypeScript configuration file without the proper setup for your Node.js version, Node.js will throw an error when trying to import the file.
55
55
 
@@ -65,7 +65,7 @@ Here are some known caveats to be aware of:
65
65
 
66
66
  **`settings` field migration**
67
67
 
68
- The `settings` field (e.g. for setting the React version) is migrated for known oxlint-supported plugins: `jsx-a11y`, `next`, `react`, `jsdoc`, and `vitest`. By default, other settings keys are skipped since they aren't supported by oxlint. If using the `--js-plugins` flag, other settings keys will also be migrated in order to support JS Plugins.
68
+ The `settings` field (e.g. for setting the React version) is migrated for known oxlint-supported plugins: `jsx-a11y`, `next`, `react`, `jsdoc`, and `vitest`. By default, other settings keys are also migrated to support JS Plugins. Use `--js-plugins=false` to skip migrating unknown settings keys.
69
69
 
70
70
  Note: Oxlint does not support `settings` in override configs. If your ESLint config has settings in configs with `files` patterns, those settings will be skipped and a warning will be shown.
71
71
 
@@ -73,7 +73,7 @@ Not all `settings` options are supported by oxlint, and so rule behavior in cert
73
73
 
74
74
  **Local ESLint Plugins imported via path are not migrated**
75
75
 
76
- The `--js-plugins` flag cannot migrate ESLint plugins from file paths in the same repo currently (e.g. if you have `../eslint-plugin-myplugin` in your `eslint.config.mjs`). You will need to copy them over into the `jsPlugins` manually. See [the JS Plugins docs]() for more info.
76
+ JS plugin migration cannot migrate ESLint plugins from file paths in the same repo currently (e.g. if you have `../eslint-plugin-myplugin` in your `eslint.config.mjs`). You will need to copy them over into the `jsPlugins` manually. See [the JS Plugins docs]() for more info.
77
77
 
78
78
  **`globals` field with large number of values**
79
79
 
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as preFixForJsPlugins, f as buildUnsupportedRuleExplanations, m as rules_exports, p as nurseryRules, u as isOffValue } from "../settings-D8R7axmT.mjs";
3
- import main from "../src/index.mjs";
2
+ import { a as nurseryRules, i as buildUnsupportedRuleExplanations, n as preFixForJsPlugins, o as rules_exports, r as isOffValue, t as main } from "../src-TZG8ybfH.mjs";
4
3
  import { program } from "commander";
5
4
  import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
6
5
  import path from "node:path";
@@ -8,7 +7,6 @@ import { pathToFileURL } from "node:url";
8
7
  import { parseSync } from "oxc-parser";
9
8
  import { glob } from "tinyglobby";
10
9
  import { writeFile } from "node:fs/promises";
11
-
12
10
  //#region bin/config-loader.ts
13
11
  const FLAT_CONFIG_FILENAMES = [
14
12
  "eslint.config.js",
@@ -30,11 +28,9 @@ const loadESLintConfig = async (filePath) => {
30
28
  if (!existsSync(filePath)) throw new Error(`eslint config file not found: ${filePath}`);
31
29
  return import(url);
32
30
  };
33
-
34
31
  //#endregion
35
32
  //#region package.json
36
- var version = "1.50.0";
37
-
33
+ var version = "1.52.0";
38
34
  //#endregion
39
35
  //#region src/walker/comments/replaceRuleDirectiveComment.ts
40
36
  const allRules = Object.values(rules_exports).flat();
@@ -69,7 +65,6 @@ function replaceRuleDirectiveComment(comment, type, options) {
69
65
  }
70
66
  return originalComment.replace(/eslint-/, "oxlint-");
71
67
  }
72
-
73
68
  //#endregion
74
69
  //#region src/walker/comments/index.ts
75
70
  function replaceComments(comment, type, options) {
@@ -82,7 +77,6 @@ function replaceComments(comment, type, options) {
82
77
  }
83
78
  return originalComment;
84
79
  }
85
-
86
80
  //#endregion
87
81
  //#region src/walker/partialSourceTextLoader.ts
88
82
  function extractLangAttribute(source) {
@@ -212,7 +206,6 @@ function partialAstroSourceTextLoader(sourceText) {
212
206
  }));
213
207
  return results;
214
208
  }
215
-
216
209
  //#endregion
217
210
  //#region src/walker/replaceCommentsInFile.ts
218
211
  const getComments = (absoluteFilePath, partialSourceText, options) => {
@@ -248,7 +241,6 @@ function replaceCommentsInFile(absoluteFilePath, fileContent, options) {
248
241
  }
249
242
  return fileContent;
250
243
  }
251
-
252
244
  //#endregion
253
245
  //#region src/walker/index.ts
254
246
  const walkAndReplaceProjectFiles = (projectFiles, readFileSync, writeFile, options) => {
@@ -260,7 +252,6 @@ const walkAndReplaceProjectFiles = (projectFiles, readFileSync, writeFile, optio
260
252
  return writeFile(file, newSourceText);
261
253
  }));
262
254
  };
263
-
264
255
  //#endregion
265
256
  //#region bin/project-loader.ts
266
257
  const getAllProjectFiles = () => {
@@ -270,7 +261,6 @@ const getAllProjectFiles = () => {
270
261
  "!**/dist/**"
271
262
  ], { absolute: true });
272
263
  };
273
-
274
264
  //#endregion
275
265
  //#region src/reporter.ts
276
266
  var DefaultReporter = class {
@@ -306,7 +296,6 @@ var DefaultReporter = class {
306
296
  return result;
307
297
  }
308
298
  };
309
-
310
299
  //#endregion
311
300
  //#region bin/output-formatter.ts
312
301
  const unsupportedRuleExplanations = buildUnsupportedRuleExplanations();
@@ -357,7 +346,7 @@ function detectMissingFlags(byCategory, cliOptions) {
357
346
  const missingFlags = [];
358
347
  if (byCategory.nursery.length > 0 && !cliOptions.withNursery) missingFlags.push("--with-nursery");
359
348
  if (byCategory["type-aware"].length > 0 && !cliOptions.typeAware) missingFlags.push("--type-aware");
360
- if (byCategory["js-plugins"].length > 0 && !cliOptions.jsPlugins) missingFlags.push("--js-plugins");
349
+ if (byCategory["js-plugins"].length > 0 && !cliOptions.jsPlugins) missingFlags.push("--js-plugins=true");
361
350
  return missingFlags;
362
351
  }
363
352
  /**
@@ -399,14 +388,24 @@ function formatMigrationOutput(data) {
399
388
  }
400
389
  return output;
401
390
  }
391
+ function formatWarningsOutput(warnings) {
392
+ if (warnings.length === 0) return "";
393
+ let output = `⚠️ Warnings (${warnings.length}):\n`;
394
+ for (const warning of warnings) {
395
+ const [message, ...details] = warning.split("\n");
396
+ output += ` * ${message}\n`;
397
+ for (const detail of details.filter((line) => line.trim().length)) output += ` * ${detail}\n`;
398
+ }
399
+ return output.trimEnd();
400
+ }
402
401
  function displayMigrationResult(outputMessage, warnings) {
403
402
  console.log(outputMessage);
404
- for (const warning of warnings) console.warn(warning);
403
+ if (warnings.length > 0) console.warn(formatWarningsOutput(warnings));
405
404
  }
406
-
407
405
  //#endregion
408
406
  //#region bin/oxlint-migrate.ts
409
407
  const cwd = process.cwd();
408
+ const parseCliBoolean = (value) => value === "false" ? false : !!value;
410
409
  const getFileContent = (absoluteFilePath) => {
411
410
  try {
412
411
  return readFileSync(absoluteFilePath, "utf-8");
@@ -429,8 +428,9 @@ const countEnabledRules = (config) => {
429
428
  }
430
429
  return enabledRules.size;
431
430
  };
432
- program.name("oxlint-migrate").version(version).argument("[eslint-config]", "The path to the eslint v9 config file").option("--output-file <file>", "The oxlint configuration file where to eslint v9 rules will be written to", ".oxlintrc.json").option("--merge", "Merge eslint configuration with an existing .oxlintrc.json configuration", false).option("--with-nursery", "Include oxlint rules which are currently under development", false).option("--replace-eslint-comments", "Search in the project files for eslint comments and replaces them with oxlint. Some eslint comments are not supported and will be reported.").option("--type-aware", "Includes supported type-aware rules. Needs the same flag in `oxlint` to enable it.").option("--js-plugins", "Tries to convert unsupported oxlint plugins with `jsPlugins`.").option("--details", "List rules that could not be migrated to oxlint.", false).action(async (filePath) => {
431
+ program.name("oxlint-migrate").version(version).argument("[eslint-config]", "The path to the eslint v9 config file").option("--output-file <file>", "The oxlint configuration file where to eslint v9 rules will be written to", ".oxlintrc.json").option("--merge", "Merge eslint configuration with an existing .oxlintrc.json configuration", false).option("--with-nursery", "Include oxlint rules which are currently under development", false).option("--replace-eslint-comments", "Search in the project files for eslint comments and replaces them with oxlint. Some eslint comments are not supported and will be reported.").option("--type-aware", "Includes supported type-aware rules. Needs the same flag in `oxlint` or the `typeAware` config option to enable it.").option("--js-plugins [bool]", "Tries to convert unsupported oxlint plugins with `jsPlugins`. Enabled by default; pass `--js-plugins=false` to disable.", true).option("--details", "List rules that could not be migrated to oxlint.", false).action(async (filePath) => {
433
432
  const cliOptions = program.opts();
433
+ const jsPlugins = parseCliBoolean(cliOptions.jsPlugins);
434
434
  const oxlintFilePath = path.join(cwd, cliOptions.outputFile);
435
435
  const reporter = new DefaultReporter();
436
436
  const options = {
@@ -438,7 +438,7 @@ program.name("oxlint-migrate").version(version).argument("[eslint-config]", "The
438
438
  merge: !!cliOptions.merge,
439
439
  withNursery: !!cliOptions.withNursery,
440
440
  typeAware: !!cliOptions.typeAware,
441
- jsPlugins: !!cliOptions.jsPlugins
441
+ jsPlugins
442
442
  };
443
443
  if (cliOptions.replaceEslintComments) {
444
444
  await walkAndReplaceProjectFiles(await getAllProjectFiles(), (filePath) => getFileContent(filePath), (filePath, content) => writeFile(filePath, content, "utf-8"), options);
@@ -467,12 +467,11 @@ program.name("oxlint-migrate").version(version).argument("[eslint-config]", "The
467
467
  withNursery: !!cliOptions.withNursery,
468
468
  typeAware: !!cliOptions.typeAware,
469
469
  details: !!cliOptions.details,
470
- jsPlugins: !!cliOptions.jsPlugins
470
+ jsPlugins
471
471
  },
472
472
  eslintConfigPath: filePath
473
473
  }), reporter.getWarnings());
474
474
  });
475
475
  program.parse();
476
-
477
476
  //#endregion
478
- export { };
477
+ export {};