@eslint-react/kit 4.0.0-beta.3 → 4.0.1-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 +146 -73
- package/dist/index.d.ts +11 -8
- package/dist/index.js +74 -66
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -7,7 +7,9 @@ ESLint React's toolkit for building custom React lint rules right inside your `e
|
|
|
7
7
|
- [Installation](#installation)
|
|
8
8
|
- [Quick Start](#quick-start)
|
|
9
9
|
- [API Reference](#api-reference)
|
|
10
|
-
- [`
|
|
10
|
+
- [`eslintReactKit` (default export)](#eslintreactkit-default-export)
|
|
11
|
+
- [`RuleDefinition`](#ruledefinition)
|
|
12
|
+
- [`Builder`](#builder)
|
|
11
13
|
- [`merge`](#merge)
|
|
12
14
|
- [`Kit` — the toolkit object](#kit--the-toolkit-object)
|
|
13
15
|
- [`kit.collect`](#kitcollect) — Semantic collectors
|
|
@@ -33,10 +35,32 @@ npm install --save-dev @eslint-react/kit@beta
|
|
|
33
35
|
```ts
|
|
34
36
|
import eslintReact from "@eslint-react/eslint-plugin";
|
|
35
37
|
import eslintReactKit, { merge } from "@eslint-react/kit";
|
|
38
|
+
import type { RuleDefinition } from "@eslint-react/kit";
|
|
36
39
|
import eslintJs from "@eslint/js";
|
|
37
40
|
import { defineConfig } from "eslint/config";
|
|
38
41
|
import tseslint from "typescript-eslint";
|
|
39
42
|
|
|
43
|
+
/** Enforce function declarations for function components. */
|
|
44
|
+
function functionComponentDefinition(): RuleDefinition {
|
|
45
|
+
return (context, { collect }) => {
|
|
46
|
+
const { query, visitor } = collect.components(context);
|
|
47
|
+
return merge(
|
|
48
|
+
visitor,
|
|
49
|
+
{
|
|
50
|
+
"Program:exit"(program) {
|
|
51
|
+
for (const { node } of query.all(program)) {
|
|
52
|
+
if (node.type === "FunctionDeclaration") continue;
|
|
53
|
+
context.report({
|
|
54
|
+
node,
|
|
55
|
+
message: "Function components must be defined with function declarations.",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
40
64
|
export default defineConfig(
|
|
41
65
|
{
|
|
42
66
|
files: ["**/*.{ts,tsx}"],
|
|
@@ -44,55 +68,75 @@ export default defineConfig(
|
|
|
44
68
|
eslintJs.configs.recommended,
|
|
45
69
|
tseslint.configs.recommended,
|
|
46
70
|
eslintReact.configs["recommended-typescript"],
|
|
47
|
-
eslintReactKit(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
make: (context, { collect }) => {
|
|
51
|
-
const { query, visitor } = collect.components(context);
|
|
52
|
-
|
|
53
|
-
return merge(
|
|
54
|
-
visitor,
|
|
55
|
-
{
|
|
56
|
-
"Program:exit"(program) {
|
|
57
|
-
for (const { node } of query.all(program)) {
|
|
58
|
-
if (node.type === "FunctionDeclaration") continue;
|
|
59
|
-
context.report({
|
|
60
|
-
node,
|
|
61
|
-
message: "Function components must be defined with function declarations.",
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
);
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
),
|
|
71
|
+
eslintReactKit()
|
|
72
|
+
.use(functionComponentDefinition)
|
|
73
|
+
.getConfig(),
|
|
70
74
|
],
|
|
71
|
-
rules: {
|
|
72
|
-
"@eslint-react/kit/function-component-definition": "error",
|
|
73
|
-
},
|
|
74
75
|
},
|
|
75
76
|
);
|
|
76
77
|
```
|
|
77
78
|
|
|
79
|
+
The rule name is derived automatically from the function name (`functionComponentDefinition` → `function-component-definition`), and registered as `@eslint-react/kit/function-component-definition` at `"error"` severity.
|
|
80
|
+
|
|
78
81
|
## API Reference
|
|
79
82
|
|
|
80
|
-
### `
|
|
83
|
+
### `eslintReactKit` (default export)
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import eslintReactKit from "@eslint-react/kit";
|
|
87
|
+
|
|
88
|
+
eslintReactKit(): Builder
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Creates a `Builder` instance for registering custom rules via the chainable `.use()` API.
|
|
92
|
+
|
|
93
|
+
### `RuleDefinition`
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import type { RuleDefinition } from "@eslint-react/kit";
|
|
97
|
+
|
|
98
|
+
type RuleDefinition = (ctx: RuleContext, kit: RuleToolkit) => RuleListener;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
A rule definition is a function that receives the ESLint rule context and the structured `Kit` toolkit, and returns a `RuleListener` (AST visitor object).
|
|
102
|
+
|
|
103
|
+
Rules are defined as **named functions** that return a `RuleDefinition`. The function name is automatically converted to kebab-case and used as the rule name under the `@eslint-react/kit` plugin namespace.
|
|
81
104
|
|
|
82
105
|
```ts
|
|
83
|
-
|
|
106
|
+
// Function name `noForwardRef` → rule name `no-forward-ref`
|
|
107
|
+
// Registered as `@eslint-react/kit/no-forward-ref`
|
|
108
|
+
function noForwardRef(): RuleDefinition {
|
|
109
|
+
return (context, { is }) => ({ ... });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Functions that accept options work the same way
|
|
113
|
+
function forbidElements({ forbidden }: ForbidElementsOptions): RuleDefinition {
|
|
114
|
+
return (context) => ({ ... });
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### `Builder`
|
|
84
119
|
|
|
85
|
-
|
|
120
|
+
```ts
|
|
121
|
+
interface Builder {
|
|
122
|
+
use<F extends (...args: any[]) => RuleDefinition>(factory: F, ...args: Parameters<F>): Builder;
|
|
123
|
+
getConfig(): Linter.Config;
|
|
124
|
+
}
|
|
86
125
|
```
|
|
87
126
|
|
|
88
|
-
|
|
127
|
+
A chainable builder for registering custom rules.
|
|
89
128
|
|
|
90
|
-
|
|
129
|
+
| Method | Description |
|
|
130
|
+
| ----------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
131
|
+
| `use` | Registers a rule factory. The rule name is `kebabCase(factory.name)`. Options type is inferred from the factory signature. |
|
|
132
|
+
| `getConfig` | Returns a `Linter.Config` with all registered rules enabled at `"error"` severity. |
|
|
91
133
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
134
|
+
```ts
|
|
135
|
+
eslintReactKit()
|
|
136
|
+
.use(noForwardRef) // no-arg factory
|
|
137
|
+
.use(forbidElements, { forbidden: new Map() }) // factory with inferred options
|
|
138
|
+
.getConfig();
|
|
139
|
+
```
|
|
96
140
|
|
|
97
141
|
### `merge`
|
|
98
142
|
|
|
@@ -108,7 +152,7 @@ This is essential for combining a collector's `visitor` with your own inspection
|
|
|
108
152
|
|
|
109
153
|
### Kit — the toolkit object
|
|
110
154
|
|
|
111
|
-
The second argument to `
|
|
155
|
+
The second argument passed to the `RuleDefinition` function is a structured `Kit` object:
|
|
112
156
|
|
|
113
157
|
```
|
|
114
158
|
kit
|
|
@@ -273,9 +317,10 @@ Exposes the normalized `react-x` settings from the ESLint shared configuration (
|
|
|
273
317
|
**Usage:**
|
|
274
318
|
|
|
275
319
|
```ts
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
320
|
+
import type { RuleDefinition } from "@eslint-react/kit";
|
|
321
|
+
|
|
322
|
+
function requireReact19(): RuleDefinition {
|
|
323
|
+
return (context, { settings }) => ({
|
|
279
324
|
Program(program) {
|
|
280
325
|
if (!settings.version.startsWith("19.")) {
|
|
281
326
|
context.report({
|
|
@@ -284,8 +329,8 @@ defineReactConfig({
|
|
|
284
329
|
});
|
|
285
330
|
}
|
|
286
331
|
},
|
|
287
|
-
})
|
|
288
|
-
}
|
|
332
|
+
});
|
|
333
|
+
}
|
|
289
334
|
```
|
|
290
335
|
|
|
291
336
|
---
|
|
@@ -297,16 +342,22 @@ defineReactConfig({
|
|
|
297
342
|
This is a simplified kit reimplementation of the built-in [`react-x/no-forwardRef`](https://beta.eslint-react.xyz/docs/rules/no-forward-ref) rule.
|
|
298
343
|
|
|
299
344
|
```ts
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
345
|
+
import type { RuleDefinition } from "@eslint-react/kit";
|
|
346
|
+
|
|
347
|
+
function noForwardRef(): RuleDefinition {
|
|
348
|
+
return (context, { is }) => ({
|
|
303
349
|
CallExpression(node) {
|
|
304
350
|
if (is.forwardRefCall(node)) {
|
|
305
351
|
context.report({ node, message: "forwardRef is deprecated in React 19. Pass ref as a prop instead." });
|
|
306
352
|
}
|
|
307
353
|
},
|
|
308
|
-
})
|
|
309
|
-
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Usage
|
|
358
|
+
eslintReactKit()
|
|
359
|
+
.use(noForwardRef)
|
|
360
|
+
.getConfig();
|
|
310
361
|
```
|
|
311
362
|
|
|
312
363
|
### Component: Destructure component props
|
|
@@ -314,9 +365,11 @@ defineReactConfig({
|
|
|
314
365
|
This is a simplified kit reimplementation of the built-in [`react-x/prefer-destructuring-assignment`](https://beta.eslint-react.xyz/docs/rules/prefer-destructuring-assignment) rule.
|
|
315
366
|
|
|
316
367
|
```ts
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
368
|
+
import type { RuleDefinition } from "@eslint-react/kit";
|
|
369
|
+
import { merge } from "@eslint-react/kit";
|
|
370
|
+
|
|
371
|
+
function destructureComponentProps(): RuleDefinition {
|
|
372
|
+
return (context, { collect }) => {
|
|
320
373
|
const { query, visitor } = collect.components(context);
|
|
321
374
|
|
|
322
375
|
return merge(visitor, {
|
|
@@ -324,13 +377,13 @@ defineReactConfig({
|
|
|
324
377
|
for (const { node } of query.all(program)) {
|
|
325
378
|
const [props] = node.params;
|
|
326
379
|
if (props == null) continue;
|
|
327
|
-
if (props.type !==
|
|
380
|
+
if (props.type !== "Identifier") continue;
|
|
328
381
|
const propName = props.name;
|
|
329
382
|
const propVariable = context.sourceCode.getScope(node).variables.find((v) => v.name === propName);
|
|
330
383
|
const propReferences = propVariable?.references ?? [];
|
|
331
384
|
for (const ref of propReferences) {
|
|
332
385
|
const { parent } = ref.identifier;
|
|
333
|
-
if (parent.type !==
|
|
386
|
+
if (parent.type !== "MemberExpression") continue;
|
|
334
387
|
context.report({
|
|
335
388
|
message: "Use destructuring assignment for component props.",
|
|
336
389
|
node: parent,
|
|
@@ -339,8 +392,13 @@ defineReactConfig({
|
|
|
339
392
|
}
|
|
340
393
|
},
|
|
341
394
|
});
|
|
342
|
-
}
|
|
343
|
-
}
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// Usage
|
|
399
|
+
eslintReactKit()
|
|
400
|
+
.use(destructureComponentProps)
|
|
401
|
+
.getConfig();
|
|
344
402
|
```
|
|
345
403
|
|
|
346
404
|
### Hooks: Warn on custom hooks that don't call other hooks
|
|
@@ -348,9 +406,11 @@ defineReactConfig({
|
|
|
348
406
|
This is a simplified kit reimplementation of the built-in [`react-x/no-unnecessary-use-prefix`](https://beta.eslint-react.xyz/docs/rules/no-unnecessary-use-prefix) rule.
|
|
349
407
|
|
|
350
408
|
```ts
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
409
|
+
import type { RuleDefinition } from "@eslint-react/kit";
|
|
410
|
+
import { merge } from "@eslint-react/kit";
|
|
411
|
+
|
|
412
|
+
function noUnnecessaryUsePrefix(): RuleDefinition {
|
|
413
|
+
return (context, { collect }) => {
|
|
354
414
|
const { query, visitor } = collect.hooks(context);
|
|
355
415
|
|
|
356
416
|
return merge(visitor, {
|
|
@@ -365,8 +425,13 @@ defineReactConfig({
|
|
|
365
425
|
}
|
|
366
426
|
},
|
|
367
427
|
});
|
|
368
|
-
}
|
|
369
|
-
}
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Usage
|
|
432
|
+
eslintReactKit()
|
|
433
|
+
.use(noUnnecessaryUsePrefix)
|
|
434
|
+
.getConfig();
|
|
370
435
|
```
|
|
371
436
|
|
|
372
437
|
### Multiple Collectors: No component/hook factories
|
|
@@ -375,9 +440,23 @@ Disallow defining components or hooks inside other functions (factory pattern).
|
|
|
375
440
|
This is a simplified kit reimplementation of the built-in [`react-x/component-hook-factories`](https://beta.eslint-react.xyz/docs/rules/component-hook-factories) rule.
|
|
376
441
|
|
|
377
442
|
```ts
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
443
|
+
import type { RuleDefinition } from "@eslint-react/kit";
|
|
444
|
+
import { merge } from "@eslint-react/kit";
|
|
445
|
+
import type { TSESTree } from "@typescript-eslint/utils";
|
|
446
|
+
|
|
447
|
+
function findParent({ parent }: TSESTree.Node, test: (n: TSESTree.Node) => boolean): TSESTree.Node | null {
|
|
448
|
+
if (parent == null) return null;
|
|
449
|
+
if (test(parent)) return parent;
|
|
450
|
+
if (parent.type === "Program") return null;
|
|
451
|
+
return findParent(parent, test);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function isFunction({ type }: TSESTree.Node) {
|
|
455
|
+
return type === "FunctionDeclaration" || type === "FunctionExpression" || type === "ArrowFunctionExpression";
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function componentHookFactories(): RuleDefinition {
|
|
459
|
+
return (context, { collect }) => {
|
|
381
460
|
const fc = collect.components(context);
|
|
382
461
|
const hk = collect.hooks(context);
|
|
383
462
|
return merge(
|
|
@@ -398,19 +477,13 @@ defineReactConfig({
|
|
|
398
477
|
},
|
|
399
478
|
},
|
|
400
479
|
);
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
function findParent({ parent }: TSESTree.Node, test: (n: TSESTree.Node) => boolean): TSESTree.Node | null {
|
|
405
|
-
if (parent == null) return null;
|
|
406
|
-
if (test(parent)) return parent;
|
|
407
|
-
if (parent.type === "Program") return null;
|
|
408
|
-
return findParent(parent, test);
|
|
480
|
+
};
|
|
409
481
|
}
|
|
410
482
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
483
|
+
// Usage
|
|
484
|
+
eslintReactKit()
|
|
485
|
+
.use(componentHookFactories)
|
|
486
|
+
.getConfig();
|
|
414
487
|
```
|
|
415
488
|
|
|
416
489
|
## More Examples
|
package/dist/index.d.ts
CHANGED
|
@@ -17,17 +17,13 @@ interface CollectorWithContext<T> extends Collector<T> {
|
|
|
17
17
|
all(program: TSESTree.Program): T[];
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
interface RuleDefinition {
|
|
21
|
-
name: string;
|
|
22
|
-
make(ctx: RuleContext, kit: RuleToolkit): RuleListener;
|
|
23
|
-
}
|
|
24
20
|
interface RuleToolkit {
|
|
25
21
|
collect: {
|
|
26
|
-
components(
|
|
22
|
+
components(context: RuleContext, options?: {
|
|
27
23
|
collectDisplayName?: boolean;
|
|
28
24
|
hint?: bigint;
|
|
29
25
|
}): CollectorWithContext<core.FunctionComponentSemanticNode>;
|
|
30
|
-
hooks(
|
|
26
|
+
hooks(context: RuleContext): CollectorWithContext<core.HookSemanticNode>;
|
|
31
27
|
};
|
|
32
28
|
flag: {
|
|
33
29
|
component: typeof core.ComponentFlag;
|
|
@@ -103,7 +99,14 @@ interface RuleToolkit {
|
|
|
103
99
|
};
|
|
104
100
|
settings: ESLintReactSettingsNormalized;
|
|
105
101
|
}
|
|
106
|
-
|
|
102
|
+
type RuleDefinition = (context: RuleContext, toolkit: RuleToolkit) => RuleListener;
|
|
103
|
+
interface Builder {
|
|
104
|
+
getConfig(args?: {
|
|
105
|
+
files?: string[];
|
|
106
|
+
}): Linter.Config;
|
|
107
|
+
use<F extends (...args: any[]) => RuleDefinition>(factory: F, ...args: Parameters<F>): Builder;
|
|
108
|
+
}
|
|
109
|
+
declare function eslintReactKit(): Builder;
|
|
107
110
|
declare module "@typescript-eslint/utils/ts-eslint" {
|
|
108
111
|
interface RuleContext<MessageIds extends string = string, Options extends readonly unknown[] = readonly unknown[]> {
|
|
109
112
|
report(descriptor: {
|
|
@@ -121,4 +124,4 @@ declare module "@typescript-eslint/utils/ts-eslint" {
|
|
|
121
124
|
}
|
|
122
125
|
}
|
|
123
126
|
//#endregion
|
|
124
|
-
export { Collector, CollectorWithContext, RuleDefinition, type RuleFix, type RuleFixer, type RuleListener,
|
|
127
|
+
export { Builder, Collector, CollectorWithContext, RuleDefinition, type RuleFix, type RuleFixer, type RuleListener, eslintReactKit as default, merge };
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import * as core from "@eslint-react/core";
|
|
2
|
-
import { defineRuleListener as merge, getSettingsFromContext } from "@eslint-react/shared";
|
|
2
|
+
import { IdGenerator, defineRuleListener as merge, getSettingsFromContext } from "@eslint-react/shared";
|
|
3
|
+
import { kebabCase } from "string-ts";
|
|
3
4
|
|
|
4
5
|
//#region package.json
|
|
5
6
|
var name = "@eslint-react/kit";
|
|
6
|
-
var version = "4.0.
|
|
7
|
+
var version = "4.0.1-beta.1";
|
|
7
8
|
|
|
8
9
|
//#endregion
|
|
9
10
|
//#region src/index.ts
|
|
10
|
-
function
|
|
11
|
+
function makeRuleToolkit(context) {
|
|
11
12
|
return {
|
|
12
13
|
collect: {
|
|
13
|
-
components(
|
|
14
|
-
const { api, visitor } = core.getComponentCollector(
|
|
14
|
+
components(context, options) {
|
|
15
|
+
const { api, visitor } = core.getComponentCollector(context, options);
|
|
15
16
|
return {
|
|
16
17
|
query: { all(program) {
|
|
17
18
|
return api.getAllComponents(program);
|
|
@@ -19,8 +20,8 @@ function createKit(ctx) {
|
|
|
19
20
|
visitor
|
|
20
21
|
};
|
|
21
22
|
},
|
|
22
|
-
hooks(
|
|
23
|
-
const { api, visitor } = core.getHookCollector(
|
|
23
|
+
hooks(context) {
|
|
24
|
+
const { api, visitor } = core.getHookCollector(context);
|
|
24
25
|
return {
|
|
25
26
|
query: { all(program) {
|
|
26
27
|
return api.getAllHooks(program);
|
|
@@ -35,45 +36,45 @@ function createKit(ctx) {
|
|
|
35
36
|
Default: core.DEFAULT_COMPONENT_DETECTION_HINT
|
|
36
37
|
} },
|
|
37
38
|
is: {
|
|
38
|
-
captureOwnerStack: core.isCaptureOwnerStack(
|
|
39
|
-
captureOwnerStackCall: core.isCaptureOwnerStackCall(
|
|
40
|
-
childrenCount: core.isChildrenCount(
|
|
41
|
-
childrenCountCall: core.isChildrenCountCall(
|
|
42
|
-
childrenForEach: core.isChildrenForEach(
|
|
43
|
-
childrenForEachCall: core.isChildrenForEachCall(
|
|
44
|
-
childrenMap: core.isChildrenMap(
|
|
45
|
-
childrenMapCall: core.isChildrenMapCall(
|
|
46
|
-
childrenOnly: core.isChildrenOnly(
|
|
47
|
-
childrenOnlyCall: core.isChildrenOnlyCall(
|
|
48
|
-
childrenToArray: core.isChildrenToArray(
|
|
49
|
-
childrenToArrayCall: core.isChildrenToArrayCall(
|
|
50
|
-
cloneElement: core.isCloneElement(
|
|
51
|
-
cloneElementCall: core.isCloneElementCall(
|
|
52
|
-
componentDefinition: (node, hint) => core.isComponentDefinition(
|
|
39
|
+
captureOwnerStack: core.isCaptureOwnerStack(context),
|
|
40
|
+
captureOwnerStackCall: core.isCaptureOwnerStackCall(context),
|
|
41
|
+
childrenCount: core.isChildrenCount(context),
|
|
42
|
+
childrenCountCall: core.isChildrenCountCall(context),
|
|
43
|
+
childrenForEach: core.isChildrenForEach(context),
|
|
44
|
+
childrenForEachCall: core.isChildrenForEachCall(context),
|
|
45
|
+
childrenMap: core.isChildrenMap(context),
|
|
46
|
+
childrenMapCall: core.isChildrenMapCall(context),
|
|
47
|
+
childrenOnly: core.isChildrenOnly(context),
|
|
48
|
+
childrenOnlyCall: core.isChildrenOnlyCall(context),
|
|
49
|
+
childrenToArray: core.isChildrenToArray(context),
|
|
50
|
+
childrenToArrayCall: core.isChildrenToArrayCall(context),
|
|
51
|
+
cloneElement: core.isCloneElement(context),
|
|
52
|
+
cloneElementCall: core.isCloneElementCall(context),
|
|
53
|
+
componentDefinition: (node, hint) => core.isComponentDefinition(context, node, hint),
|
|
53
54
|
componentName: core.isComponentName,
|
|
54
55
|
componentNameLoose: core.isComponentNameLoose,
|
|
55
|
-
componentWrapperCall: (node) => core.isComponentWrapperCall(
|
|
56
|
-
componentWrapperCallback: (node) => core.isComponentWrapperCallback(
|
|
57
|
-
componentWrapperCallLoose: (node) => core.isComponentWrapperCallLoose(
|
|
58
|
-
createContext: core.isCreateContext(
|
|
59
|
-
createContextCall: core.isCreateContextCall(
|
|
60
|
-
createElement: core.isCreateElement(
|
|
61
|
-
createElementCall: core.isCreateElementCall(
|
|
62
|
-
createRef: core.isCreateRef(
|
|
63
|
-
createRefCall: core.isCreateRefCall(
|
|
64
|
-
forwardRef: core.isForwardRef(
|
|
65
|
-
forwardRefCall: core.isForwardRefCall(
|
|
56
|
+
componentWrapperCall: (node) => core.isComponentWrapperCall(context, node),
|
|
57
|
+
componentWrapperCallback: (node) => core.isComponentWrapperCallback(context, node),
|
|
58
|
+
componentWrapperCallLoose: (node) => core.isComponentWrapperCallLoose(context, node),
|
|
59
|
+
createContext: core.isCreateContext(context),
|
|
60
|
+
createContextCall: core.isCreateContextCall(context),
|
|
61
|
+
createElement: core.isCreateElement(context),
|
|
62
|
+
createElementCall: core.isCreateElementCall(context),
|
|
63
|
+
createRef: core.isCreateRef(context),
|
|
64
|
+
createRefCall: core.isCreateRefCall(context),
|
|
65
|
+
forwardRef: core.isForwardRef(context),
|
|
66
|
+
forwardRefCall: core.isForwardRefCall(context),
|
|
66
67
|
hook: core.isHook,
|
|
67
68
|
hookCall: core.isHookCall,
|
|
68
69
|
hookName: core.isHookName,
|
|
69
70
|
initializedFromReact: core.isInitializedFromReact,
|
|
70
71
|
initializedFromReactNative: core.isInitializedFromReactNative,
|
|
71
|
-
lazy: core.isLazy(
|
|
72
|
-
lazyCall: core.isLazyCall(
|
|
73
|
-
memo: core.isMemo(
|
|
74
|
-
memoCall: core.isMemoCall(
|
|
75
|
-
reactAPI: (api) => core.isReactAPI(api)(
|
|
76
|
-
reactAPICall: (api) => core.isReactAPICall(api)(
|
|
72
|
+
lazy: core.isLazy(context),
|
|
73
|
+
lazyCall: core.isLazyCall(context),
|
|
74
|
+
memo: core.isMemo(context),
|
|
75
|
+
memoCall: core.isMemoCall(context),
|
|
76
|
+
reactAPI: (api) => core.isReactAPI(api)(context),
|
|
77
|
+
reactAPICall: (api) => core.isReactAPICall(api)(context),
|
|
77
78
|
useActionStateCall: core.isUseActionStateCall,
|
|
78
79
|
useCall: core.isUseCall,
|
|
79
80
|
useCallbackCall: core.isUseCallbackCall,
|
|
@@ -98,36 +99,43 @@ function createKit(ctx) {
|
|
|
98
99
|
useSyncExternalStoreCall: core.isUseSyncExternalStoreCall,
|
|
99
100
|
useTransitionCall: core.isUseTransitionCall
|
|
100
101
|
},
|
|
101
|
-
settings: getSettingsFromContext(
|
|
102
|
+
settings: getSettingsFromContext(context)
|
|
102
103
|
};
|
|
103
104
|
}
|
|
104
|
-
function
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
105
|
+
function eslintReactKit() {
|
|
106
|
+
const idGen = new IdGenerator();
|
|
107
|
+
const plugin = {
|
|
108
|
+
meta: {
|
|
109
|
+
name,
|
|
110
|
+
version
|
|
111
|
+
},
|
|
112
|
+
rules: {}
|
|
113
|
+
};
|
|
114
|
+
const builder = {
|
|
115
|
+
getConfig({ files = ["**/*.ts", "**/*.tsx"] } = {}) {
|
|
116
|
+
return {
|
|
117
|
+
files,
|
|
118
|
+
plugins: { [name]: plugin },
|
|
119
|
+
rules: Object.keys(plugin.rules).reduce((acc, name$1) => {
|
|
120
|
+
acc[`${name}/${name$1}`] = "error";
|
|
121
|
+
return acc;
|
|
122
|
+
}, {})
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
use(make, ...args) {
|
|
126
|
+
const name = kebabCase(make.name === "" ? idGen.next() : make.name);
|
|
127
|
+
Reflect.set(plugin.rules, name, {
|
|
128
|
+
meta: {
|
|
129
|
+
fixable: "code",
|
|
130
|
+
hasSuggestions: true
|
|
131
|
+
},
|
|
132
|
+
create: (context) => make(...args)(context, makeRuleToolkit(context))
|
|
133
|
+
});
|
|
134
|
+
return builder;
|
|
135
|
+
}
|
|
129
136
|
};
|
|
137
|
+
return builder;
|
|
130
138
|
}
|
|
131
139
|
|
|
132
140
|
//#endregion
|
|
133
|
-
export {
|
|
141
|
+
export { eslintReactKit 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.1-beta.1",
|
|
4
4
|
"description": "ESLint React's utility module for building custom rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -37,9 +37,10 @@
|
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@typescript-eslint/utils": "^8.57.2",
|
|
40
|
-
"
|
|
41
|
-
"@eslint-react/
|
|
42
|
-
"@eslint-react/
|
|
40
|
+
"string-ts": "^2.3.1",
|
|
41
|
+
"@eslint-react/ast": "4.0.1-beta.1",
|
|
42
|
+
"@eslint-react/core": "4.0.1-beta.1",
|
|
43
|
+
"@eslint-react/shared": "4.0.1-beta.1"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"eslint": "^10.1.0",
|