From 4e6fa5d52e059b1f14d0830c3cde5aa73a20e544 Mon Sep 17 00:00:00 2001 From: Sysix Date: Fri, 8 Nov 2024 18:39:31 +0100 Subject: [PATCH 1/6] fix: disable alias `eslint` and `@typescript-eslint` rules together --- src/build-from-oxlint-config.spec.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/build-from-oxlint-config.spec.ts b/src/build-from-oxlint-config.spec.ts index 3c97cb3..f05e072 100644 --- a/src/build-from-oxlint-config.spec.ts +++ b/src/build-from-oxlint-config.spec.ts @@ -184,6 +184,23 @@ describe('buildFromOxlintConfig', () => { expect('unknown' in rules[0].rules!).toBe(false); expect('@next/next/no-img-element' in rules[0].rules!).toBe(false); }); + + for (const alias of typescriptRulesExtendEslintRules) { + it(`disables matching typescript and eslint rules for ${alias}`, () => { + for (const rule in [alias, `@typescript-eslint/${alias}`]) { + const rules = buildFromOxlintConfig({ + rules: { + [rule]: 'warn', + }, + }); + + expect(rules.length).toBe(1); + expect(rules[0].rules).not.toBeUndefined(); + expect(alias in rules[0].rules!).toBe(true); + expect(`@typescript-eslint/${alias}` in rules[0].rules!).toBe(true); + } + }); + } }); const createConfigFileAndBuildFromIt = ( From a5bd7b75c14e1beeb89b1fb7933dbebc7e8139ed Mon Sep 17 00:00:00 2001 From: Sysix Date: Fri, 8 Nov 2024 18:46:46 +0100 Subject: [PATCH 2/6] fix: disable alias eslint and @typescript-eslint rules together --- src/build-from-oxlint-config.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build-from-oxlint-config.spec.ts b/src/build-from-oxlint-config.spec.ts index f05e072..9299841 100644 --- a/src/build-from-oxlint-config.spec.ts +++ b/src/build-from-oxlint-config.spec.ts @@ -187,7 +187,7 @@ describe('buildFromOxlintConfig', () => { for (const alias of typescriptRulesExtendEslintRules) { it(`disables matching typescript and eslint rules for ${alias}`, () => { - for (const rule in [alias, `@typescript-eslint/${alias}`]) { + for (const rule of [alias, `@typescript-eslint/${alias}`]) { const rules = buildFromOxlintConfig({ rules: { [rule]: 'warn', From a117859e2197a018a2764d906329b318ba3001e0 Mon Sep 17 00:00:00 2001 From: Sysix Date: Sat, 9 Nov 2024 12:59:09 +0100 Subject: [PATCH 3/6] fix: disable alias eslint and @typescript-eslint rules together --- src/build-from-oxlint-config.spec.ts | 14 ++++++- src/build-from-oxlint-config.ts | 57 ++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/build-from-oxlint-config.spec.ts b/src/build-from-oxlint-config.spec.ts index 9299841..75eacee 100644 --- a/src/build-from-oxlint-config.spec.ts +++ b/src/build-from-oxlint-config.spec.ts @@ -7,6 +7,18 @@ import fs from 'node:fs'; import { execSync } from 'node:child_process'; import type { Linter } from 'eslint'; import { typescriptRulesExtendEslintRules } from './constants.js'; +import configByCategory from './generated/configs-by-category.js'; + +const allRulesObjects = Object.values(configByCategory).map( + (config) => config.rules +); +const allRules: string[] = allRulesObjects.flatMap((rulesObject) => + Object.keys(rulesObject) +); + +const supportedTypescriptRulesExtendEslintRules = allRules.filter((rule) => + typescriptRulesExtendEslintRules.includes(rule) +); describe('buildFromOxlintConfig', () => { describe('rule values', () => { @@ -185,7 +197,7 @@ describe('buildFromOxlintConfig', () => { expect('@next/next/no-img-element' in rules[0].rules!).toBe(false); }); - for (const alias of typescriptRulesExtendEslintRules) { + for (const alias of supportedTypescriptRulesExtendEslintRules) { it(`disables matching typescript and eslint rules for ${alias}`, () => { for (const rule of [alias, `@typescript-eslint/${alias}`]) { const rules = buildFromOxlintConfig({ diff --git a/src/build-from-oxlint-config.ts b/src/build-from-oxlint-config.ts index 5d00f85..dcd3971 100644 --- a/src/build-from-oxlint-config.ts +++ b/src/build-from-oxlint-config.ts @@ -109,12 +109,26 @@ const handleCategoriesScope = ( } }; -const getEsLintRuleName = (rule: string): string | undefined => { +/** + * returns all eslint rules names for a oxlint rule. + * oxlint rules are deactivating one or more eslint rules. + * + * Oxlint rules do not need a plugin-scope. + * When no eslint rules are found, undefined is returned. + * + */ +const getEsLintRuleNames = (rule: string): string[] | undefined => { // there is no plugin prefix, it can be all plugin if (!rule.includes('/')) { - return allRules.find( + const founds = allRules.filter( (search) => search.endsWith(`/${rule}`) || search === rule ); + + if (founds.length === 0) { + return undefined; + } + + return founds; } // greedy works with `@next/next/no-img-element` as an example @@ -143,7 +157,26 @@ const getEsLintRuleName = (rule: string): string | undefined => { const expectedRule = esPluginName === '' ? ruleName : `${esPluginName}/${ruleName}`; - return allRules.find((rule) => rule == expectedRule); + // Some typescript-eslint rules are re-implemented version of eslint rules. + if (esPluginName === '@typescript-eslint') { + const founds = allRules.filter( + (rule) => rule === expectedRule || rule === ruleName + ); + + if (founds === undefined) { + return undefined; + } + + return founds; + } + + const found = allRules.find((rule) => rule === expectedRule); + + if (found === undefined) { + return undefined; + } + + return [found]; }; /** @@ -154,21 +187,23 @@ const handleRulesScope = ( rules: Record ): void => { for (const rule in oxlintRules) { - const eslintName = getEsLintRuleName(rule); + const eslintNames = getEsLintRuleNames(rule); - if (eslintName === undefined) { + if (eslintNames === undefined) { console.warn( `eslint-plugin-oxlint: could not find matching eslint rule for "${rule}"` ); continue; } - // is this rules not turned off - if (isActiveValue(oxlintRules[rule])) { - rules[eslintName] = 'off'; - } else if (rule in rules && isDeactivateValue(oxlintRules[rule])) { - // rules extended by categories or plugins can be disabled manually - delete rules[eslintName]; + for (const eslintName of eslintNames) { + // is this rules not turned off + if (isActiveValue(oxlintRules[rule])) { + rules[eslintName] = 'off'; + } else if (rule in rules && isDeactivateValue(oxlintRules[rule])) { + // rules extended by categories or plugins can be disabled manually + delete rules[eslintName]; + } } } }; From 5173e4fae4013d1c143c5966b2f6c2202ba9acf1 Mon Sep 17 00:00:00 2001 From: Sysix Date: Sat, 9 Nov 2024 13:04:20 +0100 Subject: [PATCH 4/6] fix: disable alias eslint and @typescript-eslint rules together --- src/build-from-oxlint-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build-from-oxlint-config.ts b/src/build-from-oxlint-config.ts index dcd3971..1bbf7d2 100644 --- a/src/build-from-oxlint-config.ts +++ b/src/build-from-oxlint-config.ts @@ -163,7 +163,7 @@ const getEsLintRuleNames = (rule: string): string[] | undefined => { (rule) => rule === expectedRule || rule === ruleName ); - if (founds === undefined) { + if (founds.length === 0) { return undefined; } From acb739bbff5f2e34d97e3425a4ea9f9071fff90b Mon Sep 17 00:00:00 2001 From: Sysix Date: Sat, 9 Nov 2024 13:46:06 +0100 Subject: [PATCH 5/6] fix: disable alias eslint and @typescript-eslint rules together --- src/build-from-oxlint-config.ts | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/src/build-from-oxlint-config.ts b/src/build-from-oxlint-config.ts index 1bbf7d2..0df310d 100644 --- a/src/build-from-oxlint-config.ts +++ b/src/build-from-oxlint-config.ts @@ -114,28 +114,22 @@ const handleCategoriesScope = ( * oxlint rules are deactivating one or more eslint rules. * * Oxlint rules do not need a plugin-scope. - * When no eslint rules are found, undefined is returned. + * When no eslint rules are found, an empty array is returned. * */ -const getEsLintRuleNames = (rule: string): string[] | undefined => { +const getEsLintRuleNames = (rule: string): string[] => { // there is no plugin prefix, it can be all plugin if (!rule.includes('/')) { - const founds = allRules.filter( + return allRules.filter( (search) => search.endsWith(`/${rule}`) || search === rule ); - - if (founds.length === 0) { - return undefined; - } - - return founds; } // greedy works with `@next/next/no-img-element` as an example const match = rule.match(/(^.*)\/(.*)/); if (match === null) { - return undefined; + return []; } const pluginName = match[1]; @@ -159,24 +153,14 @@ const getEsLintRuleNames = (rule: string): string[] | undefined => { // Some typescript-eslint rules are re-implemented version of eslint rules. if (esPluginName === '@typescript-eslint') { - const founds = allRules.filter( + return allRules.filter( (rule) => rule === expectedRule || rule === ruleName ); - - if (founds.length === 0) { - return undefined; - } - - return founds; } const found = allRules.find((rule) => rule === expectedRule); - if (found === undefined) { - return undefined; - } - - return [found]; + return found === undefined ? [] : [found]; }; /** @@ -189,7 +173,7 @@ const handleRulesScope = ( for (const rule in oxlintRules) { const eslintNames = getEsLintRuleNames(rule); - if (eslintNames === undefined) { + if (eslintNames.length === 0) { console.warn( `eslint-plugin-oxlint: could not find matching eslint rule for "${rule}"` ); From 5f0efc9eb170d992bfe3566ee857365b95ac093c Mon Sep 17 00:00:00 2001 From: Sysix Date: Sat, 9 Nov 2024 13:52:00 +0100 Subject: [PATCH 6/6] fix: disable alias eslint and @typescript-eslint rules together --- src/build-from-oxlint-config.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/build-from-oxlint-config.ts b/src/build-from-oxlint-config.ts index 0df310d..2638bbf 100644 --- a/src/build-from-oxlint-config.ts +++ b/src/build-from-oxlint-config.ts @@ -152,9 +152,12 @@ const getEsLintRuleNames = (rule: string): string[] => { esPluginName === '' ? ruleName : `${esPluginName}/${ruleName}`; // Some typescript-eslint rules are re-implemented version of eslint rules. - if (esPluginName === '@typescript-eslint') { + if (esPluginName === '@typescript-eslint' || esPluginName === '') { return allRules.filter( - (rule) => rule === expectedRule || rule === ruleName + (rule) => + rule === expectedRule || + (esPluginName === '@typescript-eslint' && rule === ruleName) || + (esPluginName === '' && rule === `@typescript-eslint/${ruleName}`) ); }