From e51d5d7e82934f6456d7be6136a2372f4f350c87 Mon Sep 17 00:00:00 2001 From: Azat S Date: Wed, 26 Apr 2023 19:25:21 +0300 Subject: [PATCH] Add support for react-hooks (#194) Co-authored-by: Shinigami92 --- package.json | 1 + pnpm-lock.yaml | 12 +++++++ .../generate-rule-files/src/plugins-map.ts | 4 +++ .../extends/eslint-plugin-react-hooks.d.ts | 6 ++++ src/config/extends/index.d.ts | 2 ++ src/rules/index.d.ts | 2 ++ src/rules/react-hooks/exhaustive-deps.d.ts | 35 +++++++++++++++++++ src/rules/react-hooks/index.d.ts | 7 ++++ src/rules/react-hooks/rules-of-hooks.d.ts | 22 ++++++++++++ 9 files changed, 91 insertions(+) create mode 100644 src/config/extends/eslint-plugin-react-hooks.d.ts create mode 100644 src/rules/react-hooks/exhaustive-deps.d.ts create mode 100644 src/rules/react-hooks/index.d.ts create mode 100644 src/rules/react-hooks/rules-of-hooks.d.ts diff --git a/package.json b/package.json index 4a2b2f5c..43c6a862 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "eslint-plugin-prettier": "~4.2.1", "eslint-plugin-promise": "~6.1.1", "eslint-plugin-react": "~7.32.2", + "eslint-plugin-react-hooks": "~4.6.0", "eslint-plugin-sonarjs": "~0.19.0", "eslint-plugin-spellcheck": "~0.0.20", "eslint-plugin-unicorn": "~46.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98fc21d1..a599dad1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -76,6 +76,9 @@ devDependencies: eslint-plugin-react: specifier: ~7.32.2 version: 7.32.2(eslint@8.39.0) + eslint-plugin-react-hooks: + specifier: ~4.6.0 + version: 4.6.0(eslint@8.39.0) eslint-plugin-sonarjs: specifier: ~0.19.0 version: 0.19.0(eslint@8.39.0) @@ -2417,6 +2420,15 @@ packages: eslint: 8.39.0 dev: true + /eslint-plugin-react-hooks@4.6.0(eslint@8.39.0): + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 8.39.0 + dev: true + /eslint-plugin-react@7.32.2(eslint@8.39.0): resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} engines: {node: '>=4'} diff --git a/scripts/generate-rule-files/src/plugins-map.ts b/scripts/generate-rule-files/src/plugins-map.ts index 86d8e499..bf68a0c9 100644 --- a/scripts/generate-rule-files/src/plugins-map.ts +++ b/scripts/generate-rule-files/src/plugins-map.ts @@ -59,6 +59,10 @@ export const PLUGIN_REGISTRY: Readonly> = { name: 'React', module: 'eslint-plugin-react', }, + 'react-hooks': { + name: 'ReactHooks', + module: 'eslint-plugin-react-hooks', + }, sonarjs: { name: 'SonarJS', prefix: 'sonarjs', diff --git a/src/config/extends/eslint-plugin-react-hooks.d.ts b/src/config/extends/eslint-plugin-react-hooks.d.ts new file mode 100644 index 00000000..92f9ab56 --- /dev/null +++ b/src/config/extends/eslint-plugin-react-hooks.d.ts @@ -0,0 +1,6 @@ +/** + * Eslint ReactHooks extensions. + * + * @see [Eslint ReactHooks extensions](https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks) + */ +export type ReactHooksExtensions = 'plugin:react-hooks/recommended'; diff --git a/src/config/extends/index.d.ts b/src/config/extends/index.d.ts index b26f946f..0b4d6c63 100644 --- a/src/config/extends/index.d.ts +++ b/src/config/extends/index.d.ts @@ -11,6 +11,7 @@ import type { NodeExtensions } from './eslint-plugin-node'; import type { PrettierExtensions } from './eslint-plugin-prettier'; import type { PromiseExtensions } from './eslint-plugin-promise'; import type { ReactExtensions } from './eslint-plugin-react'; +import type { ReactHooksExtensions } from './eslint-plugin-react-hooks'; import type { SonarjsExtensions } from './eslint-plugin-sonarjs'; import type { UnicornExtensions } from './eslint-plugin-unicorn'; import type { VitestExtensions } from './eslint-plugin-vitest'; @@ -36,6 +37,7 @@ export type KnownExtensions = LiteralUnion< | PrettierExtensions | PromiseExtensions | ReactExtensions + | ReactHooksExtensions | SonarjsExtensions | TypescriptEslintExtensions | UnicornExtensions diff --git a/src/rules/index.d.ts b/src/rules/index.d.ts index 0d3d15fd..73e5ec1a 100644 --- a/src/rules/index.d.ts +++ b/src/rules/index.d.ts @@ -9,6 +9,7 @@ import type { NRules } from './n'; import type { NodeRules } from './node'; import type { PromiseRules } from './promise'; import type { ReactRules } from './react'; +import type { ReactHooksRules } from './react-hooks'; import type { RuleConfig } from './rule-config'; import type { SonarJSRules } from './sonarjs'; import type { SpellcheckRules } from './spellcheck'; @@ -35,6 +36,7 @@ export type Rules = Partial< NodeRules & NRules & PromiseRules & + ReactHooksRules & ReactRules & SonarJSRules & SpellcheckRules & diff --git a/src/rules/react-hooks/exhaustive-deps.d.ts b/src/rules/react-hooks/exhaustive-deps.d.ts new file mode 100644 index 00000000..eef26916 --- /dev/null +++ b/src/rules/react-hooks/exhaustive-deps.d.ts @@ -0,0 +1,35 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Option. + */ +export interface ExhaustiveDepsOption { + additionalHooks?: string; + enableDangerousAutofixThisMayCauseInfiniteLoops?: boolean; +} + +/** + * Options. + */ +export type ExhaustiveDepsOptions = [ExhaustiveDepsOption?]; + +/** + * Verifies the list of dependencies for Hooks like useEffect and similar. + * + * @see [exhaustive-deps](https://github.com/facebook/react/issues/14920) + */ +export type ExhaustiveDepsRuleConfig = RuleConfig; + +/** + * Verifies the list of dependencies for Hooks like useEffect and similar. + * + * @see [exhaustive-deps](https://github.com/facebook/react/issues/14920) + */ +export interface ExhaustiveDepsRule { + /** + * Verifies the list of dependencies for Hooks like useEffect and similar. + * + * @see [exhaustive-deps](https://github.com/facebook/react/issues/14920) + */ + 'react-hooks/exhaustive-deps': ExhaustiveDepsRuleConfig; +} diff --git a/src/rules/react-hooks/index.d.ts b/src/rules/react-hooks/index.d.ts new file mode 100644 index 00000000..d0754823 --- /dev/null +++ b/src/rules/react-hooks/index.d.ts @@ -0,0 +1,7 @@ +import type { ExhaustiveDepsRule } from './exhaustive-deps'; +import type { RulesOfHooksRule } from './rules-of-hooks'; + +/** + * All ReactHooks rules. + */ +export type ReactHooksRules = RulesOfHooksRule & ExhaustiveDepsRule; diff --git a/src/rules/react-hooks/rules-of-hooks.d.ts b/src/rules/react-hooks/rules-of-hooks.d.ts new file mode 100644 index 00000000..b336ae53 --- /dev/null +++ b/src/rules/react-hooks/rules-of-hooks.d.ts @@ -0,0 +1,22 @@ +import type { RuleConfig } from '../rule-config'; + +/** + * Enforces the Rules of Hooks. + * + * @see [rules-of-hooks](https://reactjs.org/docs/hooks-rules.html) + */ +export type RulesOfHooksRuleConfig = RuleConfig<[]>; + +/** + * Enforces the Rules of Hooks. + * + * @see [rules-of-hooks](https://reactjs.org/docs/hooks-rules.html) + */ +export interface RulesOfHooksRule { + /** + * Enforces the Rules of Hooks. + * + * @see [rules-of-hooks](https://reactjs.org/docs/hooks-rules.html) + */ + 'react-hooks/rules-of-hooks': RulesOfHooksRuleConfig; +}