@eslint-react/kit 4.0.1-beta.0 → 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 CHANGED
@@ -9,7 +9,7 @@ ESLint React's toolkit for building custom React lint rules right inside your `e
9
9
  - [API Reference](#api-reference)
10
10
  - [`eslintReactKit` (default export)](#eslintreactkit-default-export)
11
11
  - [`RuleDefinition`](#ruledefinition)
12
- - [`KitBuilder`](#kitbuilder)
12
+ - [`Builder`](#builder)
13
13
  - [`merge`](#merge)
14
14
  - [`Kit` — the toolkit object](#kit--the-toolkit-object)
15
15
  - [`kit.collect`](#kitcollect) — Semantic collectors
@@ -85,10 +85,10 @@ The rule name is derived automatically from the function name (`functionComponen
85
85
  ```ts
86
86
  import eslintReactKit from "@eslint-react/kit";
87
87
 
88
- eslintReactKit(): KitBuilder
88
+ eslintReactKit(): Builder
89
89
  ```
90
90
 
91
- Creates a `KitBuilder` instance for registering custom rules via the chainable `.use()` API.
91
+ Creates a `Builder` instance for registering custom rules via the chainable `.use()` API.
92
92
 
93
93
  ### `RuleDefinition`
94
94
 
@@ -115,11 +115,11 @@ function forbidElements({ forbidden }: ForbidElementsOptions): RuleDefinition {
115
115
  }
116
116
  ```
117
117
 
118
- ### `KitBuilder`
118
+ ### `Builder`
119
119
 
120
120
  ```ts
121
- interface KitBuilder {
122
- use<F extends (...args: any[]) => RuleDefinition>(factory: F, ...args: Parameters<F>): KitBuilder;
121
+ interface Builder {
122
+ use<F extends (...args: any[]) => RuleDefinition>(factory: F, ...args: Parameters<F>): Builder;
123
123
  getConfig(): Linter.Config;
124
124
  }
125
125
  ```
@@ -317,6 +317,8 @@ Exposes the normalized `react-x` settings from the ESLint shared configuration (
317
317
  **Usage:**
318
318
 
319
319
  ```ts
320
+ import type { RuleDefinition } from "@eslint-react/kit";
321
+
320
322
  function requireReact19(): RuleDefinition {
321
323
  return (context, { settings }) => ({
322
324
  Program(program) {
@@ -340,6 +342,8 @@ function requireReact19(): RuleDefinition {
340
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.
341
343
 
342
344
  ```ts
345
+ import type { RuleDefinition } from "@eslint-react/kit";
346
+
343
347
  function noForwardRef(): RuleDefinition {
344
348
  return (context, { is }) => ({
345
349
  CallExpression(node) {
@@ -361,6 +365,9 @@ eslintReactKit()
361
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.
362
366
 
363
367
  ```ts
368
+ import type { RuleDefinition } from "@eslint-react/kit";
369
+ import { merge } from "@eslint-react/kit";
370
+
364
371
  function destructureComponentProps(): RuleDefinition {
365
372
  return (context, { collect }) => {
366
373
  const { query, visitor } = collect.components(context);
@@ -370,13 +377,13 @@ function destructureComponentProps(): RuleDefinition {
370
377
  for (const { node } of query.all(program)) {
371
378
  const [props] = node.params;
372
379
  if (props == null) continue;
373
- if (props.type !== AST.Identifier) continue;
380
+ if (props.type !== "Identifier") continue;
374
381
  const propName = props.name;
375
382
  const propVariable = context.sourceCode.getScope(node).variables.find((v) => v.name === propName);
376
383
  const propReferences = propVariable?.references ?? [];
377
384
  for (const ref of propReferences) {
378
385
  const { parent } = ref.identifier;
379
- if (parent.type !== AST.MemberExpression) continue;
386
+ if (parent.type !== "MemberExpression") continue;
380
387
  context.report({
381
388
  message: "Use destructuring assignment for component props.",
382
389
  node: parent,
@@ -399,6 +406,9 @@ eslintReactKit()
399
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.
400
407
 
401
408
  ```ts
409
+ import type { RuleDefinition } from "@eslint-react/kit";
410
+ import { merge } from "@eslint-react/kit";
411
+
402
412
  function noUnnecessaryUsePrefix(): RuleDefinition {
403
413
  return (context, { collect }) => {
404
414
  const { query, visitor } = collect.hooks(context);
@@ -430,6 +440,10 @@ Disallow defining components or hooks inside other functions (factory pattern).
430
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.
431
441
 
432
442
  ```ts
443
+ import type { RuleDefinition } from "@eslint-react/kit";
444
+ import { merge } from "@eslint-react/kit";
445
+ import type { TSESTree } from "@typescript-eslint/utils";
446
+
433
447
  function findParent({ parent }: TSESTree.Node, test: (n: TSESTree.Node) => boolean): TSESTree.Node | null {
434
448
  if (parent == null) return null;
435
449
  if (test(parent)) return parent;
package/dist/index.d.ts CHANGED
@@ -17,20 +17,13 @@ interface CollectorWithContext<T> extends Collector<T> {
17
17
  all(program: TSESTree.Program): T[];
18
18
  };
19
19
  }
20
- type RuleDefinition = (ctx: RuleContext, kit: RuleToolkit) => RuleListener;
21
- interface KitBuilder {
22
- getConfig(args?: {
23
- files?: string[];
24
- }): Linter.Config;
25
- use<F extends (...args: any[]) => RuleDefinition>(factory: F, ...args: Parameters<F>): KitBuilder;
26
- }
27
20
  interface RuleToolkit {
28
21
  collect: {
29
- components(ctx: RuleContext, options?: {
22
+ components(context: RuleContext, options?: {
30
23
  collectDisplayName?: boolean;
31
24
  hint?: bigint;
32
25
  }): CollectorWithContext<core.FunctionComponentSemanticNode>;
33
- hooks(ctx: RuleContext): CollectorWithContext<core.HookSemanticNode>;
26
+ hooks(context: RuleContext): CollectorWithContext<core.HookSemanticNode>;
34
27
  };
35
28
  flag: {
36
29
  component: typeof core.ComponentFlag;
@@ -106,7 +99,14 @@ interface RuleToolkit {
106
99
  };
107
100
  settings: ESLintReactSettingsNormalized;
108
101
  }
109
- declare function eslintReactKit(): KitBuilder;
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;
110
110
  declare module "@typescript-eslint/utils/ts-eslint" {
111
111
  interface RuleContext<MessageIds extends string = string, Options extends readonly unknown[] = readonly unknown[]> {
112
112
  report(descriptor: {
@@ -124,4 +124,4 @@ declare module "@typescript-eslint/utils/ts-eslint" {
124
124
  }
125
125
  }
126
126
  //#endregion
127
- export { Collector, CollectorWithContext, KitBuilder, RuleDefinition, type RuleFix, type RuleFixer, type RuleListener, eslintReactKit as default, merge };
127
+ export { Builder, Collector, CollectorWithContext, RuleDefinition, type RuleFix, type RuleFixer, type RuleListener, eslintReactKit as default, merge };
package/dist/index.js CHANGED
@@ -4,15 +4,15 @@ import { kebabCase } from "string-ts";
4
4
 
5
5
  //#region package.json
6
6
  var name = "@eslint-react/kit";
7
- var version = "4.0.1-beta.0";
7
+ var version = "4.0.1-beta.1";
8
8
 
9
9
  //#endregion
10
10
  //#region src/index.ts
11
- function createKit(ctx) {
11
+ function makeRuleToolkit(context) {
12
12
  return {
13
13
  collect: {
14
- components(ctx, options) {
15
- const { api, visitor } = core.getComponentCollector(ctx, options);
14
+ components(context, options) {
15
+ const { api, visitor } = core.getComponentCollector(context, options);
16
16
  return {
17
17
  query: { all(program) {
18
18
  return api.getAllComponents(program);
@@ -20,8 +20,8 @@ function createKit(ctx) {
20
20
  visitor
21
21
  };
22
22
  },
23
- hooks(ctx) {
24
- const { api, visitor } = core.getHookCollector(ctx);
23
+ hooks(context) {
24
+ const { api, visitor } = core.getHookCollector(context);
25
25
  return {
26
26
  query: { all(program) {
27
27
  return api.getAllHooks(program);
@@ -36,45 +36,45 @@ function createKit(ctx) {
36
36
  Default: core.DEFAULT_COMPONENT_DETECTION_HINT
37
37
  } },
38
38
  is: {
39
- captureOwnerStack: core.isCaptureOwnerStack(ctx),
40
- captureOwnerStackCall: core.isCaptureOwnerStackCall(ctx),
41
- childrenCount: core.isChildrenCount(ctx),
42
- childrenCountCall: core.isChildrenCountCall(ctx),
43
- childrenForEach: core.isChildrenForEach(ctx),
44
- childrenForEachCall: core.isChildrenForEachCall(ctx),
45
- childrenMap: core.isChildrenMap(ctx),
46
- childrenMapCall: core.isChildrenMapCall(ctx),
47
- childrenOnly: core.isChildrenOnly(ctx),
48
- childrenOnlyCall: core.isChildrenOnlyCall(ctx),
49
- childrenToArray: core.isChildrenToArray(ctx),
50
- childrenToArrayCall: core.isChildrenToArrayCall(ctx),
51
- cloneElement: core.isCloneElement(ctx),
52
- cloneElementCall: core.isCloneElementCall(ctx),
53
- componentDefinition: (node, hint) => core.isComponentDefinition(ctx, node, hint),
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),
54
54
  componentName: core.isComponentName,
55
55
  componentNameLoose: core.isComponentNameLoose,
56
- componentWrapperCall: (node) => core.isComponentWrapperCall(ctx, node),
57
- componentWrapperCallback: (node) => core.isComponentWrapperCallback(ctx, node),
58
- componentWrapperCallLoose: (node) => core.isComponentWrapperCallLoose(ctx, node),
59
- createContext: core.isCreateContext(ctx),
60
- createContextCall: core.isCreateContextCall(ctx),
61
- createElement: core.isCreateElement(ctx),
62
- createElementCall: core.isCreateElementCall(ctx),
63
- createRef: core.isCreateRef(ctx),
64
- createRefCall: core.isCreateRefCall(ctx),
65
- forwardRef: core.isForwardRef(ctx),
66
- forwardRefCall: core.isForwardRefCall(ctx),
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),
67
67
  hook: core.isHook,
68
68
  hookCall: core.isHookCall,
69
69
  hookName: core.isHookName,
70
70
  initializedFromReact: core.isInitializedFromReact,
71
71
  initializedFromReactNative: core.isInitializedFromReactNative,
72
- lazy: core.isLazy(ctx),
73
- lazyCall: core.isLazyCall(ctx),
74
- memo: core.isMemo(ctx),
75
- memoCall: core.isMemoCall(ctx),
76
- reactAPI: (api) => core.isReactAPI(api)(ctx),
77
- reactAPICall: (api) => core.isReactAPICall(api)(ctx),
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),
78
78
  useActionStateCall: core.isUseActionStateCall,
79
79
  useCall: core.isUseCall,
80
80
  useCallbackCall: core.isUseCallbackCall,
@@ -99,45 +99,37 @@ function createKit(ctx) {
99
99
  useSyncExternalStoreCall: core.isUseSyncExternalStoreCall,
100
100
  useTransitionCall: core.isUseTransitionCall
101
101
  },
102
- settings: getSettingsFromContext(ctx)
102
+ settings: getSettingsFromContext(context)
103
103
  };
104
104
  }
105
105
  function eslintReactKit() {
106
106
  const idGen = new IdGenerator();
107
- const rules = [];
107
+ const plugin = {
108
+ meta: {
109
+ name,
110
+ version
111
+ },
112
+ rules: {}
113
+ };
108
114
  const builder = {
109
115
  getConfig({ files = ["**/*.ts", "**/*.tsx"] } = {}) {
110
116
  return {
111
117
  files,
112
- plugins: { [name]: {
113
- meta: {
114
- name,
115
- version
116
- },
117
- rules: rules.reduce((acc, { name, make }) => {
118
- Reflect.set(acc, name, {
119
- meta: {
120
- fixable: "code",
121
- hasSuggestions: true
122
- },
123
- create(ctx) {
124
- return make(ctx, createKit(ctx));
125
- }
126
- });
127
- return acc;
128
- }, {})
129
- } },
130
- rules: rules.reduce((acc, { name: name$1 }) => {
118
+ plugins: { [name]: plugin },
119
+ rules: Object.keys(plugin.rules).reduce((acc, name$1) => {
131
120
  acc[`${name}/${name$1}`] = "error";
132
121
  return acc;
133
122
  }, {})
134
123
  };
135
124
  },
136
- use(factory, ...args) {
137
- const name = kebabCase(factory.name === "" ? idGen.next() : factory.name);
138
- rules.push({
139
- name,
140
- make: factory(...args)
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))
141
133
  });
142
134
  return builder;
143
135
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/kit",
3
- "version": "4.0.1-beta.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",
@@ -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/core": "4.0.1-beta.0",
42
- "@eslint-react/shared": "4.0.1-beta.0",
43
- "@eslint-react/ast": "4.0.1-beta.0"
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"
44
44
  },
45
45
  "devDependencies": {
46
46
  "eslint": "^10.1.0",