@eslint-react/kit 4.0.1-beta.1 → 4.0.2-beta.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 +94 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +14 -11
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -10,6 +10,8 @@ ESLint React's toolkit for building custom React lint rules right inside your `e
|
|
|
10
10
|
- [`eslintReactKit` (default export)](#eslintreactkit-default-export)
|
|
11
11
|
- [`RuleDefinition`](#ruledefinition)
|
|
12
12
|
- [`Builder`](#builder)
|
|
13
|
+
- [`getConfig`](#getconfig)
|
|
14
|
+
- [`getPlugin`](#getplugin)
|
|
13
15
|
- [`merge`](#merge)
|
|
14
16
|
- [`Kit` — the toolkit object](#kit--the-toolkit-object)
|
|
15
17
|
- [`kit.collect`](#kitcollect) — Semantic collectors
|
|
@@ -22,6 +24,7 @@ ESLint React's toolkit for building custom React lint rules right inside your `e
|
|
|
22
24
|
- [Component: Destructure component props](#component-destructure-component-props)
|
|
23
25
|
- [Hooks: Warn on custom hooks that don't call other hooks](#hooks-warn-on-custom-hooks-that-dont-call-other-hooks)
|
|
24
26
|
- [Multiple Collectors: No component/hook factories](#multiple-collectors-no-componenthook-factories)
|
|
27
|
+
- [Advanced Config: Using `getPlugin` for custom plugin namespace](#advanced-config-using-getplugin-for-custom-plugin-namespace)
|
|
25
28
|
- [More Examples](#more-examples)
|
|
26
29
|
|
|
27
30
|
## Installation
|
|
@@ -120,7 +123,8 @@ function forbidElements({ forbidden }: ForbidElementsOptions): RuleDefinition {
|
|
|
120
123
|
```ts
|
|
121
124
|
interface Builder {
|
|
122
125
|
use<F extends (...args: any[]) => RuleDefinition>(factory: F, ...args: Parameters<F>): Builder;
|
|
123
|
-
getConfig(): Linter.Config;
|
|
126
|
+
getConfig(args?: { files?: string[] }): Linter.Config;
|
|
127
|
+
getPlugin(): ESLint.Plugin;
|
|
124
128
|
}
|
|
125
129
|
```
|
|
126
130
|
|
|
@@ -130,6 +134,11 @@ A chainable builder for registering custom rules.
|
|
|
130
134
|
| ----------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
131
135
|
| `use` | Registers a rule factory. The rule name is `kebabCase(factory.name)`. Options type is inferred from the factory signature. |
|
|
132
136
|
| `getConfig` | Returns a `Linter.Config` with all registered rules enabled at `"error"` severity. |
|
|
137
|
+
| `getPlugin` | Returns an `ESLint.Plugin` containing the registered rules and plugin metadata. |
|
|
138
|
+
|
|
139
|
+
#### `getConfig`
|
|
140
|
+
|
|
141
|
+
Returns a flat `Linter.Config` object with all registered rules set to `"error"`. This is a convenience wrapper that calls `getPlugin()` internally and adds the plugin plus rule entries to the config.
|
|
133
142
|
|
|
134
143
|
```ts
|
|
135
144
|
eslintReactKit()
|
|
@@ -138,6 +147,34 @@ eslintReactKit()
|
|
|
138
147
|
.getConfig();
|
|
139
148
|
```
|
|
140
149
|
|
|
150
|
+
#### `getPlugin`
|
|
151
|
+
|
|
152
|
+
Returns an `ESLint.Plugin` object containing the registered rules and plugin metadata (`name` and `version`). Use this when you need finer-grained control over how the plugin is integrated into your ESLint configuration — for example, when you want to choose the plugin namespace, set per-rule severities, or compose the plugin with other configs manually.
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
const kit = eslintReactKit()
|
|
156
|
+
.use(noForwardRef)
|
|
157
|
+
.use(forbidElements, { forbidden: new Map() });
|
|
158
|
+
|
|
159
|
+
// Retrieve the raw plugin object
|
|
160
|
+
const plugin = kit.getPlugin();
|
|
161
|
+
// => { meta: { name: "@eslint-react/kit", version: "..." }, rules: { "no-forward-ref": ..., "forbid-elements": ... } }
|
|
162
|
+
|
|
163
|
+
// Use it in a custom flat config with your own namespace and severity
|
|
164
|
+
export default [
|
|
165
|
+
{
|
|
166
|
+
files: ["**/*.{ts,tsx}"],
|
|
167
|
+
plugins: {
|
|
168
|
+
"react-custom-rules": plugin,
|
|
169
|
+
},
|
|
170
|
+
rules: {
|
|
171
|
+
"react-custom-rules/no-forward-ref": "error",
|
|
172
|
+
"react-custom-rules/forbid-elements": "warn",
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
];
|
|
176
|
+
```
|
|
177
|
+
|
|
141
178
|
### `merge`
|
|
142
179
|
|
|
143
180
|
```ts
|
|
@@ -486,6 +523,60 @@ eslintReactKit()
|
|
|
486
523
|
.getConfig();
|
|
487
524
|
```
|
|
488
525
|
|
|
489
|
-
|
|
526
|
+
### Advanced Config: Using `getPlugin` for custom plugin namespace
|
|
527
|
+
|
|
528
|
+
Use `getPlugin()` when you want full control over the plugin namespace and rule severities instead of the all-in-one `getConfig()`.
|
|
529
|
+
|
|
530
|
+
```ts
|
|
531
|
+
import eslintReactKit from "@eslint-react/kit";
|
|
532
|
+
import type { RuleDefinition } from "@eslint-react/kit";
|
|
533
|
+
|
|
534
|
+
function noForwardRef(): RuleDefinition {
|
|
535
|
+
return (context, { is }) => ({
|
|
536
|
+
CallExpression(node) {
|
|
537
|
+
if (is.forwardRefCall(node)) {
|
|
538
|
+
context.report({ node, message: "forwardRef is deprecated in React 19." });
|
|
539
|
+
}
|
|
540
|
+
},
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function requireReact19(): RuleDefinition {
|
|
545
|
+
return (context, { settings }) => ({
|
|
546
|
+
Program(program) {
|
|
547
|
+
if (!settings.version.startsWith("19.")) {
|
|
548
|
+
context.report({
|
|
549
|
+
node: program,
|
|
550
|
+
message: `This project requires React 19, but detected version ${settings.version}.`,
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
const kit = eslintReactKit()
|
|
558
|
+
.use(noForwardRef)
|
|
559
|
+
.use(requireReact19);
|
|
560
|
+
|
|
561
|
+
// Instead of kit.getConfig(), use kit.getPlugin() for full control:
|
|
562
|
+
const plugin = kit.getPlugin();
|
|
563
|
+
|
|
564
|
+
export default [
|
|
565
|
+
{
|
|
566
|
+
files: ["**/*.{ts,tsx}"],
|
|
567
|
+
plugins: {
|
|
568
|
+
// Choose your own namespace
|
|
569
|
+
"react-custom": plugin,
|
|
570
|
+
},
|
|
571
|
+
rules: {
|
|
572
|
+
// Set individual severities
|
|
573
|
+
"react-custom/no-forward-ref": "error",
|
|
574
|
+
"react-custom/require-react-19": "error",
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
];
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
<!--## More Examples
|
|
490
581
|
|
|
491
|
-
Please check the [Rule Recipes](https://beta.eslint-react.xyz/docs/configuration/configure-custom-rules#rule-recipes) in the documentation site
|
|
582
|
+
Please check the [Rule Recipes](https://beta.eslint-react.xyz/docs/configuration/configure-custom-rules#rule-recipes) in the documentation site.-->
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ESLintReactSettingsNormalized, RuleFix, RuleFixer, RuleListener, define
|
|
|
3
3
|
import { TSESTreeFunction } from "@eslint-react/ast";
|
|
4
4
|
import { TSESTree } from "@typescript-eslint/utils";
|
|
5
5
|
import { RuleContext } from "@typescript-eslint/utils/ts-eslint";
|
|
6
|
-
import { Linter } from "eslint";
|
|
6
|
+
import { ESLint, Linter } from "eslint";
|
|
7
7
|
|
|
8
8
|
//#region src/index.d.ts
|
|
9
9
|
interface Collector<T> {
|
|
@@ -104,6 +104,7 @@ interface Builder {
|
|
|
104
104
|
getConfig(args?: {
|
|
105
105
|
files?: string[];
|
|
106
106
|
}): Linter.Config;
|
|
107
|
+
getPlugin(): ESLint.Plugin;
|
|
107
108
|
use<F extends (...args: any[]) => RuleDefinition>(factory: F, ...args: Parameters<F>): Builder;
|
|
108
109
|
}
|
|
109
110
|
declare function eslintReactKit(): Builder;
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { kebabCase } from "string-ts";
|
|
|
4
4
|
|
|
5
5
|
//#region package.json
|
|
6
6
|
var name = "@eslint-react/kit";
|
|
7
|
-
var version = "4.0.
|
|
7
|
+
var version = "4.0.2-beta.0";
|
|
8
8
|
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region src/index.ts
|
|
@@ -104,27 +104,30 @@ function makeRuleToolkit(context) {
|
|
|
104
104
|
}
|
|
105
105
|
function eslintReactKit() {
|
|
106
106
|
const idGen = new IdGenerator();
|
|
107
|
-
const
|
|
108
|
-
meta: {
|
|
109
|
-
name,
|
|
110
|
-
version
|
|
111
|
-
},
|
|
112
|
-
rules: {}
|
|
113
|
-
};
|
|
107
|
+
const rules = {};
|
|
114
108
|
const builder = {
|
|
115
109
|
getConfig({ files = ["**/*.ts", "**/*.tsx"] } = {}) {
|
|
116
110
|
return {
|
|
117
111
|
files,
|
|
118
|
-
plugins: { [name]:
|
|
119
|
-
rules: Object.keys(
|
|
112
|
+
plugins: { [name]: builder.getPlugin() },
|
|
113
|
+
rules: Object.keys(rules).reduce((acc, name$1) => {
|
|
120
114
|
acc[`${name}/${name$1}`] = "error";
|
|
121
115
|
return acc;
|
|
122
116
|
}, {})
|
|
123
117
|
};
|
|
124
118
|
},
|
|
119
|
+
getPlugin() {
|
|
120
|
+
return {
|
|
121
|
+
meta: {
|
|
122
|
+
name,
|
|
123
|
+
version
|
|
124
|
+
},
|
|
125
|
+
rules
|
|
126
|
+
};
|
|
127
|
+
},
|
|
125
128
|
use(make, ...args) {
|
|
126
129
|
const name = kebabCase(make.name === "" ? idGen.next() : make.name);
|
|
127
|
-
Reflect.set(
|
|
130
|
+
Reflect.set(rules, name, {
|
|
128
131
|
meta: {
|
|
129
132
|
fixable: "code",
|
|
130
133
|
hasSuggestions: true
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/kit",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2-beta.0",
|
|
4
4
|
"description": "ESLint React's utility module for building custom rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@typescript-eslint/utils": "^8.57.2",
|
|
40
40
|
"string-ts": "^2.3.1",
|
|
41
|
-
"@eslint-react/ast": "4.0.
|
|
42
|
-
"@eslint-react/core": "4.0.
|
|
43
|
-
"@eslint-react/shared": "4.0.
|
|
41
|
+
"@eslint-react/ast": "4.0.2-beta.0",
|
|
42
|
+
"@eslint-react/core": "4.0.2-beta.0",
|
|
43
|
+
"@eslint-react/shared": "4.0.2-beta.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"eslint": "^10.1.0",
|