js-style-kit 0.6.1 → 0.7.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.
Files changed (64) hide show
  1. package/README.md +5 -0
  2. package/dist/index.d.ts +11 -5
  3. package/dist/index.js +48 -7
  4. package/dist/index.js.map +1 -1
  5. package/package.json +8 -5
  6. package/src/eslint/base/README.md +186 -0
  7. package/src/eslint/base/config.ts +37 -0
  8. package/src/eslint/base/rules.ts +444 -0
  9. package/src/eslint/base/types.ts +20 -0
  10. package/src/eslint/constants.ts +52 -0
  11. package/src/eslint/convex/README.md +30 -0
  12. package/src/eslint/convex/config.ts +34 -0
  13. package/src/eslint/convex/rules.ts +8 -0
  14. package/src/eslint/convex/types.ts +8 -0
  15. package/src/eslint/ignores.ts +31 -0
  16. package/src/eslint/import/README.md +397 -0
  17. package/src/eslint/import/config.ts +48 -0
  18. package/src/eslint/import/rules.ts +81 -0
  19. package/src/eslint/index.ts +259 -0
  20. package/src/eslint/jsdoc/README.md +399 -0
  21. package/src/eslint/jsdoc/config.ts +29 -0
  22. package/src/eslint/jsdoc/rules.ts +81 -0
  23. package/src/eslint/jsdoc/types.ts +56 -0
  24. package/src/eslint/nextjs/config.ts +25 -0
  25. package/src/eslint/nextjs/rules.ts +25 -0
  26. package/src/eslint/nextjs/types.ts +27 -0
  27. package/src/eslint/perfectionist/README.md +454 -0
  28. package/src/eslint/perfectionist/config.ts +25 -0
  29. package/src/eslint/perfectionist/rules.ts +39 -0
  30. package/src/eslint/prefer-arrow-function/config.ts +33 -0
  31. package/src/eslint/prefer-arrow-function/types.ts +13 -0
  32. package/src/eslint/process-custom-rules.ts +72 -0
  33. package/src/eslint/query/README.md +254 -0
  34. package/src/eslint/query/config.ts +27 -0
  35. package/src/eslint/query/rules.ts +11 -0
  36. package/src/eslint/query/types.ts +11 -0
  37. package/src/eslint/react/README.md +416 -0
  38. package/src/eslint/react/config.ts +65 -0
  39. package/src/eslint/react/rules.ts +188 -0
  40. package/src/eslint/react/types.ts +26 -0
  41. package/src/eslint/react-refresh/config.ts +28 -0
  42. package/src/eslint/react-refresh/rules.ts +48 -0
  43. package/src/eslint/storybook/README.md +424 -0
  44. package/src/eslint/storybook/config.ts +57 -0
  45. package/src/eslint/testing/README.md +436 -0
  46. package/src/eslint/testing/config.ts +90 -0
  47. package/src/eslint/testing/jest-rules.ts +47 -0
  48. package/src/eslint/testing/vitest-rules.ts +42 -0
  49. package/src/eslint/turbo/README.md +380 -0
  50. package/src/eslint/turbo/config.ts +26 -0
  51. package/src/eslint/turbo/types.ts +7 -0
  52. package/src/eslint/types.ts +29 -0
  53. package/src/eslint/typescript/README.md +229 -0
  54. package/src/eslint/typescript/config.ts +48 -0
  55. package/src/eslint/typescript/rules.ts +137 -0
  56. package/src/eslint/typescript/types.ts +35 -0
  57. package/src/eslint/unicorn/README.md +497 -0
  58. package/src/eslint/unicorn/config.ts +36 -0
  59. package/src/eslint/unicorn/rules.ts +86 -0
  60. package/src/index.ts +3 -0
  61. package/src/modules.d.ts +5 -0
  62. package/src/prettier/README.md +413 -0
  63. package/src/prettier/index.ts +110 -0
  64. package/src/utils/is-type.ts +60 -0
@@ -0,0 +1,380 @@
1
+ # Turbo Configuration
2
+
3
+ ESLint rules for Turborepo monorepos to catch common configuration issues.
4
+
5
+ [← Back to main README](../../../README.md)
6
+
7
+ ## Overview
8
+
9
+ Turbo configuration is **disabled by default** and provides:
10
+
11
+ - Environment variable validation
12
+ - Turborepo configuration best practices
13
+ - Monorepo-specific linting
14
+
15
+ ## Quick Start
16
+
17
+ ```js
18
+ import { eslintConfig } from "js-style-kit";
19
+
20
+ export default eslintConfig({
21
+ turbo: true, // Enable Turborepo rules
22
+ });
23
+ ```
24
+
25
+ ## Key Features
26
+
27
+ ### Environment Variable Declaration
28
+
29
+ Ensures all environment variables used in your code are properly declared in Turborepo configuration:
30
+
31
+ ```ts
32
+ // turbo.json
33
+ {
34
+ "tasks": {
35
+ "build": {
36
+ "env": ["NODE_ENV", "API_URL"]
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ ```ts
43
+ // ✅ Good - declared in turbo.json
44
+ const apiUrl = process.env.API_URL;
45
+ const nodeEnv = process.env.NODE_ENV;
46
+
47
+ // ❌ Bad - not declared in turbo.json
48
+ const secretKey = process.env.SECRET_KEY; // Warning!
49
+ ```
50
+
51
+ **Rule:**
52
+
53
+ - `turbo/no-undeclared-env-vars` - Ensures env vars are declared in `turbo.json`
54
+
55
+ **Why this matters:**
56
+
57
+ - Turborepo needs to know about env vars for proper caching
58
+ - Undeclared env vars can cause cache invalidation issues
59
+ - Makes dependencies explicit and trackable
60
+
61
+ ## How It Works
62
+
63
+ The rule checks your `turbo.json` configuration and validates that any environment variables accessed in your code are listed in the appropriate task's `env` array.
64
+
65
+ ### Project-Level Configuration
66
+
67
+ ```json
68
+ // turbo.json
69
+ {
70
+ "tasks": {
71
+ "build": {
72
+ "env": [
73
+ "NODE_ENV",
74
+ "API_URL",
75
+ "NEXT_PUBLIC_*" // Wildcard pattern
76
+ ]
77
+ },
78
+ "dev": {
79
+ "cache": false,
80
+ "env": ["NODE_ENV"]
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ ### Global Environment Variables
87
+
88
+ ```json
89
+ // turbo.json
90
+ {
91
+ "globalEnv": ["CI", "VERCEL"],
92
+ "tasks": {
93
+ "build": {
94
+ "env": ["API_URL"]
95
+ }
96
+ }
97
+ }
98
+ ```
99
+
100
+ ## Examples
101
+
102
+ ### Valid Usage
103
+
104
+ ```ts
105
+ // turbo.json has: { "tasks": { "build": { "env": ["API_URL", "DB_HOST"] } } }
106
+
107
+ // ✅ Good - all declared
108
+ export const config = {
109
+ apiUrl: process.env.API_URL,
110
+ dbHost: process.env.DB_HOST,
111
+ };
112
+
113
+ // ✅ Good - using wildcard pattern
114
+ // turbo.json has: { "env": ["NEXT_PUBLIC_*"] }
115
+ const publicKey = process.env.NEXT_PUBLIC_API_KEY;
116
+ ```
117
+
118
+ ### Invalid Usage
119
+
120
+ ```ts
121
+ // turbo.json has: { "tasks": { "build": { "env": ["API_URL"] } } }
122
+
123
+ // ❌ Bad - SECRET_KEY not declared
124
+ const config = {
125
+ apiUrl: process.env.API_URL,
126
+ secret: process.env.SECRET_KEY, // Warning!
127
+ };
128
+ ```
129
+
130
+ ### Fixing the Issue
131
+
132
+ Add missing env vars to `turbo.json`:
133
+
134
+ ```json
135
+ {
136
+ "tasks": {
137
+ "build": {
138
+ "env": ["API_URL", "SECRET_KEY"]
139
+ }
140
+ }
141
+ }
142
+ ```
143
+
144
+ ## Wildcard Patterns
145
+
146
+ Turborepo supports wildcard patterns for environment variables:
147
+
148
+ ```json
149
+ {
150
+ "tasks": {
151
+ "build": {
152
+ "env": [
153
+ "NEXT_PUBLIC_*", // Matches NEXT_PUBLIC_API_URL, etc.
154
+ "VITE_*", // Matches VITE_API_URL, etc.
155
+ "REACT_APP_*" // Matches REACT_APP_VERSION, etc.
156
+ ]
157
+ }
158
+ }
159
+ }
160
+ ```
161
+
162
+ ```ts
163
+ // ✅ All valid with wildcard patterns above
164
+ const apiUrl = process.env.NEXT_PUBLIC_API_URL;
165
+ const appVersion = process.env.REACT_APP_VERSION;
166
+ const viteMode = process.env.VITE_MODE;
167
+ ```
168
+
169
+ ## Common Patterns
170
+
171
+ ### Next.js Monorepo
172
+
173
+ ```json
174
+ // turbo.json
175
+ {
176
+ "globalEnv": ["CI", "NODE_ENV"],
177
+ "tasks": {
178
+ "build": {
179
+ "env": ["NEXT_PUBLIC_*", "DATABASE_URL", "API_SECRET"],
180
+ "outputs": [".next/**", "!.next/cache/**"]
181
+ },
182
+ "dev": {
183
+ "cache": false
184
+ }
185
+ }
186
+ }
187
+ ```
188
+
189
+ ### Multi-Framework Monorepo
190
+
191
+ ```json
192
+ // turbo.json
193
+ {
194
+ "tasks": {
195
+ "build": {
196
+ "env": [
197
+ "NODE_ENV",
198
+ "NEXT_PUBLIC_*", // Next.js apps
199
+ "VITE_*", // Vite apps
200
+ "REACT_APP_*" // CRA apps
201
+ ]
202
+ }
203
+ }
204
+ }
205
+ ```
206
+
207
+ ### Backend Services
208
+
209
+ ```json
210
+ // turbo.json
211
+ {
212
+ "tasks": {
213
+ "build": {
214
+ "env": ["DATABASE_URL", "REDIS_URL", "AWS_*", "STRIPE_SECRET_KEY"]
215
+ },
216
+ "test": {
217
+ "env": ["DATABASE_URL", "TEST_DATABASE_URL"]
218
+ }
219
+ }
220
+ }
221
+ ```
222
+
223
+ ## Customization
224
+
225
+ ### Disable for Specific Files
226
+
227
+ ```js
228
+ export default eslintConfig({
229
+ turbo: true,
230
+ overrides: [
231
+ {
232
+ files: ["scripts/**/*.ts"],
233
+ rules: {
234
+ // Scripts might use env vars not in turbo.json
235
+ "turbo/no-undeclared-env-vars": "off",
236
+ },
237
+ },
238
+ ],
239
+ });
240
+ ```
241
+
242
+ ### Error Instead of Warning
243
+
244
+ ```js
245
+ export default eslintConfig({
246
+ turbo: true,
247
+ rules: {
248
+ // Make undeclared env vars an error
249
+ "turbo/no-undeclared-env-vars": "error",
250
+ },
251
+ });
252
+ ```
253
+
254
+ ### Disable Completely
255
+
256
+ ```js
257
+ export default eslintConfig({
258
+ turbo: true,
259
+ rules: {
260
+ "turbo/no-undeclared-env-vars": "off",
261
+ },
262
+ });
263
+ ```
264
+
265
+ ## Monorepo Structure
266
+
267
+ Typical monorepo using Turborepo:
268
+
269
+ ```
270
+ my-monorepo/
271
+ ├── turbo.json # Turbo configuration
272
+ ├── package.json
273
+ ├── packages/
274
+ │ ├── web/ # Next.js app
275
+ │ │ └── src/
276
+ │ ├── api/ # API service
277
+ │ │ └── src/
278
+ │ └── shared/ # Shared utilities
279
+ │ └── src/
280
+ └── apps/
281
+ └── mobile/ # React Native app
282
+ └── src/
283
+ ```
284
+
285
+ Each package can use environment variables, but they must be declared in the root `turbo.json` or task-specific configuration.
286
+
287
+ ## Environment Variables Best Practices
288
+
289
+ ### 1. Declare All Variables
290
+
291
+ Always declare environment variables in `turbo.json` for proper cache invalidation:
292
+
293
+ ```json
294
+ {
295
+ "tasks": {
296
+ "build": {
297
+ "env": ["ALL", "VARS", "HERE"]
298
+ }
299
+ }
300
+ }
301
+ ```
302
+
303
+ ### 2. Use Wildcards for Prefixes
304
+
305
+ For public/framework-specific variables:
306
+
307
+ ```json
308
+ {
309
+ "tasks": {
310
+ "build": {
311
+ "env": ["NEXT_PUBLIC_*", "VITE_*"]
312
+ }
313
+ }
314
+ }
315
+ ```
316
+
317
+ ### 3. Separate by Task
318
+
319
+ Different tasks can have different env vars:
320
+
321
+ ```json
322
+ {
323
+ "tasks": {
324
+ "build": {
325
+ "env": ["API_URL", "BUILD_ID"]
326
+ },
327
+ "test": {
328
+ "env": ["TEST_DATABASE_URL"]
329
+ }
330
+ }
331
+ }
332
+ ```
333
+
334
+ ### 4. Use Global Env for CI
335
+
336
+ Common variables used everywhere:
337
+
338
+ ```json
339
+ {
340
+ "globalEnv": ["CI", "NODE_ENV", "VERCEL"],
341
+ "tasks": {
342
+ /* ... */
343
+ }
344
+ }
345
+ ```
346
+
347
+ ## Troubleshooting
348
+
349
+ ### Rule not working
350
+
351
+ - Ensure `turbo.json` exists in your project root
352
+ - Check that the env var is being accessed as `process.env.VAR_NAME`
353
+ - Verify the task name matches your `turbo.json` tasks
354
+
355
+ ### Too many warnings
356
+
357
+ - Use wildcard patterns for common prefixes
358
+ - Add frequently-used vars to `globalEnv`
359
+ - Consider disabling for certain files (scripts, config)
360
+
361
+ ### False positives
362
+
363
+ - Dynamic env var access might not be detected correctly:
364
+
365
+ ```ts
366
+ // Might not be caught
367
+ const key = process.env[`DYNAMIC_${name}`];
368
+ ```
369
+
370
+ ## Related Configurations
371
+
372
+ - [Base](../base/README.md) - Base ESLint rules
373
+ - [TypeScript](../typescript/README.md) - TypeScript configuration
374
+
375
+ ## Learn More
376
+
377
+ - [eslint-plugin-turbo](https://github.com/vercel/turbo/tree/main/packages/eslint-plugin-turbo)
378
+ - [Turborepo Documentation](https://turbo.build/repo/docs)
379
+ - [Turborepo Environment Variables](https://turbo.build/repo/docs/core-concepts/caching#environment-variables)
380
+ - [Main README](../../../README.md)
@@ -0,0 +1,26 @@
1
+ import turbo from "eslint-plugin-turbo";
2
+
3
+ import type { EslintConfigObject, EslintRuleConfig } from "../types.js";
4
+ import type { TurboRules } from "./types.js";
5
+
6
+ import { configNames } from "../constants.js";
7
+
8
+ /**
9
+ * Creates an ESLint configuration for Turbo.
10
+ *
11
+ * @param customRules - Optional custom rules to merge with the default Turbo rules.
12
+ * @returns ESLint configuration object for Turbo.
13
+ */
14
+ export const turboConfig = (
15
+ customRules?: Record<string, EslintRuleConfig>,
16
+ ): EslintConfigObject => ({
17
+ name: configNames.turbo,
18
+ plugins: {
19
+ turbo,
20
+ },
21
+ rules:
22
+ customRules ??
23
+ ({
24
+ "turbo/no-undeclared-env-vars": "warn",
25
+ } satisfies TurboRules),
26
+ });
@@ -0,0 +1,7 @@
1
+ import type { EslintRuleConfig } from "../types.js";
2
+
3
+ export interface TurboRules {
4
+ "turbo/no-undeclared-env-vars": EslintRuleConfig<{
5
+ allowList?: string[];
6
+ }>;
7
+ }
@@ -0,0 +1,29 @@
1
+ import type { Linter } from "eslint";
2
+
3
+ import type { ConfigName } from "./constants.js";
4
+
5
+ export type EslintSeverity = 0 | 1 | 2 | "error" | "off" | "warn";
6
+
7
+ export type EslintRuleConfig<
8
+ TOptions = Record<string, unknown>,
9
+ TOptions2 = Record<string, unknown>,
10
+ > =
11
+ | [EslintSeverity, string | TOptions | undefined]
12
+ | [EslintSeverity, string | undefined, TOptions2 | undefined]
13
+ | [EslintSeverity, TOptions | undefined, TOptions2 | undefined]
14
+ | [EslintSeverity]
15
+ | EslintSeverity;
16
+
17
+ export interface EslintConfigObject<
18
+ Rules extends Linter.RulesRecord = Linter.RulesRecord,
19
+ > extends Linter.Config<Rules> {
20
+ name: ConfigName;
21
+ }
22
+
23
+ export type FilenameCase =
24
+ | "camelCase"
25
+ | "kebabCase"
26
+ | "pascalCase"
27
+ | "snakeCase";
28
+
29
+ export type FunctionStyle = "arrow" | "declaration" | "expression";
@@ -0,0 +1,229 @@
1
+ # TypeScript Configuration
2
+
3
+ Comprehensive TypeScript support with type-aware linting rules from `@typescript-eslint`. The configuration strikes a balance between strict type safety and practical development.
4
+
5
+ [← Back to main README](../../../README.md)
6
+
7
+ ## Overview
8
+
9
+ TypeScript support is **enabled by default** and provides:
10
+
11
+ - Type-aware linting rules
12
+ - Consistent TypeScript patterns
13
+ - Import/export type safety
14
+ - Modern TypeScript best practices
15
+
16
+ ## Configuration
17
+
18
+ ```js
19
+ import { eslintConfig } from "js-style-kit";
20
+
21
+ export default eslintConfig({
22
+ typescript: true, // Default - automatic project detection
23
+ });
24
+ ```
25
+
26
+ ### Options
27
+
28
+ #### Automatic Detection (Recommended)
29
+
30
+ ```js
31
+ typescript: true; // Automatically finds and uses your tsconfig.json
32
+ ```
33
+
34
+ #### Specify Path
35
+
36
+ ```js
37
+ typescript: "./tsconfig.eslint.json"; // Use specific tsconfig file
38
+ ```
39
+
40
+ #### Disable TypeScript Rules
41
+
42
+ ```js
43
+ typescript: false; // Turn off TypeScript linting
44
+ ```
45
+
46
+ ## How It Works
47
+
48
+ When TypeScript is enabled:
49
+
50
+ 1. **Automatic project detection** - Finds your `tsconfig.json` automatically
51
+ 2. **Type-aware linting** - Uses TypeScript's type information for advanced checks
52
+ 3. **JavaScript compatibility** - Type-checking disabled for `.js` files
53
+ 4. **Base rule overrides** - Replaces ESLint rules with TypeScript equivalents (e.g., `no-unused-vars` → `@typescript-eslint/no-unused-vars`)
54
+
55
+ ## Key Rule Categories
56
+
57
+ ### Type Safety
58
+
59
+ **Strict Type Checking**
60
+
61
+ - `no-explicit-any` - Warn when using `any` type
62
+ - `no-unsafe-*` - Prevent unsafe type operations
63
+ - `no-unnecessary-type-assertion` - Remove redundant type assertions
64
+ - `no-unnecessary-condition` - Detect always-true/false conditions
65
+ - `strict-boolean-expressions` - Require boolean types in conditions
66
+
67
+ **Type Inference**
68
+
69
+ - `no-inferrable-types` - Remove unnecessary type annotations
70
+ - `prefer-as-const` - Use `as const` for literal types
71
+ - `consistent-type-definitions` - Prefer `interface` or `type` consistently
72
+
73
+ ### Modern TypeScript
74
+
75
+ **Import/Export**
76
+
77
+ - `consistent-type-imports` - Use `import type` for types (inline style)
78
+ - `consistent-type-exports` - Use `export type` for types
79
+ - `no-import-type-side-effects` - Prevent import type side effects
80
+
81
+ ```ts
82
+ // ✅ Good - inline type imports
83
+ import { type User, getUser } from "./api";
84
+
85
+ // ❌ Bad - separate type import
86
+ import type { User } from "./api";
87
+ import { getUser } from "./api";
88
+ ```
89
+
90
+ **Null Safety**
91
+
92
+ - `prefer-nullish-coalescing` - Use `??` over `||` for null checks
93
+ - `prefer-optional-chain` - Use `?.` for safe property access
94
+ - `no-non-null-assertion` - Warn on `!` non-null assertions (subjective in favor of casting)
95
+
96
+ **Modern Syntax**
97
+
98
+ - `prefer-for-of` - Prefer `for...of` over traditional `for` loops
99
+ - `prefer-includes` - Use `.includes()` instead of `.indexOf()`
100
+ - `prefer-string-starts-ends-with` - Use `.startsWith()` and `.endsWith()`
101
+
102
+ ### Code Quality
103
+
104
+ **Error Prevention**
105
+
106
+ - `no-floating-promises` - Require handling Promise returns
107
+ - `await-thenable` - Only await Promise-like values
108
+ - `no-misused-promises` - Prevent Promises in wrong contexts
109
+ - `only-throw-error` - Only throw Error objects
110
+
111
+ **Best Practices**
112
+
113
+ - `no-unused-vars` - Detect unused variables (with `_` prefix exception)
114
+ - `no-empty-function` - Warn on empty functions
115
+ - `no-useless-constructor` - Remove unnecessary constructors
116
+ - `array-type` - Consistent array type syntax (defaults to `string[]` instead of `Array<string>`)
117
+
118
+ ### Documentation
119
+
120
+ **Comment Quality**
121
+
122
+ - `ban-ts-comment` - Require explanations for `@ts-ignore` & `@ts-expect-error` (min 10 chars)
123
+ - `ban-tslint-comment` - Prevent deprecated TSLint comments
124
+
125
+ ```ts
126
+ // ❌ Bad - no explanation
127
+ // @ts-ignore
128
+ const x = dangerous();
129
+
130
+ // ✅ Good - explains why
131
+ // @ts-expect-error - legacy API doesn't have types
132
+ const x = dangerous();
133
+ ```
134
+
135
+ ## TypeScript + React
136
+
137
+ When both TypeScript and React are enabled, additional rules apply:
138
+
139
+ ```js
140
+ import { eslintConfig } from "js-style-kit";
141
+
142
+ export default eslintConfig({
143
+ typescript: "./tsconfig.json",
144
+ react: true,
145
+ });
146
+ ```
147
+
148
+ React-specific TypeScript rules:
149
+
150
+ - Type-safe prop definitions
151
+ - React hooks type checking
152
+ - JSX type safety
153
+
154
+ [→ See React Configuration](../react/README.md)
155
+
156
+ ## Unused Variables
157
+
158
+ The `no-unused-vars` rule allows `_` prefix for intentionally unused variables:
159
+
160
+ ```ts
161
+ // ✅ Good - underscore prefix indicates intentional
162
+ const [_loading, setLoading] = useState(false);
163
+ const handler = (_event: Event) => {
164
+ /* ... */
165
+ };
166
+
167
+ // ❌ Bad - unused without underscore
168
+ const [loading, setLoading] = useState(false);
169
+ ```
170
+
171
+ ## Customization
172
+
173
+ Override specific TypeScript rules:
174
+
175
+ ```js
176
+ import { eslintConfig } from "js-style-kit";
177
+
178
+ export default eslintConfig({
179
+ typescript: true,
180
+ rules: {
181
+ // Allow any type in certain cases
182
+ "@typescript-eslint/no-explicit-any": "off",
183
+
184
+ // Enforce non-null assertions when you know better than TS
185
+ "@typescript-eslint/no-non-null-assertion": "off",
186
+
187
+ // Stricter unused vars (no underscore escape hatch)
188
+ "@typescript-eslint/no-unused-vars": [
189
+ "warn",
190
+ {
191
+ argsIgnorePattern: "^_",
192
+ varsIgnorePattern: "^_",
193
+ ignoreRestSiblings: true,
194
+ },
195
+ ],
196
+ },
197
+ });
198
+ ```
199
+
200
+ ## Troubleshooting
201
+
202
+ ### ESLint can't find tsconfig.json
203
+
204
+ Use explicit path:
205
+
206
+ ```js
207
+ typescript: "./tsconfig.json";
208
+ ```
209
+
210
+ ### Type checking is slow
211
+
212
+ 1. Use `tsconfig.eslint.json` with limited `include` paths
213
+ 2. Exclude test files if not needed for linting
214
+
215
+ ```js
216
+ typescript: "./tsconfig.eslint.json";
217
+ ```
218
+
219
+ ## Related Configurations
220
+
221
+ - [Base ESLint](../base/README.md) - Core JavaScript rules
222
+ - [Import Plugin](../import/README.md) - Import/export validation
223
+ - [React](../react/README.md) - React + TypeScript support
224
+
225
+ ## Learn More
226
+
227
+ - [@typescript-eslint Documentation](https://typescript-eslint.io/)
228
+ - [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
229
+ - [Main README](../../../README.md)
@@ -0,0 +1,48 @@
1
+ import { defineConfig } from "eslint/config";
2
+ import tseslint, { type Config } from "typescript-eslint";
3
+
4
+ import type { EslintRuleConfig } from "../types.js";
5
+
6
+ import { configNames } from "../constants.js";
7
+ import { tseslintRules } from "./rules.js";
8
+
9
+ /**
10
+ * Creates a TypeScript ESLint configuration object.
11
+ *
12
+ * @param tsconfigPath - Path to the TypeScript configuration file
13
+ * @param customRules - Optional object containing custom rules to override or add to the TypeScript configuration.
14
+ * @returns TypeScript ESLint configuration object
15
+ */
16
+ export const tseslintConfig = (
17
+ tsconfigPath?: string,
18
+ customRules?: Record<string, EslintRuleConfig>,
19
+ ): Config => {
20
+ const userCwd = process.cwd();
21
+
22
+ return defineConfig(
23
+ {
24
+ files: ["**/*.{js,cjs,mjs,ts,jsx,tsx}"],
25
+ languageOptions: {
26
+ parser: tseslint.parser,
27
+ parserOptions: {
28
+ ...(tsconfigPath ?
29
+ { project: tsconfigPath, tsconfigRootDir: userCwd }
30
+ : { projectService: true, tsconfigRootDir: import.meta.dirname }),
31
+ },
32
+ },
33
+ name: configNames.typescript,
34
+ plugins: {
35
+ "@typescript-eslint": tseslint.plugin,
36
+ },
37
+ rules: {
38
+ ...tseslintRules,
39
+ ...(customRules ?? {}),
40
+ },
41
+ },
42
+ {
43
+ // disable type-aware linting on JS files
44
+ extends: [tseslint.configs.disableTypeChecked],
45
+ files: ["**/*.js"],
46
+ },
47
+ );
48
+ };