@vijayhardaha/dev-config 2.0.0 → 2.0.2

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 CHANGED
@@ -27,7 +27,7 @@ bun install @vijayhardaha/dev-config --dev
27
27
  ### Install Required Packages
28
28
 
29
29
  ```bash
30
- bun add --dev eslint prettier @prettier/plugin-xml eslint-plugin-prettier globals eslint-plugin-jsdoc eslint-plugin-import-x typescript typescript-eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser
30
+ bun add --dev eslint @eslint/compat prettier @prettier/plugin-xml eslint-plugin-prettier globals eslint-plugin-jsdoc eslint-plugin-import-x typescript typescript-eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser
31
31
  ```
32
32
 
33
33
  ### Install Optional Packages
@@ -79,7 +79,7 @@ v2 drops FlatCompat and uses native ESLint 10 flat configs throughout.
79
79
 
80
80
  1. Install ESLint 10+: `bun add --dev eslint@10`
81
81
  2. Replace `eslint-plugin-import` with `eslint-plugin-import-x`
82
- 3. Remove unused deps: `@eslint/compat`, `@eslint/eslintrc`, `@eslint/js`, `eslint-config-prettier`, `eslint-import-resolver-typescript`
82
+ 3. Remove unused deps: `@eslint/eslintrc`, `@eslint/js`, `eslint-config-prettier`, `eslint-import-resolver-typescript`
83
83
 
84
84
  ## Quick Start
85
85
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vijayhardaha/dev-config",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Reusable development configurations for Next.js + TypeScript projects",
5
5
  "scripts": {
6
6
  "lint": "eslint .",
@@ -36,10 +36,17 @@
36
36
  },
37
37
  "exports": {
38
38
  ".": "./src/index.js",
39
+ "./package.json": "./package.json",
39
40
  "./eslint": "./src/eslint/index.js",
41
+ "./eslint/js": "./src/eslint/index.js",
42
+ "./eslint/base": "./src/eslint/index.js",
43
+ "./eslint/common": "./src/eslint/index.js",
40
44
  "./eslint/ts": "./src/eslint/typescript.js",
45
+ "./eslint/typescript": "./src/eslint/typescript.js",
41
46
  "./eslint/react": "./src/eslint/react.js",
47
+ "./eslint/reactjs": "./src/eslint/react.js",
42
48
  "./eslint/next": "./src/eslint/next.js",
49
+ "./eslint/nextjs": "./src/eslint/next.js",
43
50
  "./prettier": "./src/prettier/index.js",
44
51
  "./commitlint": "./src/commitlint/index.js",
45
52
  "./stylelint": "./src/stylelint/index.js",
@@ -74,10 +81,8 @@
74
81
  "stylelint-order": "^8.1.1",
75
82
  "vitest": "^4.1.7"
76
83
  },
77
- "dependencies": {
78
- "@eslint/compat": "^2.1.0"
79
- },
80
84
  "peerDependencies": {
85
+ "@eslint/compat": ">=2",
81
86
  "@prettier/plugin-xml": ">=3",
82
87
  "@typescript-eslint/eslint-plugin": ">=8",
83
88
  "@typescript-eslint/parser": ">=8",
@@ -3,20 +3,170 @@ import { defineConfig } from 'eslint/config';
3
3
  import importX from 'eslint-plugin-import-x';
4
4
  import jsdocPlugin from 'eslint-plugin-jsdoc';
5
5
  import prettierRecommended from 'eslint-plugin-prettier/recommended';
6
- import tsEslint from 'typescript-eslint';
7
6
 
8
7
  import { globalIgnores } from './ignores.js';
9
8
  import { commonLanguageOptions } from './language-options.js';
10
9
  import { commonRules } from './rules.js';
11
- import { commonParser } from './setup.js';
12
10
 
13
11
  /**
14
- * Builds a common ESLint configuration with support for various options.
12
+ * Filters conditional plugins based on user options.
13
+ *
14
+ * @param {object} conditionalPlugins - Plugin map keyed by option name.
15
+ * @param {object} options - User-provided options.
16
+ *
17
+ * @returns {object[]} Flat config objects for enabled plugins.
18
+ */
19
+ const getEnabledPlugins = (conditionalPlugins, options) =>
20
+ Object.entries(conditionalPlugins)
21
+ .filter(([key]) => options[key])
22
+ .flatMap(([, value]) => (Array.isArray(value) ? value : [value]));
23
+
24
+ /**
25
+ * Flattens a mixed list of config arrays and objects.
26
+ *
27
+ * @param {(Array|object)[]} plugins - Mixed list of flat config arrays and objects.
28
+ *
29
+ * @returns {object[]} Flattened config array.
30
+ */
31
+ const flattenPlugins = (plugins) => {
32
+ const result = [];
33
+
34
+ for (const plugin of plugins) {
35
+ if (Array.isArray(plugin)) {
36
+ result.push(...plugin);
37
+ } else if (typeof plugin === 'object' && plugin !== null) {
38
+ result.push(plugin);
39
+ }
40
+ }
41
+
42
+ return result;
43
+ };
44
+
45
+ /**
46
+ * Wraps plugin rules with fixupPluginRules for backward compatibility.
47
+ *
48
+ * @param {object[]} flatConfigs - Flat config array.
49
+ *
50
+ * @returns {object[]} Config array with wrapped plugin rules.
51
+ */
52
+ const fixPlugins = (flatConfigs) =>
53
+ flatConfigs.map((config) => {
54
+ if (!config.plugins) return config;
55
+
56
+ const fixed = { ...config, plugins: {} };
57
+
58
+ for (const [name, plugin] of Object.entries(config.plugins)) {
59
+ fixed.plugins[name] = fixupPluginRules(plugin);
60
+ }
61
+
62
+ return fixed;
63
+ });
64
+
65
+ /**
66
+ * Removes centrally-registered plugins from individual configs to prevent
67
+ * "Cannot redefine plugin" errors.
68
+ *
69
+ * @param {object[]} flatConfigs - Flat config array.
70
+ * @param {string[]} pluginNames - Plugin names to strip from configs.
71
+ *
72
+ * @returns {object[]} Config array with specified plugins removed.
73
+ */
74
+ const stripPlugins = (flatConfigs, pluginNames) => {
75
+ if (pluginNames.length === 0) return flatConfigs;
76
+
77
+ const skip = new Set(pluginNames);
78
+
79
+ return flatConfigs.map((config) => {
80
+ if (!config.plugins) return config;
81
+
82
+ const plugins = { ...config.plugins };
83
+
84
+ for (const name of skip) {
85
+ delete plugins[name];
86
+ }
87
+
88
+ if (Object.keys(plugins).length === 0) {
89
+ const { plugins: _, ...rest } = config;
90
+
91
+ return rest;
92
+ }
93
+
94
+ return { ...config, plugins };
95
+ });
96
+ };
97
+
98
+ /**
99
+ * Merges user-provided global ignores with common defaults.
100
+ *
101
+ * @param {string[]|undefined} userGlobalIgnores - User-provided ignore patterns.
102
+ *
103
+ * @returns {object} ESLint ignores config object.
104
+ */
105
+ const mergeGlobalIgnores = (userGlobalIgnores) =>
106
+ Array.isArray(userGlobalIgnores) ? globalIgnores(userGlobalIgnores) : globalIgnores();
107
+
108
+ /**
109
+ * Builds the main ESLint config object with language options, settings, rules,
110
+ * and centrally-registered plugins.
111
+ *
112
+ * @param {object} ctx - Context object with all config parameters.
113
+ * @param {string[]} ctx.filePatterns - File patterns to apply the config to.
114
+ * @param {object} ctx.opts - Resolved user options.
115
+ * @param {boolean} ctx.typescript - Enable TypeScript support.
116
+ * @param {object} ctx.centralPlugins - Plugins to register on the main config.
117
+ * @param {object} ctx.extraLanguageOptions - Additional language options.
118
+ * @param {object} ctx.parserOptions - Parser options.
119
+ * @param {object} ctx.extraSettings - Additional settings.
120
+ * @param {object} ctx.extraRules - Additional rules.
121
+ *
122
+ * @returns {import('eslint').Linter.Config} ESLint config object.
123
+ */
124
+ const buildConfigObject = ({
125
+ filePatterns,
126
+ opts,
127
+ typescript,
128
+ centralPlugins = {},
129
+ extraLanguageOptions,
130
+ parserOptions,
131
+ extraSettings,
132
+ extraRules,
133
+ }) => {
134
+ const { ignores, rules, settings, languageOptions, extend } = opts;
135
+
136
+ return {
137
+ files: [...filePatterns],
138
+ ...(ignores && { ignores }),
139
+ plugins: Object.fromEntries(
140
+ Object.entries(centralPlugins).map(([name, plugin]) => [name, fixupPluginRules(plugin)])
141
+ ),
142
+ languageOptions: {
143
+ ...commonLanguageOptions,
144
+ ...extraLanguageOptions,
145
+ ...(typescript && { parserOptions: { tsconfigRootDir: process.cwd(), ...parserOptions } }),
146
+ },
147
+ settings: {
148
+ ...(opts.importOrder && { 'import-x/resolver': { typescript: {} } }),
149
+ ...(opts.jsdoc && { jsdoc: { mode: 'typescript' } }),
150
+ ...extraSettings,
151
+ ...settings,
152
+ },
153
+ rules: {
154
+ ...commonRules({ prettier: opts.prettier, importOrder: opts.importOrder, typescript, jsdoc: opts.jsdoc }),
155
+ ...extraRules,
156
+ ...rules,
157
+ },
158
+ ...extend,
159
+ };
160
+ };
161
+
162
+ /**
163
+ * Builds a flat ESLint configuration.
15
164
  *
16
165
  * @param {object} config - Configuration options.
17
166
  * @param {string[]} config.files - File patterns to apply the config to.
18
167
  * @param {(Array|object)[]} config.builtinPlugins - Flat config arrays or objects to always include.
19
- * @param {object} config.conditionalPlugins - Conditional plugins based on options (e.g., { react: true, a11y: true }).
168
+ * @param {object} config.conditionalPlugins - Conditional plugins based on options.
169
+ * @param {object} config.centralPlugins - Plugins registered on the main config object.
20
170
  * @param {object} [config.languageOptions] - Additional language options.
21
171
  * @param {object} [config.parserOptions] - Parser options.
22
172
  * @param {object} [config.settings] - Settings object.
@@ -30,6 +180,7 @@ export const buildConfig = ({
30
180
  files: filePatterns,
31
181
  builtinPlugins = [],
32
182
  conditionalPlugins = {},
183
+ centralPlugins = {},
33
184
  languageOptions: extraLanguageOptions = {},
34
185
  parserOptions = {},
35
186
  settings: extraSettings = {},
@@ -37,80 +188,34 @@ export const buildConfig = ({
37
188
  options = {},
38
189
  typescript = false,
39
190
  }) => {
40
- const {
41
- prettier = true,
42
- importOrder = true,
43
- jsdoc = true,
44
- ignores,
45
- rules,
46
- settings,
47
- languageOptions,
48
- plugins: userPlugins,
49
- globalIgnores: userGlobalIgnores,
50
- extend,
51
- } = options;
52
-
53
- // ---- Build extends configs ----
54
- const conditionalPluginList = Object.entries(conditionalPlugins)
55
- .filter(([key]) => options[key])
56
- .flatMap(([, value]) => (Array.isArray(value) ? value : [value]));
191
+ const opts = { prettier: true, importOrder: true, jsdoc: true, ...options };
192
+
193
+ const conditionalPluginList = getEnabledPlugins(conditionalPlugins, opts);
57
194
 
58
- const builtPlugins = [
195
+ const mergedPlugins = [
59
196
  ...builtinPlugins,
60
- importOrder && importX.flatConfigs.recommended,
61
- jsdoc && jsdocPlugin.configs['flat/recommended'],
62
- prettier && prettierRecommended,
197
+ opts.importOrder && importX.flatConfigs.recommended,
198
+ opts.jsdoc && jsdocPlugin.configs['flat/recommended'],
199
+ opts.prettier && prettierRecommended,
63
200
  ...conditionalPluginList,
201
+ ...(opts.plugins || []),
64
202
  ].filter(Boolean);
65
203
 
66
- const plugins = [...builtPlugins, ...(userPlugins || [])];
204
+ const flatConfigs = flattenPlugins(mergedPlugins);
205
+ const wrappedConfigs = fixPlugins(flatConfigs);
206
+ const strippedConfigs = stripPlugins(wrappedConfigs, Object.keys(centralPlugins));
207
+ const mergedGlobalIgnores = mergeGlobalIgnores(opts.globalIgnores);
67
208
 
68
- // ---- Build config object ----
69
- const configObject = {
70
- files: [...filePatterns],
71
- ...(ignores && { ignores }),
72
- ...(typescript && { plugins: { '@typescript-eslint': tsEslint.plugin } }),
73
- languageOptions: {
74
- ...commonLanguageOptions,
75
- ...(typescript && commonParser),
76
- ...extraLanguageOptions,
77
- ...languageOptions,
78
- ...(typescript && { parserOptions: { tsconfigRootDir: process.cwd(), ...parserOptions } }),
79
- },
80
- settings: {
81
- ...(importOrder && { 'import-x/resolver': { typescript: {} } }),
82
- ...(jsdoc && { jsdoc: { mode: 'typescript' } }),
83
- ...extraSettings,
84
- ...settings,
85
- },
86
- rules: { ...commonRules({ prettier, importOrder, typescript, jsdoc }), ...extraRules, ...rules },
87
- ...extend,
88
- };
89
-
90
- // Merge user global ignores with common global ignores
91
- const mergedGlobalIgnores = Array.isArray(userGlobalIgnores) ? globalIgnores(userGlobalIgnores) : globalIgnores();
92
-
93
- // Collect all flat configs (arrays spread, objects added directly)
94
- const flatConfigs = [];
95
-
96
- for (const plugin of plugins) {
97
- if (Array.isArray(plugin)) {
98
- flatConfigs.push(...plugin);
99
- } else if (typeof plugin === 'object' && plugin !== null) {
100
- flatConfigs.push(plugin);
101
- }
102
- }
103
-
104
- // Wrap plugins with fixupPluginRules for ESLint 10 backward compatibility
105
- // (addresses removed APIs like context.getFilename in eslint-plugin-react)
106
- const fixedConfigs = flatConfigs.map((config) => {
107
- if (!config.plugins) return config;
108
- const fixed = { ...config, plugins: {} };
109
- for (const [name, plugin] of Object.entries(config.plugins)) {
110
- fixed.plugins[name] = fixupPluginRules(plugin);
111
- }
112
- return fixed;
209
+ const configObject = buildConfigObject({
210
+ filePatterns,
211
+ opts,
212
+ typescript,
213
+ centralPlugins,
214
+ extraLanguageOptions,
215
+ parserOptions,
216
+ extraSettings,
217
+ extraRules,
113
218
  });
114
219
 
115
- return defineConfig([...mergedGlobalIgnores, ...fixedConfigs, configObject]);
220
+ return defineConfig([...mergedGlobalIgnores, ...strippedConfigs, configObject]);
116
221
  };
@@ -1,3 +1,72 @@
1
+ // ---- JSDoc Rules: enforce documentation on public/exported APIs ----
2
+
3
+ /**
4
+ * JSDoc rules that enforce documentation presence on public/exported APIs.
5
+ * Covers `@param`, `@returns`, `@throws`, `@description`, and `@property-description`.
6
+ *
7
+ * @type {object}
8
+ */
9
+ const JSDOC_REQUIRE_RULES = {
10
+ 'jsdoc/require-jsdoc': [
11
+ 'error',
12
+ {
13
+ publicOnly: true,
14
+ require: {
15
+ FunctionDeclaration: true,
16
+ MethodDefinition: true,
17
+ ClassDeclaration: true,
18
+ ArrowFunctionExpression: true,
19
+ },
20
+ },
21
+ ],
22
+ 'jsdoc/require-description': 'error',
23
+ 'jsdoc/require-param': 'error',
24
+ 'jsdoc/require-param-name': 'error',
25
+ 'jsdoc/require-param-description': 'error',
26
+ 'jsdoc/require-param-type': 'error',
27
+ 'jsdoc/require-returns': 'error',
28
+ 'jsdoc/require-returns-description': 'error',
29
+ 'jsdoc/require-returns-type': 'error',
30
+ 'jsdoc/require-throws': 'error',
31
+ 'jsdoc/require-property-description': 'warn',
32
+ };
33
+
34
+ /**
35
+ * JSDoc rules that validate tag names, types, and undefined type references.
36
+ *
37
+ * @type {object}
38
+ */
39
+ const JSDOC_CORRECTNESS_RULES = {
40
+ 'jsdoc/check-tag-names': 'error',
41
+ 'jsdoc/no-undefined-types': ['error', { definedTypes: ['JSX.Element'] }],
42
+ 'jsdoc/valid-types': 'error',
43
+ };
44
+
45
+ /**
46
+ * JSDoc rules that enforce consistent formatting and tag ordering.
47
+ *
48
+ * @type {object}
49
+ */
50
+ const JSDOC_STYLE_RULES = {
51
+ 'jsdoc/tag-lines': ['error', 'any', { startLines: 1, endLines: 0, applyToEndTag: true }],
52
+ 'jsdoc/check-alignment': 'error',
53
+ 'jsdoc/check-indentation': 'off',
54
+ 'jsdoc/sort-tags': [
55
+ 'warn',
56
+ {
57
+ tagSequence: [
58
+ { tags: ['description'] },
59
+ { tags: ['template'] },
60
+ { tags: ['param'] },
61
+ { tags: ['returns'] },
62
+ { tags: ['example'] },
63
+ ],
64
+ },
65
+ ],
66
+ 'jsdoc/no-types': 'off',
67
+ 'jsdoc/informative-docs': 'off',
68
+ };
69
+
1
70
  /**
2
71
  * Creates JSDoc rules for enforcing documentation on public/exported APIs.
3
72
  *
@@ -6,72 +75,7 @@
6
75
  * @returns {object} JSDoc ESLint rules object.
7
76
  */
8
77
  const jsdocRules = (jsdoc = true) =>
9
- jsdoc
10
- ? {
11
- // ---- JSDoc Rules for PUBLIC / EXPORTED APIs ----
12
- 'jsdoc/require-jsdoc': [
13
- 'error',
14
- {
15
- publicOnly: true,
16
- require: {
17
- FunctionDeclaration: true,
18
- MethodDefinition: true,
19
- ClassDeclaration: true,
20
- ArrowFunctionExpression: true,
21
- },
22
- },
23
- ],
24
-
25
- // Descriptions must exist and be meaningful
26
- 'jsdoc/require-description': 'error',
27
-
28
- // Params must be fully documented
29
- 'jsdoc/require-param': 'error',
30
- 'jsdoc/require-param-name': 'error',
31
- 'jsdoc/require-param-description': 'error',
32
- 'jsdoc/require-param-type': 'error',
33
-
34
- // Returns must be documented
35
- 'jsdoc/require-returns': 'error',
36
- 'jsdoc/require-returns-description': 'error',
37
- 'jsdoc/require-returns-type': 'error',
38
-
39
- // Throws must be documented
40
- 'jsdoc/require-throws': 'error',
41
-
42
- // Strict correctness
43
- 'jsdoc/check-tag-names': 'error',
44
- 'jsdoc/no-undefined-types': ['error', { definedTypes: ['JSX.Element'] }],
45
- 'jsdoc/valid-types': 'error',
46
-
47
- // Enforce clean structure
48
- 'jsdoc/tag-lines': ['error', 'any', { startLines: 1, endLines: 0, applyToEndTag: true }],
49
-
50
- 'jsdoc/check-alignment': 'error',
51
- 'jsdoc/check-indentation': 'off',
52
-
53
- // Optional but powerful for large teams
54
- 'jsdoc/sort-tags': [
55
- 'warn',
56
- {
57
- tagSequence: [
58
- { tags: ['description'] },
59
- { tags: ['template'] },
60
- { tags: ['param'] },
61
- { tags: ['returns'] },
62
- { tags: ['example'] },
63
- ],
64
- },
65
- ],
66
-
67
- // Avoid useless docs
68
- 'jsdoc/no-types': 'off',
69
- 'jsdoc/informative-docs': 'off',
70
-
71
- // Enforce property docs in typedef-style (optional)
72
- 'jsdoc/require-property-description': 'warn',
73
- }
74
- : {};
78
+ jsdoc ? { ...JSDOC_REQUIRE_RULES, ...JSDOC_CORRECTNESS_RULES, ...JSDOC_STYLE_RULES } : {};
75
79
 
76
80
  /**
77
81
  * Creates TypeScript-specific rules.
@@ -1,71 +1,61 @@
1
- import { describe, it, expect } from 'vitest';
1
+ import { describe, it, expect, beforeAll } from 'vitest';
2
2
 
3
3
  // Test suite for the ESLint rules configuration module.
4
4
  describe('eslint/lib/rules.js', () => {
5
- // Test that the module exports the commonRules function.
6
- it('should export commonRules function', async () => {
7
- // Dynamically import the rules module to test its exports.
5
+ let commonRules;
6
+
7
+ // Module-level import before tests to reduce duplication.
8
+ beforeAll(async () => {
8
9
  const module = await import('./rules.js');
10
+ commonRules = module.commonRules;
11
+ });
9
12
 
13
+ // Test that the module exports the commonRules function.
14
+ it('should export commonRules function', () => {
10
15
  // Verify that commonRules is a function.
11
- expect(typeof module.commonRules).toBe('function');
16
+ expect(typeof commonRules).toBe('function');
12
17
  });
13
18
 
14
19
  // Test that commonRules returns an object containing ESLint rules.
15
- it('should return an object with rules', async () => {
16
- // Dynamically import the rules module to test its function.
17
- const module = await import('./rules.js');
18
-
20
+ it('should return an object with rules', () => {
19
21
  // Call commonRules with no options to get base rules.
20
- const result = module.commonRules();
22
+ const result = commonRules();
21
23
 
22
24
  // Verify that the result is an object (ESLint rules config).
23
25
  expect(typeof result).toBe('object');
24
26
  });
25
27
 
26
28
  // Test that TypeScript rules are included when typescript option is true.
27
- it('should include TypeScript rules when typescript is true', async () => {
28
- // Dynamically import the rules module to test its function.
29
- const module = await import('./rules.js');
30
-
29
+ it('should include TypeScript rules when typescript is true', () => {
31
30
  // Call commonRules with typescript option enabled.
32
- const result = module.commonRules({ typescript: true });
31
+ const result = commonRules({ typescript: true });
33
32
 
34
33
  // Verify that a TypeScript-specific rule is present in the config.
35
34
  expect(result['@typescript-eslint/no-unused-vars']).toBeDefined();
36
35
  });
37
36
 
38
37
  // Test that import order rules are included when importOrder option is true.
39
- it('should include import order rules when importOrder is true', async () => {
40
- // Dynamically import the rules module to test its function.
41
- const module = await import('./rules.js');
42
-
38
+ it('should include import order rules when importOrder is true', () => {
43
39
  // Call commonRules with importOrder option enabled.
44
- const result = module.commonRules({ importOrder: true });
40
+ const result = commonRules({ importOrder: true });
45
41
 
46
42
  // Verify that the import-x/order rule is present in the config.
47
43
  expect(result['import-x/order']).toBeDefined();
48
44
  });
49
45
 
50
46
  // Test that Prettier rules are included when prettier option is true.
51
- it('should include Prettier rules when prettier is true', async () => {
52
- // Dynamically import the rules module to test its function.
53
- const module = await import('./rules.js');
54
-
47
+ it('should include Prettier rules when prettier is true', () => {
55
48
  // Call commonRules with prettier option enabled.
56
- const result = module.commonRules({ prettier: true });
49
+ const result = commonRules({ prettier: true });
57
50
 
58
51
  // Verify that the prettier/prettier rule is present in the config.
59
52
  expect(result['prettier/prettier']).toBeDefined();
60
53
  });
61
54
 
62
55
  // Test that JSDoc rules are included when jsdoc option is true.
63
- it('should include JSDoc rules when jsdoc is true', async () => {
64
- // Dynamically import the rules module to test its function.
65
- const module = await import('./rules.js');
66
-
56
+ it('should include JSDoc rules when jsdoc is true', () => {
67
57
  // Call commonRules with jsdoc option enabled.
68
- const result = module.commonRules({ jsdoc: true });
58
+ const result = commonRules({ jsdoc: true });
69
59
 
70
60
  // Verify that the jsdoc/require-jsdoc rule is present in the config.
71
61
  expect(result['jsdoc/require-jsdoc']).toBeDefined();
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  import jsxA11y from 'eslint-plugin-jsx-a11y';
13
+ import reactPlugin from 'eslint-plugin-react';
13
14
  import reactRecommended from 'eslint-plugin-react/configs/recommended.js';
14
15
  import reactHooks from 'eslint-plugin-react-hooks';
15
16
  import tsEslint from 'typescript-eslint';
@@ -42,11 +43,12 @@ export const createConfig = (options = {}) => {
42
43
  return buildConfig({
43
44
  files: files.withTs,
44
45
  builtinPlugins: [
45
- { ...reactRecommended, files: ['**/*.{jsx,tsx}'] },
46
- { ...reactHooks.configs.flat.recommended, files: ['**/*.{jsx,tsx}'] },
46
+ { ...reactRecommended, files: files.withTs },
47
+ { ...reactHooks.configs.flat.recommended, files: files.withTs },
47
48
  ...tsEslint.configs.recommended,
48
49
  ],
49
- conditionalPlugins: { a11y: { ...jsxA11y.flatConfigs.recommended, files: ['**/*.{jsx,tsx}'] } },
50
+ centralPlugins: { react: reactPlugin, 'react-hooks': reactHooks, '@typescript-eslint': tsEslint.plugin },
51
+ conditionalPlugins: { a11y: { ...jsxA11y.flatConfigs.recommended, files: files.withTs } },
50
52
  parserOptions: { ecmaFeatures: { jsx: true } },
51
53
  settings: { react: { version: 'detect' } },
52
54
  rules: { 'react/react-in-jsx-scope': 'off', 'react/no-unknown-property': ['error', { ignore: ['jsx', 'global'] }] },
@@ -37,6 +37,7 @@ export const createConfig = (options = {}) => {
37
37
  return buildConfig({
38
38
  files: files.withTs,
39
39
  builtinPlugins: [...tsEslint.configs.recommended],
40
+ centralPlugins: { '@typescript-eslint': tsEslint.plugin },
40
41
  typescript: true,
41
42
  options: { ...options, prettier, importOrder, jsdoc },
42
43
  });