@eslint-react/kit 4.0.1-beta.1 → 4.0.2-beta.1
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 +97 -7
- package/dist/index.d.ts +4 -3
- package/dist/index.js +16 -13
- 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,14 +134,46 @@ 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()
|
|
136
145
|
.use(noForwardRef) // no-arg factory
|
|
137
|
-
.use(
|
|
146
|
+
.use(version, "19") // factory with inferred options
|
|
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(version, "19")
|
|
158
|
+
|
|
159
|
+
// Retrieve the raw plugin object
|
|
160
|
+
const plugin = kit.getPlugin();
|
|
161
|
+
|
|
162
|
+
// Use it in a custom flat config with your own namespace and severity
|
|
163
|
+
export default [
|
|
164
|
+
{
|
|
165
|
+
files: ["**/*.{ts,tsx}"],
|
|
166
|
+
plugins: {
|
|
167
|
+
react: plugin,
|
|
168
|
+
},
|
|
169
|
+
rules: {
|
|
170
|
+
"react/version": "error",
|
|
171
|
+
"react/no-forward-ref": "error",
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
];
|
|
175
|
+
```
|
|
176
|
+
|
|
141
177
|
### `merge`
|
|
142
178
|
|
|
143
179
|
```ts
|
|
@@ -319,13 +355,13 @@ Exposes the normalized `react-x` settings from the ESLint shared configuration (
|
|
|
319
355
|
```ts
|
|
320
356
|
import type { RuleDefinition } from "@eslint-react/kit";
|
|
321
357
|
|
|
322
|
-
function
|
|
358
|
+
function version(major = "19"): RuleDefinition {
|
|
323
359
|
return (context, { settings }) => ({
|
|
324
360
|
Program(program) {
|
|
325
|
-
if (!settings.version.startsWith(
|
|
361
|
+
if (!settings.version.startsWith(`${major}.`)) {
|
|
326
362
|
context.report({
|
|
327
363
|
node: program,
|
|
328
|
-
message: `This project requires React
|
|
364
|
+
message: `This project requires React ${major}, but detected version ${settings.version}.`,
|
|
329
365
|
});
|
|
330
366
|
}
|
|
331
367
|
},
|
|
@@ -486,6 +522,60 @@ eslintReactKit()
|
|
|
486
522
|
.getConfig();
|
|
487
523
|
```
|
|
488
524
|
|
|
489
|
-
|
|
525
|
+
### Advanced Config: Using `getPlugin` for custom plugin namespace
|
|
526
|
+
|
|
527
|
+
Use `getPlugin()` when you want full control over the plugin namespace and rule severities instead of the all-in-one `getConfig()`.
|
|
528
|
+
|
|
529
|
+
```ts
|
|
530
|
+
import eslintReactKit from "@eslint-react/kit";
|
|
531
|
+
import type { RuleDefinition } from "@eslint-react/kit";
|
|
532
|
+
|
|
533
|
+
function version(major = "19"): RuleDefinition {
|
|
534
|
+
return (context, { settings }) => ({
|
|
535
|
+
Program(program) {
|
|
536
|
+
if (!settings.version.startsWith(`${major}.`)) {
|
|
537
|
+
context.report({
|
|
538
|
+
node: program,
|
|
539
|
+
message: `This project requires React ${major}, but detected version ${settings.version}.`,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
},
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
function noForwardRef(): RuleDefinition {
|
|
547
|
+
return (context, { is }) => ({
|
|
548
|
+
CallExpression(node) {
|
|
549
|
+
if (is.forwardRefCall(node)) {
|
|
550
|
+
context.report({ node, message: "forwardRef is deprecated in React 19." });
|
|
551
|
+
}
|
|
552
|
+
},
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const kit = eslintReactKit()
|
|
557
|
+
.use(noForwardRef);
|
|
558
|
+
.use(version, "19")
|
|
559
|
+
|
|
560
|
+
// Instead of kit.getConfig(), use kit.getPlugin() for full control:
|
|
561
|
+
const plugin = kit.getPlugin();
|
|
562
|
+
|
|
563
|
+
export default [
|
|
564
|
+
{
|
|
565
|
+
files: ["**/*.{ts,tsx}"],
|
|
566
|
+
plugins: {
|
|
567
|
+
// Choose your own namespace
|
|
568
|
+
react: plugin,
|
|
569
|
+
},
|
|
570
|
+
rules: {
|
|
571
|
+
// Set individual severities
|
|
572
|
+
"react/version": "error",
|
|
573
|
+
"react/no-forward-ref": "error",
|
|
574
|
+
},
|
|
575
|
+
},
|
|
576
|
+
];
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
<!--## More Examples
|
|
490
580
|
|
|
491
|
-
Please check the [Rule Recipes](https://beta.eslint-react.xyz/docs/configuration/configure-custom-rules#rule-recipes) in the documentation site
|
|
581
|
+
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,9 +104,10 @@ 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
|
-
declare function
|
|
110
|
+
declare function build(): Builder;
|
|
110
111
|
declare module "@typescript-eslint/utils/ts-eslint" {
|
|
111
112
|
interface RuleContext<MessageIds extends string = string, Options extends readonly unknown[] = readonly unknown[]> {
|
|
112
113
|
report(descriptor: {
|
|
@@ -124,4 +125,4 @@ declare module "@typescript-eslint/utils/ts-eslint" {
|
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
//#endregion
|
|
127
|
-
export { Builder, Collector, CollectorWithContext, RuleDefinition, type RuleFix, type RuleFixer, type RuleListener,
|
|
128
|
+
export { Builder, Collector, CollectorWithContext, RuleDefinition, type RuleFix, type RuleFixer, type RuleListener, build as default, merge };
|
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.1";
|
|
8
8
|
|
|
9
9
|
//#endregion
|
|
10
10
|
//#region src/index.ts
|
|
@@ -102,29 +102,32 @@ function makeRuleToolkit(context) {
|
|
|
102
102
|
settings: getSettingsFromContext(context)
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
|
-
function
|
|
105
|
+
function build() {
|
|
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
|
|
@@ -138,4 +141,4 @@ function eslintReactKit() {
|
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
//#endregion
|
|
141
|
-
export {
|
|
144
|
+
export { build as default, merge };
|
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.1",
|
|
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/
|
|
43
|
-
"@eslint-react/
|
|
41
|
+
"@eslint-react/ast": "4.0.2-beta.1",
|
|
42
|
+
"@eslint-react/shared": "4.0.2-beta.1",
|
|
43
|
+
"@eslint-react/core": "4.0.2-beta.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"eslint": "^10.1.0",
|