diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintPlugin-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintPlugin-test.js new file mode 100644 index 000000000000..a250e161ec31 --- /dev/null +++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintPlugin-test.js @@ -0,0 +1,29 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const ReactHooksESLintPlugin = require('eslint-plugin-react-hooks').default; + +describe('eslint-plugin-react-hooks flat configs', () => { + it('binds both flat presets to the plugin instance', () => { + const flatConfigs = ReactHooksESLintPlugin.configs.flat; + + expect(flatConfigs.recommended.plugins['react-hooks']).toBe( + ReactHooksESLintPlugin + ); + expect(flatConfigs['recommended-latest'].plugins['react-hooks']).toBe( + ReactHooksESLintPlugin + ); + expect(flatConfigs.recommended.rules).toBe( + ReactHooksESLintPlugin.configs.recommended.rules + ); + expect(flatConfigs['recommended-latest'].rules).toBe( + ReactHooksESLintPlugin.configs['recommended-latest'].rules + ); + }); +}); diff --git a/packages/eslint-plugin-react-hooks/src/index.ts b/packages/eslint-plugin-react-hooks/src/index.ts index 924299d89894..b28939428723 100644 --- a/packages/eslint-plugin-react-hooks/src/index.ts +++ b/packages/eslint-plugin-react-hooks/src/index.ts @@ -58,10 +58,61 @@ const recommendedLatestRuleConfigs: Linter.RulesRecord = { const plugins = ['react-hooks']; type ReactHooksFlatConfig = { - plugins: {react: any}; + plugins: {'react-hooks': ReactHooksPlugin}; rules: Linter.RulesRecord; }; +type ReactHooksFlatConfigs = { + readonly recommended: ReactHooksFlatConfig; + readonly 'recommended-latest': ReactHooksFlatConfig; +}; + +type ReactHooksPlugin = { + meta: { + name: string; + version: string; + }; + rules: Record; + configs: { + recommended: { + plugins: string[]; + rules: Linter.RulesRecord; + }; + 'recommended-latest': { + plugins: string[]; + rules: Linter.RulesRecord; + }; + flat: ReactHooksFlatConfigs; + }; +}; + +let plugin: ReactHooksPlugin; +let cachedRecommended: ReactHooksFlatConfig | null = null; +let cachedRecommendedLatest: ReactHooksFlatConfig | null = null; + +const flatConfigs: ReactHooksFlatConfigs = { + get recommended() { + if (cachedRecommended !== null) { + return cachedRecommended; + } + cachedRecommended = { + plugins: {'react-hooks': plugin}, + rules: recommendedRuleConfigs, + }; + return cachedRecommended; + }, + get 'recommended-latest'() { + if (cachedRecommendedLatest !== null) { + return cachedRecommendedLatest; + } + cachedRecommendedLatest = { + plugins: {'react-hooks': plugin}, + rules: recommendedLatestRuleConfigs, + }; + return cachedRecommendedLatest; + }, +}; + const configs = { recommended: { plugins, @@ -71,13 +122,10 @@ const configs = { plugins, rules: recommendedLatestRuleConfigs, }, - flat: {} as { - recommended: ReactHooksFlatConfig; - 'recommended-latest': ReactHooksFlatConfig; - }, + flat: flatConfigs, }; -const plugin = { +plugin = { meta: { name: 'eslint-plugin-react-hooks', version: '7.0.0', @@ -86,15 +134,4 @@ const plugin = { configs, }; -Object.assign(configs.flat, { - 'recommended-latest': { - plugins: {'react-hooks': plugin}, - rules: configs['recommended-latest'].rules, - }, - recommended: { - plugins: {'react-hooks': plugin}, - rules: configs.recommended.rules, - }, -}); - export default plugin;