@eslint-react/jsx 1.40.3-next.0 → 1.40.3-next.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/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
- * Check if a node is a `JSXFragment` or a `Fragment` element
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,18 +65,33 @@ declare const JSXValueHint: {
78
65
  readonly StrictLogical: bigint;
79
66
  readonly StrictConditional: bigint;
80
67
  };
81
- declare const DEFAULT_JSX_VALUE_HINT: bigint;
68
+ declare const DEFAULT_JSX_DETECTION_HINT: bigint;
69
+
82
70
  /**
83
- * Heuristic decision to determine if a node is a JSX value
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 `JSXValueHint` to use
75
+ * @param hint The `JSXDetectionHint` to use
88
76
  * @returns boolean
89
77
  */
90
- declare function isJSXValue(node: TSESTree$1.Node | _ | null, jsxCtx: {
78
+ declare function isJSXLike(node: TSESTree$1.Node | _ | null, jsxCtx: {
91
79
  getScope: (node: TSESTree$1.Node) => Scope;
92
- }, hint?: bigint): boolean;
80
+ }, hint?: JSXDetectionHint): boolean;
81
+
82
+ /**
83
+ * Check if a node is a `JSXFragment` or a `Fragment` element
84
+ * @param node The AST node to check
85
+ * @returns `true` if the node is a `JSXFragment` or a `Fragment` element
86
+ */
87
+ declare function isJSXFragmentLike(node: TSESTree.Node | null | _): boolean;
88
+
89
+ /**
90
+ * Check if a node is a `JSXText` or a `Literal` node
91
+ * @param node The AST node to check
92
+ * @returns `true` if the node is a `JSXText` or a `Literal` node
93
+ */
94
+ declare function isJSXTextLike(node: TSESTree.Node | null | _): node is TSESTree.JSXText | TSESTree.Literal;
93
95
 
94
96
  /**
95
97
  * Check if a node is a Fragment element
@@ -124,4 +126,4 @@ declare function isUserDefinedElement(node: TSESTree.Node): boolean;
124
126
  */
125
127
  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
128
 
127
- export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isFragmentElement, isJSXFragmentLike, isJSXTextLike, isJSXValue, isKeyedElement, isUserDefinedElement, toString };
129
+ export { DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isFragmentElement, isJSXFragmentLike, isJSXLike, isJSXTextLike, isKeyedElement, isUserDefinedElement, 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
- * Check if a node is a `JSXFragment` or a `Fragment` element
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,18 +65,33 @@ declare const JSXValueHint: {
78
65
  readonly StrictLogical: bigint;
79
66
  readonly StrictConditional: bigint;
80
67
  };
81
- declare const DEFAULT_JSX_VALUE_HINT: bigint;
68
+ declare const DEFAULT_JSX_DETECTION_HINT: bigint;
69
+
82
70
  /**
83
- * Heuristic decision to determine if a node is a JSX value
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 `JSXValueHint` to use
75
+ * @param hint The `JSXDetectionHint` to use
88
76
  * @returns boolean
89
77
  */
90
- declare function isJSXValue(node: TSESTree$1.Node | _ | null, jsxCtx: {
78
+ declare function isJSXLike(node: TSESTree$1.Node | _ | null, jsxCtx: {
91
79
  getScope: (node: TSESTree$1.Node) => Scope;
92
- }, hint?: bigint): boolean;
80
+ }, hint?: JSXDetectionHint): boolean;
81
+
82
+ /**
83
+ * Check if a node is a `JSXFragment` or a `Fragment` element
84
+ * @param node The AST node to check
85
+ * @returns `true` if the node is a `JSXFragment` or a `Fragment` element
86
+ */
87
+ declare function isJSXFragmentLike(node: TSESTree.Node | null | _): boolean;
88
+
89
+ /**
90
+ * Check if a node is a `JSXText` or a `Literal` node
91
+ * @param node The AST node to check
92
+ * @returns `true` if the node is a `JSXText` or a `Literal` node
93
+ */
94
+ declare function isJSXTextLike(node: TSESTree.Node | null | _): node is TSESTree.JSXText | TSESTree.Literal;
93
95
 
94
96
  /**
95
97
  * Check if a node is a Fragment element
@@ -124,4 +126,4 @@ declare function isUserDefinedElement(node: TSESTree.Node): boolean;
124
126
  */
125
127
  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
128
 
127
- export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isFragmentElement, isJSXFragmentLike, isJSXTextLike, isJSXValue, isKeyedElement, isUserDefinedElement, toString };
129
+ export { DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isFragmentElement, isJSXFragmentLike, isJSXLike, isJSXTextLike, isKeyedElement, isUserDefinedElement, 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/is-jsx-fragment.ts
156
- function isJSXFragmentLike(node) {
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 DEFAULT_JSX_VALUE_HINT = 0n | JSXValueHint.SkipUndefined | JSXValueHint.SkipBooleanLiteral;
179
- function isJSXValue(node, jsxCtx, hint = DEFAULT_JSX_VALUE_HINT) {
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 & JSXValueHint.SkipBooleanLiteral);
182
+ return !(hint & JSXDetectionHint.SkipBooleanLiteral);
191
183
  case "string":
192
- return !(hint & JSXValueHint.SkipStringLiteral);
184
+ return !(hint & JSXDetectionHint.SkipStringLiteral);
193
185
  case "number":
194
- return !(hint & JSXValueHint.SkipNumberLiteral);
186
+ return !(hint & JSXDetectionHint.SkipNumberLiteral);
195
187
  case "bigint":
196
- return !(hint & JSXValueHint.SkipBigIntLiteral);
188
+ return !(hint & JSXDetectionHint.SkipBigIntLiteral);
197
189
  }
198
190
  if (node.value == null) {
199
- return !(hint & JSXValueHint.SkipNullLiteral);
191
+ return !(hint & JSXDetectionHint.SkipNullLiteral);
200
192
  }
201
193
  return false;
202
194
  }
203
195
  case types.AST_NODE_TYPES.TemplateLiteral: {
204
- return !(hint & JSXValueHint.SkipStringLiteral);
196
+ return !(hint & JSXDetectionHint.SkipStringLiteral);
205
197
  }
206
198
  case types.AST_NODE_TYPES.ArrayExpression: {
207
- if (hint & JSXValueHint.StrictArray) {
208
- return node.elements.every((n) => isJSXValue(n, jsxCtx, hint));
199
+ if (hint & JSXDetectionHint.StrictArray) {
200
+ return node.elements.every((n) => isJSXLike(n, jsxCtx, hint));
209
201
  }
210
- return node.elements.some((n) => isJSXValue(n, jsxCtx, hint));
202
+ return node.elements.some((n) => isJSXLike(n, jsxCtx, hint));
211
203
  }
212
204
  case types.AST_NODE_TYPES.LogicalExpression: {
213
- if (hint & JSXValueHint.StrictLogical) {
214
- return isJSXValue(node.left, jsxCtx, hint) && isJSXValue(node.right, jsxCtx, hint);
205
+ if (hint & JSXDetectionHint.StrictLogical) {
206
+ return isJSXLike(node.left, jsxCtx, hint) && isJSXLike(node.right, jsxCtx, hint);
215
207
  }
216
- return isJSXValue(node.left, jsxCtx, hint) || isJSXValue(node.right, jsxCtx, hint);
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 & JSXValueHint.SkipEmptyArray);
214
+ return !(hint & JSXDetectionHint.SkipEmptyArray);
223
215
  }
224
- if (hint & JSXValueHint.StrictArray) {
225
- return node2.consequent.every((n) => isJSXValue(n, jsxCtx, hint));
216
+ if (hint & JSXDetectionHint.StrictArray) {
217
+ return node2.consequent.every((n) => isJSXLike(n, jsxCtx, hint));
226
218
  }
227
- return node2.consequent.some((n) => isJSXValue(n, jsxCtx, hint));
219
+ return node2.consequent.some((n) => isJSXLike(n, jsxCtx, hint));
228
220
  }
229
- return isJSXValue(node2.consequent, jsxCtx, hint);
221
+ return isJSXLike(node2.consequent, jsxCtx, hint);
230
222
  }, rightHasJSX2 = function(node2) {
231
- return isJSXValue(node2.alternate, jsxCtx, hint);
223
+ return isJSXLike(node2.alternate, jsxCtx, hint);
232
224
  };
233
- if (hint & JSXValueHint.StrictConditional) {
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 isJSXValue(exp, jsxCtx, hint);
232
+ return isJSXLike(exp, jsxCtx, hint);
241
233
  }
242
234
  case types.AST_NODE_TYPES.CallExpression: {
243
- if (hint & JSXValueHint.SkipCreateElement) {
235
+ if (hint & JSXDetectionHint.SkipCreateElement) {
244
236
  return false;
245
237
  }
246
238
  switch (node.callee.type) {
@@ -254,21 +246,44 @@ 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 & JSXValueHint.SkipUndefined);
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 && isJSXValue(variableNode, jsxCtx, hint);
256
+ return !!variableNode && isJSXLike(variableNode, jsxCtx, hint);
265
257
  }
266
258
  }
267
259
  return false;
268
260
  }
261
+ function isFragmentElement(node) {
262
+ if (node.type !== types.AST_NODE_TYPES.JSXElement) return false;
263
+ return getElementType(node).split(".").at(-1) === "Fragment";
264
+ }
265
+ function isKeyedElement(node, initialScope) {
266
+ return node.type === types.AST_NODE_TYPES.JSXElement && hasAttribute("key", node.openingElement.attributes, initialScope);
267
+ }
268
+ function isBuiltInElement(node) {
269
+ 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);
270
+ }
271
+ function isUserDefinedElement(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
+
275
+ // src/is-jsx-fragment.ts
276
+ function isJSXFragmentLike(node) {
277
+ if (node == null) return false;
278
+ return node.type === types.AST_NODE_TYPES.JSXFragment || isFragmentElement(node);
279
+ }
280
+ function isJSXTextLike(node) {
281
+ if (node == null) return false;
282
+ return node.type === types.AST_NODE_TYPES.JSXText || node.type === types.AST_NODE_TYPES.Literal;
283
+ }
269
284
 
270
- exports.DEFAULT_JSX_VALUE_HINT = DEFAULT_JSX_VALUE_HINT;
271
- exports.JSXValueHint = JSXValueHint;
285
+ exports.DEFAULT_JSX_DETECTION_HINT = DEFAULT_JSX_DETECTION_HINT;
286
+ exports.JSXDetectionHint = JSXDetectionHint;
272
287
  exports.findParentAttribute = findParentAttribute;
273
288
  exports.getAttribute = getAttribute;
274
289
  exports.getAttributeName = getAttributeName;
@@ -280,8 +295,8 @@ exports.hasEveryAttribute = hasEveryAttribute;
280
295
  exports.isBuiltInElement = isBuiltInElement;
281
296
  exports.isFragmentElement = isFragmentElement;
282
297
  exports.isJSXFragmentLike = isJSXFragmentLike;
298
+ exports.isJSXLike = isJSXLike;
283
299
  exports.isJSXTextLike = isJSXTextLike;
284
- exports.isJSXValue = isJSXValue;
285
300
  exports.isKeyedElement = isKeyedElement;
286
301
  exports.isUserDefinedElement = isUserDefinedElement;
287
302
  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/is-jsx-fragment.ts
133
- function isJSXFragmentLike(node) {
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 DEFAULT_JSX_VALUE_HINT = 0n | JSXValueHint.SkipUndefined | JSXValueHint.SkipBooleanLiteral;
156
- function isJSXValue(node, jsxCtx, hint = DEFAULT_JSX_VALUE_HINT) {
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 & JSXValueHint.SkipBooleanLiteral);
159
+ return !(hint & JSXDetectionHint.SkipBooleanLiteral);
168
160
  case "string":
169
- return !(hint & JSXValueHint.SkipStringLiteral);
161
+ return !(hint & JSXDetectionHint.SkipStringLiteral);
170
162
  case "number":
171
- return !(hint & JSXValueHint.SkipNumberLiteral);
163
+ return !(hint & JSXDetectionHint.SkipNumberLiteral);
172
164
  case "bigint":
173
- return !(hint & JSXValueHint.SkipBigIntLiteral);
165
+ return !(hint & JSXDetectionHint.SkipBigIntLiteral);
174
166
  }
175
167
  if (node.value == null) {
176
- return !(hint & JSXValueHint.SkipNullLiteral);
168
+ return !(hint & JSXDetectionHint.SkipNullLiteral);
177
169
  }
178
170
  return false;
179
171
  }
180
172
  case AST_NODE_TYPES.TemplateLiteral: {
181
- return !(hint & JSXValueHint.SkipStringLiteral);
173
+ return !(hint & JSXDetectionHint.SkipStringLiteral);
182
174
  }
183
175
  case AST_NODE_TYPES.ArrayExpression: {
184
- if (hint & JSXValueHint.StrictArray) {
185
- return node.elements.every((n) => isJSXValue(n, jsxCtx, hint));
176
+ if (hint & JSXDetectionHint.StrictArray) {
177
+ return node.elements.every((n) => isJSXLike(n, jsxCtx, hint));
186
178
  }
187
- return node.elements.some((n) => isJSXValue(n, jsxCtx, hint));
179
+ return node.elements.some((n) => isJSXLike(n, jsxCtx, hint));
188
180
  }
189
181
  case AST_NODE_TYPES.LogicalExpression: {
190
- if (hint & JSXValueHint.StrictLogical) {
191
- return isJSXValue(node.left, jsxCtx, hint) && isJSXValue(node.right, jsxCtx, hint);
182
+ if (hint & JSXDetectionHint.StrictLogical) {
183
+ return isJSXLike(node.left, jsxCtx, hint) && isJSXLike(node.right, jsxCtx, hint);
192
184
  }
193
- return isJSXValue(node.left, jsxCtx, hint) || isJSXValue(node.right, jsxCtx, hint);
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 & JSXValueHint.SkipEmptyArray);
191
+ return !(hint & JSXDetectionHint.SkipEmptyArray);
200
192
  }
201
- if (hint & JSXValueHint.StrictArray) {
202
- return node2.consequent.every((n) => isJSXValue(n, jsxCtx, hint));
193
+ if (hint & JSXDetectionHint.StrictArray) {
194
+ return node2.consequent.every((n) => isJSXLike(n, jsxCtx, hint));
203
195
  }
204
- return node2.consequent.some((n) => isJSXValue(n, jsxCtx, hint));
196
+ return node2.consequent.some((n) => isJSXLike(n, jsxCtx, hint));
205
197
  }
206
- return isJSXValue(node2.consequent, jsxCtx, hint);
198
+ return isJSXLike(node2.consequent, jsxCtx, hint);
207
199
  }, rightHasJSX2 = function(node2) {
208
- return isJSXValue(node2.alternate, jsxCtx, hint);
200
+ return isJSXLike(node2.alternate, jsxCtx, hint);
209
201
  };
210
- if (hint & JSXValueHint.StrictConditional) {
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 isJSXValue(exp, jsxCtx, hint);
209
+ return isJSXLike(exp, jsxCtx, hint);
218
210
  }
219
211
  case AST_NODE_TYPES.CallExpression: {
220
- if (hint & JSXValueHint.SkipCreateElement) {
212
+ if (hint & JSXDetectionHint.SkipCreateElement) {
221
213
  return false;
222
214
  }
223
215
  switch (node.callee.type) {
@@ -231,17 +223,40 @@ 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 & JSXValueHint.SkipUndefined);
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 && isJSXValue(variableNode, jsxCtx, hint);
233
+ return !!variableNode && isJSXLike(variableNode, jsxCtx, hint);
242
234
  }
243
235
  }
244
236
  return false;
245
237
  }
238
+ function isFragmentElement(node) {
239
+ if (node.type !== AST_NODE_TYPES.JSXElement) return false;
240
+ return getElementType(node).split(".").at(-1) === "Fragment";
241
+ }
242
+ function isKeyedElement(node, initialScope) {
243
+ return node.type === AST_NODE_TYPES.JSXElement && hasAttribute("key", node.openingElement.attributes, initialScope);
244
+ }
245
+ function isBuiltInElement(node) {
246
+ 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);
247
+ }
248
+ function isUserDefinedElement(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
+
252
+ // src/is-jsx-fragment.ts
253
+ function isJSXFragmentLike(node) {
254
+ if (node == null) return false;
255
+ return node.type === AST_NODE_TYPES.JSXFragment || isFragmentElement(node);
256
+ }
257
+ function isJSXTextLike(node) {
258
+ if (node == null) return false;
259
+ return node.type === AST_NODE_TYPES.JSXText || node.type === AST_NODE_TYPES.Literal;
260
+ }
246
261
 
247
- export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isFragmentElement, isJSXFragmentLike, isJSXTextLike, isJSXValue, isKeyedElement, isUserDefinedElement, toString };
262
+ export { DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isFragmentElement, isJSXFragmentLike, isJSXLike, isJSXTextLike, isKeyedElement, isUserDefinedElement, toString };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/jsx",
3
- "version": "1.40.3-next.0",
3
+ "version": "1.40.3-next.1",
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-next.0",
43
- "@eslint-react/eff": "1.40.3-next.0",
44
- "@eslint-react/var": "1.40.3-next.0"
42
+ "@eslint-react/ast": "1.40.3-next.1",
43
+ "@eslint-react/eff": "1.40.3-next.1",
44
+ "@eslint-react/var": "1.40.3-next.1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "tsup": "^8.4.0",