@eslint-react/jsx 1.40.3-next.0 → 1.40.3
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.d.mts +21 -40
- package/dist/index.d.ts +21 -40
- package/dist/index.js +70 -57
- package/dist/index.mjs +62 -49
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -50,21 +50,8 @@ declare function hasAttribute(name: string, attributes: TSESTree.JSXOpeningEleme
|
|
|
50
50
|
declare function hasAnyAttribute(names: string[], attributes: TSESTree.JSXOpeningElement["attributes"], initialScope?: Scope): boolean;
|
|
51
51
|
declare function hasEveryAttribute(names: string[], attributes: TSESTree.JSXOpeningElement["attributes"], initialScope?: Scope): boolean;
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
* @param node The AST node to check
|
|
56
|
-
* @returns `true` if the node is a `JSXFragment` or a `Fragment` element
|
|
57
|
-
*/
|
|
58
|
-
declare function isJSXFragmentLike(node: TSESTree.Node | null | _): boolean;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Check if a node is a `JSXText` or a `Literal` node
|
|
62
|
-
* @param node The AST node to check
|
|
63
|
-
* @returns `true` if the node is a `JSXText` or a `Literal` node
|
|
64
|
-
*/
|
|
65
|
-
declare function isJSXTextLike(node: TSESTree.Node | null | _): node is TSESTree.JSXText | TSESTree.Literal;
|
|
66
|
-
|
|
67
|
-
declare const JSXValueHint: {
|
|
53
|
+
type JSXDetectionHint = bigint;
|
|
54
|
+
declare const JSXDetectionHint: {
|
|
68
55
|
readonly None: 0n;
|
|
69
56
|
readonly SkipUndefined: bigint;
|
|
70
57
|
readonly SkipNullLiteral: bigint;
|
|
@@ -78,44 +65,38 @@ declare const JSXValueHint: {
|
|
|
78
65
|
readonly StrictLogical: bigint;
|
|
79
66
|
readonly StrictConditional: bigint;
|
|
80
67
|
};
|
|
81
|
-
declare const
|
|
68
|
+
declare const DEFAULT_JSX_DETECTION_HINT: bigint;
|
|
69
|
+
|
|
82
70
|
/**
|
|
83
|
-
* Heuristic decision to determine if a node is a JSX
|
|
71
|
+
* Heuristic decision to determine if a node is a JSX-like node.
|
|
84
72
|
* @param node The AST node to check
|
|
85
73
|
* @param jsxCtx The requirements for the check
|
|
86
74
|
* @param jsxCtx.getScope The function to get the scope of a node
|
|
87
|
-
* @param hint The `
|
|
75
|
+
* @param hint The `JSXDetectionHint` to use
|
|
88
76
|
* @returns boolean
|
|
89
77
|
*/
|
|
90
|
-
declare function
|
|
78
|
+
declare function isJSXLike(node: TSESTree$1.Node | _ | null, jsxCtx: {
|
|
91
79
|
getScope: (node: TSESTree$1.Node) => Scope;
|
|
92
|
-
}, hint?:
|
|
80
|
+
}, hint?: JSXDetectionHint): boolean;
|
|
81
|
+
|
|
82
|
+
declare function isJsxFragmentElement(node: TSESTree.Node): boolean;
|
|
83
|
+
declare function isJsxKeyedElement(node: TSESTree.Node, initialScope?: Scope): boolean;
|
|
84
|
+
declare function isJsxBuiltInElement(node: TSESTree.Node): boolean;
|
|
85
|
+
declare function isJsxUserDefinedElement(node: TSESTree.Node): boolean;
|
|
93
86
|
|
|
94
87
|
/**
|
|
95
|
-
* Check if a node is a Fragment element
|
|
96
|
-
* @param node The AST node to check
|
|
97
|
-
* @returns `true` if the node is a `JSXElement` of `Fragment` type
|
|
98
|
-
*/
|
|
99
|
-
declare function isFragmentElement(node: TSESTree.Node): boolean;
|
|
100
|
-
/**
|
|
101
|
-
* Check if a node has a `key` prop
|
|
102
|
-
* @param node The AST node to check
|
|
103
|
-
* @param initialScope The initial scope to start searching for the `key` attribute
|
|
104
|
-
* @returns `true` if the node is a `JSXElement` of `Keyed Component` type
|
|
105
|
-
*/
|
|
106
|
-
declare function isKeyedElement(node: TSESTree.Node, initialScope?: Scope): boolean;
|
|
107
|
-
/**
|
|
108
|
-
* Check if a node is a `JSXElement` of built-in component
|
|
88
|
+
* Check if a node is a `JSXFragment` or a `Fragment` element
|
|
109
89
|
* @param node The AST node to check
|
|
110
|
-
* @returns `true` if the node is a `JSXFragment`
|
|
90
|
+
* @returns `true` if the node is a `JSXFragment` or a `Fragment` element
|
|
111
91
|
*/
|
|
112
|
-
declare function
|
|
92
|
+
declare function isJsxFragment(node: TSESTree.Node | null | _): boolean;
|
|
93
|
+
|
|
113
94
|
/**
|
|
114
|
-
* Check if a node is a `
|
|
95
|
+
* Check if a node is a `JSXText` or a `Literal` node
|
|
115
96
|
* @param node The AST node to check
|
|
116
|
-
* @returns `true` if the node is a `
|
|
97
|
+
* @returns `true` if the node is a `JSXText` or a `Literal` node
|
|
117
98
|
*/
|
|
118
|
-
declare function
|
|
99
|
+
declare function isJsxText(node: TSESTree.Node | null | _): node is TSESTree.JSXText | TSESTree.Literal;
|
|
119
100
|
|
|
120
101
|
/**
|
|
121
102
|
* Get the stringified representation of a JSX node
|
|
@@ -124,4 +105,4 @@ declare function isUserDefinedElement(node: TSESTree.Node): boolean;
|
|
|
124
105
|
*/
|
|
125
106
|
declare function toString(node: TSESTree$1.JSXIdentifier | TSESTree$1.JSXMemberExpression | TSESTree$1.JSXNamespacedName | TSESTree$1.JSXOpeningElement | TSESTree$1.JSXClosingElement | TSESTree$1.JSXOpeningFragment | TSESTree$1.JSXClosingFragment | TSESTree$1.JSXText): string;
|
|
126
107
|
|
|
127
|
-
export {
|
|
108
|
+
export { DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isJSXLike, isJsxBuiltInElement, isJsxFragment, isJsxFragmentElement, isJsxKeyedElement, isJsxText, isJsxUserDefinedElement, toString };
|
package/dist/index.d.ts
CHANGED
|
@@ -50,21 +50,8 @@ declare function hasAttribute(name: string, attributes: TSESTree.JSXOpeningEleme
|
|
|
50
50
|
declare function hasAnyAttribute(names: string[], attributes: TSESTree.JSXOpeningElement["attributes"], initialScope?: Scope): boolean;
|
|
51
51
|
declare function hasEveryAttribute(names: string[], attributes: TSESTree.JSXOpeningElement["attributes"], initialScope?: Scope): boolean;
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
* @param node The AST node to check
|
|
56
|
-
* @returns `true` if the node is a `JSXFragment` or a `Fragment` element
|
|
57
|
-
*/
|
|
58
|
-
declare function isJSXFragmentLike(node: TSESTree.Node | null | _): boolean;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Check if a node is a `JSXText` or a `Literal` node
|
|
62
|
-
* @param node The AST node to check
|
|
63
|
-
* @returns `true` if the node is a `JSXText` or a `Literal` node
|
|
64
|
-
*/
|
|
65
|
-
declare function isJSXTextLike(node: TSESTree.Node | null | _): node is TSESTree.JSXText | TSESTree.Literal;
|
|
66
|
-
|
|
67
|
-
declare const JSXValueHint: {
|
|
53
|
+
type JSXDetectionHint = bigint;
|
|
54
|
+
declare const JSXDetectionHint: {
|
|
68
55
|
readonly None: 0n;
|
|
69
56
|
readonly SkipUndefined: bigint;
|
|
70
57
|
readonly SkipNullLiteral: bigint;
|
|
@@ -78,44 +65,38 @@ declare const JSXValueHint: {
|
|
|
78
65
|
readonly StrictLogical: bigint;
|
|
79
66
|
readonly StrictConditional: bigint;
|
|
80
67
|
};
|
|
81
|
-
declare const
|
|
68
|
+
declare const DEFAULT_JSX_DETECTION_HINT: bigint;
|
|
69
|
+
|
|
82
70
|
/**
|
|
83
|
-
* Heuristic decision to determine if a node is a JSX
|
|
71
|
+
* Heuristic decision to determine if a node is a JSX-like node.
|
|
84
72
|
* @param node The AST node to check
|
|
85
73
|
* @param jsxCtx The requirements for the check
|
|
86
74
|
* @param jsxCtx.getScope The function to get the scope of a node
|
|
87
|
-
* @param hint The `
|
|
75
|
+
* @param hint The `JSXDetectionHint` to use
|
|
88
76
|
* @returns boolean
|
|
89
77
|
*/
|
|
90
|
-
declare function
|
|
78
|
+
declare function isJSXLike(node: TSESTree$1.Node | _ | null, jsxCtx: {
|
|
91
79
|
getScope: (node: TSESTree$1.Node) => Scope;
|
|
92
|
-
}, hint?:
|
|
80
|
+
}, hint?: JSXDetectionHint): boolean;
|
|
81
|
+
|
|
82
|
+
declare function isJsxFragmentElement(node: TSESTree.Node): boolean;
|
|
83
|
+
declare function isJsxKeyedElement(node: TSESTree.Node, initialScope?: Scope): boolean;
|
|
84
|
+
declare function isJsxBuiltInElement(node: TSESTree.Node): boolean;
|
|
85
|
+
declare function isJsxUserDefinedElement(node: TSESTree.Node): boolean;
|
|
93
86
|
|
|
94
87
|
/**
|
|
95
|
-
* Check if a node is a Fragment element
|
|
96
|
-
* @param node The AST node to check
|
|
97
|
-
* @returns `true` if the node is a `JSXElement` of `Fragment` type
|
|
98
|
-
*/
|
|
99
|
-
declare function isFragmentElement(node: TSESTree.Node): boolean;
|
|
100
|
-
/**
|
|
101
|
-
* Check if a node has a `key` prop
|
|
102
|
-
* @param node The AST node to check
|
|
103
|
-
* @param initialScope The initial scope to start searching for the `key` attribute
|
|
104
|
-
* @returns `true` if the node is a `JSXElement` of `Keyed Component` type
|
|
105
|
-
*/
|
|
106
|
-
declare function isKeyedElement(node: TSESTree.Node, initialScope?: Scope): boolean;
|
|
107
|
-
/**
|
|
108
|
-
* Check if a node is a `JSXElement` of built-in component
|
|
88
|
+
* Check if a node is a `JSXFragment` or a `Fragment` element
|
|
109
89
|
* @param node The AST node to check
|
|
110
|
-
* @returns `true` if the node is a `JSXFragment`
|
|
90
|
+
* @returns `true` if the node is a `JSXFragment` or a `Fragment` element
|
|
111
91
|
*/
|
|
112
|
-
declare function
|
|
92
|
+
declare function isJsxFragment(node: TSESTree.Node | null | _): boolean;
|
|
93
|
+
|
|
113
94
|
/**
|
|
114
|
-
* Check if a node is a `
|
|
95
|
+
* Check if a node is a `JSXText` or a `Literal` node
|
|
115
96
|
* @param node The AST node to check
|
|
116
|
-
* @returns `true` if the node is a `
|
|
97
|
+
* @returns `true` if the node is a `JSXText` or a `Literal` node
|
|
117
98
|
*/
|
|
118
|
-
declare function
|
|
99
|
+
declare function isJsxText(node: TSESTree.Node | null | _): node is TSESTree.JSXText | TSESTree.Literal;
|
|
119
100
|
|
|
120
101
|
/**
|
|
121
102
|
* Get the stringified representation of a JSX node
|
|
@@ -124,4 +105,4 @@ declare function isUserDefinedElement(node: TSESTree.Node): boolean;
|
|
|
124
105
|
*/
|
|
125
106
|
declare function toString(node: TSESTree$1.JSXIdentifier | TSESTree$1.JSXMemberExpression | TSESTree$1.JSXNamespacedName | TSESTree$1.JSXOpeningElement | TSESTree$1.JSXClosingElement | TSESTree$1.JSXOpeningFragment | TSESTree$1.JSXClosingFragment | TSESTree$1.JSXText): string;
|
|
126
107
|
|
|
127
|
-
export {
|
|
108
|
+
export { DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isJSXLike, isJsxBuiltInElement, isJsxFragment, isJsxFragmentElement, isJsxKeyedElement, isJsxText, isJsxUserDefinedElement, toString };
|
package/dist/index.js
CHANGED
|
@@ -138,30 +138,9 @@ function hasAnyAttribute(names, attributes, initialScope) {
|
|
|
138
138
|
function hasEveryAttribute(names, attributes, initialScope) {
|
|
139
139
|
return names.every((n) => hasAttribute(n, attributes, initialScope));
|
|
140
140
|
}
|
|
141
|
-
function isFragmentElement(node) {
|
|
142
|
-
if (node.type !== types.AST_NODE_TYPES.JSXElement) return false;
|
|
143
|
-
return getElementType(node).split(".").at(-1) === "Fragment";
|
|
144
|
-
}
|
|
145
|
-
function isKeyedElement(node, initialScope) {
|
|
146
|
-
return node.type === types.AST_NODE_TYPES.JSXElement && hasAttribute("key", node.openingElement.attributes, initialScope);
|
|
147
|
-
}
|
|
148
|
-
function isBuiltInElement(node) {
|
|
149
|
-
return node.type === types.AST_NODE_TYPES.JSXElement && node.openingElement.name.type === types.AST_NODE_TYPES.JSXIdentifier && node.openingElement.name.name.toLowerCase() === node.openingElement.name.name && /^[a-z]/u.test(node.openingElement.name.name);
|
|
150
|
-
}
|
|
151
|
-
function isUserDefinedElement(node) {
|
|
152
|
-
return node.type === types.AST_NODE_TYPES.JSXElement && node.openingElement.name.type === types.AST_NODE_TYPES.JSXIdentifier && /^[A-Z]/u.test(node.openingElement.name.name);
|
|
153
|
-
}
|
|
154
141
|
|
|
155
|
-
// src/
|
|
156
|
-
|
|
157
|
-
if (node == null) return false;
|
|
158
|
-
return node.type === types.AST_NODE_TYPES.JSXFragment || isFragmentElement(node);
|
|
159
|
-
}
|
|
160
|
-
function isJSXTextLike(node) {
|
|
161
|
-
if (node == null) return false;
|
|
162
|
-
return node.type === types.AST_NODE_TYPES.JSXText || node.type === types.AST_NODE_TYPES.Literal;
|
|
163
|
-
}
|
|
164
|
-
var JSXValueHint = {
|
|
142
|
+
// src/jsx-detection-hint.ts
|
|
143
|
+
var JSXDetectionHint = {
|
|
165
144
|
None: 0n,
|
|
166
145
|
SkipUndefined: 1n << 0n,
|
|
167
146
|
SkipNullLiteral: 1n << 1n,
|
|
@@ -175,72 +154,85 @@ var JSXValueHint = {
|
|
|
175
154
|
StrictLogical: 1n << 9n,
|
|
176
155
|
StrictConditional: 1n << 10n
|
|
177
156
|
};
|
|
178
|
-
var
|
|
179
|
-
|
|
157
|
+
var DEFAULT_JSX_DETECTION_HINT = 0n | JSXDetectionHint.SkipUndefined | JSXDetectionHint.SkipBooleanLiteral;
|
|
158
|
+
|
|
159
|
+
// src/is-jsx.ts
|
|
160
|
+
function isJSXLike(node, jsxCtx, hint = DEFAULT_JSX_DETECTION_HINT) {
|
|
180
161
|
switch (node?.type) {
|
|
162
|
+
case types.AST_NODE_TYPES.JSXText:
|
|
181
163
|
case types.AST_NODE_TYPES.JSXElement:
|
|
182
164
|
case types.AST_NODE_TYPES.JSXFragment:
|
|
165
|
+
case types.AST_NODE_TYPES.JSXAttribute:
|
|
166
|
+
case types.AST_NODE_TYPES.JSXClosingElement:
|
|
167
|
+
case types.AST_NODE_TYPES.JSXClosingFragment:
|
|
168
|
+
case types.AST_NODE_TYPES.JSXEmptyExpression:
|
|
169
|
+
case types.AST_NODE_TYPES.JSXExpressionContainer:
|
|
170
|
+
case types.AST_NODE_TYPES.JSXIdentifier:
|
|
183
171
|
case types.AST_NODE_TYPES.JSXMemberExpression:
|
|
172
|
+
case types.AST_NODE_TYPES.JSXOpeningElement:
|
|
173
|
+
case types.AST_NODE_TYPES.JSXOpeningFragment:
|
|
174
|
+
case types.AST_NODE_TYPES.JSXSpreadAttribute:
|
|
175
|
+
case types.AST_NODE_TYPES.JSXSpreadChild:
|
|
184
176
|
case types.AST_NODE_TYPES.JSXNamespacedName: {
|
|
185
177
|
return true;
|
|
186
178
|
}
|
|
187
179
|
case types.AST_NODE_TYPES.Literal: {
|
|
188
180
|
switch (typeof node.value) {
|
|
189
181
|
case "boolean":
|
|
190
|
-
return !(hint &
|
|
182
|
+
return !(hint & JSXDetectionHint.SkipBooleanLiteral);
|
|
191
183
|
case "string":
|
|
192
|
-
return !(hint &
|
|
184
|
+
return !(hint & JSXDetectionHint.SkipStringLiteral);
|
|
193
185
|
case "number":
|
|
194
|
-
return !(hint &
|
|
186
|
+
return !(hint & JSXDetectionHint.SkipNumberLiteral);
|
|
195
187
|
case "bigint":
|
|
196
|
-
return !(hint &
|
|
188
|
+
return !(hint & JSXDetectionHint.SkipBigIntLiteral);
|
|
197
189
|
}
|
|
198
190
|
if (node.value == null) {
|
|
199
|
-
return !(hint &
|
|
191
|
+
return !(hint & JSXDetectionHint.SkipNullLiteral);
|
|
200
192
|
}
|
|
201
193
|
return false;
|
|
202
194
|
}
|
|
203
195
|
case types.AST_NODE_TYPES.TemplateLiteral: {
|
|
204
|
-
return !(hint &
|
|
196
|
+
return !(hint & JSXDetectionHint.SkipStringLiteral);
|
|
205
197
|
}
|
|
206
198
|
case types.AST_NODE_TYPES.ArrayExpression: {
|
|
207
|
-
if (hint &
|
|
208
|
-
return node.elements.every((n) =>
|
|
199
|
+
if (hint & JSXDetectionHint.StrictArray) {
|
|
200
|
+
return node.elements.every((n) => isJSXLike(n, jsxCtx, hint));
|
|
209
201
|
}
|
|
210
|
-
return node.elements.some((n) =>
|
|
202
|
+
return node.elements.some((n) => isJSXLike(n, jsxCtx, hint));
|
|
211
203
|
}
|
|
212
204
|
case types.AST_NODE_TYPES.LogicalExpression: {
|
|
213
|
-
if (hint &
|
|
214
|
-
return
|
|
205
|
+
if (hint & JSXDetectionHint.StrictLogical) {
|
|
206
|
+
return isJSXLike(node.left, jsxCtx, hint) && isJSXLike(node.right, jsxCtx, hint);
|
|
215
207
|
}
|
|
216
|
-
return
|
|
208
|
+
return isJSXLike(node.left, jsxCtx, hint) || isJSXLike(node.right, jsxCtx, hint);
|
|
217
209
|
}
|
|
218
210
|
case types.AST_NODE_TYPES.ConditionalExpression: {
|
|
219
211
|
let leftHasJSX2 = function(node2) {
|
|
220
212
|
if (Array.isArray(node2.consequent)) {
|
|
221
213
|
if (node2.consequent.length === 0) {
|
|
222
|
-
return !(hint &
|
|
214
|
+
return !(hint & JSXDetectionHint.SkipEmptyArray);
|
|
223
215
|
}
|
|
224
|
-
if (hint &
|
|
225
|
-
return node2.consequent.every((n) =>
|
|
216
|
+
if (hint & JSXDetectionHint.StrictArray) {
|
|
217
|
+
return node2.consequent.every((n) => isJSXLike(n, jsxCtx, hint));
|
|
226
218
|
}
|
|
227
|
-
return node2.consequent.some((n) =>
|
|
219
|
+
return node2.consequent.some((n) => isJSXLike(n, jsxCtx, hint));
|
|
228
220
|
}
|
|
229
|
-
return
|
|
221
|
+
return isJSXLike(node2.consequent, jsxCtx, hint);
|
|
230
222
|
}, rightHasJSX2 = function(node2) {
|
|
231
|
-
return
|
|
223
|
+
return isJSXLike(node2.alternate, jsxCtx, hint);
|
|
232
224
|
};
|
|
233
|
-
if (hint &
|
|
225
|
+
if (hint & JSXDetectionHint.StrictConditional) {
|
|
234
226
|
return leftHasJSX2(node) && rightHasJSX2(node);
|
|
235
227
|
}
|
|
236
228
|
return leftHasJSX2(node) || rightHasJSX2(node);
|
|
237
229
|
}
|
|
238
230
|
case types.AST_NODE_TYPES.SequenceExpression: {
|
|
239
231
|
const exp = node.expressions.at(-1);
|
|
240
|
-
return
|
|
232
|
+
return isJSXLike(exp, jsxCtx, hint);
|
|
241
233
|
}
|
|
242
234
|
case types.AST_NODE_TYPES.CallExpression: {
|
|
243
|
-
if (hint &
|
|
235
|
+
if (hint & JSXDetectionHint.SkipCreateElement) {
|
|
244
236
|
return false;
|
|
245
237
|
}
|
|
246
238
|
switch (node.callee.type) {
|
|
@@ -254,21 +246,42 @@ function isJSXValue(node, jsxCtx, hint = DEFAULT_JSX_VALUE_HINT) {
|
|
|
254
246
|
case types.AST_NODE_TYPES.Identifier: {
|
|
255
247
|
const { name } = node;
|
|
256
248
|
if (name === "undefined") {
|
|
257
|
-
return !(hint &
|
|
249
|
+
return !(hint & JSXDetectionHint.SkipUndefined);
|
|
258
250
|
}
|
|
259
251
|
if (AST__namespace.isJSXTagNameExpression(node)) {
|
|
260
252
|
return true;
|
|
261
253
|
}
|
|
262
254
|
const variable = VAR__namespace.findVariable(name, jsxCtx.getScope(node));
|
|
263
255
|
const variableNode = variable && VAR__namespace.getVariableInitNode(variable, 0);
|
|
264
|
-
return !!variableNode &&
|
|
256
|
+
return !!variableNode && isJSXLike(variableNode, jsxCtx, hint);
|
|
265
257
|
}
|
|
266
258
|
}
|
|
267
259
|
return false;
|
|
268
260
|
}
|
|
261
|
+
function isJsxFragmentElement(node) {
|
|
262
|
+
if (node.type !== types.AST_NODE_TYPES.JSXElement) return false;
|
|
263
|
+
return getElementType(node).split(".").at(-1) === "Fragment";
|
|
264
|
+
}
|
|
265
|
+
function isJsxKeyedElement(node, initialScope) {
|
|
266
|
+
return node.type === types.AST_NODE_TYPES.JSXElement && hasAttribute("key", node.openingElement.attributes, initialScope);
|
|
267
|
+
}
|
|
268
|
+
function isJsxBuiltInElement(node) {
|
|
269
|
+
return node.type === types.AST_NODE_TYPES.JSXElement && node.openingElement.name.type === types.AST_NODE_TYPES.JSXIdentifier && /^[a-z]/u.test(node.openingElement.name.name);
|
|
270
|
+
}
|
|
271
|
+
function isJsxUserDefinedElement(node) {
|
|
272
|
+
return node.type === types.AST_NODE_TYPES.JSXElement && node.openingElement.name.type === types.AST_NODE_TYPES.JSXIdentifier && /^[A-Z]/u.test(node.openingElement.name.name);
|
|
273
|
+
}
|
|
274
|
+
function isJsxFragment(node) {
|
|
275
|
+
if (node == null) return false;
|
|
276
|
+
return node.type === types.AST_NODE_TYPES.JSXFragment || isJsxFragmentElement(node);
|
|
277
|
+
}
|
|
278
|
+
function isJsxText(node) {
|
|
279
|
+
if (node == null) return false;
|
|
280
|
+
return node.type === types.AST_NODE_TYPES.JSXText || node.type === types.AST_NODE_TYPES.Literal;
|
|
281
|
+
}
|
|
269
282
|
|
|
270
|
-
exports.
|
|
271
|
-
exports.
|
|
283
|
+
exports.DEFAULT_JSX_DETECTION_HINT = DEFAULT_JSX_DETECTION_HINT;
|
|
284
|
+
exports.JSXDetectionHint = JSXDetectionHint;
|
|
272
285
|
exports.findParentAttribute = findParentAttribute;
|
|
273
286
|
exports.getAttribute = getAttribute;
|
|
274
287
|
exports.getAttributeName = getAttributeName;
|
|
@@ -277,11 +290,11 @@ exports.getElementType = getElementType;
|
|
|
277
290
|
exports.hasAnyAttribute = hasAnyAttribute;
|
|
278
291
|
exports.hasAttribute = hasAttribute;
|
|
279
292
|
exports.hasEveryAttribute = hasEveryAttribute;
|
|
280
|
-
exports.
|
|
281
|
-
exports.
|
|
282
|
-
exports.
|
|
283
|
-
exports.
|
|
284
|
-
exports.
|
|
285
|
-
exports.
|
|
286
|
-
exports.
|
|
293
|
+
exports.isJSXLike = isJSXLike;
|
|
294
|
+
exports.isJsxBuiltInElement = isJsxBuiltInElement;
|
|
295
|
+
exports.isJsxFragment = isJsxFragment;
|
|
296
|
+
exports.isJsxFragmentElement = isJsxFragmentElement;
|
|
297
|
+
exports.isJsxKeyedElement = isJsxKeyedElement;
|
|
298
|
+
exports.isJsxText = isJsxText;
|
|
299
|
+
exports.isJsxUserDefinedElement = isJsxUserDefinedElement;
|
|
287
300
|
exports.toString = toString;
|
package/dist/index.mjs
CHANGED
|
@@ -115,30 +115,9 @@ function hasAnyAttribute(names, attributes, initialScope) {
|
|
|
115
115
|
function hasEveryAttribute(names, attributes, initialScope) {
|
|
116
116
|
return names.every((n) => hasAttribute(n, attributes, initialScope));
|
|
117
117
|
}
|
|
118
|
-
function isFragmentElement(node) {
|
|
119
|
-
if (node.type !== AST_NODE_TYPES.JSXElement) return false;
|
|
120
|
-
return getElementType(node).split(".").at(-1) === "Fragment";
|
|
121
|
-
}
|
|
122
|
-
function isKeyedElement(node, initialScope) {
|
|
123
|
-
return node.type === AST_NODE_TYPES.JSXElement && hasAttribute("key", node.openingElement.attributes, initialScope);
|
|
124
|
-
}
|
|
125
|
-
function isBuiltInElement(node) {
|
|
126
|
-
return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && node.openingElement.name.name.toLowerCase() === node.openingElement.name.name && /^[a-z]/u.test(node.openingElement.name.name);
|
|
127
|
-
}
|
|
128
|
-
function isUserDefinedElement(node) {
|
|
129
|
-
return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && /^[A-Z]/u.test(node.openingElement.name.name);
|
|
130
|
-
}
|
|
131
118
|
|
|
132
|
-
// src/
|
|
133
|
-
|
|
134
|
-
if (node == null) return false;
|
|
135
|
-
return node.type === AST_NODE_TYPES.JSXFragment || isFragmentElement(node);
|
|
136
|
-
}
|
|
137
|
-
function isJSXTextLike(node) {
|
|
138
|
-
if (node == null) return false;
|
|
139
|
-
return node.type === AST_NODE_TYPES.JSXText || node.type === AST_NODE_TYPES.Literal;
|
|
140
|
-
}
|
|
141
|
-
var JSXValueHint = {
|
|
119
|
+
// src/jsx-detection-hint.ts
|
|
120
|
+
var JSXDetectionHint = {
|
|
142
121
|
None: 0n,
|
|
143
122
|
SkipUndefined: 1n << 0n,
|
|
144
123
|
SkipNullLiteral: 1n << 1n,
|
|
@@ -152,72 +131,85 @@ var JSXValueHint = {
|
|
|
152
131
|
StrictLogical: 1n << 9n,
|
|
153
132
|
StrictConditional: 1n << 10n
|
|
154
133
|
};
|
|
155
|
-
var
|
|
156
|
-
|
|
134
|
+
var DEFAULT_JSX_DETECTION_HINT = 0n | JSXDetectionHint.SkipUndefined | JSXDetectionHint.SkipBooleanLiteral;
|
|
135
|
+
|
|
136
|
+
// src/is-jsx.ts
|
|
137
|
+
function isJSXLike(node, jsxCtx, hint = DEFAULT_JSX_DETECTION_HINT) {
|
|
157
138
|
switch (node?.type) {
|
|
139
|
+
case AST_NODE_TYPES.JSXText:
|
|
158
140
|
case AST_NODE_TYPES.JSXElement:
|
|
159
141
|
case AST_NODE_TYPES.JSXFragment:
|
|
142
|
+
case AST_NODE_TYPES.JSXAttribute:
|
|
143
|
+
case AST_NODE_TYPES.JSXClosingElement:
|
|
144
|
+
case AST_NODE_TYPES.JSXClosingFragment:
|
|
145
|
+
case AST_NODE_TYPES.JSXEmptyExpression:
|
|
146
|
+
case AST_NODE_TYPES.JSXExpressionContainer:
|
|
147
|
+
case AST_NODE_TYPES.JSXIdentifier:
|
|
160
148
|
case AST_NODE_TYPES.JSXMemberExpression:
|
|
149
|
+
case AST_NODE_TYPES.JSXOpeningElement:
|
|
150
|
+
case AST_NODE_TYPES.JSXOpeningFragment:
|
|
151
|
+
case AST_NODE_TYPES.JSXSpreadAttribute:
|
|
152
|
+
case AST_NODE_TYPES.JSXSpreadChild:
|
|
161
153
|
case AST_NODE_TYPES.JSXNamespacedName: {
|
|
162
154
|
return true;
|
|
163
155
|
}
|
|
164
156
|
case AST_NODE_TYPES.Literal: {
|
|
165
157
|
switch (typeof node.value) {
|
|
166
158
|
case "boolean":
|
|
167
|
-
return !(hint &
|
|
159
|
+
return !(hint & JSXDetectionHint.SkipBooleanLiteral);
|
|
168
160
|
case "string":
|
|
169
|
-
return !(hint &
|
|
161
|
+
return !(hint & JSXDetectionHint.SkipStringLiteral);
|
|
170
162
|
case "number":
|
|
171
|
-
return !(hint &
|
|
163
|
+
return !(hint & JSXDetectionHint.SkipNumberLiteral);
|
|
172
164
|
case "bigint":
|
|
173
|
-
return !(hint &
|
|
165
|
+
return !(hint & JSXDetectionHint.SkipBigIntLiteral);
|
|
174
166
|
}
|
|
175
167
|
if (node.value == null) {
|
|
176
|
-
return !(hint &
|
|
168
|
+
return !(hint & JSXDetectionHint.SkipNullLiteral);
|
|
177
169
|
}
|
|
178
170
|
return false;
|
|
179
171
|
}
|
|
180
172
|
case AST_NODE_TYPES.TemplateLiteral: {
|
|
181
|
-
return !(hint &
|
|
173
|
+
return !(hint & JSXDetectionHint.SkipStringLiteral);
|
|
182
174
|
}
|
|
183
175
|
case AST_NODE_TYPES.ArrayExpression: {
|
|
184
|
-
if (hint &
|
|
185
|
-
return node.elements.every((n) =>
|
|
176
|
+
if (hint & JSXDetectionHint.StrictArray) {
|
|
177
|
+
return node.elements.every((n) => isJSXLike(n, jsxCtx, hint));
|
|
186
178
|
}
|
|
187
|
-
return node.elements.some((n) =>
|
|
179
|
+
return node.elements.some((n) => isJSXLike(n, jsxCtx, hint));
|
|
188
180
|
}
|
|
189
181
|
case AST_NODE_TYPES.LogicalExpression: {
|
|
190
|
-
if (hint &
|
|
191
|
-
return
|
|
182
|
+
if (hint & JSXDetectionHint.StrictLogical) {
|
|
183
|
+
return isJSXLike(node.left, jsxCtx, hint) && isJSXLike(node.right, jsxCtx, hint);
|
|
192
184
|
}
|
|
193
|
-
return
|
|
185
|
+
return isJSXLike(node.left, jsxCtx, hint) || isJSXLike(node.right, jsxCtx, hint);
|
|
194
186
|
}
|
|
195
187
|
case AST_NODE_TYPES.ConditionalExpression: {
|
|
196
188
|
let leftHasJSX2 = function(node2) {
|
|
197
189
|
if (Array.isArray(node2.consequent)) {
|
|
198
190
|
if (node2.consequent.length === 0) {
|
|
199
|
-
return !(hint &
|
|
191
|
+
return !(hint & JSXDetectionHint.SkipEmptyArray);
|
|
200
192
|
}
|
|
201
|
-
if (hint &
|
|
202
|
-
return node2.consequent.every((n) =>
|
|
193
|
+
if (hint & JSXDetectionHint.StrictArray) {
|
|
194
|
+
return node2.consequent.every((n) => isJSXLike(n, jsxCtx, hint));
|
|
203
195
|
}
|
|
204
|
-
return node2.consequent.some((n) =>
|
|
196
|
+
return node2.consequent.some((n) => isJSXLike(n, jsxCtx, hint));
|
|
205
197
|
}
|
|
206
|
-
return
|
|
198
|
+
return isJSXLike(node2.consequent, jsxCtx, hint);
|
|
207
199
|
}, rightHasJSX2 = function(node2) {
|
|
208
|
-
return
|
|
200
|
+
return isJSXLike(node2.alternate, jsxCtx, hint);
|
|
209
201
|
};
|
|
210
|
-
if (hint &
|
|
202
|
+
if (hint & JSXDetectionHint.StrictConditional) {
|
|
211
203
|
return leftHasJSX2(node) && rightHasJSX2(node);
|
|
212
204
|
}
|
|
213
205
|
return leftHasJSX2(node) || rightHasJSX2(node);
|
|
214
206
|
}
|
|
215
207
|
case AST_NODE_TYPES.SequenceExpression: {
|
|
216
208
|
const exp = node.expressions.at(-1);
|
|
217
|
-
return
|
|
209
|
+
return isJSXLike(exp, jsxCtx, hint);
|
|
218
210
|
}
|
|
219
211
|
case AST_NODE_TYPES.CallExpression: {
|
|
220
|
-
if (hint &
|
|
212
|
+
if (hint & JSXDetectionHint.SkipCreateElement) {
|
|
221
213
|
return false;
|
|
222
214
|
}
|
|
223
215
|
switch (node.callee.type) {
|
|
@@ -231,17 +223,38 @@ function isJSXValue(node, jsxCtx, hint = DEFAULT_JSX_VALUE_HINT) {
|
|
|
231
223
|
case AST_NODE_TYPES.Identifier: {
|
|
232
224
|
const { name } = node;
|
|
233
225
|
if (name === "undefined") {
|
|
234
|
-
return !(hint &
|
|
226
|
+
return !(hint & JSXDetectionHint.SkipUndefined);
|
|
235
227
|
}
|
|
236
228
|
if (AST.isJSXTagNameExpression(node)) {
|
|
237
229
|
return true;
|
|
238
230
|
}
|
|
239
231
|
const variable = VAR.findVariable(name, jsxCtx.getScope(node));
|
|
240
232
|
const variableNode = variable && VAR.getVariableInitNode(variable, 0);
|
|
241
|
-
return !!variableNode &&
|
|
233
|
+
return !!variableNode && isJSXLike(variableNode, jsxCtx, hint);
|
|
242
234
|
}
|
|
243
235
|
}
|
|
244
236
|
return false;
|
|
245
237
|
}
|
|
238
|
+
function isJsxFragmentElement(node) {
|
|
239
|
+
if (node.type !== AST_NODE_TYPES.JSXElement) return false;
|
|
240
|
+
return getElementType(node).split(".").at(-1) === "Fragment";
|
|
241
|
+
}
|
|
242
|
+
function isJsxKeyedElement(node, initialScope) {
|
|
243
|
+
return node.type === AST_NODE_TYPES.JSXElement && hasAttribute("key", node.openingElement.attributes, initialScope);
|
|
244
|
+
}
|
|
245
|
+
function isJsxBuiltInElement(node) {
|
|
246
|
+
return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && /^[a-z]/u.test(node.openingElement.name.name);
|
|
247
|
+
}
|
|
248
|
+
function isJsxUserDefinedElement(node) {
|
|
249
|
+
return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && /^[A-Z]/u.test(node.openingElement.name.name);
|
|
250
|
+
}
|
|
251
|
+
function isJsxFragment(node) {
|
|
252
|
+
if (node == null) return false;
|
|
253
|
+
return node.type === AST_NODE_TYPES.JSXFragment || isJsxFragmentElement(node);
|
|
254
|
+
}
|
|
255
|
+
function isJsxText(node) {
|
|
256
|
+
if (node == null) return false;
|
|
257
|
+
return node.type === AST_NODE_TYPES.JSXText || node.type === AST_NODE_TYPES.Literal;
|
|
258
|
+
}
|
|
246
259
|
|
|
247
|
-
export {
|
|
260
|
+
export { DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isJSXLike, isJsxBuiltInElement, isJsxFragment, isJsxFragmentElement, isJsxKeyedElement, isJsxText, isJsxUserDefinedElement, toString };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/jsx",
|
|
3
|
-
"version": "1.40.3
|
|
3
|
+
"version": "1.40.3",
|
|
4
4
|
"description": "ESLint React's TSESTree AST utility module for static analysis of JSX.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"@typescript-eslint/types": "^8.29.0",
|
|
40
40
|
"@typescript-eslint/utils": "^8.29.0",
|
|
41
41
|
"ts-pattern": "^5.7.0",
|
|
42
|
-
"@eslint-react/ast": "1.40.3
|
|
43
|
-
"@eslint-react/eff": "1.40.3
|
|
44
|
-
"@eslint-react/var": "1.40.3
|
|
42
|
+
"@eslint-react/ast": "1.40.3",
|
|
43
|
+
"@eslint-react/eff": "1.40.3",
|
|
44
|
+
"@eslint-react/var": "1.40.3"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"tsup": "^8.4.0",
|