eslint-plugin-react-x 5.4.0-next.0 → 5.5.0-next.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/dist/index.js +15 -142
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -2,9 +2,9 @@ import { DEFAULT_ESLINT_REACT_SETTINGS, getSettingsFromContext, toRegExp } from
|
|
|
2
2
|
import { Check, Compare, Extract, Traverse, is, isOneOf } from "@eslint-react/ast";
|
|
3
3
|
import * as core from "@eslint-react/core";
|
|
4
4
|
import { merge } from "@eslint-react/eslint";
|
|
5
|
+
import { JsxDetectionHint, findParentAttribute, getElementFullType, hasAttribute, isJsxLike } from "@eslint-react/jsx";
|
|
5
6
|
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
6
7
|
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
7
|
-
import { JsxDetectionHint, findParentAttribute, getElementFullType, hasAttribute, isJsxLike } from "@eslint-react/jsx";
|
|
8
8
|
import { findVariable, getStaticValue } from "@typescript-eslint/utils/ast-utils";
|
|
9
9
|
import { computeObjectType, isAssignmentTargetEqual, resolve, resolveEnclosingAssignmentTarget } from "@eslint-react/var";
|
|
10
10
|
import { DefinitionType } from "@typescript-eslint/scope-manager";
|
|
@@ -35,7 +35,7 @@ var __exportAll = (all, no_symbols) => {
|
|
|
35
35
|
//#region src/configs/disable-conflict-eslint-plugin-react.ts
|
|
36
36
|
var disable_conflict_eslint_plugin_react_exports = /* @__PURE__ */ __exportAll({
|
|
37
37
|
name: () => name$10,
|
|
38
|
-
rules: () => rules$
|
|
38
|
+
rules: () => rules$9
|
|
39
39
|
});
|
|
40
40
|
const conflictingRules$1 = [
|
|
41
41
|
"react/button-has-type",
|
|
@@ -80,18 +80,17 @@ const conflictingRules$1 = [
|
|
|
80
80
|
"react/void-dom-elements-no-children"
|
|
81
81
|
];
|
|
82
82
|
const name$10 = "react-x/disable-conflict-eslint-plugin-react";
|
|
83
|
-
const rules$
|
|
83
|
+
const rules$9 = Object.fromEntries(conflictingRules$1.map((key) => [key, "off"]));
|
|
84
84
|
|
|
85
85
|
//#endregion
|
|
86
86
|
//#region src/configs/disable-conflict-eslint-plugin-react-hooks.ts
|
|
87
87
|
var disable_conflict_eslint_plugin_react_hooks_exports = /* @__PURE__ */ __exportAll({
|
|
88
88
|
name: () => name$9,
|
|
89
|
-
rules: () => rules$
|
|
89
|
+
rules: () => rules$8
|
|
90
90
|
});
|
|
91
91
|
const conflictingRules = [
|
|
92
92
|
"react-hooks/exhaustive-deps",
|
|
93
93
|
"react-hooks/rules-of-hooks",
|
|
94
|
-
"react-hooks/component-hook-factories",
|
|
95
94
|
"react-hooks/error-boundaries",
|
|
96
95
|
"react-hooks/globals",
|
|
97
96
|
"react-hooks/immutability",
|
|
@@ -103,16 +102,16 @@ const conflictingRules = [
|
|
|
103
102
|
"react-hooks/use-memo"
|
|
104
103
|
];
|
|
105
104
|
const name$9 = "react-x/disable-conflict-eslint-plugin-react-hooks";
|
|
106
|
-
const rules$
|
|
105
|
+
const rules$8 = Object.fromEntries(conflictingRules.map((key) => [key, "off"]));
|
|
107
106
|
|
|
108
107
|
//#endregion
|
|
109
108
|
//#region src/configs/disable-experimental.ts
|
|
110
109
|
var disable_experimental_exports = /* @__PURE__ */ __exportAll({
|
|
111
110
|
name: () => name$8,
|
|
112
|
-
rules: () => rules$
|
|
111
|
+
rules: () => rules$7
|
|
113
112
|
});
|
|
114
113
|
const name$8 = "react-x/disable-experimental";
|
|
115
|
-
const rules$
|
|
114
|
+
const rules$7 = {
|
|
116
115
|
"react-x/globals": "off",
|
|
117
116
|
"react-x/immutability": "off",
|
|
118
117
|
"react-x/no-duplicate-key": "off",
|
|
@@ -129,10 +128,10 @@ const rules$8 = {
|
|
|
129
128
|
//#region src/configs/disable-type-checked.ts
|
|
130
129
|
var disable_type_checked_exports = /* @__PURE__ */ __exportAll({
|
|
131
130
|
name: () => name$7,
|
|
132
|
-
rules: () => rules$
|
|
131
|
+
rules: () => rules$6
|
|
133
132
|
});
|
|
134
133
|
const name$7 = "react-x/disable-type-checked";
|
|
135
|
-
const rules$
|
|
134
|
+
const rules$6 = {
|
|
136
135
|
"react-x/no-implicit-children": "off",
|
|
137
136
|
"react-x/no-implicit-key": "off",
|
|
138
137
|
"react-x/no-implicit-ref": "off",
|
|
@@ -143,52 +142,7 @@ const rules$7 = {
|
|
|
143
142
|
//#endregion
|
|
144
143
|
//#region package.json
|
|
145
144
|
var name$6 = "eslint-plugin-react-x";
|
|
146
|
-
var version = "5.
|
|
147
|
-
|
|
148
|
-
//#endregion
|
|
149
|
-
//#region src/rules/component-hook-factories/lib.ts
|
|
150
|
-
/**
|
|
151
|
-
* Check if a function parameter has a type annotation that looks like a React component type.
|
|
152
|
-
* Matches types like ComponentType, React.ComponentType, FC, React.FC, etc.
|
|
153
|
-
* @param param The parameter to check.
|
|
154
|
-
*/
|
|
155
|
-
function hasComponentTypeAnnotation(param) {
|
|
156
|
-
if (param.type !== AST_NODE_TYPES.Identifier || param.typeAnnotation == null) return false;
|
|
157
|
-
const annotation = param.typeAnnotation.typeAnnotation;
|
|
158
|
-
if (annotation.type === AST_NODE_TYPES.TSTypeReference) return isComponentTypeName(annotation.typeName);
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Check if a type name refers to a known React component type.
|
|
163
|
-
* @param typeName The type name to check.
|
|
164
|
-
*/
|
|
165
|
-
function isComponentTypeName(typeName) {
|
|
166
|
-
if (typeName.type === AST_NODE_TYPES.Identifier) return /^(ComponentType|FC|ComponentClass|FunctionComponent|Component)$/.test(typeName.name);
|
|
167
|
-
if (typeName.type === AST_NODE_TYPES.TSQualifiedName) {
|
|
168
|
-
if (typeName.left.type === AST_NODE_TYPES.Identifier && typeName.left.name === "React") return isComponentTypeName(typeName.right);
|
|
169
|
-
}
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Heuristically check if a function is a Higher Order Component (HOC) based on its parameters.
|
|
174
|
-
* Considers a function an HOC if it takes a parameter that looks like a React component
|
|
175
|
-
* (by name or type annotation). This does not validate that the function actually returns
|
|
176
|
-
* a React component.
|
|
177
|
-
* @param fn The function to check.
|
|
178
|
-
*/
|
|
179
|
-
function isHigherOrderComponent(fn) {
|
|
180
|
-
return fn.params.some((param) => {
|
|
181
|
-
if (param.type === AST_NODE_TYPES.Identifier && core.isFunctionComponentNameLoose(param.name)) return true;
|
|
182
|
-
if (hasComponentTypeAnnotation(param)) return true;
|
|
183
|
-
return false;
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
function isTestMock$1(node) {
|
|
187
|
-
return node != null && node.type === AST_NODE_TYPES.MemberExpression && node.object.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === "mock";
|
|
188
|
-
}
|
|
189
|
-
function isTestMockCallback$1(node) {
|
|
190
|
-
return node != null && Check.isFunction(node) && node.parent.type === AST_NODE_TYPES.CallExpression && isTestMock$1(node.parent.callee) && node.parent.arguments[1] === node;
|
|
191
|
-
}
|
|
145
|
+
var version = "5.5.0-next.0";
|
|
192
146
|
|
|
193
147
|
//#endregion
|
|
194
148
|
//#region src/utils/create-rule.ts
|
|
@@ -197,72 +151,6 @@ function getDocsUrl(ruleName) {
|
|
|
197
151
|
}
|
|
198
152
|
const createRule = ESLintUtils.RuleCreator(getDocsUrl);
|
|
199
153
|
|
|
200
|
-
//#endregion
|
|
201
|
-
//#region src/rules/component-hook-factories/component-hook-factories.ts
|
|
202
|
-
const RULE_NAME$50 = "component-hook-factories";
|
|
203
|
-
var component_hook_factories_default = createRule({
|
|
204
|
-
meta: {
|
|
205
|
-
type: "problem",
|
|
206
|
-
docs: { description: "Disallows higher order functions that define components or hooks inside them." },
|
|
207
|
-
messages: {
|
|
208
|
-
component: "Do not define component '{{name}}' inside a function. Components should be defined at the module level. Move it to the top level.",
|
|
209
|
-
hook: "Do not define hook '{{name}}' inside a function. Hooks should be defined at the module level. Move it to the top level."
|
|
210
|
-
},
|
|
211
|
-
schema: []
|
|
212
|
-
},
|
|
213
|
-
name: RULE_NAME$50,
|
|
214
|
-
create: create$50,
|
|
215
|
-
defaultOptions: []
|
|
216
|
-
});
|
|
217
|
-
function create$50(context) {
|
|
218
|
-
const hint = core.FunctionComponentDetectionHint.DoNotIncludeJsxWithNumberValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithNullValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithStringValue | core.FunctionComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | core.FunctionComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx | core.FunctionComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayPatternElement | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayExpressionElement | core.FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback;
|
|
219
|
-
const fc = core.getFunctionComponentCollector(context, { hint });
|
|
220
|
-
const cc = core.getClassComponentCollector(context);
|
|
221
|
-
const hc = core.getHookCollector(context);
|
|
222
|
-
const reported = /* @__PURE__ */ new Set();
|
|
223
|
-
return merge(fc.visitor, cc.visitor, hc.visitor, { "Program:exit"(program) {
|
|
224
|
-
const fComponents = [...fc.api.getAllComponents(program)];
|
|
225
|
-
const cComponents = [...cc.api.getAllComponents(program)];
|
|
226
|
-
const hooks = [...hc.api.getAllHooks(program)];
|
|
227
|
-
for (const { name, node } of fComponents) {
|
|
228
|
-
if (name == null) continue;
|
|
229
|
-
const parentFn = Traverse.findParent(node, Check.isFunction);
|
|
230
|
-
if (parentFn == null) continue;
|
|
231
|
-
if (Traverse.findParent(node, isTestMockCallback$1) != null) continue;
|
|
232
|
-
if (isHigherOrderComponent(parentFn)) continue;
|
|
233
|
-
if (reported.has(node)) continue;
|
|
234
|
-
context.report({
|
|
235
|
-
data: { name },
|
|
236
|
-
messageId: "component",
|
|
237
|
-
node
|
|
238
|
-
});
|
|
239
|
-
reported.add(node);
|
|
240
|
-
}
|
|
241
|
-
for (const { name = "unknown", node } of cComponents) {
|
|
242
|
-
const parentFn = Traverse.findParent(node, Check.isFunction);
|
|
243
|
-
if (parentFn == null) continue;
|
|
244
|
-
if (Traverse.findParent(node, isTestMockCallback$1) != null) continue;
|
|
245
|
-
if (isHigherOrderComponent(parentFn)) continue;
|
|
246
|
-
context.report({
|
|
247
|
-
data: { name },
|
|
248
|
-
messageId: "component",
|
|
249
|
-
node
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
for (const { name, node } of hooks) {
|
|
253
|
-
if (Traverse.findParent(node, Check.isFunction) == null) continue;
|
|
254
|
-
if (Traverse.findParent(node, isTestMockCallback$1) != null) continue;
|
|
255
|
-
if (reported.has(node)) continue;
|
|
256
|
-
context.report({
|
|
257
|
-
data: { name },
|
|
258
|
-
messageId: "hook",
|
|
259
|
-
node
|
|
260
|
-
});
|
|
261
|
-
reported.add(node);
|
|
262
|
-
}
|
|
263
|
-
} });
|
|
264
|
-
}
|
|
265
|
-
|
|
266
154
|
//#endregion
|
|
267
155
|
//#region src/rules/error-boundaries/error-boundaries.ts
|
|
268
156
|
const RULE_NAME$49 = "error-boundaries";
|
|
@@ -7520,7 +7408,6 @@ const plugin = {
|
|
|
7520
7408
|
version
|
|
7521
7409
|
},
|
|
7522
7410
|
rules: {
|
|
7523
|
-
"component-hook-factories": component_hook_factories_default,
|
|
7524
7411
|
"error-boundaries": error_boundaries_default,
|
|
7525
7412
|
"exhaustive-deps": rule$1,
|
|
7526
7413
|
globals: globals_default,
|
|
@@ -7581,12 +7468,11 @@ const plugin = {
|
|
|
7581
7468
|
var recommended_exports = /* @__PURE__ */ __exportAll({
|
|
7582
7469
|
name: () => name$5,
|
|
7583
7470
|
plugins: () => plugins$5,
|
|
7584
|
-
rules: () => rules$
|
|
7471
|
+
rules: () => rules$5,
|
|
7585
7472
|
settings: () => settings$5
|
|
7586
7473
|
});
|
|
7587
7474
|
const name$5 = "react-x/recommended";
|
|
7588
|
-
const rules$
|
|
7589
|
-
"react-x/component-hook-factories": "error",
|
|
7475
|
+
const rules$5 = {
|
|
7590
7476
|
"react-x/error-boundaries": "error",
|
|
7591
7477
|
"react-x/exhaustive-deps": "warn",
|
|
7592
7478
|
"react-x/no-access-state-in-setstate": "error",
|
|
@@ -7628,13 +7514,6 @@ const rules$6 = {
|
|
|
7628
7514
|
const plugins$5 = { "react-x": plugin };
|
|
7629
7515
|
const settings$5 = { "react-x": DEFAULT_ESLINT_REACT_SETTINGS };
|
|
7630
7516
|
|
|
7631
|
-
//#endregion
|
|
7632
|
-
//#region src/configs/_ts.ts
|
|
7633
|
-
/**
|
|
7634
|
-
* Disables rules that are already handled by TypeScript
|
|
7635
|
-
*/
|
|
7636
|
-
const rules$5 = {};
|
|
7637
|
-
|
|
7638
7517
|
//#endregion
|
|
7639
7518
|
//#region src/configs/recommended-typescript.ts
|
|
7640
7519
|
var recommended_typescript_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -7644,10 +7523,7 @@ var recommended_typescript_exports = /* @__PURE__ */ __exportAll({
|
|
|
7644
7523
|
settings: () => settings$4
|
|
7645
7524
|
});
|
|
7646
7525
|
const name$4 = "react-x/recommended-typescript";
|
|
7647
|
-
const rules$4 = {
|
|
7648
|
-
...rules$6,
|
|
7649
|
-
...rules$5
|
|
7650
|
-
};
|
|
7526
|
+
const rules$4 = { ...rules$5 };
|
|
7651
7527
|
const plugins$4 = { ...plugins$5 };
|
|
7652
7528
|
const settings$4 = { ...settings$5 };
|
|
7653
7529
|
|
|
@@ -7677,7 +7553,7 @@ var strict_exports = /* @__PURE__ */ __exportAll({
|
|
|
7677
7553
|
});
|
|
7678
7554
|
const name$2 = "react-x/strict";
|
|
7679
7555
|
const rules$2 = {
|
|
7680
|
-
...rules$
|
|
7556
|
+
...rules$5,
|
|
7681
7557
|
"react-x/no-class-component": "error",
|
|
7682
7558
|
"react-x/no-misused-capture-owner-stack": "error",
|
|
7683
7559
|
"react-x/no-unstable-context-value": "warn",
|
|
@@ -7695,10 +7571,7 @@ var strict_typescript_exports = /* @__PURE__ */ __exportAll({
|
|
|
7695
7571
|
settings: () => settings$1
|
|
7696
7572
|
});
|
|
7697
7573
|
const name$1 = "react-x/strict-typescript";
|
|
7698
|
-
const rules$1 = {
|
|
7699
|
-
...rules$2,
|
|
7700
|
-
...rules$5
|
|
7701
|
-
};
|
|
7574
|
+
const rules$1 = { ...rules$2 };
|
|
7702
7575
|
const plugins$1 = { ...plugins$2 };
|
|
7703
7576
|
const settings$1 = { ...settings$2 };
|
|
7704
7577
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-x",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0-next.0",
|
|
4
4
|
"description": "A set of composable ESLint rules for libraries and frameworks that use React as a UI runtime.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"string-ts": "^2.3.1",
|
|
47
47
|
"ts-api-utils": "^2.5.0",
|
|
48
48
|
"ts-pattern": "^5.9.0",
|
|
49
|
-
"@eslint-react/ast": "5.
|
|
50
|
-
"@eslint-react/
|
|
51
|
-
"@eslint-react/
|
|
52
|
-
"@eslint-react/shared": "5.
|
|
53
|
-
"@eslint-react/
|
|
54
|
-
"@eslint-react/var": "5.
|
|
49
|
+
"@eslint-react/ast": "5.5.0-next.0",
|
|
50
|
+
"@eslint-react/core": "5.5.0-next.0",
|
|
51
|
+
"@eslint-react/eslint": "5.5.0-next.0",
|
|
52
|
+
"@eslint-react/shared": "5.5.0-next.0",
|
|
53
|
+
"@eslint-react/jsx": "5.5.0-next.0",
|
|
54
|
+
"@eslint-react/var": "5.5.0-next.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/react": "^19.2.14",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"eslint": "^10.2.1",
|
|
60
60
|
"tsdown": "^0.21.10",
|
|
61
61
|
"tsl-dx": "^0.12.0",
|
|
62
|
-
"@local/
|
|
63
|
-
"@local/
|
|
62
|
+
"@local/eff": "3.0.0-beta.72",
|
|
63
|
+
"@local/configs": "0.0.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"eslint": "^10.2.1",
|