@oxlint/migrate 1.28.0 → 1.30.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 +1 -1
- package/dist/bin/project-loader.mjs +1 -1
- package/dist/package.json.mjs +1 -1
- package/dist/src/cleanup.mjs +66 -1
- package/dist/src/cleanup.test.d.ts +1 -0
- package/dist/src/env_globals.d.ts +8 -0
- package/dist/src/env_globals.mjs +57 -6
- package/dist/src/generated/rules.mjs +3 -0
- package/dist/src/plugins_rules.mjs +34 -9
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/@oxlint/migrate)
|
|
5
5
|
[](https://www.npmjs.com/package/@oxlint/migrate)
|
|
6
6
|
|
|
7
|
-
Generates a `.oxlintrc.json` from
|
|
7
|
+
Generates a `.oxlintrc.json` from an existing eslint flat config.
|
|
8
8
|
|
|
9
9
|
## Usage
|
|
10
10
|
|
package/dist/package.json.mjs
CHANGED
package/dist/src/cleanup.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { removeGlobalsWithAreCoveredByEnv, transformBoolGlobalToString, ES_VERSIONS, cleanUpUselessOverridesEnv } from "./env_globals.mjs";
|
|
1
|
+
import { removeGlobalsWithAreCoveredByEnv, transformBoolGlobalToString, ES_VERSIONS, cleanUpUselessOverridesEnv, cleanUpSupersetEnvs } from "./env_globals.mjs";
|
|
2
2
|
import { replaceTypescriptAliasRules, replaceNodePluginName, cleanUpRulesWhichAreCoveredByCategory, cleanUpDisabledRootRules, cleanUpUselessOverridesRules, cleanUpUselessOverridesPlugins } from "./plugins_rules.mjs";
|
|
3
3
|
import { isEqualDeep } from "./utilities.mjs";
|
|
4
4
|
const TS_ESLINT_DEFAULT_OVERRIDE = {
|
|
@@ -42,6 +42,7 @@ const cleanUpUselessOverridesEntries = (config) => {
|
|
|
42
42
|
cleanUpUselessOverridesRules(config);
|
|
43
43
|
cleanUpUselessOverridesPlugins(config);
|
|
44
44
|
cleanUpUselessOverridesEnv(config);
|
|
45
|
+
cleanUpSupersetEnvs(config);
|
|
45
46
|
if (config.overrides === void 0) {
|
|
46
47
|
return;
|
|
47
48
|
}
|
|
@@ -53,6 +54,8 @@ const cleanUpUselessOverridesEntries = (config) => {
|
|
|
53
54
|
config.overrides = config.overrides.filter(
|
|
54
55
|
(overrides) => Object.keys(overrides).length > 0
|
|
55
56
|
);
|
|
57
|
+
mergeConsecutiveIdenticalOverrides(config);
|
|
58
|
+
mergeConsecutiveOverridesWithDifferingFiles(config);
|
|
56
59
|
if (config.overrides.length === 0) {
|
|
57
60
|
delete config.overrides;
|
|
58
61
|
}
|
|
@@ -84,6 +87,68 @@ const cleanUpOxlintConfig = (config) => {
|
|
|
84
87
|
cleanUpDisabledRootRules(config);
|
|
85
88
|
}
|
|
86
89
|
};
|
|
90
|
+
function mergeConsecutiveIdenticalOverrides(config) {
|
|
91
|
+
if (config.overrides === void 0) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (config.overrides.length <= 1) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const mergedOverrides = [];
|
|
98
|
+
let i = 0;
|
|
99
|
+
while (i < config.overrides.length) {
|
|
100
|
+
const current = config.overrides[i];
|
|
101
|
+
if (i + 1 < config.overrides.length && isEqualDeep(current, config.overrides[i + 1])) {
|
|
102
|
+
mergedOverrides.push(current);
|
|
103
|
+
while (i + 1 < config.overrides.length && isEqualDeep(current, config.overrides[i + 1])) {
|
|
104
|
+
i++;
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
mergedOverrides.push(current);
|
|
108
|
+
}
|
|
109
|
+
i++;
|
|
110
|
+
}
|
|
111
|
+
config.overrides = mergedOverrides;
|
|
112
|
+
}
|
|
113
|
+
function mergeConsecutiveOverridesWithDifferingFiles(config) {
|
|
114
|
+
if (config.overrides === void 0) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (config.overrides.length <= 1) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const mergedOverrides = [];
|
|
121
|
+
let i = 0;
|
|
122
|
+
while (i < config.overrides.length) {
|
|
123
|
+
const current = config.overrides[i];
|
|
124
|
+
const currentFiles = current.files;
|
|
125
|
+
const { files: _, ...currentWithoutFiles } = current;
|
|
126
|
+
let j = i + 1;
|
|
127
|
+
const filesToMerge = [...currentFiles];
|
|
128
|
+
while (j < config.overrides.length) {
|
|
129
|
+
const next = config.overrides[j];
|
|
130
|
+
const { files: __, ...nextWithoutFiles } = next;
|
|
131
|
+
if (isEqualDeep(currentWithoutFiles, nextWithoutFiles)) {
|
|
132
|
+
filesToMerge.push(...next.files);
|
|
133
|
+
j++;
|
|
134
|
+
} else {
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (j > i + 1) {
|
|
139
|
+
const uniqueFiles = [...new Set(filesToMerge)];
|
|
140
|
+
mergedOverrides.push({
|
|
141
|
+
...current,
|
|
142
|
+
files: uniqueFiles
|
|
143
|
+
});
|
|
144
|
+
i = j;
|
|
145
|
+
} else {
|
|
146
|
+
mergedOverrides.push(current);
|
|
147
|
+
i++;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
config.overrides = mergedOverrides;
|
|
151
|
+
}
|
|
87
152
|
export {
|
|
88
153
|
cleanUpOxlintConfig
|
|
89
154
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -6,3 +6,11 @@ export declare const transformBoolGlobalToString: (config: OxlintConfigOrOverrid
|
|
|
6
6
|
export declare const detectEnvironmentByGlobals: (config: OxlintConfigOrOverride) => void;
|
|
7
7
|
export declare const transformEnvAndGlobals: (eslintConfig: Linter.Config, targetConfig: OxlintConfigOrOverride, options?: Options) => void;
|
|
8
8
|
export declare const cleanUpUselessOverridesEnv: (config: OxlintConfig) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Cleans up superset environments in the config and its overrides.
|
|
11
|
+
* If a superset environment is present, its subset environments are removed, e.g. all globals from `shared-node-browser` are also in `browser` and `node`.
|
|
12
|
+
*
|
|
13
|
+
* This also applies for overrides, where if a superset env is defined in the override or main config,
|
|
14
|
+
* the subset envs can be removed from the override if the override has the same value as the superset.
|
|
15
|
+
*/
|
|
16
|
+
export declare const cleanUpSupersetEnvs: (config: OxlintConfig) => void;
|
package/dist/src/env_globals.mjs
CHANGED
|
@@ -21,6 +21,7 @@ const OTHER_SUPPORTED_ENVS = [
|
|
|
21
21
|
"serviceworker",
|
|
22
22
|
"amd",
|
|
23
23
|
"applescript",
|
|
24
|
+
"astro",
|
|
24
25
|
"atomtest",
|
|
25
26
|
"commonjs",
|
|
26
27
|
"embertest",
|
|
@@ -36,9 +37,11 @@ const OTHER_SUPPORTED_ENVS = [
|
|
|
36
37
|
"prototypejs",
|
|
37
38
|
"phantomjs",
|
|
38
39
|
"shelljs",
|
|
40
|
+
"svelte",
|
|
39
41
|
"webextensions",
|
|
40
42
|
"qunit",
|
|
41
|
-
"vitest"
|
|
43
|
+
"vitest",
|
|
44
|
+
"vue"
|
|
42
45
|
];
|
|
43
46
|
const SUPPORTED_ESLINT_PARSERS = ["typescript-eslint/parser"];
|
|
44
47
|
const normalizeGlobValue = (value) => {
|
|
@@ -79,6 +82,7 @@ const transformBoolGlobalToString = (config) => {
|
|
|
79
82
|
}
|
|
80
83
|
}
|
|
81
84
|
};
|
|
85
|
+
const THRESHOLD_ENVS = ["browser", "node", "serviceworker", "worker"];
|
|
82
86
|
const detectEnvironmentByGlobals = (config) => {
|
|
83
87
|
if (config.globals === void 0) {
|
|
84
88
|
return;
|
|
@@ -93,12 +97,14 @@ const detectEnvironmentByGlobals = (config) => {
|
|
|
93
97
|
let search = Object.keys(entries);
|
|
94
98
|
let matches = search.filter(
|
|
95
99
|
(entry) => (
|
|
96
|
-
// @ts-
|
|
97
|
-
entry in config.globals && // @ts-
|
|
100
|
+
// @ts-expect-error -- we already checked for undefined
|
|
101
|
+
entry in config.globals && // @ts-expect-error -- filtering makes the key to any
|
|
98
102
|
normalizeGlobValue(config.globals[entry]) === entries[entry]
|
|
99
103
|
)
|
|
100
104
|
);
|
|
101
|
-
|
|
105
|
+
const useThreshold = THRESHOLD_ENVS.includes(env);
|
|
106
|
+
const withinThreshold = useThreshold && matches.length / search.length >= 0.97;
|
|
107
|
+
if (withinThreshold || !useThreshold && matches.length === search.length) {
|
|
102
108
|
if (config.env === void 0) {
|
|
103
109
|
config.env = {};
|
|
104
110
|
}
|
|
@@ -108,11 +114,11 @@ const detectEnvironmentByGlobals = (config) => {
|
|
|
108
114
|
};
|
|
109
115
|
const transformEnvAndGlobals = (eslintConfig, targetConfig, options) => {
|
|
110
116
|
if (eslintConfig.languageOptions?.parser !== void 0 && eslintConfig.languageOptions?.parser !== null && typeof eslintConfig.languageOptions.parser === "object" && "meta" in eslintConfig.languageOptions.parser && !SUPPORTED_ESLINT_PARSERS.includes(
|
|
111
|
-
// @ts-
|
|
117
|
+
// @ts-expect-error
|
|
112
118
|
eslintConfig.languageOptions.parser.meta?.name
|
|
113
119
|
)) {
|
|
114
120
|
options?.reporter?.report(
|
|
115
|
-
"special parser detected: " + // @ts-
|
|
121
|
+
"special parser detected: " + // @ts-expect-error
|
|
116
122
|
eslintConfig.languageOptions.parser.meta?.name
|
|
117
123
|
);
|
|
118
124
|
}
|
|
@@ -172,8 +178,53 @@ const cleanUpUselessOverridesEnv = (config) => {
|
|
|
172
178
|
}
|
|
173
179
|
}
|
|
174
180
|
};
|
|
181
|
+
const SUPERSET_ENVS = {
|
|
182
|
+
node: ["nodeBuiltin", "shared-node-browser", "commonjs"],
|
|
183
|
+
browser: ["shared-node-browser"]
|
|
184
|
+
};
|
|
185
|
+
const cleanUpSupersetEnvs = (config) => {
|
|
186
|
+
if (config.env !== void 0) {
|
|
187
|
+
for (const [supersetEnv, subsetEnvs] of Object.entries(SUPERSET_ENVS)) {
|
|
188
|
+
if (!(supersetEnv in config.env)) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
for (const subsetEnv of subsetEnvs) {
|
|
192
|
+
if (config.env[subsetEnv] === config.env[supersetEnv]) {
|
|
193
|
+
delete config.env[subsetEnv];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (config.overrides !== void 0) {
|
|
199
|
+
for (const override of config.overrides) {
|
|
200
|
+
if (override.env === void 0) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
for (const [supersetEnv, subsetEnvs] of Object.entries(SUPERSET_ENVS)) {
|
|
204
|
+
const supersetInOverride = supersetEnv in override.env;
|
|
205
|
+
const supersetInMain = config.env !== void 0 && supersetEnv in config.env;
|
|
206
|
+
for (const subsetEnv of subsetEnvs) {
|
|
207
|
+
if (!(subsetEnv in override.env)) {
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (supersetInOverride && override.env[subsetEnv] === override.env[supersetEnv]) {
|
|
211
|
+
delete override.env[subsetEnv];
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (supersetInMain && !supersetInOverride && config.env[supersetEnv] === override.env[subsetEnv]) {
|
|
215
|
+
delete override.env[subsetEnv];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (Object.keys(override.env).length === 0) {
|
|
220
|
+
delete override.env;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
175
225
|
export {
|
|
176
226
|
ES_VERSIONS,
|
|
227
|
+
cleanUpSupersetEnvs,
|
|
177
228
|
cleanUpUselessOverridesEnv,
|
|
178
229
|
detectEnvironmentByGlobals,
|
|
179
230
|
removeGlobalsWithAreCoveredByEnv,
|
|
@@ -53,6 +53,7 @@ const pedanticRules = [
|
|
|
53
53
|
"@typescript-eslint/no-unsafe-return",
|
|
54
54
|
"@typescript-eslint/only-throw-error",
|
|
55
55
|
"@typescript-eslint/prefer-enum-initializers",
|
|
56
|
+
"@typescript-eslint/prefer-includes",
|
|
56
57
|
"@typescript-eslint/prefer-promise-reject-errors",
|
|
57
58
|
"@typescript-eslint/prefer-ts-expect-error",
|
|
58
59
|
"@typescript-eslint/related-getter-setter-pairs",
|
|
@@ -251,6 +252,8 @@ const styleRules = [
|
|
|
251
252
|
"unicorn/numeric-separators-style",
|
|
252
253
|
"unicorn/prefer-classlist-toggle",
|
|
253
254
|
"unicorn/prefer-class-fields",
|
|
255
|
+
"unicorn/prefer-bigint-literals",
|
|
256
|
+
"unicorn/prefer-response-static-json",
|
|
254
257
|
"unicorn/prefer-global-this",
|
|
255
258
|
"unicorn/prefer-object-from-entries",
|
|
256
259
|
"unicorn/prefer-array-index-of",
|
|
@@ -6,8 +6,8 @@ const allRules = Object.values(rules).flat();
|
|
|
6
6
|
const isValueInSet = (value, validSet) => validSet.includes(value) || Array.isArray(value) && validSet.includes(value[0]);
|
|
7
7
|
const isActiveValue = (value) => isValueInSet(value, ["error", "warn", 1, 2]);
|
|
8
8
|
const isOffValue = (value) => isValueInSet(value, ["off", 0]);
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const isWarnValue = (value) => isValueInSet(value, ["warn", 1]);
|
|
10
|
+
const isErrorValue = (value) => isValueInSet(value, ["error", 2]);
|
|
11
11
|
const normalizeSeverityValue = (value) => {
|
|
12
12
|
if (value === void 0) {
|
|
13
13
|
return value;
|
|
@@ -120,17 +120,42 @@ const cleanUpUselessOverridesRules = (config) => {
|
|
|
120
120
|
if (config.rules === void 0 || config.overrides === void 0) {
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
const filesPatternMap = /* @__PURE__ */ new Map();
|
|
124
|
+
for (const [i, override] of config.overrides.entries()) {
|
|
125
|
+
if (override.files === void 0) {
|
|
125
126
|
continue;
|
|
126
127
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
const filesKey = JSON.stringify(override.files);
|
|
129
|
+
let entry = filesPatternMap.get(filesKey);
|
|
130
|
+
if (!entry) {
|
|
131
|
+
entry = {
|
|
132
|
+
firstIndex: i,
|
|
133
|
+
finalRules: {},
|
|
134
|
+
indicesToRemove: []
|
|
135
|
+
};
|
|
136
|
+
filesPatternMap.set(filesKey, entry);
|
|
137
|
+
} else {
|
|
138
|
+
entry.indicesToRemove.push(i);
|
|
139
|
+
}
|
|
140
|
+
if (override.rules) {
|
|
141
|
+
Object.assign(entry.finalRules, override.rules);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
for (const entry of filesPatternMap.values()) {
|
|
145
|
+
const firstOverride = config.overrides[entry.firstIndex];
|
|
146
|
+
firstOverride.rules = entry.finalRules;
|
|
147
|
+
if (firstOverride.rules) {
|
|
148
|
+
for (const [rule, settings] of Object.entries(firstOverride.rules)) {
|
|
149
|
+
if (config.rules[rule] === settings) {
|
|
150
|
+
delete firstOverride.rules[rule];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (Object.keys(firstOverride.rules).length === 0) {
|
|
154
|
+
delete firstOverride.rules;
|
|
130
155
|
}
|
|
131
156
|
}
|
|
132
|
-
|
|
133
|
-
delete
|
|
157
|
+
for (const indexToRemove of entry.indicesToRemove) {
|
|
158
|
+
delete config.overrides[indexToRemove].rules;
|
|
134
159
|
}
|
|
135
160
|
}
|
|
136
161
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxlint/migrate",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.0",
|
|
4
4
|
"description": "Generates a `.oxlintrc.json` from a existing eslint flat config",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -63,14 +63,14 @@
|
|
|
63
63
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
64
64
|
"eslint-plugin-react-perf": "^3.3.3",
|
|
65
65
|
"eslint-plugin-regexp": "^2.9.0",
|
|
66
|
-
"eslint-plugin-tsdoc": "^0.
|
|
66
|
+
"eslint-plugin-tsdoc": "^0.5.0",
|
|
67
67
|
"eslint-plugin-unicorn": "^62.0.0",
|
|
68
68
|
"husky": "^9.1.7",
|
|
69
69
|
"jiti": "^2.4.2",
|
|
70
70
|
"lint-staged": "^16.1.2",
|
|
71
71
|
"next": "^16.0.0",
|
|
72
|
-
"oxlint": "^1.
|
|
73
|
-
"oxlint-tsgolint": "^0.
|
|
72
|
+
"oxlint": "^1.30.0",
|
|
73
|
+
"oxlint-tsgolint": "^0.8.0",
|
|
74
74
|
"prettier": "^3.6.1",
|
|
75
75
|
"typescript": "^5.8.3",
|
|
76
76
|
"typescript-eslint": "^8.35.0",
|
|
@@ -84,11 +84,11 @@
|
|
|
84
84
|
"dependencies": {
|
|
85
85
|
"commander": "^14.0.0",
|
|
86
86
|
"globals": "^16.3.0",
|
|
87
|
-
"oxc-parser": "^0.
|
|
87
|
+
"oxc-parser": "^0.98.0",
|
|
88
88
|
"tinyglobby": "^0.2.14"
|
|
89
89
|
},
|
|
90
90
|
"peerDependencies": {
|
|
91
91
|
"jiti": "*"
|
|
92
92
|
},
|
|
93
|
-
"packageManager": "pnpm@10.
|
|
93
|
+
"packageManager": "pnpm@10.23.0"
|
|
94
94
|
}
|