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.
- package/README.md +5 -0
- package/dist/index.d.ts +11 -5
- package/dist/index.js +48 -7
- package/dist/index.js.map +1 -1
- package/package.json +8 -5
- package/src/eslint/base/README.md +186 -0
- package/src/eslint/base/config.ts +37 -0
- package/src/eslint/base/rules.ts +444 -0
- package/src/eslint/base/types.ts +20 -0
- package/src/eslint/constants.ts +52 -0
- package/src/eslint/convex/README.md +30 -0
- package/src/eslint/convex/config.ts +34 -0
- package/src/eslint/convex/rules.ts +8 -0
- package/src/eslint/convex/types.ts +8 -0
- package/src/eslint/ignores.ts +31 -0
- package/src/eslint/import/README.md +397 -0
- package/src/eslint/import/config.ts +48 -0
- package/src/eslint/import/rules.ts +81 -0
- package/src/eslint/index.ts +259 -0
- package/src/eslint/jsdoc/README.md +399 -0
- package/src/eslint/jsdoc/config.ts +29 -0
- package/src/eslint/jsdoc/rules.ts +81 -0
- package/src/eslint/jsdoc/types.ts +56 -0
- package/src/eslint/nextjs/config.ts +25 -0
- package/src/eslint/nextjs/rules.ts +25 -0
- package/src/eslint/nextjs/types.ts +27 -0
- package/src/eslint/perfectionist/README.md +454 -0
- package/src/eslint/perfectionist/config.ts +25 -0
- package/src/eslint/perfectionist/rules.ts +39 -0
- package/src/eslint/prefer-arrow-function/config.ts +33 -0
- package/src/eslint/prefer-arrow-function/types.ts +13 -0
- package/src/eslint/process-custom-rules.ts +72 -0
- package/src/eslint/query/README.md +254 -0
- package/src/eslint/query/config.ts +27 -0
- package/src/eslint/query/rules.ts +11 -0
- package/src/eslint/query/types.ts +11 -0
- package/src/eslint/react/README.md +416 -0
- package/src/eslint/react/config.ts +65 -0
- package/src/eslint/react/rules.ts +188 -0
- package/src/eslint/react/types.ts +26 -0
- package/src/eslint/react-refresh/config.ts +28 -0
- package/src/eslint/react-refresh/rules.ts +48 -0
- package/src/eslint/storybook/README.md +424 -0
- package/src/eslint/storybook/config.ts +57 -0
- package/src/eslint/testing/README.md +436 -0
- package/src/eslint/testing/config.ts +90 -0
- package/src/eslint/testing/jest-rules.ts +47 -0
- package/src/eslint/testing/vitest-rules.ts +42 -0
- package/src/eslint/turbo/README.md +380 -0
- package/src/eslint/turbo/config.ts +26 -0
- package/src/eslint/turbo/types.ts +7 -0
- package/src/eslint/types.ts +29 -0
- package/src/eslint/typescript/README.md +229 -0
- package/src/eslint/typescript/config.ts +48 -0
- package/src/eslint/typescript/rules.ts +137 -0
- package/src/eslint/typescript/types.ts +35 -0
- package/src/eslint/unicorn/README.md +497 -0
- package/src/eslint/unicorn/config.ts +36 -0
- package/src/eslint/unicorn/rules.ts +86 -0
- package/src/index.ts +3 -0
- package/src/modules.d.ts +5 -0
- package/src/prettier/README.md +413 -0
- package/src/prettier/index.ts +110 -0
- package/src/utils/is-type.ts +60 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { EslintRuleConfig } from "../types.js";
|
|
2
|
+
|
|
3
|
+
interface PerfectionistRuleOptions {
|
|
4
|
+
order: "asc" | "desc";
|
|
5
|
+
type: "alphabetical" | "custom" | "line-length" | "natural";
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const defaultOptions: PerfectionistRuleOptions = {
|
|
9
|
+
order: "asc",
|
|
10
|
+
type: "natural",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type PerfectionRules = Record<
|
|
14
|
+
`perfectionist/${string}`,
|
|
15
|
+
EslintRuleConfig<PerfectionistRuleOptions>
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
export const perfectionistRules: PerfectionRules = {
|
|
19
|
+
"perfectionist/sort-array-includes": ["warn", defaultOptions],
|
|
20
|
+
"perfectionist/sort-classes": ["warn", defaultOptions],
|
|
21
|
+
"perfectionist/sort-decorators": ["warn", defaultOptions],
|
|
22
|
+
"perfectionist/sort-enums": ["warn", defaultOptions],
|
|
23
|
+
"perfectionist/sort-exports": ["warn", defaultOptions],
|
|
24
|
+
"perfectionist/sort-heritage-clauses": ["warn", defaultOptions],
|
|
25
|
+
"perfectionist/sort-imports": ["warn", defaultOptions],
|
|
26
|
+
"perfectionist/sort-interfaces": ["warn", defaultOptions],
|
|
27
|
+
"perfectionist/sort-intersection-types": ["warn", defaultOptions],
|
|
28
|
+
"perfectionist/sort-jsx-props": ["warn", defaultOptions],
|
|
29
|
+
"perfectionist/sort-maps": ["warn", defaultOptions],
|
|
30
|
+
"perfectionist/sort-modules": ["off", defaultOptions],
|
|
31
|
+
"perfectionist/sort-named-exports": ["warn", defaultOptions],
|
|
32
|
+
"perfectionist/sort-named-imports": ["warn", defaultOptions],
|
|
33
|
+
"perfectionist/sort-object-types": ["warn", defaultOptions],
|
|
34
|
+
"perfectionist/sort-objects": ["warn", defaultOptions],
|
|
35
|
+
"perfectionist/sort-sets": ["warn", defaultOptions],
|
|
36
|
+
"perfectionist/sort-switch-case": ["warn", defaultOptions],
|
|
37
|
+
"perfectionist/sort-union-types": ["warn", defaultOptions],
|
|
38
|
+
"perfectionist/sort-variable-declarations": ["warn", defaultOptions],
|
|
39
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ESLint } from "eslint";
|
|
2
|
+
|
|
3
|
+
import preferArrowFunctions from "eslint-plugin-prefer-arrow-functions";
|
|
4
|
+
|
|
5
|
+
import type { EslintConfigObject, EslintRuleConfig } from "../types.js";
|
|
6
|
+
import type { PreferArrowFunctionsRules } from "./types.js";
|
|
7
|
+
|
|
8
|
+
import { configNames } from "../constants.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates an ESLint configuration for Prefer Arrow Functions.
|
|
12
|
+
*
|
|
13
|
+
* @param customRules - Optional object containing custom rules to override or add to the configuration.
|
|
14
|
+
* @returns ESLint configuration object for Prefer Arrow Functions
|
|
15
|
+
*/
|
|
16
|
+
export const preferArrowFunctionConfig = (
|
|
17
|
+
customRules?: Record<string, EslintRuleConfig>,
|
|
18
|
+
): EslintConfigObject => ({
|
|
19
|
+
name: configNames.preferArrowFunction,
|
|
20
|
+
plugins: {
|
|
21
|
+
"prefer-arrow-functions": preferArrowFunctions as ESLint.Plugin,
|
|
22
|
+
},
|
|
23
|
+
rules: {
|
|
24
|
+
"prefer-arrow-functions/prefer-arrow-functions": [
|
|
25
|
+
"warn",
|
|
26
|
+
{
|
|
27
|
+
returnStyle: "unchanged",
|
|
28
|
+
singleReturnOnly: false,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
...(customRules ?? {}),
|
|
32
|
+
} satisfies PreferArrowFunctionsRules,
|
|
33
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { EslintRuleConfig } from "../types.js";
|
|
2
|
+
|
|
3
|
+
export interface PreferArrowFunctionsRules {
|
|
4
|
+
"prefer-arrow-functions/prefer-arrow-functions": EslintRuleConfig<{
|
|
5
|
+
allowedNames?: string[];
|
|
6
|
+
allowNamedFunctions?: boolean;
|
|
7
|
+
allowObjectProperties?: boolean;
|
|
8
|
+
classPropertiesAllowed?: boolean;
|
|
9
|
+
disallowPrototype?: boolean;
|
|
10
|
+
returnStyle?: "explicit" | "implicit" | "unchanged";
|
|
11
|
+
singleReturnOnly?: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ConfigName } from "./constants.js";
|
|
2
|
+
import type { EslintRuleConfig } from "./types.js";
|
|
3
|
+
|
|
4
|
+
import { configNames, pluginPrefixMap } from "./constants.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Categorizes custom rules provided by the user based on plugin prefixes.
|
|
8
|
+
*
|
|
9
|
+
* @param customRules - The custom rules provided by the user.
|
|
10
|
+
* @returns An object where keys are config names (e.g., 'base', 'typescript')
|
|
11
|
+
* and values are the corresponding rule subsets for that config.
|
|
12
|
+
*/
|
|
13
|
+
export const processCustomRules = (
|
|
14
|
+
customRules: Record<string, EslintRuleConfig>,
|
|
15
|
+
): Partial<Record<ConfigName, Record<string, EslintRuleConfig>>> => {
|
|
16
|
+
// Initialize result object with all possible config categories
|
|
17
|
+
const categorizedRules = Object.values(configNames).reduce<
|
|
18
|
+
Record<ConfigName, Record<string, EslintRuleConfig>>
|
|
19
|
+
>(
|
|
20
|
+
(acc, configName) => {
|
|
21
|
+
acc[configName] = {};
|
|
22
|
+
return acc;
|
|
23
|
+
},
|
|
24
|
+
{} as Record<ConfigName, Record<string, EslintRuleConfig>>,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Process each custom rule
|
|
28
|
+
for (const [ruleKey, ruleValue] of Object.entries(customRules)) {
|
|
29
|
+
// Quick check if rule has no prefix (no '/' or '@')
|
|
30
|
+
// Rules without prefixes go directly to base config
|
|
31
|
+
if (!ruleKey.includes("/") && !ruleKey.startsWith("@")) {
|
|
32
|
+
categorizedRules[configNames.base][ruleKey] = ruleValue;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Extract the plugin prefix from the rule key
|
|
37
|
+
let prefix: null | string = null;
|
|
38
|
+
|
|
39
|
+
if (ruleKey.startsWith("@")) {
|
|
40
|
+
// Handle scoped packages like @typescript-eslint/rule-name
|
|
41
|
+
const firstSlashIndex = ruleKey.indexOf("/");
|
|
42
|
+
if (firstSlashIndex !== -1) {
|
|
43
|
+
prefix = ruleKey.substring(0, firstSlashIndex);
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
// Handle regular plugins like eslint-plugin-react/rule-name
|
|
47
|
+
const firstSlashIndex = ruleKey.indexOf("/");
|
|
48
|
+
if (firstSlashIndex !== -1) {
|
|
49
|
+
prefix = ruleKey.substring(0, firstSlashIndex);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Find the corresponding config name for this prefix
|
|
54
|
+
const configName =
|
|
55
|
+
prefix ?
|
|
56
|
+
(pluginPrefixMap.get(prefix) ?? configNames.base)
|
|
57
|
+
: configNames.base;
|
|
58
|
+
|
|
59
|
+
// Add the rule to the appropriate config
|
|
60
|
+
categorizedRules[configName][ruleKey] = ruleValue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Filter out empty config objects to save memory
|
|
64
|
+
return Object.entries(categorizedRules).reduce<
|
|
65
|
+
Partial<Record<ConfigName, Record<string, EslintRuleConfig>>>
|
|
66
|
+
>((acc, [configName, rules]) => {
|
|
67
|
+
if (Object.keys(rules).length > 0) {
|
|
68
|
+
acc[configName as ConfigName] = rules;
|
|
69
|
+
}
|
|
70
|
+
return acc;
|
|
71
|
+
}, {});
|
|
72
|
+
};
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# TanStack Query Configuration
|
|
2
|
+
|
|
3
|
+
ESLint rules for [TanStack Query](https://tanstack.com/query) (formerly React Query) to ensure proper usage patterns and prevent common mistakes.
|
|
4
|
+
|
|
5
|
+
[← Back to main README](../../../README.md)
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
TanStack Query support is **disabled by default** and provides:
|
|
10
|
+
|
|
11
|
+
- Query dependency validation
|
|
12
|
+
- Property ordering consistency
|
|
13
|
+
- Stable query client patterns
|
|
14
|
+
- Hook usage best practices
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
import { eslintConfig } from "js-style-kit";
|
|
20
|
+
|
|
21
|
+
export default eslintConfig({
|
|
22
|
+
query: true, // Enable TanStack Query rules
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## When to Use
|
|
27
|
+
|
|
28
|
+
Enable this configuration when using TanStack Query in your project:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @tanstack/react-query
|
|
32
|
+
# or
|
|
33
|
+
yarn add @tanstack/react-query
|
|
34
|
+
# or
|
|
35
|
+
pnpm add @tanstack/react-query
|
|
36
|
+
# or
|
|
37
|
+
bun add @tanstack/react-query
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Rules
|
|
41
|
+
|
|
42
|
+
### Dependency Validation
|
|
43
|
+
|
|
44
|
+
**`exhaustive-deps`**
|
|
45
|
+
Ensures all dependencies are declared in query keys and function scopes.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
// ✅ Good
|
|
49
|
+
const { data } = useQuery({
|
|
50
|
+
queryKey: ["users", userId], // userId in queryKey
|
|
51
|
+
queryFn: () => fetchUser(userId),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// ❌ Bad
|
|
55
|
+
const { data } = useQuery({
|
|
56
|
+
queryKey: ["users"], // Missing userId
|
|
57
|
+
queryFn: () => fetchUser(userId),
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**`no-unstable-deps`**
|
|
62
|
+
Prevents unstable references in query keys that could cause unnecessary refetches.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
// ✅ Good
|
|
66
|
+
const queryKey = useMemo(() => ["users", userId], [userId]);
|
|
67
|
+
const { data } = useQuery({
|
|
68
|
+
queryKey,
|
|
69
|
+
queryFn: fetchUsers,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// ❌ Bad
|
|
73
|
+
const { data } = useQuery({
|
|
74
|
+
queryKey: ["users", { id: userId }], // New object each render
|
|
75
|
+
queryFn: fetchUsers,
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Property Ordering
|
|
80
|
+
|
|
81
|
+
**`infinite-query-property-order`**
|
|
82
|
+
Enforces consistent property order in `useInfiniteQuery`:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// ✅ Good - correct order
|
|
86
|
+
useInfiniteQuery({
|
|
87
|
+
queryKey: ["projects"],
|
|
88
|
+
queryFn: fetchProjects,
|
|
89
|
+
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
|
90
|
+
initialPageParam: 0,
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**`mutation-property-order`**
|
|
95
|
+
Enforces consistent property order in `useMutation`:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
// ✅ Good - correct order
|
|
99
|
+
useMutation({
|
|
100
|
+
mutationFn: createUser,
|
|
101
|
+
onSuccess: () => {
|
|
102
|
+
/* ... */
|
|
103
|
+
},
|
|
104
|
+
onError: () => {
|
|
105
|
+
/* ... */
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Query Function Patterns
|
|
111
|
+
|
|
112
|
+
**`no-void-query-fn`**
|
|
113
|
+
Prevents `void` returning query functions:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
// ✅ Good
|
|
117
|
+
useQuery({
|
|
118
|
+
queryKey: ["users"],
|
|
119
|
+
queryFn: () => fetchUsers(), // Returns Promise<User[]>
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// ❌ Bad
|
|
123
|
+
useQuery({
|
|
124
|
+
queryKey: ["users"],
|
|
125
|
+
queryFn: () => {
|
|
126
|
+
fetchUsers();
|
|
127
|
+
}, // Returns void
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**`no-rest-destructuring`**
|
|
132
|
+
Prevents rest destructuring which can lead to serialization issues:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
// ✅ Good
|
|
136
|
+
const { data, isLoading, error } = useQuery({
|
|
137
|
+
queryKey: ["users"],
|
|
138
|
+
queryFn: fetchUsers,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// ❌ Bad
|
|
142
|
+
const { data, ...rest } = useQuery({
|
|
143
|
+
queryKey: ["users"],
|
|
144
|
+
queryFn: fetchUsers,
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Client Stability
|
|
149
|
+
|
|
150
|
+
**`stable-query-client`**
|
|
151
|
+
Ensures QueryClient is stable across renders:
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
// ✅ Good - client created outside component or with useMemo
|
|
155
|
+
const queryClient = new QueryClient();
|
|
156
|
+
|
|
157
|
+
function App() {
|
|
158
|
+
return (
|
|
159
|
+
<QueryClientProvider client={queryClient}>{/* ... */}</QueryClientProvider>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ❌ Bad - new client every render
|
|
164
|
+
function App() {
|
|
165
|
+
const queryClient = new QueryClient();
|
|
166
|
+
return (
|
|
167
|
+
<QueryClientProvider client={queryClient}>{/* ... */}</QueryClientProvider>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Common Patterns
|
|
173
|
+
|
|
174
|
+
### With React and TypeScript
|
|
175
|
+
|
|
176
|
+
```js
|
|
177
|
+
export default eslintConfig({
|
|
178
|
+
typescript: true,
|
|
179
|
+
react: { framework: "vite" },
|
|
180
|
+
query: true,
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### With Next.js
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
export default eslintConfig({
|
|
188
|
+
typescript: true,
|
|
189
|
+
react: { framework: "next" },
|
|
190
|
+
query: true,
|
|
191
|
+
});
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Customization
|
|
195
|
+
|
|
196
|
+
Override specific Query rules:
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
export default eslintConfig({
|
|
200
|
+
query: true,
|
|
201
|
+
rules: {
|
|
202
|
+
// Disable property ordering if you prefer different order
|
|
203
|
+
"@tanstack/query/mutation-property-order": "off",
|
|
204
|
+
|
|
205
|
+
// Make exhaustive-deps an error instead of warning
|
|
206
|
+
"@tanstack/query/exhaustive-deps": "error",
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Best Practices
|
|
212
|
+
|
|
213
|
+
1. **Always declare dependencies** in query keys
|
|
214
|
+
2. **Use stable references** for query keys (memoize objects)
|
|
215
|
+
3. **Keep query functions pure** - return data, don't mutate
|
|
216
|
+
4. **Hoist QueryClient** creation outside components
|
|
217
|
+
5. **Follow property order conventions** for consistency
|
|
218
|
+
|
|
219
|
+
## Troubleshooting
|
|
220
|
+
|
|
221
|
+
### False positives on exhaustive-deps
|
|
222
|
+
|
|
223
|
+
Ensure all variables used in `queryFn` are in `queryKey`:
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
const { data } = useQuery({
|
|
227
|
+
queryKey: ["users", filter, sort], // Include all dependencies
|
|
228
|
+
queryFn: () => fetchUsers({ filter, sort }),
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Object key instability warnings
|
|
233
|
+
|
|
234
|
+
Memoize object keys:
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
const params = useMemo(() => ({ filter, sort }), [filter, sort]);
|
|
238
|
+
const { data } = useQuery({
|
|
239
|
+
queryKey: ["users", params],
|
|
240
|
+
queryFn: () => fetchUsers(params),
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Related Configurations
|
|
245
|
+
|
|
246
|
+
- [React](../react/README.md) - React configuration
|
|
247
|
+
- [TypeScript](../typescript/README.md) - TypeScript support
|
|
248
|
+
- [Testing](../testing/README.md) - Test Query hooks
|
|
249
|
+
|
|
250
|
+
## Learn More
|
|
251
|
+
|
|
252
|
+
- [TanStack Query ESLint Plugin](https://tanstack.com/query/latest/docs/eslint/eslint-plugin-query)
|
|
253
|
+
- [TanStack Query Documentation](https://tanstack.com/query/latest)
|
|
254
|
+
- [Main README](../../../README.md)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ESLint } from "eslint";
|
|
2
|
+
|
|
3
|
+
import queryPlugin from "@tanstack/eslint-plugin-query";
|
|
4
|
+
|
|
5
|
+
import type { EslintConfigObject, EslintRuleConfig } from "../types.js";
|
|
6
|
+
|
|
7
|
+
import { configNames } from "../constants.js";
|
|
8
|
+
import { queryRules } from "./rules.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Creates an ESLint configuration for TanStack Query.
|
|
12
|
+
*
|
|
13
|
+
* @param customRules - Optional object containing custom rules to override or add to the Query configuration.
|
|
14
|
+
* @returns ESLint configuration object for TanStack Query
|
|
15
|
+
*/
|
|
16
|
+
export const queryConfig = (
|
|
17
|
+
customRules?: Record<string, EslintRuleConfig>,
|
|
18
|
+
): EslintConfigObject => ({
|
|
19
|
+
name: configNames.query,
|
|
20
|
+
plugins: {
|
|
21
|
+
"@tanstack/query": queryPlugin as unknown as ESLint.Plugin,
|
|
22
|
+
},
|
|
23
|
+
rules: {
|
|
24
|
+
...queryRules,
|
|
25
|
+
...(customRules ?? {}),
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { QueryRules } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export const queryRules: QueryRules = {
|
|
4
|
+
"@tanstack/query/exhaustive-deps": "warn",
|
|
5
|
+
"@tanstack/query/infinite-query-property-order": "warn",
|
|
6
|
+
"@tanstack/query/mutation-property-order": "warn",
|
|
7
|
+
"@tanstack/query/no-rest-destructuring": "warn",
|
|
8
|
+
"@tanstack/query/no-unstable-deps": "warn",
|
|
9
|
+
"@tanstack/query/no-void-query-fn": "warn",
|
|
10
|
+
"@tanstack/query/stable-query-client": "warn",
|
|
11
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EslintRuleConfig } from "../types.js";
|
|
2
|
+
|
|
3
|
+
export interface QueryRules {
|
|
4
|
+
"@tanstack/query/exhaustive-deps": EslintRuleConfig;
|
|
5
|
+
"@tanstack/query/infinite-query-property-order": EslintRuleConfig;
|
|
6
|
+
"@tanstack/query/mutation-property-order": EslintRuleConfig;
|
|
7
|
+
"@tanstack/query/no-rest-destructuring": EslintRuleConfig;
|
|
8
|
+
"@tanstack/query/no-unstable-deps": EslintRuleConfig;
|
|
9
|
+
"@tanstack/query/no-void-query-fn": EslintRuleConfig;
|
|
10
|
+
"@tanstack/query/stable-query-client": EslintRuleConfig;
|
|
11
|
+
}
|