@oxlint/migrate 1.56.0 → 1.58.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 -5
- package/dist/bin/oxlint-migrate.mjs +11 -11
- package/dist/src/index.d.mts +2 -2
- package/dist/src/index.mjs +1 -1
- package/dist/{src-DIfNUkJH.mjs → src-BLIW50Ng.mjs} +455 -443
- package/package.json +11 -9
package/README.md
CHANGED
|
@@ -114,8 +114,4 @@ Depending on how this is implemented by the given config, these behaviors may no
|
|
|
114
114
|
|
|
115
115
|
The JS Plugins API supports almost all ESLint v9+ plugins for linting JS/TS/JSX/TSX files, but there are still some minor holes in support. See the [JS Plugins documentation](https://oxc.rs/docs/guide/usage/linter/js-plugins.html) for specifics.
|
|
116
116
|
|
|
117
|
-
For example, if you currently use `eslint-plugin-
|
|
118
|
-
|
|
119
|
-
You could also consider [replacing Prettier with Oxfmt](https://oxc.rs/docs/guide/usage/formatter/migrate-from-prettier.html).
|
|
120
|
-
|
|
121
|
-
Note that `eslint-config-prettier` is different from the prettier plugin, and _will_ be migrated fine, as it's just a config to disable formatting-related ESLint rules, not an actual plugin.
|
|
117
|
+
For example, if you currently use `eslint-plugin-svelte`, only some of its rules will work via JS Plugin, as Oxlint does not yet fully support custom file formats like `.svelte`. This means that Oxlint will only be able to lint the script blocks in your `.svelte` files, and not the template blocks where many of the `eslint-plugin-svelte` rules apply.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as nurseryRules, i as buildUnsupportedRuleExplanations, n as preFixForJsPlugins, o as rules_exports, r as isOffValue, t as main } from "../src-
|
|
2
|
+
import { a as nurseryRules, i as buildUnsupportedRuleExplanations, n as preFixForJsPlugins, o as rules_exports, r as isOffValue, s as normalizeRuleToCanonical, t as main } from "../src-BLIW50Ng.mjs";
|
|
3
3
|
import { program } from "commander";
|
|
4
4
|
import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
@@ -30,10 +30,11 @@ const loadESLintConfig = async (filePath) => {
|
|
|
30
30
|
};
|
|
31
31
|
//#endregion
|
|
32
32
|
//#region package.json
|
|
33
|
-
var version = "1.
|
|
33
|
+
var version = "1.58.0";
|
|
34
34
|
//#endregion
|
|
35
35
|
//#region src/walker/comments/replaceRuleDirectiveComment.ts
|
|
36
|
-
const
|
|
36
|
+
const allRulesSet = new Set(Object.values(rules_exports).flat());
|
|
37
|
+
const nurseryRulesSet = new Set(nurseryRules);
|
|
37
38
|
function replaceRuleDirectiveComment(comment, type, options) {
|
|
38
39
|
const originalComment = comment;
|
|
39
40
|
comment = comment.split(" -- ")[0].trimStart();
|
|
@@ -51,14 +52,13 @@ function replaceRuleDirectiveComment(comment, type, options) {
|
|
|
51
52
|
comment = comment.trimStart();
|
|
52
53
|
if (comment.length === 0) return originalComment;
|
|
53
54
|
while (comment.length) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (!foundRule) return originalComment;
|
|
55
|
+
const commaIdx = comment.indexOf(",");
|
|
56
|
+
const candidateEnd = commaIdx === -1 ? comment.length : commaIdx;
|
|
57
|
+
const candidate = comment.substring(0, candidateEnd).trimEnd();
|
|
58
|
+
const canonical = normalizeRuleToCanonical(candidate);
|
|
59
|
+
if (!allRulesSet.has(canonical)) return originalComment;
|
|
60
|
+
if (!options.withNursery && nurseryRulesSet.has(canonical)) return originalComment;
|
|
61
|
+
comment = comment.substring(candidate.length).trimStart();
|
|
62
62
|
if (!comment.length) break;
|
|
63
63
|
if (!comment.startsWith(", ")) return originalComment;
|
|
64
64
|
comment = comment.substring(1).trimStart();
|
package/dist/src/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region node_modules/.pnpm/oxlint@1.
|
|
1
|
+
//#region node_modules/.pnpm/oxlint@1.58.0_oxlint-tsgolint@0.18.1/node_modules/oxlint/dist/index.d.ts
|
|
2
2
|
//#region src-js/package/config.generated.d.ts
|
|
3
3
|
type AllowWarnDeny = ("allow" | "off" | "warn" | "error" | "deny") | number;
|
|
4
4
|
type GlobalValue = "readonly" | "writable" | "off";
|
|
@@ -37,7 +37,7 @@ type ExternalPluginEntry = string | {
|
|
|
37
37
|
type GlobSet = string[];
|
|
38
38
|
type LintPluginOptionsSchema = "eslint" | "react" | "unicorn" | "typescript" | "oxc" | "import" | "jsdoc" | "jest" | "vitest" | "jsx-a11y" | "nextjs" | "react-perf" | "promise" | "node" | "vue";
|
|
39
39
|
type LintPlugins = LintPluginOptionsSchema[];
|
|
40
|
-
type DummyRule = AllowWarnDeny | unknown[];
|
|
40
|
+
type DummyRule = AllowWarnDeny | [AllowWarnDeny, ...unknown[]];
|
|
41
41
|
type OxlintOverrides = OxlintOverride[];
|
|
42
42
|
type TagNamePreference = string | {
|
|
43
43
|
message: string;
|
package/dist/src/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as main } from "../src-
|
|
1
|
+
import { t as main } from "../src-BLIW50Ng.mjs";
|
|
2
2
|
export { main as default };
|
|
@@ -165,6 +165,223 @@ const cleanUpSupersetEnvs = (config) => {
|
|
|
165
165
|
}
|
|
166
166
|
};
|
|
167
167
|
//#endregion
|
|
168
|
+
//#region src/constants.ts
|
|
169
|
+
const rulesPrefixesForPlugins = {
|
|
170
|
+
import: "import",
|
|
171
|
+
"import-x": "import",
|
|
172
|
+
jest: "jest",
|
|
173
|
+
jsdoc: "jsdoc",
|
|
174
|
+
"jsx-a11y": "jsx-a11y",
|
|
175
|
+
"@next/next": "nextjs",
|
|
176
|
+
node: "node",
|
|
177
|
+
n: "node",
|
|
178
|
+
promise: "promise",
|
|
179
|
+
react: "react",
|
|
180
|
+
"react-perf": "react-perf",
|
|
181
|
+
"react-hooks": "react",
|
|
182
|
+
"react-refresh": "react",
|
|
183
|
+
"@typescript-eslint": "typescript",
|
|
184
|
+
unicorn: "unicorn",
|
|
185
|
+
vitest: "vitest",
|
|
186
|
+
vue: "vue"
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Normalizes an ESLint-style rule name to its canonical Oxlint form.
|
|
190
|
+
* e.g. "@typescript-eslint/no-floating-promises" → "typescript/no-floating-promises"
|
|
191
|
+
* "react-hooks/exhaustive-deps" → "react/exhaustive-deps"
|
|
192
|
+
* "@next/next/inline-script-id" → "nextjs/inline-script-id"
|
|
193
|
+
* "no-unused-vars" → "no-unused-vars" (unchanged for unprefixed rules)
|
|
194
|
+
*/
|
|
195
|
+
function normalizeRuleToCanonical(rule) {
|
|
196
|
+
for (const [prefix, plugin] of Object.entries(rulesPrefixesForPlugins)) if (prefix !== plugin && rule.startsWith(`${prefix}/`)) return `${plugin}/${rule.slice(prefix.length + 1)}`;
|
|
197
|
+
return rule;
|
|
198
|
+
}
|
|
199
|
+
const eslintRulesToTypescriptEquivalents = {
|
|
200
|
+
"dot-notation": "@typescript-eslint/dot-notation",
|
|
201
|
+
"consistent-return": "@typescript-eslint/consistent-return"
|
|
202
|
+
};
|
|
203
|
+
const typescriptRulesExtendEslintRules = [
|
|
204
|
+
"class-methods-use-this",
|
|
205
|
+
"default-param-last",
|
|
206
|
+
"init-declarations",
|
|
207
|
+
"max-params",
|
|
208
|
+
"no-array-constructor",
|
|
209
|
+
"no-dupe-class-members",
|
|
210
|
+
"no-empty-function",
|
|
211
|
+
"no-invalid-this",
|
|
212
|
+
"no-loop-func",
|
|
213
|
+
"no-loss-of-precision",
|
|
214
|
+
"no-magic-numbers",
|
|
215
|
+
"no-redeclare",
|
|
216
|
+
"no-restricted-imports",
|
|
217
|
+
"no-shadow",
|
|
218
|
+
"no-unused-expressions",
|
|
219
|
+
"no-unused-vars",
|
|
220
|
+
"no-use-before-define",
|
|
221
|
+
"no-useless-constructor"
|
|
222
|
+
];
|
|
223
|
+
//#endregion
|
|
224
|
+
//#region src/jsPlugins.ts
|
|
225
|
+
const ignorePlugins = new Set([
|
|
226
|
+
...Object.keys(rulesPrefixesForPlugins),
|
|
227
|
+
...Object.values(rulesPrefixesForPlugins),
|
|
228
|
+
"local"
|
|
229
|
+
]);
|
|
230
|
+
const tryResolvePackage = (packageName) => {
|
|
231
|
+
try {
|
|
232
|
+
import.meta.resolve(packageName);
|
|
233
|
+
return true;
|
|
234
|
+
} catch {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
const pluginNameCache = /* @__PURE__ */ new Map();
|
|
239
|
+
/**
|
|
240
|
+
* Resolves the npm package name for an ESLint plugin given its scope name.
|
|
241
|
+
*
|
|
242
|
+
* For scoped plugin names (starting with `@`), the mapping is unambiguous:
|
|
243
|
+
* - `@scope` -> `@scope/eslint-plugin`
|
|
244
|
+
* - `@scope/sub` -> `@scope/eslint-plugin-sub`
|
|
245
|
+
*
|
|
246
|
+
* For non-scoped names, the npm package could follow either convention:
|
|
247
|
+
* - `eslint-plugin-{name}` (e.g. `eslint-plugin-mocha`)
|
|
248
|
+
* - `@{name}/eslint-plugin` (e.g. `@e18e/eslint-plugin`)
|
|
249
|
+
*
|
|
250
|
+
* We try to resolve both candidates against the installed packages and
|
|
251
|
+
* use the one that is actually present, falling back to the standard
|
|
252
|
+
* `eslint-plugin-{name}` convention when neither can be resolved.
|
|
253
|
+
*/
|
|
254
|
+
const resolveEslintPluginName = (pluginName) => {
|
|
255
|
+
const cached = pluginNameCache.get(pluginName);
|
|
256
|
+
if (cached !== void 0) return cached;
|
|
257
|
+
let result;
|
|
258
|
+
if (pluginName.startsWith("@")) {
|
|
259
|
+
const [scope, maybeSub] = pluginName.split("/");
|
|
260
|
+
if (maybeSub) result = `${scope}/eslint-plugin-${maybeSub}`;
|
|
261
|
+
else result = `${scope}/eslint-plugin`;
|
|
262
|
+
} else {
|
|
263
|
+
const standardName = `eslint-plugin-${pluginName}`;
|
|
264
|
+
const scopedName = `@${pluginName}/eslint-plugin`;
|
|
265
|
+
if (tryResolvePackage(standardName)) result = standardName;
|
|
266
|
+
else if (tryResolvePackage(scopedName)) result = scopedName;
|
|
267
|
+
else result = standardName;
|
|
268
|
+
}
|
|
269
|
+
pluginNameCache.set(pluginName, result);
|
|
270
|
+
return result;
|
|
271
|
+
};
|
|
272
|
+
const extractPluginId = (ruleId) => {
|
|
273
|
+
const firstSlash = ruleId.indexOf("/");
|
|
274
|
+
if (firstSlash === -1) return;
|
|
275
|
+
if (ruleId.startsWith("@")) {
|
|
276
|
+
const secondSlash = ruleId.indexOf("/", firstSlash + 1);
|
|
277
|
+
if (secondSlash !== -1) return ruleId.substring(0, secondSlash);
|
|
278
|
+
}
|
|
279
|
+
return ruleId.substring(0, firstSlash);
|
|
280
|
+
};
|
|
281
|
+
const isIgnoredPluginRule = (ruleId) => {
|
|
282
|
+
const pluginName = extractPluginId(ruleId);
|
|
283
|
+
if (pluginName === void 0) return true;
|
|
284
|
+
return ignorePlugins.has(pluginName);
|
|
285
|
+
};
|
|
286
|
+
/**
|
|
287
|
+
* Derives the npm package name for a plugin from its `meta.name` field.
|
|
288
|
+
*
|
|
289
|
+
* If `meta.name` already looks like a full npm package name (contains
|
|
290
|
+
* "eslint-plugin"), it is returned as-is. Otherwise it is fed through
|
|
291
|
+
* {@link resolveEslintPluginName} for the usual heuristic resolution.
|
|
292
|
+
*/
|
|
293
|
+
const resolveFromMetaName = (metaName) => {
|
|
294
|
+
if (metaName.includes("eslint-plugin")) return metaName;
|
|
295
|
+
return resolveEslintPluginName(metaName);
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* Derives the rule-ID prefix that an npm package exposes.
|
|
299
|
+
*
|
|
300
|
+
* Examples:
|
|
301
|
+
* `eslint-plugin-react-dom` -> `react-dom`
|
|
302
|
+
* `eslint-plugin-mocha` -> `mocha`
|
|
303
|
+
* `@stylistic/eslint-plugin` -> `@stylistic`
|
|
304
|
+
* `@stylistic/eslint-plugin-ts` -> `@stylistic/ts`
|
|
305
|
+
*/
|
|
306
|
+
const deriveRulePrefix = (packageName) => {
|
|
307
|
+
if (packageName.startsWith("@")) {
|
|
308
|
+
const slashIdx = packageName.indexOf("/");
|
|
309
|
+
const scope = packageName.substring(0, slashIdx);
|
|
310
|
+
const rest = packageName.substring(slashIdx + 1);
|
|
311
|
+
if (rest === "eslint-plugin") return scope;
|
|
312
|
+
if (rest.startsWith("eslint-plugin-")) return `${scope}/${rest.substring(14)}`;
|
|
313
|
+
return packageName;
|
|
314
|
+
}
|
|
315
|
+
if (packageName.startsWith("eslint-plugin-")) return packageName.substring(14);
|
|
316
|
+
return packageName;
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* Resolves the canonical rule name for a jsPlugin rule.
|
|
320
|
+
*
|
|
321
|
+
* When a plugin is registered under an alias (e.g. `@eslint-react/dom`) but
|
|
322
|
+
* its `meta.name` reveals a different canonical package (`eslint-plugin-react-dom`),
|
|
323
|
+
* the rule must be rewritten so that oxlint can match it to the loaded plugin.
|
|
324
|
+
*
|
|
325
|
+
* For example:
|
|
326
|
+
* `@eslint-react/dom/no-find-dom-node` -> `react-dom/no-find-dom-node`
|
|
327
|
+
*/
|
|
328
|
+
const resolveJsPluginRuleName = (rule, plugins) => {
|
|
329
|
+
const pluginName = extractPluginId(rule);
|
|
330
|
+
if (pluginName === void 0) return rule;
|
|
331
|
+
const metaName = plugins?.[pluginName]?.meta?.name;
|
|
332
|
+
if (!metaName || !metaName.includes("eslint-plugin")) return rule;
|
|
333
|
+
const canonicalPrefix = deriveRulePrefix(metaName);
|
|
334
|
+
if (canonicalPrefix === pluginName) return rule;
|
|
335
|
+
return `${canonicalPrefix}/${rule.substring(pluginName.length + 1)}`;
|
|
336
|
+
};
|
|
337
|
+
const enableJsPluginRule = (targetConfig, rule, ruleEntry, plugins) => {
|
|
338
|
+
const pluginName = extractPluginId(rule);
|
|
339
|
+
if (pluginName === void 0) return false;
|
|
340
|
+
if (ignorePlugins.has(pluginName)) return false;
|
|
341
|
+
if (targetConfig.jsPlugins === void 0 || targetConfig.jsPlugins === null) targetConfig.jsPlugins = [];
|
|
342
|
+
const metaName = plugins?.[pluginName]?.meta?.name;
|
|
343
|
+
const eslintPluginName = metaName ? resolveFromMetaName(metaName) : resolveEslintPluginName(pluginName);
|
|
344
|
+
if (!targetConfig.jsPlugins.includes(eslintPluginName)) targetConfig.jsPlugins.push(eslintPluginName);
|
|
345
|
+
const resolvedRule = resolveJsPluginRuleName(rule, plugins);
|
|
346
|
+
targetConfig.rules = targetConfig.rules ?? {};
|
|
347
|
+
targetConfig.rules[resolvedRule] = ruleEntry;
|
|
348
|
+
return true;
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* Returns true if any rule name matches the given jsPlugin package.
|
|
352
|
+
*
|
|
353
|
+
* Handles aliased plugins where the ESLint registration name differs from the
|
|
354
|
+
* canonical prefix derived from the npm package name:
|
|
355
|
+
* - `@e18e/eslint-plugin` → prefix `@e18e`, but rules may use `e18e/`
|
|
356
|
+
* - `@eslint/eslint-plugin-markdown` → prefix `@eslint/markdown`, but rules
|
|
357
|
+
* may use `markdown/`
|
|
358
|
+
*/
|
|
359
|
+
const hasRulesForPlugin = (ruleNames, pluginPackage) => {
|
|
360
|
+
const prefix = deriveRulePrefix(pluginPackage);
|
|
361
|
+
if (ruleNames.some((rule) => rule.startsWith(`${prefix}/`))) return true;
|
|
362
|
+
if (prefix.startsWith("@")) {
|
|
363
|
+
const slashIdx = prefix.indexOf("/");
|
|
364
|
+
const unscoped = slashIdx === -1 ? prefix.substring(1) : prefix.substring(slashIdx + 1);
|
|
365
|
+
return ruleNames.some((rule) => rule.startsWith(`${unscoped}/`));
|
|
366
|
+
}
|
|
367
|
+
return false;
|
|
368
|
+
};
|
|
369
|
+
/**
|
|
370
|
+
* Removes jsPlugin entries that have no corresponding rules left in the config.
|
|
371
|
+
*
|
|
372
|
+
* This can happen when an earlier ESLint config enables a plugin rule (adding the
|
|
373
|
+
* jsPlugin) but a later config (e.g. eslint-config-prettier) turns all of that
|
|
374
|
+
* plugin's rules off (deleting them from the rules object).
|
|
375
|
+
*/
|
|
376
|
+
const cleanUpUnusedJsPlugins = (config) => {
|
|
377
|
+
if (config.jsPlugins === void 0 || config.jsPlugins === null || config.jsPlugins.length === 0) return;
|
|
378
|
+
const ruleNames = Object.keys(config.rules ?? {});
|
|
379
|
+
config.jsPlugins = config.jsPlugins.filter((entry) => {
|
|
380
|
+
return hasRulesForPlugin(ruleNames, typeof entry === "string" ? entry : entry.specifier);
|
|
381
|
+
});
|
|
382
|
+
if (config.jsPlugins.length === 0) delete config.jsPlugins;
|
|
383
|
+
};
|
|
384
|
+
//#endregion
|
|
168
385
|
//#region src/generated/rules.ts
|
|
169
386
|
var rules_exports = /* @__PURE__ */ __exportAll({
|
|
170
387
|
correctnessRules: () => correctnessRules,
|
|
@@ -222,31 +439,31 @@ const pedanticRules = [
|
|
|
222
439
|
"react/jsx-no-target-blank",
|
|
223
440
|
"react/jsx-no-useless-fragment",
|
|
224
441
|
"react/no-unescaped-entities",
|
|
225
|
-
"react
|
|
226
|
-
"
|
|
227
|
-
"
|
|
228
|
-
"
|
|
229
|
-
"
|
|
230
|
-
"
|
|
231
|
-
"
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
235
|
-
"
|
|
236
|
-
"
|
|
237
|
-
"
|
|
238
|
-
"
|
|
239
|
-
"
|
|
240
|
-
"
|
|
241
|
-
"
|
|
242
|
-
"
|
|
243
|
-
"
|
|
244
|
-
"
|
|
245
|
-
"
|
|
246
|
-
"
|
|
247
|
-
"
|
|
248
|
-
"
|
|
249
|
-
"
|
|
442
|
+
"react/rules-of-hooks",
|
|
443
|
+
"typescript/ban-ts-comment",
|
|
444
|
+
"typescript/ban-types",
|
|
445
|
+
"typescript/no-confusing-void-expression",
|
|
446
|
+
"typescript/no-deprecated",
|
|
447
|
+
"typescript/no-misused-promises",
|
|
448
|
+
"typescript/no-mixed-enums",
|
|
449
|
+
"typescript/no-unsafe-argument",
|
|
450
|
+
"typescript/no-unsafe-assignment",
|
|
451
|
+
"typescript/no-unsafe-call",
|
|
452
|
+
"typescript/no-unsafe-function-type",
|
|
453
|
+
"typescript/no-unsafe-member-access",
|
|
454
|
+
"typescript/no-unsafe-return",
|
|
455
|
+
"typescript/only-throw-error",
|
|
456
|
+
"typescript/prefer-enum-initializers",
|
|
457
|
+
"typescript/prefer-includes",
|
|
458
|
+
"typescript/prefer-nullish-coalescing",
|
|
459
|
+
"typescript/prefer-promise-reject-errors",
|
|
460
|
+
"typescript/prefer-ts-expect-error",
|
|
461
|
+
"typescript/related-getter-setter-pairs",
|
|
462
|
+
"typescript/require-await",
|
|
463
|
+
"typescript/restrict-plus-operands",
|
|
464
|
+
"typescript/return-await",
|
|
465
|
+
"typescript/strict-boolean-expressions",
|
|
466
|
+
"typescript/switch-exhaustiveness-check",
|
|
250
467
|
"unicorn/consistent-assert",
|
|
251
468
|
"unicorn/consistent-empty-array-spread",
|
|
252
469
|
"unicorn/escape-case",
|
|
@@ -291,11 +508,10 @@ const pedanticRules = [
|
|
|
291
508
|
"unicorn/prefer-top-level-await",
|
|
292
509
|
"unicorn/prefer-type-error",
|
|
293
510
|
"unicorn/require-number-to-fixed-digits-argument",
|
|
294
|
-
"
|
|
295
|
-
"
|
|
511
|
+
"typescript/no-array-constructor",
|
|
512
|
+
"typescript/no-loop-func",
|
|
296
513
|
"unicorn/no-negated-condition",
|
|
297
|
-
"
|
|
298
|
-
"import-x/max-dependencies",
|
|
514
|
+
"typescript/no-redeclare",
|
|
299
515
|
"vitest/no-conditional-in-test"
|
|
300
516
|
];
|
|
301
517
|
const styleRules = [
|
|
@@ -420,26 +636,31 @@ const styleRules = [
|
|
|
420
636
|
"react/prefer-es6-class",
|
|
421
637
|
"react/self-closing-comp",
|
|
422
638
|
"react/state-in-constructor",
|
|
423
|
-
"
|
|
424
|
-
"
|
|
425
|
-
"
|
|
426
|
-
"
|
|
427
|
-
"
|
|
428
|
-
"
|
|
429
|
-
"
|
|
430
|
-
"
|
|
431
|
-
"
|
|
432
|
-
"
|
|
433
|
-
"
|
|
434
|
-
"
|
|
435
|
-
"
|
|
436
|
-
"
|
|
437
|
-
"
|
|
438
|
-
"
|
|
439
|
-
"
|
|
639
|
+
"typescript/adjacent-overload-signatures",
|
|
640
|
+
"typescript/array-type",
|
|
641
|
+
"typescript/ban-tslint-comment",
|
|
642
|
+
"typescript/class-literal-property-style",
|
|
643
|
+
"typescript/consistent-generic-constructors",
|
|
644
|
+
"typescript/consistent-indexed-object-style",
|
|
645
|
+
"typescript/consistent-type-assertions",
|
|
646
|
+
"typescript/consistent-type-definitions",
|
|
647
|
+
"typescript/consistent-type-imports",
|
|
648
|
+
"typescript/no-empty-interface",
|
|
649
|
+
"typescript/no-inferrable-types",
|
|
650
|
+
"typescript/parameter-properties",
|
|
651
|
+
"typescript/prefer-find",
|
|
652
|
+
"typescript/prefer-for-of",
|
|
653
|
+
"typescript/prefer-function-type",
|
|
654
|
+
"typescript/prefer-readonly",
|
|
655
|
+
"typescript/prefer-reduce-type-parameter",
|
|
656
|
+
"typescript/prefer-regexp-exec",
|
|
657
|
+
"typescript/prefer-return-this-type",
|
|
658
|
+
"typescript/prefer-string-starts-ends-with",
|
|
659
|
+
"typescript/unified-signatures",
|
|
440
660
|
"unicorn/catch-error-name",
|
|
441
661
|
"unicorn/consistent-date-clone",
|
|
442
662
|
"unicorn/consistent-existence-index-check",
|
|
663
|
+
"unicorn/custom-error-definition",
|
|
443
664
|
"unicorn/empty-brace-spaces",
|
|
444
665
|
"unicorn/error-message",
|
|
445
666
|
"unicorn/filename-case",
|
|
@@ -484,11 +705,13 @@ const styleRules = [
|
|
|
484
705
|
"vitest/consistent-vitest-vi",
|
|
485
706
|
"vitest/no-import-node-test",
|
|
486
707
|
"vitest/no-importing-vitest-globals",
|
|
708
|
+
"vitest/prefer-called-exactly-once-with",
|
|
487
709
|
"vitest/prefer-called-once",
|
|
488
710
|
"vitest/prefer-called-times",
|
|
489
711
|
"vitest/prefer-describe-function-title",
|
|
490
712
|
"vitest/prefer-expect-type-of",
|
|
491
713
|
"vitest/prefer-import-in-mock",
|
|
714
|
+
"vitest/prefer-strict-boolean-matchers",
|
|
492
715
|
"vitest/prefer-to-be-falsy",
|
|
493
716
|
"vitest/prefer-to-be-object",
|
|
494
717
|
"vitest/prefer-to-be-truthy",
|
|
@@ -496,22 +719,10 @@ const styleRules = [
|
|
|
496
719
|
"vue/define-props-declaration",
|
|
497
720
|
"vue/define-props-destructuring",
|
|
498
721
|
"vue/require-typed-ref",
|
|
499
|
-
"
|
|
500
|
-
"
|
|
501
|
-
"
|
|
502
|
-
"
|
|
503
|
-
"import-x/consistent-type-specifier-style",
|
|
504
|
-
"import-x/exports-last",
|
|
505
|
-
"import-x/first",
|
|
506
|
-
"import-x/group-exports",
|
|
507
|
-
"import-x/no-anonymous-default-export",
|
|
508
|
-
"import-x/no-duplicates",
|
|
509
|
-
"import-x/no-mutable-exports",
|
|
510
|
-
"import-x/no-named-default",
|
|
511
|
-
"import-x/no-named-export",
|
|
512
|
-
"import-x/no-namespace",
|
|
513
|
-
"import-x/no-nodejs-modules",
|
|
514
|
-
"import-x/prefer-default-export",
|
|
722
|
+
"typescript/default-param-last",
|
|
723
|
+
"typescript/init-declarations",
|
|
724
|
+
"typescript/max-params",
|
|
725
|
+
"typescript/no-magic-numbers",
|
|
515
726
|
"vitest/consistent-test-it",
|
|
516
727
|
"vitest/max-expects",
|
|
517
728
|
"vitest/max-nested-describe",
|
|
@@ -541,12 +752,11 @@ const styleRules = [
|
|
|
541
752
|
"vitest/prefer-strict-equal",
|
|
542
753
|
"vitest/prefer-to-be",
|
|
543
754
|
"vitest/prefer-to-contain",
|
|
755
|
+
"vitest/prefer-to-have-been-called-times",
|
|
544
756
|
"vitest/prefer-to-have-length",
|
|
545
757
|
"vitest/prefer-todo",
|
|
546
758
|
"vitest/require-hook",
|
|
547
|
-
"vitest/require-top-level-describe"
|
|
548
|
-
"n/global-require",
|
|
549
|
-
"n/no-exports-assign"
|
|
759
|
+
"vitest/require-top-level-describe"
|
|
550
760
|
];
|
|
551
761
|
const suspiciousRules = [
|
|
552
762
|
"block-scoped-var",
|
|
@@ -576,15 +786,15 @@ const suspiciousRules = [
|
|
|
576
786
|
"react/no-namespace",
|
|
577
787
|
"react/react-in-jsx-scope",
|
|
578
788
|
"react/style-prop-object",
|
|
579
|
-
"
|
|
580
|
-
"
|
|
581
|
-
"
|
|
582
|
-
"
|
|
583
|
-
"
|
|
584
|
-
"
|
|
585
|
-
"
|
|
586
|
-
"
|
|
587
|
-
"
|
|
789
|
+
"typescript/no-confusing-non-null-assertion",
|
|
790
|
+
"typescript/no-extraneous-class",
|
|
791
|
+
"typescript/no-unnecessary-boolean-literal-compare",
|
|
792
|
+
"typescript/no-unnecessary-template-expression",
|
|
793
|
+
"typescript/no-unnecessary-type-arguments",
|
|
794
|
+
"typescript/no-unnecessary-type-assertion",
|
|
795
|
+
"typescript/no-unnecessary-type-constraint",
|
|
796
|
+
"typescript/no-unsafe-enum-comparison",
|
|
797
|
+
"typescript/no-unsafe-type-assertion",
|
|
588
798
|
"unicorn/consistent-function-scoping",
|
|
589
799
|
"unicorn/no-accessor-recursion",
|
|
590
800
|
"unicorn/no-array-reverse",
|
|
@@ -595,14 +805,8 @@ const suspiciousRules = [
|
|
|
595
805
|
"unicorn/require-post-message-target-origin",
|
|
596
806
|
"vue/no-required-prop-with-default",
|
|
597
807
|
"vue/require-default-export",
|
|
598
|
-
"
|
|
599
|
-
"
|
|
600
|
-
"import-x/no-absolute-path",
|
|
601
|
-
"import-x/no-empty-named-blocks",
|
|
602
|
-
"import-x/no-named-as-default",
|
|
603
|
-
"import-x/no-named-as-default-member",
|
|
604
|
-
"import-x/no-self-import",
|
|
605
|
-
"import-x/no-unassigned-import",
|
|
808
|
+
"typescript/no-shadow",
|
|
809
|
+
"typescript/no-useless-constructor",
|
|
606
810
|
"vitest/no-commented-out-tests"
|
|
607
811
|
];
|
|
608
812
|
const restrictionRules = [
|
|
@@ -656,23 +860,23 @@ const restrictionRules = [
|
|
|
656
860
|
"react/no-react-children",
|
|
657
861
|
"react/no-unknown-property",
|
|
658
862
|
"react/only-export-components",
|
|
659
|
-
"
|
|
660
|
-
"
|
|
661
|
-
"
|
|
662
|
-
"
|
|
663
|
-
"
|
|
664
|
-
"
|
|
665
|
-
"
|
|
666
|
-
"
|
|
667
|
-
"
|
|
668
|
-
"
|
|
669
|
-
"
|
|
670
|
-
"
|
|
671
|
-
"
|
|
672
|
-
"
|
|
673
|
-
"
|
|
674
|
-
"
|
|
675
|
-
"
|
|
863
|
+
"typescript/explicit-function-return-type",
|
|
864
|
+
"typescript/explicit-module-boundary-types",
|
|
865
|
+
"typescript/no-dynamic-delete",
|
|
866
|
+
"typescript/no-empty-object-type",
|
|
867
|
+
"typescript/no-explicit-any",
|
|
868
|
+
"typescript/no-import-type-side-effects",
|
|
869
|
+
"typescript/no-invalid-void-type",
|
|
870
|
+
"typescript/no-namespace",
|
|
871
|
+
"typescript/no-non-null-asserted-nullish-coalescing",
|
|
872
|
+
"typescript/no-non-null-assertion",
|
|
873
|
+
"typescript/no-require-imports",
|
|
874
|
+
"typescript/no-restricted-types",
|
|
875
|
+
"typescript/no-var-requires",
|
|
876
|
+
"typescript/non-nullable-type-assertion-style",
|
|
877
|
+
"typescript/prefer-literal-enum-member",
|
|
878
|
+
"typescript/promise-function-async",
|
|
879
|
+
"typescript/use-unknown-in-catch-callback-variable",
|
|
676
880
|
"unicorn/no-abusive-eslint-disable",
|
|
677
881
|
"unicorn/no-anonymous-default-export",
|
|
678
882
|
"unicorn/no-array-for-each",
|
|
@@ -686,27 +890,14 @@ const restrictionRules = [
|
|
|
686
890
|
"unicorn/prefer-module",
|
|
687
891
|
"unicorn/prefer-node-protocol",
|
|
688
892
|
"unicorn/prefer-number-properties",
|
|
893
|
+
"vitest/require-test-timeout",
|
|
689
894
|
"vue/max-props",
|
|
690
895
|
"vue/no-import-compiler-macros",
|
|
691
896
|
"vue/no-multiple-slot-args",
|
|
692
|
-
"
|
|
693
|
-
"
|
|
694
|
-
"
|
|
695
|
-
"
|
|
696
|
-
"import-x/extensions",
|
|
697
|
-
"import-x/no-amd",
|
|
698
|
-
"import-x/no-commonjs",
|
|
699
|
-
"import-x/no-cycle",
|
|
700
|
-
"import-x/no-default-export",
|
|
701
|
-
"import-x/no-dynamic-require",
|
|
702
|
-
"import-x/no-relative-parent-imports",
|
|
703
|
-
"import-x/no-webpack-loader-syntax",
|
|
704
|
-
"import-x/unambiguous",
|
|
705
|
-
"n/handle-callback-err",
|
|
706
|
-
"n/no-new-require",
|
|
707
|
-
"n/no-path-concat",
|
|
708
|
-
"n/no-process-env",
|
|
709
|
-
"react-refresh/only-export-components"
|
|
897
|
+
"typescript/class-methods-use-this",
|
|
898
|
+
"typescript/no-empty-function",
|
|
899
|
+
"typescript/no-restricted-imports",
|
|
900
|
+
"typescript/no-use-before-define"
|
|
710
901
|
];
|
|
711
902
|
const correctnessRules = [
|
|
712
903
|
"constructor-super",
|
|
@@ -815,31 +1006,31 @@ const correctnessRules = [
|
|
|
815
1006
|
"jsx-a11y/role-supports-aria-props",
|
|
816
1007
|
"jsx-a11y/scope",
|
|
817
1008
|
"jsx-a11y/tabindex-no-positive",
|
|
818
|
-
"
|
|
819
|
-
"
|
|
820
|
-
"
|
|
821
|
-
"
|
|
822
|
-
"
|
|
823
|
-
"
|
|
824
|
-
"
|
|
825
|
-
"
|
|
826
|
-
"
|
|
827
|
-
"
|
|
828
|
-
"
|
|
829
|
-
"
|
|
830
|
-
"
|
|
831
|
-
"
|
|
832
|
-
"
|
|
833
|
-
"
|
|
834
|
-
"
|
|
835
|
-
"
|
|
836
|
-
"
|
|
837
|
-
"
|
|
838
|
-
"
|
|
1009
|
+
"nextjs/google-font-display",
|
|
1010
|
+
"nextjs/google-font-preconnect",
|
|
1011
|
+
"nextjs/inline-script-id",
|
|
1012
|
+
"nextjs/next-script-for-ga",
|
|
1013
|
+
"nextjs/no-assign-module-variable",
|
|
1014
|
+
"nextjs/no-async-client-component",
|
|
1015
|
+
"nextjs/no-before-interactive-script-outside-document",
|
|
1016
|
+
"nextjs/no-css-tags",
|
|
1017
|
+
"nextjs/no-document-import-in-page",
|
|
1018
|
+
"nextjs/no-duplicate-head",
|
|
1019
|
+
"nextjs/no-head-element",
|
|
1020
|
+
"nextjs/no-head-import-in-document",
|
|
1021
|
+
"nextjs/no-html-link-for-pages",
|
|
1022
|
+
"nextjs/no-img-element",
|
|
1023
|
+
"nextjs/no-page-custom-font",
|
|
1024
|
+
"nextjs/no-script-component-in-head",
|
|
1025
|
+
"nextjs/no-styled-jsx-in-document",
|
|
1026
|
+
"nextjs/no-sync-scripts",
|
|
1027
|
+
"nextjs/no-title-in-document-head",
|
|
1028
|
+
"nextjs/no-typos",
|
|
1029
|
+
"nextjs/no-unwanted-polyfillio",
|
|
839
1030
|
"promise/no-callback-in-promise",
|
|
840
1031
|
"promise/no-new-statics",
|
|
841
1032
|
"promise/valid-params",
|
|
842
|
-
"react
|
|
1033
|
+
"react/exhaustive-deps",
|
|
843
1034
|
"react/forward-ref-uses-ref",
|
|
844
1035
|
"react/jsx-key",
|
|
845
1036
|
"react/jsx-no-duplicate-props",
|
|
@@ -857,32 +1048,32 @@ const correctnessRules = [
|
|
|
857
1048
|
"react/no-unsafe",
|
|
858
1049
|
"react/no-will-update-set-state",
|
|
859
1050
|
"react/void-dom-elements-no-children",
|
|
860
|
-
"
|
|
861
|
-
"
|
|
862
|
-
"
|
|
863
|
-
"
|
|
864
|
-
"
|
|
865
|
-
"
|
|
866
|
-
"
|
|
867
|
-
"
|
|
868
|
-
"
|
|
869
|
-
"
|
|
870
|
-
"
|
|
871
|
-
"
|
|
872
|
-
"
|
|
873
|
-
"
|
|
874
|
-
"
|
|
875
|
-
"
|
|
876
|
-
"
|
|
877
|
-
"
|
|
878
|
-
"
|
|
879
|
-
"
|
|
880
|
-
"
|
|
881
|
-
"
|
|
882
|
-
"
|
|
883
|
-
"
|
|
884
|
-
"
|
|
885
|
-
"
|
|
1051
|
+
"typescript/await-thenable",
|
|
1052
|
+
"typescript/no-array-delete",
|
|
1053
|
+
"typescript/no-base-to-string",
|
|
1054
|
+
"typescript/no-duplicate-enum-values",
|
|
1055
|
+
"typescript/no-duplicate-type-constituents",
|
|
1056
|
+
"typescript/no-extra-non-null-assertion",
|
|
1057
|
+
"typescript/no-floating-promises",
|
|
1058
|
+
"typescript/no-for-in-array",
|
|
1059
|
+
"typescript/no-implied-eval",
|
|
1060
|
+
"typescript/no-meaningless-void-operator",
|
|
1061
|
+
"typescript/no-misused-new",
|
|
1062
|
+
"typescript/no-misused-spread",
|
|
1063
|
+
"typescript/no-non-null-asserted-optional-chain",
|
|
1064
|
+
"typescript/no-redundant-type-constituents",
|
|
1065
|
+
"typescript/no-this-alias",
|
|
1066
|
+
"typescript/no-unnecessary-parameter-property-assignment",
|
|
1067
|
+
"typescript/no-unsafe-declaration-merging",
|
|
1068
|
+
"typescript/no-unsafe-unary-minus",
|
|
1069
|
+
"typescript/no-useless-empty-export",
|
|
1070
|
+
"typescript/no-wrapper-object-types",
|
|
1071
|
+
"typescript/prefer-as-const",
|
|
1072
|
+
"typescript/prefer-namespace-keyword",
|
|
1073
|
+
"typescript/require-array-sort-compare",
|
|
1074
|
+
"typescript/restrict-template-expressions",
|
|
1075
|
+
"typescript/triple-slash-reference",
|
|
1076
|
+
"typescript/unbound-method",
|
|
886
1077
|
"unicorn/no-await-in-promise-methods",
|
|
887
1078
|
"unicorn/no-empty-file",
|
|
888
1079
|
"unicorn/no-invalid-fetch-options",
|
|
@@ -899,7 +1090,9 @@ const correctnessRules = [
|
|
|
899
1090
|
"vitest/consistent-each-for",
|
|
900
1091
|
"vitest/hoisted-apis-on-top",
|
|
901
1092
|
"vitest/no-conditional-tests",
|
|
1093
|
+
"vitest/require-awaited-expect-poll",
|
|
902
1094
|
"vitest/require-local-test-context-for-concurrent-snapshots",
|
|
1095
|
+
"vitest/require-mock-type-parameters",
|
|
903
1096
|
"vitest/warn-todo",
|
|
904
1097
|
"vue/no-arrow-functions-in-watch",
|
|
905
1098
|
"vue/no-deprecated-destroyed-lifecycle",
|
|
@@ -909,12 +1102,10 @@ const correctnessRules = [
|
|
|
909
1102
|
"vue/prefer-import-from-vue",
|
|
910
1103
|
"vue/valid-define-emits",
|
|
911
1104
|
"vue/valid-define-props",
|
|
912
|
-
"
|
|
913
|
-
"
|
|
914
|
-
"
|
|
915
|
-
"
|
|
916
|
-
"import-x/default",
|
|
917
|
-
"import-x/namespace",
|
|
1105
|
+
"typescript/no-dupe-class-members",
|
|
1106
|
+
"typescript/no-loss-of-precision",
|
|
1107
|
+
"typescript/no-unused-expressions",
|
|
1108
|
+
"typescript/no-unused-vars",
|
|
918
1109
|
"vitest/expect-expect",
|
|
919
1110
|
"vitest/no-conditional-expect",
|
|
920
1111
|
"vitest/no-disabled-tests",
|
|
@@ -922,7 +1113,8 @@ const correctnessRules = [
|
|
|
922
1113
|
"vitest/no-standalone-expect",
|
|
923
1114
|
"vitest/require-to-throw-message",
|
|
924
1115
|
"vitest/valid-describe-callback",
|
|
925
|
-
"vitest/valid-expect"
|
|
1116
|
+
"vitest/valid-expect",
|
|
1117
|
+
"vitest/valid-title"
|
|
926
1118
|
];
|
|
927
1119
|
const nurseryRules = [
|
|
928
1120
|
"getter-return",
|
|
@@ -932,23 +1124,17 @@ const nurseryRules = [
|
|
|
932
1124
|
"import/named",
|
|
933
1125
|
"promise/no-return-in-finally",
|
|
934
1126
|
"react/require-render-return",
|
|
935
|
-
"
|
|
936
|
-
"
|
|
937
|
-
"
|
|
938
|
-
"
|
|
939
|
-
"
|
|
940
|
-
"
|
|
941
|
-
"
|
|
942
|
-
"
|
|
943
|
-
"
|
|
944
|
-
"
|
|
945
|
-
"
|
|
946
|
-
"@typescript-eslint/prefer-readonly-parameter-types",
|
|
947
|
-
"@typescript-eslint/prefer-regexp-exec",
|
|
948
|
-
"@typescript-eslint/prefer-string-starts-ends-with",
|
|
949
|
-
"@typescript-eslint/strict-void-return",
|
|
950
|
-
"import-x/export",
|
|
951
|
-
"import-x/named"
|
|
1127
|
+
"typescript/consistent-return",
|
|
1128
|
+
"typescript/consistent-type-exports",
|
|
1129
|
+
"typescript/dot-notation",
|
|
1130
|
+
"typescript/no-unnecessary-condition",
|
|
1131
|
+
"typescript/no-unnecessary-qualifier",
|
|
1132
|
+
"typescript/no-unnecessary-type-conversion",
|
|
1133
|
+
"typescript/no-unnecessary-type-parameters",
|
|
1134
|
+
"typescript/no-useless-default-assignment",
|
|
1135
|
+
"typescript/prefer-optional-chain",
|
|
1136
|
+
"typescript/prefer-readonly-parameter-types",
|
|
1137
|
+
"typescript/strict-void-return"
|
|
952
1138
|
];
|
|
953
1139
|
const perfRules = [
|
|
954
1140
|
"no-await-in-loop",
|
|
@@ -964,239 +1150,67 @@ const perfRules = [
|
|
|
964
1150
|
"unicorn/prefer-set-has"
|
|
965
1151
|
];
|
|
966
1152
|
const typeAwareRules = [
|
|
967
|
-
"
|
|
968
|
-
"
|
|
969
|
-
"
|
|
970
|
-
"
|
|
971
|
-
"
|
|
972
|
-
"
|
|
973
|
-
"
|
|
974
|
-
"
|
|
975
|
-
"
|
|
976
|
-
"
|
|
977
|
-
"
|
|
978
|
-
"
|
|
979
|
-
"
|
|
980
|
-
"
|
|
981
|
-
"
|
|
982
|
-
"
|
|
983
|
-
"
|
|
984
|
-
"
|
|
985
|
-
"
|
|
986
|
-
"
|
|
987
|
-
"
|
|
988
|
-
"
|
|
989
|
-
"
|
|
990
|
-
"
|
|
991
|
-
"
|
|
992
|
-
"
|
|
993
|
-
"
|
|
994
|
-
"
|
|
995
|
-
"
|
|
996
|
-
"
|
|
997
|
-
"
|
|
998
|
-
"
|
|
999
|
-
"
|
|
1000
|
-
"
|
|
1001
|
-
"
|
|
1002
|
-
"
|
|
1003
|
-
"
|
|
1004
|
-
"
|
|
1005
|
-
"
|
|
1006
|
-
"
|
|
1007
|
-
"
|
|
1008
|
-
"
|
|
1009
|
-
"
|
|
1010
|
-
"
|
|
1011
|
-
"
|
|
1012
|
-
"
|
|
1013
|
-
"
|
|
1014
|
-
"
|
|
1015
|
-
"
|
|
1016
|
-
"
|
|
1017
|
-
"
|
|
1018
|
-
"
|
|
1019
|
-
"
|
|
1020
|
-
"
|
|
1021
|
-
"
|
|
1022
|
-
"
|
|
1023
|
-
"
|
|
1024
|
-
"
|
|
1025
|
-
"
|
|
1153
|
+
"typescript/await-thenable",
|
|
1154
|
+
"typescript/consistent-return",
|
|
1155
|
+
"typescript/consistent-type-exports",
|
|
1156
|
+
"typescript/dot-notation",
|
|
1157
|
+
"typescript/no-array-delete",
|
|
1158
|
+
"typescript/no-base-to-string",
|
|
1159
|
+
"typescript/no-confusing-void-expression",
|
|
1160
|
+
"typescript/no-deprecated",
|
|
1161
|
+
"typescript/no-duplicate-type-constituents",
|
|
1162
|
+
"typescript/no-floating-promises",
|
|
1163
|
+
"typescript/no-for-in-array",
|
|
1164
|
+
"typescript/no-implied-eval",
|
|
1165
|
+
"typescript/no-meaningless-void-operator",
|
|
1166
|
+
"typescript/no-misused-promises",
|
|
1167
|
+
"typescript/no-misused-spread",
|
|
1168
|
+
"typescript/no-mixed-enums",
|
|
1169
|
+
"typescript/no-redundant-type-constituents",
|
|
1170
|
+
"typescript/no-unnecessary-boolean-literal-compare",
|
|
1171
|
+
"typescript/no-unnecessary-condition",
|
|
1172
|
+
"typescript/no-unnecessary-qualifier",
|
|
1173
|
+
"typescript/no-unnecessary-template-expression",
|
|
1174
|
+
"typescript/no-unnecessary-type-arguments",
|
|
1175
|
+
"typescript/no-unnecessary-type-assertion",
|
|
1176
|
+
"typescript/no-unnecessary-type-conversion",
|
|
1177
|
+
"typescript/no-unnecessary-type-parameters",
|
|
1178
|
+
"typescript/no-unsafe-argument",
|
|
1179
|
+
"typescript/no-unsafe-assignment",
|
|
1180
|
+
"typescript/no-unsafe-call",
|
|
1181
|
+
"typescript/no-unsafe-enum-comparison",
|
|
1182
|
+
"typescript/no-unsafe-member-access",
|
|
1183
|
+
"typescript/no-unsafe-return",
|
|
1184
|
+
"typescript/no-unsafe-type-assertion",
|
|
1185
|
+
"typescript/no-unsafe-unary-minus",
|
|
1186
|
+
"typescript/no-useless-default-assignment",
|
|
1187
|
+
"typescript/non-nullable-type-assertion-style",
|
|
1188
|
+
"typescript/only-throw-error",
|
|
1189
|
+
"typescript/prefer-find",
|
|
1190
|
+
"typescript/prefer-includes",
|
|
1191
|
+
"typescript/prefer-nullish-coalescing",
|
|
1192
|
+
"typescript/prefer-optional-chain",
|
|
1193
|
+
"typescript/prefer-promise-reject-errors",
|
|
1194
|
+
"typescript/prefer-readonly",
|
|
1195
|
+
"typescript/prefer-readonly-parameter-types",
|
|
1196
|
+
"typescript/prefer-reduce-type-parameter",
|
|
1197
|
+
"typescript/prefer-regexp-exec",
|
|
1198
|
+
"typescript/prefer-return-this-type",
|
|
1199
|
+
"typescript/prefer-string-starts-ends-with",
|
|
1200
|
+
"typescript/promise-function-async",
|
|
1201
|
+
"typescript/related-getter-setter-pairs",
|
|
1202
|
+
"typescript/require-array-sort-compare",
|
|
1203
|
+
"typescript/require-await",
|
|
1204
|
+
"typescript/restrict-plus-operands",
|
|
1205
|
+
"typescript/restrict-template-expressions",
|
|
1206
|
+
"typescript/return-await",
|
|
1207
|
+
"typescript/strict-boolean-expressions",
|
|
1208
|
+
"typescript/strict-void-return",
|
|
1209
|
+
"typescript/switch-exhaustiveness-check",
|
|
1210
|
+
"typescript/unbound-method",
|
|
1211
|
+
"typescript/use-unknown-in-catch-callback-variable"
|
|
1026
1212
|
];
|
|
1027
1213
|
//#endregion
|
|
1028
|
-
//#region src/constants.ts
|
|
1029
|
-
const rulesPrefixesForPlugins = {
|
|
1030
|
-
import: "import",
|
|
1031
|
-
"import-x": "import",
|
|
1032
|
-
jest: "jest",
|
|
1033
|
-
jsdoc: "jsdoc",
|
|
1034
|
-
"jsx-a11y": "jsx-a11y",
|
|
1035
|
-
"@next/next": "nextjs",
|
|
1036
|
-
node: "node",
|
|
1037
|
-
n: "node",
|
|
1038
|
-
promise: "promise",
|
|
1039
|
-
react: "react",
|
|
1040
|
-
"react-perf": "react-perf",
|
|
1041
|
-
"react-hooks": "react",
|
|
1042
|
-
"react-refresh": "react",
|
|
1043
|
-
"@typescript-eslint": "typescript",
|
|
1044
|
-
unicorn: "unicorn",
|
|
1045
|
-
vitest: "vitest",
|
|
1046
|
-
vue: "vue"
|
|
1047
|
-
};
|
|
1048
|
-
const eslintRulesToTypescriptEquivalents = {
|
|
1049
|
-
"dot-notation": "@typescript-eslint/dot-notation",
|
|
1050
|
-
"consistent-return": "@typescript-eslint/consistent-return"
|
|
1051
|
-
};
|
|
1052
|
-
const typescriptRulesExtendEslintRules = [
|
|
1053
|
-
"class-methods-use-this",
|
|
1054
|
-
"default-param-last",
|
|
1055
|
-
"init-declarations",
|
|
1056
|
-
"max-params",
|
|
1057
|
-
"no-array-constructor",
|
|
1058
|
-
"no-dupe-class-members",
|
|
1059
|
-
"no-empty-function",
|
|
1060
|
-
"no-invalid-this",
|
|
1061
|
-
"no-loop-func",
|
|
1062
|
-
"no-loss-of-precision",
|
|
1063
|
-
"no-magic-numbers",
|
|
1064
|
-
"no-redeclare",
|
|
1065
|
-
"no-restricted-imports",
|
|
1066
|
-
"no-shadow",
|
|
1067
|
-
"no-unused-expressions",
|
|
1068
|
-
"no-unused-vars",
|
|
1069
|
-
"no-use-before-define",
|
|
1070
|
-
"no-useless-constructor"
|
|
1071
|
-
];
|
|
1072
|
-
//#endregion
|
|
1073
|
-
//#region src/jsPlugins.ts
|
|
1074
|
-
const ignorePlugins = new Set([
|
|
1075
|
-
...Object.keys(rulesPrefixesForPlugins),
|
|
1076
|
-
...Object.values(rulesPrefixesForPlugins),
|
|
1077
|
-
"local"
|
|
1078
|
-
]);
|
|
1079
|
-
const tryResolvePackage = (packageName) => {
|
|
1080
|
-
try {
|
|
1081
|
-
import.meta.resolve(packageName);
|
|
1082
|
-
return true;
|
|
1083
|
-
} catch {
|
|
1084
|
-
return false;
|
|
1085
|
-
}
|
|
1086
|
-
};
|
|
1087
|
-
const pluginNameCache = /* @__PURE__ */ new Map();
|
|
1088
|
-
/**
|
|
1089
|
-
* Resolves the npm package name for an ESLint plugin given its scope name.
|
|
1090
|
-
*
|
|
1091
|
-
* For scoped plugin names (starting with `@`), the mapping is unambiguous:
|
|
1092
|
-
* - `@scope` -> `@scope/eslint-plugin`
|
|
1093
|
-
* - `@scope/sub` -> `@scope/eslint-plugin-sub`
|
|
1094
|
-
*
|
|
1095
|
-
* For non-scoped names, the npm package could follow either convention:
|
|
1096
|
-
* - `eslint-plugin-{name}` (e.g. `eslint-plugin-mocha`)
|
|
1097
|
-
* - `@{name}/eslint-plugin` (e.g. `@e18e/eslint-plugin`)
|
|
1098
|
-
*
|
|
1099
|
-
* We try to resolve both candidates against the installed packages and
|
|
1100
|
-
* use the one that is actually present, falling back to the standard
|
|
1101
|
-
* `eslint-plugin-{name}` convention when neither can be resolved.
|
|
1102
|
-
*/
|
|
1103
|
-
const resolveEslintPluginName = (pluginName) => {
|
|
1104
|
-
const cached = pluginNameCache.get(pluginName);
|
|
1105
|
-
if (cached !== void 0) return cached;
|
|
1106
|
-
let result;
|
|
1107
|
-
if (pluginName.startsWith("@")) {
|
|
1108
|
-
const [scope, maybeSub] = pluginName.split("/");
|
|
1109
|
-
if (maybeSub) result = `${scope}/eslint-plugin-${maybeSub}`;
|
|
1110
|
-
else result = `${scope}/eslint-plugin`;
|
|
1111
|
-
} else {
|
|
1112
|
-
const standardName = `eslint-plugin-${pluginName}`;
|
|
1113
|
-
const scopedName = `@${pluginName}/eslint-plugin`;
|
|
1114
|
-
if (tryResolvePackage(standardName)) result = standardName;
|
|
1115
|
-
else if (tryResolvePackage(scopedName)) result = scopedName;
|
|
1116
|
-
else result = standardName;
|
|
1117
|
-
}
|
|
1118
|
-
pluginNameCache.set(pluginName, result);
|
|
1119
|
-
return result;
|
|
1120
|
-
};
|
|
1121
|
-
const extractPluginId = (ruleId) => {
|
|
1122
|
-
const firstSlash = ruleId.indexOf("/");
|
|
1123
|
-
if (firstSlash === -1) return;
|
|
1124
|
-
if (ruleId.startsWith("@")) {
|
|
1125
|
-
const secondSlash = ruleId.indexOf("/", firstSlash + 1);
|
|
1126
|
-
if (secondSlash !== -1) return ruleId.substring(0, secondSlash);
|
|
1127
|
-
}
|
|
1128
|
-
return ruleId.substring(0, firstSlash);
|
|
1129
|
-
};
|
|
1130
|
-
const isIgnoredPluginRule = (ruleId) => {
|
|
1131
|
-
const pluginName = extractPluginId(ruleId);
|
|
1132
|
-
if (pluginName === void 0) return true;
|
|
1133
|
-
return ignorePlugins.has(pluginName);
|
|
1134
|
-
};
|
|
1135
|
-
/**
|
|
1136
|
-
* Derives the npm package name for a plugin from its `meta.name` field.
|
|
1137
|
-
*
|
|
1138
|
-
* If `meta.name` already looks like a full npm package name (contains
|
|
1139
|
-
* "eslint-plugin"), it is returned as-is. Otherwise it is fed through
|
|
1140
|
-
* {@link resolveEslintPluginName} for the usual heuristic resolution.
|
|
1141
|
-
*/
|
|
1142
|
-
const resolveFromMetaName = (metaName) => {
|
|
1143
|
-
if (metaName.includes("eslint-plugin")) return metaName;
|
|
1144
|
-
return resolveEslintPluginName(metaName);
|
|
1145
|
-
};
|
|
1146
|
-
/**
|
|
1147
|
-
* Derives the rule-ID prefix that an npm package exposes.
|
|
1148
|
-
*
|
|
1149
|
-
* Examples:
|
|
1150
|
-
* `eslint-plugin-react-dom` -> `react-dom`
|
|
1151
|
-
* `eslint-plugin-mocha` -> `mocha`
|
|
1152
|
-
* `@stylistic/eslint-plugin` -> `@stylistic`
|
|
1153
|
-
* `@stylistic/eslint-plugin-ts` -> `@stylistic/ts`
|
|
1154
|
-
*/
|
|
1155
|
-
const deriveRulePrefix = (packageName) => {
|
|
1156
|
-
if (packageName.startsWith("@")) {
|
|
1157
|
-
const slashIdx = packageName.indexOf("/");
|
|
1158
|
-
const scope = packageName.substring(0, slashIdx);
|
|
1159
|
-
const rest = packageName.substring(slashIdx + 1);
|
|
1160
|
-
if (rest === "eslint-plugin") return scope;
|
|
1161
|
-
if (rest.startsWith("eslint-plugin-")) return `${scope}/${rest.substring(14)}`;
|
|
1162
|
-
return packageName;
|
|
1163
|
-
}
|
|
1164
|
-
if (packageName.startsWith("eslint-plugin-")) return packageName.substring(14);
|
|
1165
|
-
return packageName;
|
|
1166
|
-
};
|
|
1167
|
-
/**
|
|
1168
|
-
* Resolves the canonical rule name for a jsPlugin rule.
|
|
1169
|
-
*
|
|
1170
|
-
* When a plugin is registered under an alias (e.g. `@eslint-react/dom`) but
|
|
1171
|
-
* its `meta.name` reveals a different canonical package (`eslint-plugin-react-dom`),
|
|
1172
|
-
* the rule must be rewritten so that oxlint can match it to the loaded plugin.
|
|
1173
|
-
*
|
|
1174
|
-
* For example:
|
|
1175
|
-
* `@eslint-react/dom/no-find-dom-node` -> `react-dom/no-find-dom-node`
|
|
1176
|
-
*/
|
|
1177
|
-
const resolveJsPluginRuleName = (rule, plugins) => {
|
|
1178
|
-
const pluginName = extractPluginId(rule);
|
|
1179
|
-
if (pluginName === void 0) return rule;
|
|
1180
|
-
const metaName = plugins?.[pluginName]?.meta?.name;
|
|
1181
|
-
if (!metaName || !metaName.includes("eslint-plugin")) return rule;
|
|
1182
|
-
const canonicalPrefix = deriveRulePrefix(metaName);
|
|
1183
|
-
if (canonicalPrefix === pluginName) return rule;
|
|
1184
|
-
return `${canonicalPrefix}/${rule.substring(pluginName.length + 1)}`;
|
|
1185
|
-
};
|
|
1186
|
-
const enableJsPluginRule = (targetConfig, rule, ruleEntry, plugins) => {
|
|
1187
|
-
const pluginName = extractPluginId(rule);
|
|
1188
|
-
if (pluginName === void 0) return false;
|
|
1189
|
-
if (ignorePlugins.has(pluginName)) return false;
|
|
1190
|
-
if (targetConfig.jsPlugins === void 0 || targetConfig.jsPlugins === null) targetConfig.jsPlugins = [];
|
|
1191
|
-
const metaName = plugins?.[pluginName]?.meta?.name;
|
|
1192
|
-
const eslintPluginName = metaName ? resolveFromMetaName(metaName) : resolveEslintPluginName(pluginName);
|
|
1193
|
-
if (!targetConfig.jsPlugins.includes(eslintPluginName)) targetConfig.jsPlugins.push(eslintPluginName);
|
|
1194
|
-
const resolvedRule = resolveJsPluginRuleName(rule, plugins);
|
|
1195
|
-
targetConfig.rules = targetConfig.rules ?? {};
|
|
1196
|
-
targetConfig.rules[resolvedRule] = ruleEntry;
|
|
1197
|
-
return true;
|
|
1198
|
-
};
|
|
1199
|
-
//#endregion
|
|
1200
1214
|
//#region src/generated/unsupported-rules.json
|
|
1201
1215
|
var unsupportedRules = {
|
|
1202
1216
|
"eslint/no-dupe-args": "Superseded by strict mode.",
|
|
@@ -1569,8 +1583,7 @@ var unsupportedRules = {
|
|
|
1569
1583
|
//#region src/utilities.ts
|
|
1570
1584
|
const isEqualDeep = (a, b) => {
|
|
1571
1585
|
if (a === b) return true;
|
|
1572
|
-
|
|
1573
|
-
return Boolean(bothAreObjects && Object.keys(a).length === Object.keys(b).length && Object.entries(a).every(([k, v]) => isEqualDeep(v, b[k])));
|
|
1586
|
+
return Boolean(a && b && typeof a === "object" && typeof b === "object" && Object.keys(a).length === Object.keys(b).length && Object.entries(a).every(([k, v]) => isEqualDeep(v, b[k])));
|
|
1574
1587
|
};
|
|
1575
1588
|
/**
|
|
1576
1589
|
* Builds a lookup map of unsupported rule explanations.
|
|
@@ -1692,12 +1705,13 @@ const transformRuleEntry = (eslintConfig, targetConfig, baseConfig, options, ove
|
|
|
1692
1705
|
if (resolved !== rule) removePreviousOverrideRule(resolved, eslintConfig, overrides);
|
|
1693
1706
|
}
|
|
1694
1707
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1708
|
+
const canonicalRule = normalizeRuleToCanonical(rule);
|
|
1709
|
+
if (allRules.includes(canonicalRule)) {
|
|
1710
|
+
if (!options?.withNursery && nurseryRules.includes(canonicalRule)) {
|
|
1697
1711
|
options?.reporter?.markSkipped(rule, "nursery");
|
|
1698
1712
|
continue;
|
|
1699
1713
|
}
|
|
1700
|
-
if (!options?.typeAware && typeAwareRules.includes(
|
|
1714
|
+
if (!options?.typeAware && typeAwareRules.includes(canonicalRule)) {
|
|
1701
1715
|
options?.reporter?.markSkipped(rule, "type-aware");
|
|
1702
1716
|
continue;
|
|
1703
1717
|
}
|
|
@@ -1844,29 +1858,26 @@ const replaceTypescriptAliasRules = (config) => {
|
|
|
1844
1858
|
if (Object.keys(config.rules).length === 0) delete config.rules;
|
|
1845
1859
|
};
|
|
1846
1860
|
/**
|
|
1847
|
-
*
|
|
1861
|
+
* Renames rules from an ESLint plugin prefix to the canonical Oxlint plugin prefix.
|
|
1848
1862
|
*/
|
|
1849
|
-
const
|
|
1863
|
+
const replaceRulePrefix = (config, oldPrefix, newPrefix) => {
|
|
1850
1864
|
if (config.rules === void 0) return;
|
|
1851
1865
|
for (const rule of Object.keys(config.rules)) {
|
|
1852
|
-
if (!rule.startsWith(
|
|
1853
|
-
const
|
|
1854
|
-
config.rules[
|
|
1866
|
+
if (!rule.startsWith(`${oldPrefix}/`)) continue;
|
|
1867
|
+
const canonicalRule = `${newPrefix}/${rule.slice(oldPrefix.length + 1)}`;
|
|
1868
|
+
config.rules[canonicalRule] = config.rules[rule];
|
|
1855
1869
|
delete config.rules[rule];
|
|
1856
1870
|
}
|
|
1857
1871
|
};
|
|
1858
1872
|
/**
|
|
1859
|
-
*
|
|
1860
|
-
*
|
|
1873
|
+
* Renames all ESLint plugin prefixes to their canonical Oxlint equivalents,
|
|
1874
|
+
* driven by the `rulesPrefixesForPlugins` mapping in constants.ts.
|
|
1875
|
+
*
|
|
1876
|
+
* This should run AFTER `replaceTypescriptAliasRules` so that rules which
|
|
1877
|
+
* extend core ESLint rules have already been stripped of their prefix.
|
|
1861
1878
|
*/
|
|
1862
|
-
const
|
|
1863
|
-
|
|
1864
|
-
for (const rule of Object.keys(config.rules)) {
|
|
1865
|
-
if (!rule.startsWith("react-refresh/")) continue;
|
|
1866
|
-
const reactRefreshRule = `react/${rule.slice(14)}`;
|
|
1867
|
-
config.rules[reactRefreshRule] = config.rules[rule];
|
|
1868
|
-
delete config.rules[rule];
|
|
1869
|
-
}
|
|
1879
|
+
const replaceCanonicalPluginPrefixes = (config) => {
|
|
1880
|
+
for (const [prefix, plugin] of Object.entries(rulesPrefixesForPlugins)) if (prefix !== plugin) replaceRulePrefix(config, prefix, plugin);
|
|
1870
1881
|
};
|
|
1871
1882
|
//#endregion
|
|
1872
1883
|
//#region src/cleanup.ts
|
|
@@ -1917,9 +1928,9 @@ const cleanUpOxlintConfig = (config) => {
|
|
|
1917
1928
|
removeGlobalsWithAreCoveredByEnv(config);
|
|
1918
1929
|
transformBoolGlobalToString(config);
|
|
1919
1930
|
replaceTypescriptAliasRules(config);
|
|
1920
|
-
|
|
1921
|
-
replaceReactRefreshPluginName(config);
|
|
1931
|
+
replaceCanonicalPluginPrefixes(config);
|
|
1922
1932
|
cleanUpRulesWhichAreCoveredByCategory(config);
|
|
1933
|
+
if ("files" in config) cleanUpUnusedJsPlugins(config);
|
|
1923
1934
|
if (config.globals !== void 0 && config.globals !== null && Object.keys(config.globals).length === 0) delete config.globals;
|
|
1924
1935
|
if (config.env !== void 0 && config.env !== null) {
|
|
1925
1936
|
delete config.env.es3;
|
|
@@ -1932,6 +1943,7 @@ const cleanUpOxlintConfig = (config) => {
|
|
|
1932
1943
|
if (!("files" in config)) {
|
|
1933
1944
|
cleanUpUselessOverridesEntries(config);
|
|
1934
1945
|
cleanUpDisabledRootRules(config);
|
|
1946
|
+
cleanUpUnusedJsPlugins(config);
|
|
1935
1947
|
}
|
|
1936
1948
|
};
|
|
1937
1949
|
/**
|
|
@@ -2255,4 +2267,4 @@ const main = async (configs, oxlintConfig, options) => {
|
|
|
2255
2267
|
return buildConfig(Array.isArray(resolved) ? resolved : [resolved], oxlintConfig, options);
|
|
2256
2268
|
};
|
|
2257
2269
|
//#endregion
|
|
2258
|
-
export { nurseryRules as a, buildUnsupportedRuleExplanations as i, preFixForJsPlugins as n, rules_exports as o, isOffValue as r, main as t };
|
|
2270
|
+
export { nurseryRules as a, buildUnsupportedRuleExplanations as i, preFixForJsPlugins as n, rules_exports as o, isOffValue as r, normalizeRuleToCanonical as s, main as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxlint/migrate",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.58.0",
|
|
4
4
|
"description": "Generates a `.oxlintrc.json` from a existing eslint flat config",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -41,13 +41,14 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"commander": "^14.0.0",
|
|
43
43
|
"globals": "^17.0.0",
|
|
44
|
-
"oxc-parser": "^0.
|
|
44
|
+
"oxc-parser": "^0.121.0",
|
|
45
45
|
"tinyglobby": "^0.2.14"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@antfu/eslint-config": "^7.0.0",
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
49
|
+
"@babel/eslint-plugin": "^7.27.1",
|
|
50
|
+
"@e18e/eslint-plugin": "^0.3.0",
|
|
51
|
+
"@eslint-react/eslint-plugin": "^3.0.0",
|
|
51
52
|
"@eslint/js": "^10.0.0",
|
|
52
53
|
"@logux/eslint-config": "^57.0.0",
|
|
53
54
|
"@oxc-node/core": "^0.0.35",
|
|
@@ -76,22 +77,23 @@
|
|
|
76
77
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
77
78
|
"eslint-plugin-react-perf": "^3.3.3",
|
|
78
79
|
"eslint-plugin-react-refresh": "^0.5.0",
|
|
79
|
-
"eslint-plugin-react-web-api": "^
|
|
80
|
+
"eslint-plugin-react-web-api": "^3.0.0",
|
|
80
81
|
"eslint-plugin-regexp": "^3.0.0",
|
|
81
82
|
"eslint-plugin-tsdoc": "^0.5.0",
|
|
82
83
|
"eslint-plugin-unicorn": "^63.0.0",
|
|
83
84
|
"husky": "^9.1.7",
|
|
84
85
|
"lint-staged": "^16.1.2",
|
|
85
86
|
"next": "^16.0.0",
|
|
86
|
-
"oxfmt": "^0.
|
|
87
|
-
"oxlint": "^1.
|
|
88
|
-
"oxlint-tsgolint": "^0.
|
|
87
|
+
"oxfmt": "^0.42.0",
|
|
88
|
+
"oxlint": "^1.58.0",
|
|
89
|
+
"oxlint-tsgolint": "^0.18.0",
|
|
89
90
|
"tsdown": "^0.21.0",
|
|
91
|
+
"typescript": "^6.0.0",
|
|
90
92
|
"typescript-eslint": "^8.35.0",
|
|
91
93
|
"vitest": "^4.0.0"
|
|
92
94
|
},
|
|
93
95
|
"lint-staged": {
|
|
94
96
|
"*": "oxfmt --no-error-on-unmatched-pattern"
|
|
95
97
|
},
|
|
96
|
-
"packageManager": "pnpm@10.
|
|
98
|
+
"packageManager": "pnpm@10.33.0"
|
|
97
99
|
}
|