@oxlint/migrate 0.16.0 → 0.16.2
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 +13 -1
- package/dist/bin/oxlint-migrate.mjs +29 -5
- package/dist/package.json.mjs +1 -1
- package/dist/src/cleanup.mjs +4 -11
- package/dist/src/env_globals.d.ts +2 -2
- package/dist/src/env_globals.mjs +21 -8
- package/dist/src/generated/rules.d.ts +1 -1
- package/dist/src/generated/rules.mjs +17 -16
- package/dist/src/ignorePatterns.d.ts +2 -2
- package/dist/src/ignorePatterns.mjs +10 -4
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.mjs +45 -22
- package/dist/src/overrides.d.ts +2 -0
- package/dist/src/overrides.mjs +16 -0
- package/dist/src/plugins_rules.d.ts +4 -3
- package/dist/src/plugins_rules.mjs +30 -7
- package/dist/src/types.d.ts +7 -1
- package/dist/src/utilities.d.ts +1 -0
- package/dist/src/utilities.mjs +12 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -16,6 +16,18 @@ npx @oxlint/migrate <optional-eslint-flat-config-path>
|
|
|
16
16
|
|
|
17
17
|
When no config file provided, the script searches for the default eslint config filenames in the current directory.
|
|
18
18
|
|
|
19
|
+
### Options
|
|
20
|
+
|
|
21
|
+
| Options | Description |
|
|
22
|
+
| ---------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| `--merge` | \* merge eslint configuration with an existing .oxlintrc.json configuration |
|
|
24
|
+
| `--with-nursery` | Include oxlint rules which are currently under development |
|
|
25
|
+
| `--output-file <file>` | The oxlint configuration file where to eslint v9 rules will be written to, default: `.oxlintrc.json` |
|
|
26
|
+
|
|
27
|
+
\* WARNING: When some `categories` are enabled, this tools will enable more rules with the combination of `plugins`.
|
|
28
|
+
Else we need to disable each rule `plugin/categories` combination, which is not covered by your eslint configuration.
|
|
29
|
+
This behavior can change in the future.
|
|
30
|
+
|
|
19
31
|
### User Flow
|
|
20
32
|
|
|
21
33
|
- Upgrade `oxlint` and `@oxlint/migrate` to the same version.
|
|
@@ -33,7 +45,7 @@ pnpm generate
|
|
|
33
45
|
pnpm format
|
|
34
46
|
```
|
|
35
47
|
|
|
36
|
-
###
|
|
48
|
+
### Unit + Integration Test
|
|
37
49
|
|
|
38
50
|
```shell
|
|
39
51
|
pnpm vitest
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { program } from "commander";
|
|
3
3
|
import { getAutodetectedEslintConfigName } from "./autoDetectConfigFile.mjs";
|
|
4
|
-
import { existsSync, renameSync, writeFileSync } from "fs";
|
|
4
|
+
import { existsSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
5
5
|
import main from "../src/index.mjs";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import packageJson from "../package.json.mjs";
|
|
8
8
|
import { pathToFileURL } from "node:url";
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
program.name("oxlint-migrate").version(packageJson.version).argument("[eslint-config]", "The path to the eslint v9 config file").option(
|
|
11
|
+
"--output-file <file>",
|
|
12
|
+
"The oxlint configuration file where to eslint v9 rules will be written to",
|
|
13
|
+
".oxlintrc.json"
|
|
14
|
+
).option(
|
|
15
|
+
"--merge",
|
|
16
|
+
"Merge eslint configuration with an existing .oxlintrc.json configuration",
|
|
17
|
+
false
|
|
18
|
+
).option(
|
|
19
|
+
"--with-nursery",
|
|
20
|
+
"Include oxlint rules which are currently under development",
|
|
21
|
+
false
|
|
22
|
+
).action(async (filePath) => {
|
|
23
|
+
const cliOptions = program.opts();
|
|
24
|
+
const oxlintFilePath = path.join(cwd, cliOptions.outputFile);
|
|
11
25
|
if (filePath === void 0) {
|
|
12
26
|
filePath = getAutodetectedEslintConfigName(cwd);
|
|
13
27
|
if (filePath === void 0) {
|
|
@@ -20,8 +34,18 @@ program.name("oxlint-migrate").version(packageJson.version).argument("[eslint-co
|
|
|
20
34
|
program.error(`eslint config file not found: ${filePath}`);
|
|
21
35
|
} else {
|
|
22
36
|
const eslintConfigs = await import(pathToFileURL(filePath).toString());
|
|
23
|
-
const
|
|
24
|
-
|
|
37
|
+
const options = {
|
|
38
|
+
reporter: console.warn,
|
|
39
|
+
merge: !!cliOptions.merge,
|
|
40
|
+
withNursery: !!cliOptions.withNursery
|
|
41
|
+
};
|
|
42
|
+
let config;
|
|
43
|
+
if (options.merge && existsSync(oxlintFilePath)) {
|
|
44
|
+
config = JSON.parse(
|
|
45
|
+
readFileSync(oxlintFilePath, { encoding: "utf8", flag: "r" })
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
const oxlintConfig = "default" in eslintConfigs ? await main(eslintConfigs.default, config, options) : await main(eslintConfigs, config, options);
|
|
25
49
|
if (existsSync(oxlintFilePath)) {
|
|
26
50
|
renameSync(oxlintFilePath, `${oxlintFilePath}.bak`);
|
|
27
51
|
}
|
package/dist/package.json.mjs
CHANGED
package/dist/src/cleanup.mjs
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
import { removeGlobalsWithAreCoveredByEnv, transformBoolGlobalToString, ES_VERSIONS, cleanUpUselessOverridesEnv } from "./env_globals.mjs";
|
|
2
|
-
import { replaceTypescriptAliasRules, replaceNodePluginName, cleanUpUselessOverridesRules, cleanUpUselessOverridesPlugins } from "./plugins_rules.mjs";
|
|
3
|
-
|
|
4
|
-
if (a === b) {
|
|
5
|
-
return true;
|
|
6
|
-
}
|
|
7
|
-
const bothAreObjects = a && b && typeof a === "object" && typeof b === "object";
|
|
8
|
-
return Boolean(
|
|
9
|
-
bothAreObjects && Object.keys(a).length === Object.keys(b).length && Object.entries(a).every(([k, v]) => isEqualDeep(v, b[k]))
|
|
10
|
-
);
|
|
11
|
-
};
|
|
2
|
+
import { replaceTypescriptAliasRules, replaceNodePluginName, cleanUpRulesWhichAreCoveredByCategory, cleanUpUselessOverridesRules, cleanUpUselessOverridesPlugins } from "./plugins_rules.mjs";
|
|
3
|
+
import { isEqualDeep } from "./utilities.mjs";
|
|
12
4
|
const TS_ESLINT_DEFAULT_OVERRIDE = {
|
|
13
5
|
files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
|
|
14
6
|
rules: {
|
|
@@ -73,6 +65,7 @@ const cleanUpOxlintConfig = (config) => {
|
|
|
73
65
|
transformBoolGlobalToString(config);
|
|
74
66
|
replaceTypescriptAliasRules(config);
|
|
75
67
|
replaceNodePluginName(config);
|
|
68
|
+
cleanUpRulesWhichAreCoveredByCategory(config);
|
|
76
69
|
if (config.globals !== void 0 && Object.keys(config.globals).length === 0) {
|
|
77
70
|
delete config.globals;
|
|
78
71
|
}
|
|
@@ -81,7 +74,7 @@ const cleanUpOxlintConfig = (config) => {
|
|
|
81
74
|
delete config.env.es5;
|
|
82
75
|
delete config.env.es2015;
|
|
83
76
|
let detected = false;
|
|
84
|
-
for (const esVersion of ES_VERSIONS.reverse()) {
|
|
77
|
+
for (const esVersion of [...ES_VERSIONS].reverse()) {
|
|
85
78
|
if (detected) {
|
|
86
79
|
delete config.env[`es${esVersion}`];
|
|
87
80
|
} else if (config.env[`es${esVersion}`] === true) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { OxlintConfig, OxlintConfigOrOverride
|
|
1
|
+
import { Options, OxlintConfig, OxlintConfigOrOverride } from './types.js';
|
|
2
2
|
import { Linter } from 'eslint';
|
|
3
3
|
export declare const ES_VERSIONS: number[];
|
|
4
4
|
export declare const removeGlobalsWithAreCoveredByEnv: (config: OxlintConfigOrOverride) => void;
|
|
5
5
|
export declare const transformBoolGlobalToString: (config: OxlintConfigOrOverride) => void;
|
|
6
6
|
export declare const detectEnvironmentByGlobals: (config: OxlintConfigOrOverride) => void;
|
|
7
|
-
export declare const transformEnvAndGlobals: (eslintConfig: Linter.Config, targetConfig: OxlintConfigOrOverride,
|
|
7
|
+
export declare const transformEnvAndGlobals: (eslintConfig: Linter.Config, targetConfig: OxlintConfigOrOverride, options?: Options) => void;
|
|
8
8
|
export declare const cleanUpUselessOverridesEnv: (config: OxlintConfig) => void;
|
package/dist/src/env_globals.mjs
CHANGED
|
@@ -101,11 +101,11 @@ const detectEnvironmentByGlobals = (config) => {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
|
-
const transformEnvAndGlobals = (eslintConfig, targetConfig,
|
|
104
|
+
const transformEnvAndGlobals = (eslintConfig, targetConfig, options) => {
|
|
105
105
|
if (eslintConfig.languageOptions?.parser !== void 0 && !SUPPORTED_ESLINT_PARSERS.includes(
|
|
106
106
|
eslintConfig.languageOptions.parser.meta?.name
|
|
107
107
|
)) {
|
|
108
|
-
reporter !== void 0 && reporter(
|
|
108
|
+
options?.reporter !== void 0 && options.reporter(
|
|
109
109
|
"special parser detected: " + eslintConfig.languageOptions.parser.meta?.name
|
|
110
110
|
);
|
|
111
111
|
}
|
|
@@ -113,22 +113,35 @@ const transformEnvAndGlobals = (eslintConfig, targetConfig, reporter) => {
|
|
|
113
113
|
if (targetConfig.globals === void 0) {
|
|
114
114
|
targetConfig.globals = {};
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
if (options?.merge) {
|
|
117
|
+
for (const [global, globalSetting] of Object.entries(
|
|
118
|
+
eslintConfig.languageOptions.globals
|
|
119
|
+
)) {
|
|
120
|
+
if (!(global in targetConfig.globals)) {
|
|
121
|
+
targetConfig.globals[global] = globalSetting;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
Object.assign(targetConfig.globals, eslintConfig.languageOptions.globals);
|
|
126
|
+
}
|
|
117
127
|
}
|
|
118
128
|
if (eslintConfig.languageOptions?.ecmaVersion !== void 0) {
|
|
119
|
-
if (targetConfig.globals === void 0) {
|
|
120
|
-
targetConfig.globals = {};
|
|
121
|
-
}
|
|
122
129
|
if (eslintConfig.languageOptions?.ecmaVersion === "latest") {
|
|
123
130
|
if (targetConfig.env === void 0) {
|
|
124
131
|
targetConfig.env = {};
|
|
125
132
|
}
|
|
126
|
-
|
|
133
|
+
const latestVersion = `es${ES_VERSIONS[ES_VERSIONS.length - 1]}`;
|
|
134
|
+
if (!(latestVersion in targetConfig.env)) {
|
|
135
|
+
targetConfig.env[latestVersion] = true;
|
|
136
|
+
}
|
|
127
137
|
} else if (ES_VERSIONS.includes(eslintConfig.languageOptions?.ecmaVersion)) {
|
|
128
138
|
if (targetConfig.env === void 0) {
|
|
129
139
|
targetConfig.env = {};
|
|
130
140
|
}
|
|
131
|
-
|
|
141
|
+
const targetVersion = `es${eslintConfig.languageOptions?.ecmaVersion}`;
|
|
142
|
+
if (!(targetVersion in targetConfig.env)) {
|
|
143
|
+
targetConfig.env[targetVersion] = true;
|
|
144
|
+
}
|
|
132
145
|
}
|
|
133
146
|
}
|
|
134
147
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare const pedanticRules: string[];
|
|
2
|
-
export declare const nurseryRules: string[];
|
|
3
2
|
export declare const styleRules: string[];
|
|
4
3
|
export declare const restrictionRules: string[];
|
|
5
4
|
export declare const correctnessRules: string[];
|
|
5
|
+
export declare const nurseryRules: string[];
|
|
6
6
|
export declare const perfRules: string[];
|
|
7
7
|
export declare const suspiciousRules: string[];
|
|
@@ -84,21 +84,6 @@ const pedanticRules = [
|
|
|
84
84
|
"import-x/max-dependencies",
|
|
85
85
|
"vitest/no-conditional-in-test"
|
|
86
86
|
];
|
|
87
|
-
const nurseryRules = [
|
|
88
|
-
"constructor-super",
|
|
89
|
-
"getter-return",
|
|
90
|
-
"no-undef",
|
|
91
|
-
"no-unreachable",
|
|
92
|
-
"import/export",
|
|
93
|
-
"import/named",
|
|
94
|
-
"promise/no-return-in-finally",
|
|
95
|
-
"react-hooks/exhaustive-deps",
|
|
96
|
-
"react/require-render-return",
|
|
97
|
-
"@typescript-eslint/consistent-type-imports",
|
|
98
|
-
"@typescript-eslint/no-unnecessary-parameter-property-assignment",
|
|
99
|
-
"import-x/export",
|
|
100
|
-
"import-x/named"
|
|
101
|
-
];
|
|
102
87
|
const styleRules = [
|
|
103
88
|
"curly",
|
|
104
89
|
"default-case-last",
|
|
@@ -324,6 +309,7 @@ const restrictionRules = [
|
|
|
324
309
|
"unicorn/no-anonymous-default-export",
|
|
325
310
|
"unicorn/no-array-for-each",
|
|
326
311
|
"unicorn/no-array-reduce",
|
|
312
|
+
"unicorn/no-document-cookie",
|
|
327
313
|
"unicorn/no-length-as-slice-end",
|
|
328
314
|
"unicorn/no-magic-array-flat-depth",
|
|
329
315
|
"unicorn/no-nested-ternary",
|
|
@@ -482,6 +468,7 @@ const correctnessRules = [
|
|
|
482
468
|
"@typescript-eslint/no-misused-new",
|
|
483
469
|
"@typescript-eslint/no-non-null-asserted-optional-chain",
|
|
484
470
|
"@typescript-eslint/no-this-alias",
|
|
471
|
+
"@typescript-eslint/no-unnecessary-parameter-property-assignment",
|
|
485
472
|
"@typescript-eslint/no-unsafe-declaration-merging",
|
|
486
473
|
"@typescript-eslint/no-useless-empty-export",
|
|
487
474
|
"@typescript-eslint/no-wrapper-object-types",
|
|
@@ -489,7 +476,6 @@ const correctnessRules = [
|
|
|
489
476
|
"@typescript-eslint/triple-slash-reference",
|
|
490
477
|
"unicorn/no-invalid-fetch-options",
|
|
491
478
|
"unicorn/no-await-in-promise-methods",
|
|
492
|
-
"unicorn/no-document-cookie",
|
|
493
479
|
"unicorn/no-empty-file",
|
|
494
480
|
"unicorn/no-invalid-remove-event-listener",
|
|
495
481
|
"unicorn/no-new-array",
|
|
@@ -517,6 +503,19 @@ const correctnessRules = [
|
|
|
517
503
|
"vitest/valid-describe-callback",
|
|
518
504
|
"vitest/valid-expect"
|
|
519
505
|
];
|
|
506
|
+
const nurseryRules = [
|
|
507
|
+
"getter-return",
|
|
508
|
+
"no-undef",
|
|
509
|
+
"no-unreachable",
|
|
510
|
+
"import/export",
|
|
511
|
+
"import/named",
|
|
512
|
+
"promise/no-return-in-finally",
|
|
513
|
+
"react-hooks/exhaustive-deps",
|
|
514
|
+
"react/require-render-return",
|
|
515
|
+
"@typescript-eslint/consistent-type-imports",
|
|
516
|
+
"import-x/export",
|
|
517
|
+
"import-x/named"
|
|
518
|
+
];
|
|
520
519
|
const perfRules = [
|
|
521
520
|
"no-useless-call",
|
|
522
521
|
"no-await-in-loop",
|
|
@@ -534,6 +533,7 @@ const suspiciousRules = [
|
|
|
534
533
|
"no-unexpected-multiline",
|
|
535
534
|
"no-useless-concat",
|
|
536
535
|
"no-useless-constructor",
|
|
536
|
+
"import/no-empty-named-blocks",
|
|
537
537
|
"import/no-absolute-path",
|
|
538
538
|
"import/no-duplicates",
|
|
539
539
|
"import/no-named-as-default",
|
|
@@ -554,6 +554,7 @@ const suspiciousRules = [
|
|
|
554
554
|
"unicorn/prefer-add-event-listener",
|
|
555
555
|
"unicorn/require-post-message-target-origin",
|
|
556
556
|
"@typescript-eslint/no-useless-constructor",
|
|
557
|
+
"import-x/no-empty-named-blocks",
|
|
557
558
|
"import-x/no-absolute-path",
|
|
558
559
|
"import-x/no-duplicates",
|
|
559
560
|
"import-x/no-named-as-default",
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Linter } from 'eslint';
|
|
2
|
-
import {
|
|
3
|
-
export declare const transformIgnorePatterns: (eslintConfig: Linter.Config, targetConfig: OxlintConfigOrOverride,
|
|
2
|
+
import { Options, OxlintConfigOrOverride } from './types.js';
|
|
3
|
+
export declare const transformIgnorePatterns: (eslintConfig: Linter.Config, targetConfig: OxlintConfigOrOverride, options?: Options) => void;
|
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
const transformIgnorePatterns = (eslintConfig, targetConfig,
|
|
1
|
+
const transformIgnorePatterns = (eslintConfig, targetConfig, options) => {
|
|
2
2
|
if (eslintConfig.ignores === void 0) {
|
|
3
3
|
return;
|
|
4
4
|
}
|
|
5
5
|
if ("files" in targetConfig) {
|
|
6
|
-
reporter !== void 0 && reporter("ignore list inside overrides is not supported");
|
|
6
|
+
options?.reporter !== void 0 && options.reporter("ignore list inside overrides is not supported");
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
9
|
if (targetConfig.ignorePatterns === void 0) {
|
|
10
10
|
targetConfig.ignorePatterns = [];
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
for (const ignores of eslintConfig.ignores) {
|
|
13
|
+
if (!targetConfig.ignorePatterns.includes(ignores)) {
|
|
14
|
+
targetConfig.ignorePatterns.push(ignores);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
13
17
|
eslintConfig.ignores.filter((ignore) => ignore.startsWith("!")).forEach(
|
|
14
|
-
(ignore) => reporter !== void 0 && reporter(
|
|
18
|
+
(ignore) => options?.reporter !== void 0 && options.reporter(
|
|
19
|
+
`ignore allow list is currently not supported: ${ignore}`
|
|
20
|
+
)
|
|
15
21
|
);
|
|
16
22
|
};
|
|
17
23
|
export {
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Linter } from 'eslint';
|
|
2
|
-
import {
|
|
3
|
-
declare const main: (configs: Linter.Config | Linter.Config[] | Promise<Linter.Config> | Promise<Linter.Config[]>,
|
|
2
|
+
import { Options, OxlintConfig } from './types.js';
|
|
3
|
+
declare const main: (configs: Linter.Config | Linter.Config[] | Promise<Linter.Config> | Promise<Linter.Config[]>, oxlintConfig?: OxlintConfig, options?: Options) => Promise<OxlintConfig>;
|
|
4
4
|
export default main;
|
package/dist/src/index.mjs
CHANGED
|
@@ -2,20 +2,41 @@ import { transformEnvAndGlobals, detectEnvironmentByGlobals } from "./env_global
|
|
|
2
2
|
import { cleanUpOxlintConfig } from "./cleanup.mjs";
|
|
3
3
|
import { transformIgnorePatterns } from "./ignorePatterns.mjs";
|
|
4
4
|
import { transformRuleEntry, detectNeededRulesPlugins } from "./plugins_rules.mjs";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
import { detectSameOverride } from "./overrides.mjs";
|
|
6
|
+
const buildConfig = (configs, oxlintConfig, options) => {
|
|
7
|
+
if (oxlintConfig === void 0) {
|
|
8
|
+
if (options?.merge) {
|
|
9
|
+
oxlintConfig = {
|
|
10
|
+
// disable all plugins and check later
|
|
11
|
+
plugins: ["oxc", "typescript", "unicorn", "react"],
|
|
12
|
+
categories: {
|
|
13
|
+
correctness: "warn"
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
} else {
|
|
17
|
+
oxlintConfig = {
|
|
18
|
+
$schema: "./node_modules/oxlint/configuration_schema.json",
|
|
19
|
+
// disable all plugins and check later
|
|
20
|
+
plugins: [],
|
|
21
|
+
categories: {
|
|
22
|
+
// ToDo: for merge set the default category manuel when it is not found
|
|
23
|
+
// ToDo: later we can remove it again
|
|
24
|
+
// default category
|
|
25
|
+
correctness: "off"
|
|
26
|
+
}
|
|
27
|
+
};
|
|
16
28
|
}
|
|
17
|
-
}
|
|
18
|
-
|
|
29
|
+
}
|
|
30
|
+
if (oxlintConfig.$schema === void 0 && options?.merge) {
|
|
31
|
+
oxlintConfig.$schema = "./node_modules/oxlint/configuration_schema.json";
|
|
32
|
+
}
|
|
33
|
+
if (oxlintConfig.env?.builtin === void 0) {
|
|
34
|
+
if (oxlintConfig.env === void 0) {
|
|
35
|
+
oxlintConfig.env = {};
|
|
36
|
+
}
|
|
37
|
+
oxlintConfig.env.builtin = true;
|
|
38
|
+
}
|
|
39
|
+
const overrides = options?.merge ? oxlintConfig.overrides ?? [] : [];
|
|
19
40
|
for (const config of configs) {
|
|
20
41
|
if (config.name?.startsWith("oxlint/")) {
|
|
21
42
|
continue;
|
|
@@ -27,28 +48,30 @@ const buildConfig = (configs, reporter) => {
|
|
|
27
48
|
targetConfig = {
|
|
28
49
|
files: Array.isArray(config.files) ? config.files : [config.files]
|
|
29
50
|
};
|
|
30
|
-
|
|
51
|
+
const [push, result] = detectSameOverride(oxlintConfig, targetConfig);
|
|
52
|
+
if (push) {
|
|
53
|
+
overrides.push(result);
|
|
54
|
+
}
|
|
31
55
|
}
|
|
32
|
-
if (config.plugins !== void 0) ;
|
|
33
56
|
if (config.settings !== void 0) ;
|
|
34
|
-
transformIgnorePatterns(config, targetConfig,
|
|
35
|
-
transformRuleEntry(config, targetConfig,
|
|
36
|
-
transformEnvAndGlobals(config, targetConfig,
|
|
57
|
+
transformIgnorePatterns(config, targetConfig, options);
|
|
58
|
+
transformRuleEntry(config, targetConfig, options);
|
|
59
|
+
transformEnvAndGlobals(config, targetConfig, options);
|
|
37
60
|
if ("files" in targetConfig) {
|
|
38
|
-
detectNeededRulesPlugins(targetConfig,
|
|
61
|
+
detectNeededRulesPlugins(targetConfig, options);
|
|
39
62
|
detectEnvironmentByGlobals(targetConfig);
|
|
40
63
|
cleanUpOxlintConfig(targetConfig);
|
|
41
64
|
}
|
|
42
65
|
}
|
|
43
66
|
oxlintConfig.overrides = overrides;
|
|
44
|
-
detectNeededRulesPlugins(oxlintConfig,
|
|
67
|
+
detectNeededRulesPlugins(oxlintConfig, options);
|
|
45
68
|
detectEnvironmentByGlobals(oxlintConfig);
|
|
46
69
|
cleanUpOxlintConfig(oxlintConfig);
|
|
47
70
|
return oxlintConfig;
|
|
48
71
|
};
|
|
49
|
-
const main = async (configs,
|
|
72
|
+
const main = async (configs, oxlintConfig, options) => {
|
|
50
73
|
const resolved = await Promise.resolve(configs);
|
|
51
|
-
return Array.isArray(resolved) ? buildConfig(resolved,
|
|
74
|
+
return Array.isArray(resolved) ? buildConfig(resolved, oxlintConfig, options) : buildConfig([resolved], oxlintConfig, options);
|
|
52
75
|
};
|
|
53
76
|
export {
|
|
54
77
|
main as default
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { isEqualDeep } from "./utilities.mjs";
|
|
2
|
+
const detectSameOverride = (config, override) => {
|
|
3
|
+
if (config.overrides === void 0) {
|
|
4
|
+
return [true, override];
|
|
5
|
+
}
|
|
6
|
+
const matchedOverride = config.overrides.find(({ files, categories }) => {
|
|
7
|
+
return categories === void 0 && isEqualDeep(files, override.files);
|
|
8
|
+
});
|
|
9
|
+
if (matchedOverride !== void 0) {
|
|
10
|
+
return [false, matchedOverride];
|
|
11
|
+
}
|
|
12
|
+
return [true, override];
|
|
13
|
+
};
|
|
14
|
+
export {
|
|
15
|
+
detectSameOverride
|
|
16
|
+
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Linter } from 'eslint';
|
|
2
|
-
import { OxlintConfig, OxlintConfigOrOverride
|
|
3
|
-
export declare const transformRuleEntry: (eslintConfig: Linter.Config, targetConfig: OxlintConfigOrOverride,
|
|
4
|
-
export declare const detectNeededRulesPlugins: (targetConfig: OxlintConfigOrOverride,
|
|
2
|
+
import { Options, OxlintConfig, OxlintConfigOrOverride } from './types.js';
|
|
3
|
+
export declare const transformRuleEntry: (eslintConfig: Linter.Config, targetConfig: OxlintConfigOrOverride, options?: Options) => void;
|
|
4
|
+
export declare const detectNeededRulesPlugins: (targetConfig: OxlintConfigOrOverride, options?: Options) => void;
|
|
5
5
|
export declare const cleanUpUselessOverridesPlugins: (config: OxlintConfig) => void;
|
|
6
6
|
export declare const cleanUpUselessOverridesRules: (config: OxlintConfig) => void;
|
|
7
|
+
export declare const cleanUpRulesWhichAreCoveredByCategory: (config: OxlintConfigOrOverride) => void;
|
|
7
8
|
export declare const replaceTypescriptAliasRules: (config: OxlintConfigOrOverride) => void;
|
|
8
9
|
/**
|
|
9
10
|
* Oxlint support them only under the node plugin name
|
|
@@ -33,7 +33,7 @@ const normalizeSeverityValue = (value) => {
|
|
|
33
33
|
}
|
|
34
34
|
return void 0;
|
|
35
35
|
};
|
|
36
|
-
const transformRuleEntry = (eslintConfig, targetConfig,
|
|
36
|
+
const transformRuleEntry = (eslintConfig, targetConfig, options) => {
|
|
37
37
|
if (eslintConfig.rules === void 0) {
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
@@ -42,19 +42,25 @@ const transformRuleEntry = (eslintConfig, targetConfig, reporter) => {
|
|
|
42
42
|
}
|
|
43
43
|
for (const [rule, config] of Object.entries(eslintConfig.rules)) {
|
|
44
44
|
if (allRules.includes(rule)) {
|
|
45
|
-
if (nurseryRules.includes(rule)) {
|
|
46
|
-
reporter !== void 0 && reporter(`unsupported rule, but in development: ${rule}`);
|
|
45
|
+
if (!options?.withNursery && nurseryRules.includes(rule)) {
|
|
46
|
+
options?.reporter !== void 0 && options.reporter(`unsupported rule, but in development: ${rule}`);
|
|
47
47
|
continue;
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
if (options?.merge) {
|
|
50
|
+
if (!(rule in targetConfig.rules)) {
|
|
51
|
+
targetConfig.rules[rule] = normalizeSeverityValue(config);
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
targetConfig.rules[rule] = normalizeSeverityValue(config);
|
|
55
|
+
}
|
|
50
56
|
} else {
|
|
51
57
|
if (isActiveValue(config)) {
|
|
52
|
-
reporter !== void 0 && reporter(`unsupported rule: ${rule}`);
|
|
58
|
+
options?.reporter !== void 0 && options.reporter(`unsupported rule: ${rule}`);
|
|
53
59
|
}
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
62
|
};
|
|
57
|
-
const detectNeededRulesPlugins = (targetConfig,
|
|
63
|
+
const detectNeededRulesPlugins = (targetConfig, options) => {
|
|
58
64
|
if (targetConfig.rules === void 0) {
|
|
59
65
|
return;
|
|
60
66
|
}
|
|
@@ -75,7 +81,7 @@ const detectNeededRulesPlugins = (targetConfig, reporter) => {
|
|
|
75
81
|
}
|
|
76
82
|
}
|
|
77
83
|
if (!found) {
|
|
78
|
-
reporter !== void 0 && reporter(`unsupported plugin for rule: ${rule}`);
|
|
84
|
+
options?.reporter !== void 0 && options.reporter(`unsupported plugin for rule: ${rule}`);
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
if ("files" in targetConfig && targetConfig.plugins.length === 0) {
|
|
@@ -118,6 +124,22 @@ const cleanUpUselessOverridesRules = (config) => {
|
|
|
118
124
|
}
|
|
119
125
|
}
|
|
120
126
|
};
|
|
127
|
+
const cleanUpRulesWhichAreCoveredByCategory = (config) => {
|
|
128
|
+
if (config.rules === void 0 || config.categories === void 0) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const enabledCategories = Object.entries(config.categories).filter(([, severity]) => severity === "warn" || severity === "error").map(([category]) => category);
|
|
132
|
+
for (const [rule, settings] of Object.entries(config.rules)) {
|
|
133
|
+
for (const category of enabledCategories) {
|
|
134
|
+
if (`${category}Rules` in rules && // @ts-expect-error -- ts can not resolve the type
|
|
135
|
+
rules[`${category}Rules`].includes(rule)) {
|
|
136
|
+
if (settings === config.categories[category] || Array.isArray(settings) && settings.length === 1 && settings[0] === config.categories[category]) {
|
|
137
|
+
delete config.rules[rule];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
121
143
|
const replaceTypescriptAliasRules = (config) => {
|
|
122
144
|
if (config.rules === void 0) {
|
|
123
145
|
return;
|
|
@@ -153,6 +175,7 @@ const replaceNodePluginName = (config) => {
|
|
|
153
175
|
}
|
|
154
176
|
};
|
|
155
177
|
export {
|
|
178
|
+
cleanUpRulesWhichAreCoveredByCategory,
|
|
156
179
|
cleanUpUselessOverridesPlugins,
|
|
157
180
|
cleanUpUselessOverridesRules,
|
|
158
181
|
detectNeededRulesPlugins,
|
package/dist/src/types.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export type OxlintConfigOverride = {
|
|
|
8
8
|
env?: OxlintConfigEnv;
|
|
9
9
|
globals?: Linter.Globals;
|
|
10
10
|
plugins?: OxlintConfigPlugins;
|
|
11
|
+
categories?: OxlintConfigCategories;
|
|
11
12
|
rules?: Partial<Linter.RulesRecord>;
|
|
12
13
|
};
|
|
13
14
|
export type OxlintConfig = {
|
|
@@ -21,5 +22,10 @@ export type OxlintConfig = {
|
|
|
21
22
|
ignorePatterns?: OxlintConfigIgnorePatterns;
|
|
22
23
|
};
|
|
23
24
|
export type OxlintConfigOrOverride = OxlintConfig | OxlintConfigOverride;
|
|
24
|
-
|
|
25
|
+
type Reporter = (warning: string) => void;
|
|
26
|
+
export type Options = {
|
|
27
|
+
reporter?: Reporter;
|
|
28
|
+
merge?: boolean;
|
|
29
|
+
withNursery?: boolean;
|
|
30
|
+
};
|
|
25
31
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isEqualDeep: <T>(a: T, b: T) => boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const isEqualDeep = (a, b) => {
|
|
2
|
+
if (a === b) {
|
|
3
|
+
return true;
|
|
4
|
+
}
|
|
5
|
+
const bothAreObjects = a && b && typeof a === "object" && typeof b === "object";
|
|
6
|
+
return Boolean(
|
|
7
|
+
bothAreObjects && Object.keys(a).length === Object.keys(b).length && Object.entries(a).every(([k, v]) => isEqualDeep(v, b[k]))
|
|
8
|
+
);
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
isEqualDeep
|
|
12
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxlint/migrate",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
4
4
|
"description": "Generates a `.oxlintrc.json` from a existing eslint flat config",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@eslint/eslintrc": "^3.3.0",
|
|
38
38
|
"@eslint/js": "^9.20.0",
|
|
39
39
|
"@logux/eslint-config": "^55.0.0",
|
|
40
|
-
"@oxc-node/core": "^0.0.
|
|
40
|
+
"@oxc-node/core": "^0.0.21",
|
|
41
41
|
"@stylistic/eslint-plugin": "^4.0.1",
|
|
42
42
|
"@stylistic/eslint-plugin-ts": "^4.0.0",
|
|
43
43
|
"@types/eslint-config-prettier": "^6.11.3",
|
|
@@ -52,12 +52,12 @@
|
|
|
52
52
|
"eslint-plugin-import-x": "^4.6.1",
|
|
53
53
|
"eslint-plugin-jsdoc": "^50.6.3",
|
|
54
54
|
"eslint-plugin-local": "^6.0.0",
|
|
55
|
-
"eslint-plugin-oxlint": "^0.
|
|
55
|
+
"eslint-plugin-oxlint": "^0.16.0",
|
|
56
56
|
"eslint-plugin-regexp": "^2.7.0",
|
|
57
57
|
"eslint-plugin-unicorn": "^57.0.0",
|
|
58
58
|
"husky": "^9.1.7",
|
|
59
59
|
"lint-staged": "^15.4.3",
|
|
60
|
-
"oxlint": "^0.16.
|
|
60
|
+
"oxlint": "^0.16.2",
|
|
61
61
|
"prettier": "^3.5.1",
|
|
62
62
|
"typescript": "^5.7.3",
|
|
63
63
|
"typescript-eslint": "^8.24.0",
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"commander": "^13.1.0",
|
|
73
73
|
"globals": "^16.0.0"
|
|
74
74
|
},
|
|
75
|
-
"packageManager": "pnpm@10.6.
|
|
75
|
+
"packageManager": "pnpm@10.6.3"
|
|
76
76
|
}
|