@jimmy.codes/eslint-config 6.24.0 → 6.25.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 CHANGED
@@ -81,7 +81,7 @@ TypeScript also supports some configuration options. If options are provided the
81
81
 
82
82
  #### Configure Erasable Syntax Only
83
83
 
84
- Enable rules scoped to TypeScripts new erasable syntax only mode (TypeScript 5.8+):
84
+ Enable rules scoped to [TypeScript's new erasable syntax only mode (TypeScript 5.8+)](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-8.html#the---erasablesyntaxonly-option):
85
85
 
86
86
  ```ts
87
87
  import { defineConfig } from "@jimmy.codes/eslint-config";
@@ -131,6 +131,71 @@ export default defineConfig({
131
131
  });
132
132
  ```
133
133
 
134
+ ### Framework-Specific Rule Overrides
135
+
136
+ Many framework integrations support rule overrides, allowing you to fine-tune specific rules without affecting your entire config:
137
+
138
+ ```ts
139
+ import { defineConfig } from "@jimmy.codes/eslint-config";
140
+
141
+ export default defineConfig({
142
+ react: {
143
+ overrides: {
144
+ "react-x/no-array-index-key": "warn",
145
+ "jsx-a11y/anchor-is-valid": "off",
146
+ },
147
+ },
148
+ playwright: {
149
+ overrides: {
150
+ "playwright/no-focused-test": "error",
151
+ },
152
+ },
153
+ jest: {
154
+ overrides: {
155
+ "jest/expect-expect": "off",
156
+ },
157
+ },
158
+ testingLibrary: {
159
+ overrides: {
160
+ "testing-library/prefer-screen-queries": "warn",
161
+ },
162
+ },
163
+ nextjs: {
164
+ overrides: {
165
+ "@next/next/no-img-element": "off",
166
+ },
167
+ },
168
+ storybook: {
169
+ overrides: {
170
+ "storybook/no-uninstalled-addons": "warn",
171
+ },
172
+ },
173
+ tanstackQuery: {
174
+ overrides: {
175
+ "@tanstack/query/exhaustive-deps": "error",
176
+ },
177
+ },
178
+ astro: {
179
+ overrides: {
180
+ "astro/no-set-html-directive": "off",
181
+ },
182
+ },
183
+ vitest: {
184
+ overrides: {
185
+ "vitest/no-conditional-expect": "warn",
186
+ },
187
+ },
188
+ typescript: {
189
+ overrides: {
190
+ "@typescript-eslint/explicit-function-return-type": "error",
191
+ },
192
+ },
193
+ });
194
+ ```
195
+
196
+ > [!TIP]
197
+ > Framework-specific overrides are scoped to only rules with the appropriate plugin prefix (e.g., `vitest/*` for Vitest, `react-x/*` for React). For broader rule overrides across specific file patterns, use the `overrides` array.
198
+
134
199
  ### Override Specific Rules
135
200
 
136
201
  ```ts
@@ -1,12 +1,13 @@
1
1
  import { t as GLOB_ASTRO } from "./globs-uKx5b8lV.mjs";
2
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
2
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
3
3
  import globals from "globals";
4
4
 
5
5
  //#region src/configs/astro.ts
6
- async function astroConfig() {
6
+ async function astroConfig(options) {
7
+ const extractedOptions = extractOptions(options);
7
8
  const files = [GLOB_ASTRO];
8
- const { configs: tsConfigs, parser: tsParser } = await import("typescript-eslint");
9
- const [astroPlugin, astroParser, jsxA11yPlugin] = await Promise.all([
9
+ const [tsPlugin, astroPlugin, astroParser, jsxA11yPlugin] = await Promise.all([
10
+ import("typescript-eslint"),
10
11
  import("eslint-plugin-astro"),
11
12
  import("astro-eslint-parser"),
12
13
  interopDefault(import("eslint-plugin-jsx-a11y"))
@@ -23,7 +24,7 @@ async function astroConfig() {
23
24
  parser: astroParser,
24
25
  parserOptions: {
25
26
  extraFileExtensions: [".astro"],
26
- parser: tsParser
27
+ parser: tsPlugin.parser
27
28
  },
28
29
  sourceType: "module"
29
30
  },
@@ -44,7 +45,8 @@ async function astroConfig() {
44
45
  "astro/no-exports-from-components": "off",
45
46
  "astro/no-unsafe-inline-scripts": "error",
46
47
  "astro/no-unused-define-vars-in-style": "error",
47
- "astro/valid-compile": "error"
48
+ "astro/valid-compile": "error",
49
+ ...extractedOptions?.overrides
48
50
  }
49
51
  },
50
52
  {
@@ -55,7 +57,7 @@ async function astroConfig() {
55
57
  projectService: false
56
58
  } },
57
59
  name: "jimmy.codes/astro/disable-type-checked",
58
- rules: tsConfigs.disableTypeChecked.rules
60
+ rules: tsPlugin.configs.disableTypeChecked.rules
59
61
  },
60
62
  {
61
63
  name: "jimmy.codes/astro/imports",
package/dist/index.d.mts CHANGED
@@ -14053,6 +14053,7 @@ type PerfectionistSortVariableDeclarations = [] | [{
14053
14053
  // ----- playwright/expect-expect -----
14054
14054
  type PlaywrightExpectExpect = [] | [{
14055
14055
  assertFunctionNames?: [] | [string];
14056
+ assertFunctionPatterns?: [] | [string];
14056
14057
  }];
14057
14058
  // ----- playwright/max-expects -----
14058
14059
  type PlaywrightMaxExpects = [] | [{
@@ -15018,6 +15019,9 @@ type Base = Linter.Config<Linter.RulesRecord & Rules>;
15018
15019
  type MaybeReadonly<T> = Readonly<T> | T;
15019
15020
  type Override<T, R> = Omit<T, keyof R> & R;
15020
15021
  type Prettify<T> = { [K in keyof T]: T[K] } & {};
15022
+ type ExtractPrefix<T> = T extends `${infer Prefix}/${infer Rest}` ? Rest extends `${string}/${string}` ? `${Prefix}/${ExtractPrefix<Rest>}` : Prefix : never;
15023
+ type ValidPrefixes<T> = ExtractPrefix<keyof T>;
15024
+ type RulesWithPrefix<T, Prefix$1 extends ValidPrefixes<T>> = { [K in keyof T as K extends `${Prefix$1}${string}` ? K : never]: T[K] };
15021
15025
  interface LinterConfigOverrides {
15022
15026
  files?: MaybeReadonly<Base["files"]>;
15023
15027
  ignores?: MaybeReadonly<Base["ignores"]>;
@@ -15035,6 +15039,10 @@ interface VitestOptions {
15035
15039
  * @default 'either'
15036
15040
  */
15037
15041
  globals?: "either" | "explicit" | "implicit";
15042
+ /**
15043
+ * Additional rules to override Vitest defaults.
15044
+ */
15045
+ overrides?: RulesWithPrefix<RuleOptions, "vitest">;
15038
15046
  /**
15039
15047
  * Indicate whether [Vitest's type testing utilities](https://vitest.dev/guide/testing-types.html) are being used.
15040
15048
  *
@@ -15049,14 +15057,69 @@ interface TypeScriptOptions {
15049
15057
  * @default false
15050
15058
  */
15051
15059
  erasableSyntaxOnly?: boolean;
15060
+ /**
15061
+ * Additional rules to override TypeScript defaults.
15062
+ */
15063
+ overrides?: RulesWithPrefix<RuleOptions, "@typescript-eslint" | "erasable-syntax-only">;
15064
+ }
15065
+ interface AstroOptions {
15066
+ /**
15067
+ * Additional rules to override Astro defaults.
15068
+ */
15069
+ overrides?: RulesWithPrefix<RuleOptions, "astro" | "jsx-a11y">;
15070
+ }
15071
+ interface JestOptions {
15072
+ /**
15073
+ * Additional rules to override Jest defaults.
15074
+ */
15075
+ overrides?: RulesWithPrefix<RuleOptions, "jest">;
15076
+ }
15077
+ interface NextJSOptions {
15078
+ /**
15079
+ * Additional rules to override Next.js defaults.
15080
+ */
15081
+ overrides?: RulesWithPrefix<RuleOptions, "@next/next">;
15082
+ }
15083
+ interface PlaywrightOptions {
15084
+ /**
15085
+ * Additional rules to override Playwright defaults.
15086
+ */
15087
+ overrides?: RulesWithPrefix<RuleOptions, "playwright">;
15088
+ }
15089
+ interface ReactOptions {
15090
+ /**
15091
+ * Additional rules to override React defaults.
15092
+ */
15093
+ overrides?: RulesWithPrefix<RuleOptions, "jsx-a11y" | "react-compiler" | "react-dom" | "react-hooks" | "react-hooks-extra" | "react-naming-convention" | "react-refresh" | "react-web-api" | "react-x">;
15094
+ }
15095
+ interface StorybookOptions {
15096
+ /**
15097
+ * Additional rules to override Storybook defaults.
15098
+ */
15099
+ overrides?: RulesWithPrefix<RuleOptions, "storybook">;
15100
+ }
15101
+ interface TanstackQueryOptions {
15102
+ /**
15103
+ * Additional rules to override TanStack Query defaults.
15104
+ */
15105
+ overrides?: RulesWithPrefix<RuleOptions, "@tanstack/query">;
15106
+ }
15107
+ interface TestingLibraryOptions {
15108
+ /**
15109
+ * Additional rules to override Testing Library defaults.
15110
+ */
15111
+ overrides?: RulesWithPrefix<RuleOptions, "jest-dom" | "testing-library">;
15052
15112
  }
15053
15113
  interface Options {
15054
15114
  /**
15055
- * Are astro rules enabled?
15115
+ * Are Astro rules enabled?
15116
+ *
15117
+ * Pass `true` to enable with defaults, or an `AstroOptions` object
15118
+ * to enable and customize overrides.
15056
15119
  *
15057
15120
  * @default false
15058
15121
  */
15059
- astro?: boolean;
15122
+ astro?: AstroOptions | boolean;
15060
15123
  /**
15061
15124
  * Automatically enables rules based on installed dependencies.
15062
15125
  * For example, if `react` is installed, React-specific rules will be applied.
@@ -15080,15 +15143,21 @@ interface Options {
15080
15143
  /**
15081
15144
  * Are Jest rules enabled?
15082
15145
  *
15146
+ * Pass `true` to enable with defaults, or an `JestOptions` object
15147
+ * to enable and customize overrides.
15148
+ *
15083
15149
  * @default false
15084
15150
  */
15085
- jest?: boolean;
15151
+ jest?: boolean | JestOptions;
15086
15152
  /**
15087
15153
  * Are Next.js rules enabled?
15088
15154
  *
15155
+ * Pass `true` to enable with defaults, or a `NextJSOptions` object
15156
+ * to enable and customize overrides.
15157
+ *
15089
15158
  * @default false
15090
15159
  */
15091
- nextjs?: boolean;
15160
+ nextjs?: boolean | NextJSOptions;
15092
15161
  /**
15093
15162
  * Additional configs to extend or override rules.
15094
15163
  * Accepts ESLint configuration objects.
@@ -15099,42 +15168,63 @@ interface Options {
15099
15168
  /**
15100
15169
  * Are playwright rules enabled?
15101
15170
  *
15171
+ * Pass `true` to enable with defaults, or a `PlaywrightOptions` object
15172
+ * to enable and customize overrides.
15173
+ *
15102
15174
  * @default false
15103
15175
  */
15104
- playwright?: boolean;
15176
+ playwright?: boolean | PlaywrightOptions;
15105
15177
  /**
15106
15178
  * Are React rules enabled?
15107
15179
  *
15180
+ * Pass `true` to enable with defaults, or a `ReactOptions` object
15181
+ * to enable and customize overrides.
15182
+ *
15108
15183
  * @default false
15109
15184
  */
15110
- react?: boolean;
15185
+ react?: boolean | ReactOptions;
15111
15186
  /**
15112
15187
  * Are Storybook rules enabled?
15113
15188
  *
15189
+ * Pass `true` to enable with defaults, or a `StorybookOptions` object
15190
+ * to enable and customize overrides.
15191
+ *
15114
15192
  * @default false
15115
15193
  */
15116
- storybook?: boolean;
15194
+ storybook?: boolean | StorybookOptions;
15117
15195
  /**
15118
15196
  * Are TanStack Query rules enabled?
15119
15197
  *
15198
+ * Pass `true` to enable with defaults, or a `TanstackQueryOptions` object
15199
+ * to enable and customize overrides.
15200
+ *
15120
15201
  * @default false
15121
15202
  */
15122
- tanstackQuery?: boolean;
15203
+ tanstackQuery?: boolean | TanstackQueryOptions;
15123
15204
  /**
15124
15205
  * Are Testing Library rules enabled?
15125
15206
  *
15207
+ * Pass `true` to enable with defaults, or a `TestingLibraryOptions` object
15208
+ * to enable and customize overrides.
15209
+ *
15126
15210
  * @default false
15127
15211
  */
15128
- testingLibrary?: boolean;
15212
+ testingLibrary?: boolean | TestingLibraryOptions;
15129
15213
  /**
15130
15214
  * Are TypeScript rules enabled?
15131
15215
  *
15216
+ * Pass `true` to enable with defaults, or a `TypeScriptOptions` object
15217
+ * to enable and customize overrides.
15218
+ *
15132
15219
  * @default false
15133
15220
  */
15134
15221
  typescript?: boolean | TypeScriptOptions;
15135
15222
  /**
15136
15223
  * Are Vitest rules enabled?
15137
15224
  *
15225
+ * Pass `true` to enable with defaults, or a `VitestOptions` object
15226
+ * to enable and customize overrides.
15227
+ *
15138
15228
  * @default false
15139
15229
  */
15140
15230
  vitest?: boolean | VitestOptions;
@@ -15168,4 +15258,4 @@ declare const defineConfig: ({
15168
15258
  vitest
15169
15259
  }?: Options, ...moreOverrides: Linter.Config[] | TypedConfigItem[]) => Promise<any[]>;
15170
15260
  //#endregion
15171
- export { type Options, type TypedConfigItem, type VitestOptions, defineConfig };
15261
+ export { type AstroOptions, type JestOptions, type NextJSOptions, type Options, type PlaywrightOptions, type ReactOptions, type StorybookOptions, type TanstackQueryOptions as TanStackQueryOptions, type TestingLibraryOptions, type TypeScriptOptions, type TypedConfigItem, type VitestOptions, defineConfig };
package/dist/index.mjs CHANGED
@@ -504,16 +504,16 @@ const defineConfig = async ({ astro = false, autoDetect = true, gitignore = fals
504
504
  stylisticConfig()
505
505
  ];
506
506
  const featureConfigs = await Promise.all([
507
- isTypescriptEnabled && unwrap(import("./typescript-1X7EkO5M.mjs"), typescript),
508
- isReactEnabled && unwrap(import("./react-DY8zODCu.mjs")),
509
- isTanstackQueryEnabled && unwrap(import("./tanstack-query-DG6a41GH.mjs")),
510
- isAstroEnabled && unwrap(import("./astro-DNtOkeq5.mjs")),
511
- isJestEnabled && unwrap(import("./jest-DgTHyrfz.mjs")),
512
- isVitestEnabled && unwrap(import("./vitest-YdRMuvTR.mjs"), vitest),
513
- isTestingLibraryEnabled && unwrap(import("./testing-library-oE675dT3.mjs")),
514
- isPlaywrightEnabled && unwrap(import("./playwright-CM4et1Wx.mjs")),
515
- isStorybookEnabled && unwrap(import("./storybook-CyxpG33Q.mjs")),
516
- isNextjsEnabled && unwrap(import("./nextjs-VPeisXpq.mjs"))
507
+ isTypescriptEnabled && unwrap(import("./typescript-iybUcKhp.mjs"), typescript),
508
+ isReactEnabled && unwrap(import("./react-aPiplRN9.mjs"), react),
509
+ isTanstackQueryEnabled && unwrap(import("./tanstack-query-Dp8U2t8w.mjs"), tanstackQuery),
510
+ isAstroEnabled && unwrap(import("./astro-_OthZH0C.mjs"), astro),
511
+ isJestEnabled && unwrap(import("./jest-BxCbmb4w.mjs"), jest),
512
+ isVitestEnabled && unwrap(import("./vitest-DyQ5YML1.mjs"), vitest),
513
+ isTestingLibraryEnabled && unwrap(import("./testing-library-CQkPs8CJ.mjs"), testingLibrary),
514
+ isPlaywrightEnabled && unwrap(import("./playwright-CB73AGjW.mjs"), playwright),
515
+ isStorybookEnabled && unwrap(import("./storybook-CgfIOzEK.mjs"), storybook),
516
+ isNextjsEnabled && unwrap(import("./nextjs-Bp3ln3PT.mjs"), nextjs)
517
517
  ]);
518
518
  return [
519
519
  ...gitignore ? [gitignoreConfig({ strict: false })] : [],
@@ -1,3 +1,16 @@
1
+ //#region src/utils/extract-options.ts
2
+ /**
3
+ * A simple utility to derive options for configurations when one option is a boolean.
4
+ *
5
+ * @param options - The options to derive.
6
+ *
7
+ * @returns The extracted options or `undefined` if the input was a boolean.
8
+ */
9
+ const extractOptions = (options) => {
10
+ if (typeof options !== "boolean") return options;
11
+ };
12
+
13
+ //#endregion
1
14
  //#region src/utils/interop-default.ts
2
15
  /**
3
16
  * Utility to safely fetch an imported `ESLint` plugin.
@@ -14,4 +27,4 @@ const interopDefault = async (module) => {
14
27
  };
15
28
 
16
29
  //#endregion
17
- export { interopDefault as t };
30
+ export { extractOptions as n, interopDefault as t };
@@ -1,8 +1,8 @@
1
1
  import { l as GLOB_TESTS, r as GLOB_E2E } from "./globs-uKx5b8lV.mjs";
2
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
2
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
3
3
 
4
4
  //#region src/rules/jest.ts
5
- const jestRules = async () => {
5
+ const jestRules = async (options) => {
6
6
  const jestPlugin = await interopDefault(import("eslint-plugin-jest"));
7
7
  return {
8
8
  ...jestPlugin.configs["flat/recommended"].rules,
@@ -43,19 +43,21 @@ const jestRules = async () => {
43
43
  "jest/require-to-throw-message": "error",
44
44
  "jest/require-top-level-describe": "off",
45
45
  "jest/unbound-method": "off",
46
- "jest/valid-title": ["error", { mustMatch: { it: "^should" } }]
46
+ "jest/valid-title": ["error", { mustMatch: { it: "^should" } }],
47
+ ...options?.overrides
47
48
  };
48
49
  };
49
50
 
50
51
  //#endregion
51
52
  //#region src/configs/jest.ts
52
- async function jestConfig() {
53
+ async function jestConfig(options) {
54
+ const extractedOptions = extractOptions(options);
53
55
  return [{
54
56
  files: GLOB_TESTS,
55
57
  ignores: GLOB_E2E,
56
58
  ...(await interopDefault(import("eslint-plugin-jest"))).configs["flat/recommended"],
57
59
  name: "jimmy.codes/jest",
58
- rules: await jestRules()
60
+ rules: await jestRules(extractedOptions)
59
61
  }];
60
62
  }
61
63
 
@@ -0,0 +1,27 @@
1
+ import { s as GLOB_NEXTJS } from "./globs-uKx5b8lV.mjs";
2
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
3
+ import { t as upwarn } from "./upwarn-BWFMaOyK.mjs";
4
+
5
+ //#region src/rules/nextjs.ts
6
+ const nextjsRules = async (options) => {
7
+ return {
8
+ ...upwarn((await interopDefault(import("@next/eslint-plugin-next"))).configs.recommended.rules),
9
+ ...options?.overrides
10
+ };
11
+ };
12
+
13
+ //#endregion
14
+ //#region src/configs/nextjs.ts
15
+ async function nextjsConfig(options) {
16
+ const extractedOptions = extractOptions(options);
17
+ const nextjsPlugin = await interopDefault(import("@next/eslint-plugin-next"));
18
+ return [{
19
+ files: GLOB_NEXTJS,
20
+ name: "jimmy.codes/nextjs",
21
+ plugins: { "@next/next": nextjsPlugin },
22
+ rules: await nextjsRules(extractedOptions)
23
+ }];
24
+ }
25
+
26
+ //#endregion
27
+ export { nextjsConfig as default };
@@ -1,8 +1,8 @@
1
1
  import { c as GLOB_PLAYWRIGHT } from "./globs-uKx5b8lV.mjs";
2
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
2
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
3
3
 
4
4
  //#region src/rules/playwright.ts
5
- const playwrightRules = async () => {
5
+ const playwrightRules = async (options) => {
6
6
  return {
7
7
  ...(await interopDefault(import("eslint-plugin-playwright"))).configs["flat/recommended"].rules,
8
8
  "playwright/expect-expect": "error",
@@ -27,18 +27,20 @@ const playwrightRules = async () => {
27
27
  "playwright/prefer-to-have-count": "error",
28
28
  "playwright/prefer-to-have-length": "error",
29
29
  "playwright/require-to-throw-message": "error",
30
- "playwright/valid-title": "off"
30
+ "playwright/valid-title": "off",
31
+ ...options?.overrides
31
32
  };
32
33
  };
33
34
 
34
35
  //#endregion
35
36
  //#region src/configs/playwright.ts
36
- async function playwrightConfig() {
37
+ async function playwrightConfig(options) {
38
+ const extractedOptions = extractOptions(options);
37
39
  return [{
38
40
  ...(await interopDefault(import("eslint-plugin-playwright"))).configs["flat/recommended"],
39
41
  files: GLOB_PLAYWRIGHT,
40
42
  name: "jimmy.codes/playwright",
41
- rules: await playwrightRules()
43
+ rules: await playwrightRules(extractedOptions)
42
44
  }];
43
45
  }
44
46
 
@@ -1,6 +1,6 @@
1
1
  import { d as GLOB_TSX, o as GLOB_JSX } from "./globs-uKx5b8lV.mjs";
2
2
  import { l as hasTypescript, r as hasNext, u as hasVite } from "./has-dependency-BreXO1rF.mjs";
3
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
3
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
4
4
  import { t as upwarn } from "./upwarn-BWFMaOyK.mjs";
5
5
  import globals from "globals";
6
6
 
@@ -20,7 +20,7 @@ const nextAllowedExportNames = [
20
20
  "viewport",
21
21
  "generateViewport"
22
22
  ];
23
- const reactRules = async () => {
23
+ const reactRules = async (options) => {
24
24
  const [{ configs: reactConfigs }, { flatConfigs: jsxA11yConfigs }, { configs: reactDomConfigs }, { configs: reactHooksExtraConfigs }, { configs: reactWebApiConfigs }, { configs: reactNamingConventionConfigs }] = await Promise.all([
25
25
  interopDefault(import("eslint-plugin-react-x")),
26
26
  interopDefault(import("eslint-plugin-jsx-a11y")),
@@ -76,13 +76,15 @@ const reactRules = async () => {
76
76
  "react-x/jsx-shorthand-boolean": "error",
77
77
  "react-x/jsx-shorthand-fragment": "error",
78
78
  "react-x/no-missing-context-display-name": "error",
79
- "react-x/prefer-namespace-import": "error"
79
+ "react-x/prefer-namespace-import": "error",
80
+ ...options?.overrides
80
81
  };
81
82
  };
82
83
 
83
84
  //#endregion
84
85
  //#region src/configs/react.ts
85
- async function reactConfig() {
86
+ async function reactConfig(options) {
87
+ const extractedOptions = extractOptions(options);
86
88
  const [reactPlugin, jsxA11yPlugin, reactHooksPlugin, reactRefreshPlugin, reactCompilerPlugin, reactHooksExtraPlugin, reactDomPlugin, reactWebApiPlugin, reactNamingConventionPlugin] = await Promise.all([
87
89
  interopDefault(import("eslint-plugin-react-x")),
88
90
  interopDefault(import("eslint-plugin-jsx-a11y")),
@@ -115,7 +117,7 @@ async function reactConfig() {
115
117
  "react-web-api": reactWebApiPlugin,
116
118
  "react-x": reactPlugin
117
119
  },
118
- rules: await reactRules(),
120
+ rules: await reactRules(extractedOptions),
119
121
  settings: { react: { version: "detect" } }
120
122
  }];
121
123
  }
@@ -1,8 +1,9 @@
1
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
1
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
2
2
  import { t as upwarn } from "./upwarn-BWFMaOyK.mjs";
3
3
 
4
4
  //#region src/configs/storybook.ts
5
- async function storybookConfig() {
5
+ async function storybookConfig(options) {
6
+ const extractedOptions = extractOptions(options);
6
7
  const { configs } = await interopDefault(import("eslint-plugin-storybook"));
7
8
  const [setup, storiesConfig, mainConfig] = configs["flat/recommended"];
8
9
  return [
@@ -17,7 +18,8 @@ async function storybookConfig() {
17
18
  ...upwarn(storiesConfig?.rules),
18
19
  "import-x/no-anonymous-default-export": "off",
19
20
  "storybook/meta-satisfies-type": "error",
20
- "unicorn/no-anonymous-default-export": "off"
21
+ "unicorn/no-anonymous-default-export": "off",
22
+ ...extractedOptions?.overrides
21
23
  }
22
24
  },
23
25
  {
@@ -1,8 +1,9 @@
1
1
  import { d as GLOB_TSX, o as GLOB_JSX } from "./globs-uKx5b8lV.mjs";
2
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
2
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
3
3
 
4
4
  //#region src/configs/tanstack-query.ts
5
- async function tanstackQueryConfig() {
5
+ async function tanstackQueryConfig(options) {
6
+ const extractedOptions = extractOptions(options);
6
7
  const queryPlugin = await interopDefault(import("@tanstack/eslint-plugin-query"));
7
8
  return [{
8
9
  files: [GLOB_JSX, GLOB_TSX],
@@ -15,7 +16,8 @@ async function tanstackQueryConfig() {
15
16
  "@tanstack/query/no-rest-destructuring": "error",
16
17
  "@tanstack/query/no-unstable-deps": "error",
17
18
  "@tanstack/query/no-void-query-fn": "error",
18
- "@tanstack/query/stable-query-client": "error"
19
+ "@tanstack/query/stable-query-client": "error",
20
+ ...extractedOptions?.overrides
19
21
  }
20
22
  }];
21
23
  }
@@ -1,19 +1,21 @@
1
1
  import { l as GLOB_TESTS, r as GLOB_E2E } from "./globs-uKx5b8lV.mjs";
2
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
2
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
3
3
 
4
4
  //#region src/rules/testing-library.ts
5
- const testingLibraryRules = async () => {
5
+ const testingLibraryRules = async (options) => {
6
6
  const [jestDom, testingLibrary] = await Promise.all([import("eslint-plugin-jest-dom"), interopDefault(import("eslint-plugin-testing-library"))]);
7
7
  return {
8
8
  ...testingLibrary.configs["flat/react"].rules,
9
9
  ...jestDom.configs["flat/recommended"].rules,
10
- "testing-library/no-test-id-queries": "error"
10
+ "testing-library/no-test-id-queries": "error",
11
+ ...options?.overrides
11
12
  };
12
13
  };
13
14
 
14
15
  //#endregion
15
16
  //#region src/configs/testing-library.ts
16
- async function testingLibraryConfig() {
17
+ async function testingLibraryConfig(options) {
18
+ const extractedOptions = extractOptions(options);
17
19
  const [jestDom, testingLibrary] = await Promise.all([import("eslint-plugin-jest-dom"), interopDefault(import("eslint-plugin-testing-library"))]);
18
20
  return [{
19
21
  files: GLOB_TESTS,
@@ -23,7 +25,7 @@ async function testingLibraryConfig() {
23
25
  "jest-dom": jestDom,
24
26
  "testing-library": testingLibrary
25
27
  },
26
- rules: await testingLibraryRules()
28
+ rules: await testingLibraryRules(extractedOptions)
27
29
  }];
28
30
  }
29
31
 
@@ -1,38 +1,40 @@
1
1
  import { a as GLOB_JS, l as GLOB_TESTS, o as GLOB_JSX } from "./globs-uKx5b8lV.mjs";
2
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
3
- import { t as extractOptions } from "./extract-options-mq3SNxbU.mjs";
2
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
4
3
 
5
4
  //#region src/rules/typescript.ts
6
5
  const disabledEslintRules = {
7
6
  "no-unused-private-class-members": "off",
8
7
  "no-use-before-define": "off"
9
8
  };
10
- const typescriptRules = {
11
- ...disabledEslintRules,
12
- "@typescript-eslint/consistent-type-exports": ["error", { fixMixedExportsWithInlineTypeSpecifier: false }],
13
- "@typescript-eslint/consistent-type-imports": ["error", { fixStyle: "separate-type-imports" }],
14
- "@typescript-eslint/no-deprecated": "warn",
15
- "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: { attributes: false } }],
16
- "@typescript-eslint/no-unnecessary-type-conversion": "error",
17
- "@typescript-eslint/no-unused-private-class-members": "error",
18
- "@typescript-eslint/no-unused-vars": ["error", {
19
- args: "all",
20
- argsIgnorePattern: "^_",
21
- caughtErrors: "all",
22
- caughtErrorsIgnorePattern: "^_",
23
- destructuredArrayIgnorePattern: "^_",
24
- ignoreRestSiblings: true,
25
- varsIgnorePattern: "^_"
26
- }],
27
- "@typescript-eslint/no-use-before-define": ["error", {
28
- allowNamedExports: false,
29
- classes: false,
30
- functions: false,
31
- variables: true
32
- }],
33
- "@typescript-eslint/no-useless-empty-export": "error",
34
- "@typescript-eslint/restrict-template-expressions": ["error", { allowNumber: true }],
35
- "@typescript-eslint/switch-exhaustiveness-check": "error"
9
+ const typescriptRules = (options) => {
10
+ return {
11
+ ...disabledEslintRules,
12
+ "@typescript-eslint/consistent-type-exports": ["error", { fixMixedExportsWithInlineTypeSpecifier: false }],
13
+ "@typescript-eslint/consistent-type-imports": ["error", { fixStyle: "separate-type-imports" }],
14
+ "@typescript-eslint/no-deprecated": "warn",
15
+ "@typescript-eslint/no-misused-promises": ["error", { checksVoidReturn: { attributes: false } }],
16
+ "@typescript-eslint/no-unnecessary-type-conversion": "error",
17
+ "@typescript-eslint/no-unused-private-class-members": "error",
18
+ "@typescript-eslint/no-unused-vars": ["error", {
19
+ args: "all",
20
+ argsIgnorePattern: "^_",
21
+ caughtErrors: "all",
22
+ caughtErrorsIgnorePattern: "^_",
23
+ destructuredArrayIgnorePattern: "^_",
24
+ ignoreRestSiblings: true,
25
+ varsIgnorePattern: "^_"
26
+ }],
27
+ "@typescript-eslint/no-use-before-define": ["error", {
28
+ allowNamedExports: false,
29
+ classes: false,
30
+ functions: false,
31
+ variables: true
32
+ }],
33
+ "@typescript-eslint/no-useless-empty-export": "error",
34
+ "@typescript-eslint/restrict-template-expressions": ["error", { allowNumber: true }],
35
+ "@typescript-eslint/switch-exhaustiveness-check": "error",
36
+ ...options?.overrides
37
+ };
36
38
  };
37
39
 
38
40
  //#endregion
@@ -51,7 +53,7 @@ async function typescriptConfig(options) {
51
53
  tsconfigRootDir: process.cwd()
52
54
  } },
53
55
  name: "jimmy.codes/typescript",
54
- rules: typescriptRules
56
+ rules: typescriptRules(extractedOptions)
55
57
  },
56
58
  {
57
59
  files: [GLOB_JS, GLOB_JSX],
@@ -1,6 +1,5 @@
1
1
  import { f as GLOB_TYPE_TESTS, l as GLOB_TESTS, r as GLOB_E2E } from "./globs-uKx5b8lV.mjs";
2
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
3
- import { t as extractOptions } from "./extract-options-mq3SNxbU.mjs";
2
+ import { n as extractOptions, t as interopDefault } from "./interop-default-CKeWA-H9.mjs";
4
3
 
5
4
  //#region src/rules/vitest.ts
6
5
  const vitestRules = async (options) => {
@@ -58,7 +57,8 @@ const vitestRules = async (options) => {
58
57
  "vitest/require-to-throw-message": "error",
59
58
  "vitest/require-top-level-describe": "off",
60
59
  "vitest/valid-title": ["error", { mustMatch: { it: "^should" } }],
61
- "vitest/warn-todo": "warn"
60
+ "vitest/warn-todo": "warn",
61
+ ...options?.overrides
62
62
  };
63
63
  };
64
64
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jimmy.codes/eslint-config",
3
- "version": "6.24.0",
3
+ "version": "6.25.0",
4
4
  "description": "A simple, modern ESLint config that covers most use cases.",
5
5
  "keywords": [
6
6
  "eslint",
@@ -41,13 +41,13 @@
41
41
  "dependencies": {
42
42
  "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
43
43
  "@eslint/js": "^9.39.1",
44
- "@next/eslint-plugin-next": "^16.0.4",
44
+ "@next/eslint-plugin-next": "^16.0.6",
45
45
  "@stylistic/eslint-plugin": "^5.6.1",
46
46
  "@tanstack/eslint-plugin-query": "^5.91.2",
47
47
  "@types/eslint": "9.6.1",
48
48
  "@typescript-eslint/parser": "^8.48.0",
49
49
  "@typescript-eslint/utils": "^8.48.0",
50
- "@vitest/eslint-plugin": "^1.5.0",
50
+ "@vitest/eslint-plugin": "^1.5.1",
51
51
  "astro-eslint-parser": "^1.2.2",
52
52
  "eslint-config-flat-gitignore": "^2.1.0",
53
53
  "eslint-config-prettier": "^10.1.8",
@@ -62,7 +62,7 @@
62
62
  "eslint-plugin-jsx-a11y": "^6.10.2",
63
63
  "eslint-plugin-n": "^17.23.1",
64
64
  "eslint-plugin-perfectionist": "^4.15.1",
65
- "eslint-plugin-playwright": "^2.3.0",
65
+ "eslint-plugin-playwright": "^2.4.0",
66
66
  "eslint-plugin-react-compiler": "19.1.0-rc.2",
67
67
  "eslint-plugin-react-dom": "^2.3.9",
68
68
  "eslint-plugin-react-hooks": "^7.0.1",
@@ -1,14 +0,0 @@
1
- //#region src/utils/extract-options.ts
2
- /**
3
- * A simple utility to derive options for configurations when one option is a boolean.
4
- *
5
- * @param options - The options to derive.
6
- *
7
- * @returns The extracted options or `undefined` if the input was a boolean.
8
- */
9
- const extractOptions = (options) => {
10
- if (typeof options !== "boolean") return options;
11
- };
12
-
13
- //#endregion
14
- export { extractOptions as t };
@@ -1,23 +0,0 @@
1
- import { s as GLOB_NEXTJS } from "./globs-uKx5b8lV.mjs";
2
- import { t as interopDefault } from "./interop-default-Bn64p66u.mjs";
3
- import { t as upwarn } from "./upwarn-BWFMaOyK.mjs";
4
-
5
- //#region src/rules/nextjs.ts
6
- const nextjsRules = async () => {
7
- return upwarn((await interopDefault(import("@next/eslint-plugin-next"))).configs.recommended.rules);
8
- };
9
-
10
- //#endregion
11
- //#region src/configs/nextjs.ts
12
- async function nextjsConfig() {
13
- const nextjsPlugin = await interopDefault(import("@next/eslint-plugin-next"));
14
- return [{
15
- files: GLOB_NEXTJS,
16
- name: "jimmy.codes/nextjs",
17
- plugins: { "@next/next": nextjsPlugin },
18
- rules: await nextjsRules()
19
- }];
20
- }
21
-
22
- //#endregion
23
- export { nextjsConfig as default };