@oxlint/migrate 1.29.0 → 1.31.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.
@@ -1,4 +1,4 @@
1
- const version = "1.29.0";
1
+ const version = "1.31.0";
2
2
  const packageJson = {
3
3
  version
4
4
  };
@@ -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;
@@ -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;
@@ -98,8 +102,9 @@ const detectEnvironmentByGlobals = (config) => {
98
102
  normalizeGlobValue(config.globals[entry]) === entries[entry]
99
103
  )
100
104
  );
101
- const useThreshold = env === "browser" || env === "node";
102
- if (useThreshold && matches.length / search.length >= 0.97 || !useThreshold && matches.length === search.length) {
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) {
103
108
  if (config.env === void 0) {
104
109
  config.env = {};
105
110
  }
@@ -173,8 +178,53 @@ const cleanUpUselessOverridesEnv = (config) => {
173
178
  }
174
179
  }
175
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
+ };
176
225
  export {
177
226
  ES_VERSIONS,
227
+ cleanUpSupersetEnvs,
178
228
  cleanUpUselessOverridesEnv,
179
229
  detectEnvironmentByGlobals,
180
230
  removeGlobalsWithAreCoveredByEnv,
@@ -252,6 +252,7 @@ const styleRules = [
252
252
  "unicorn/numeric-separators-style",
253
253
  "unicorn/prefer-classlist-toggle",
254
254
  "unicorn/prefer-class-fields",
255
+ "unicorn/prefer-bigint-literals",
255
256
  "unicorn/prefer-response-static-json",
256
257
  "unicorn/prefer-global-this",
257
258
  "unicorn/prefer-object-from-entries",
@@ -426,6 +427,7 @@ const restrictionRules = [
426
427
  "@typescript-eslint/no-non-null-asserted-nullish-coalescing",
427
428
  "@typescript-eslint/no-non-null-assertion",
428
429
  "@typescript-eslint/no-require-imports",
430
+ "@typescript-eslint/no-restricted-types",
429
431
  "@typescript-eslint/no-var-requires",
430
432
  "@typescript-eslint/non-nullable-type-assertion-style",
431
433
  "@typescript-eslint/prefer-literal-enum-member",
@@ -120,17 +120,42 @@ const cleanUpUselessOverridesRules = (config) => {
120
120
  if (config.rules === void 0 || config.overrides === void 0) {
121
121
  return;
122
122
  }
123
- for (const override of config.overrides) {
124
- if (override.rules === void 0) {
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
- for (const [rule, settings] of Object.entries(override.rules)) {
128
- if (config.rules[rule] === settings) {
129
- delete override.rules[rule];
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
- if (Object.keys(override.rules).length === 0) {
133
- delete override.rules;
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.29.0",
3
+ "version": "1.31.0",
4
4
  "description": "Generates a `.oxlintrc.json` from a existing eslint flat config",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "scripts": {
18
18
  "prepare": "husky",
19
19
  "generate": "node --import @oxc-node/core/register ./scripts/generate.ts",
20
- "format": "npx prettier --write .",
20
+ "format": "oxfmt",
21
21
  "type-check": "tsc --noEmit",
22
22
  "lint": "oxlint --type-aware",
23
23
  "test": "vitest",
@@ -69,9 +69,9 @@
69
69
  "jiti": "^2.4.2",
70
70
  "lint-staged": "^16.1.2",
71
71
  "next": "^16.0.0",
72
- "oxlint": "^1.29.0",
73
- "oxlint-tsgolint": "^0.5.1",
74
- "prettier": "^3.6.1",
72
+ "oxfmt": "^0.15.0",
73
+ "oxlint": "^1.31.0",
74
+ "oxlint-tsgolint": "^0.8.3",
75
75
  "typescript": "^5.8.3",
76
76
  "typescript-eslint": "^8.35.0",
77
77
  "vite": "^7.0.0",
@@ -79,16 +79,16 @@
79
79
  "vitest": "^4.0.0"
80
80
  },
81
81
  "lint-staged": {
82
- "*": "prettier --ignore-unknown --write"
82
+ "*": "oxfmt --no-error-on-unmatched-pattern"
83
83
  },
84
84
  "dependencies": {
85
85
  "commander": "^14.0.0",
86
86
  "globals": "^16.3.0",
87
- "oxc-parser": "^0.97.0",
87
+ "oxc-parser": "^0.99.0",
88
88
  "tinyglobby": "^0.2.14"
89
89
  },
90
90
  "peerDependencies": {
91
91
  "jiti": "*"
92
92
  },
93
- "packageManager": "pnpm@10.22.0"
93
+ "packageManager": "pnpm@10.24.0"
94
94
  }