@eslint-react/jsx 1.40.2 → 1.40.3-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/dist/index.d.mts CHANGED
@@ -50,7 +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
- declare const JSXValueHint: {
53
+ type JSXDetectionHint = bigint;
54
+ declare const JSXDetectionHint: {
54
55
  readonly None: 0n;
55
56
  readonly SkipUndefined: bigint;
56
57
  readonly SkipNullLiteral: bigint;
@@ -64,69 +65,38 @@ declare const JSXValueHint: {
64
65
  readonly StrictLogical: bigint;
65
66
  readonly StrictConditional: bigint;
66
67
  };
67
- declare const DEFAULT_JSX_VALUE_HINT: bigint;
68
+ declare const DEFAULT_JSX_DETECTION_HINT: bigint;
69
+
68
70
  /**
69
- * Heuristic decision to determine if a node is a JSX value
71
+ * Heuristic decision to determine if a node is a JSX-like node.
70
72
  * @param node The AST node to check
71
73
  * @param jsxCtx The requirements for the check
72
74
  * @param jsxCtx.getScope The function to get the scope of a node
73
- * @param hint The `JSXValueHint` to use
75
+ * @param hint The `JSXDetectionHint` to use
74
76
  * @returns boolean
75
77
  */
76
- declare function isJSXValue(node: TSESTree$1.Node | _ | null, jsxCtx: {
78
+ declare function isJSXLike(node: TSESTree$1.Node | _ | null, jsxCtx: {
77
79
  getScope: (node: TSESTree$1.Node) => Scope;
78
- }, hint?: bigint): boolean;
80
+ }, hint?: JSXDetectionHint): boolean;
79
81
 
80
- /**
81
- * Check if a node is a Fragment element
82
- * @param node The AST node to check
83
- * @returns `true` if the node is a `JSXElement` of `Fragment` type
84
- */
85
- declare function isFragmentElement(node: TSESTree.Node): boolean;
86
- /**
87
- * Check if a node has a `key` prop
88
- * @param node The AST node to check
89
- * @param initialScope The initial scope to start searching for the `key` attribute
90
- * @returns `true` if the node is a `JSXElement` of `Keyed Component` type
91
- */
92
- declare function isKeyedElement(node: TSESTree.Node, initialScope?: Scope): boolean;
93
- /**
94
- * Check if a node is a `JSXFragment` of `Built-in Component` type
95
- * @param node The AST node to check
96
- * @returns `true` if the node is a `JSXFragment` of `Built-in Component` type
97
- */
98
- declare function isBuiltInElement(node: TSESTree.Node): boolean;
99
- /**
100
- * Check if a node is a `JSXElement` of `User-Defined Component` type
101
- * @param node The AST node to check
102
- * @returns `true` if the node is a `JSXElement` of `User-Defined Component` type
103
- */
104
- declare function isUserDefinedElement(node: TSESTree.Node): boolean;
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;
105
86
 
106
87
  /**
107
- * Check if a node is a Literal or JSXText
108
- * @param node The AST node to check
109
- * @returns boolean `true` if the node is a Literal or JSXText
110
- */
111
- declare const isLiteral: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXText | TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral;
112
- /**
113
- * Check if a Literal or JSXText node is whitespace
88
+ * Check if a node is a `JSXFragment` or a `Fragment` element
114
89
  * @param node The AST node to check
115
- * @returns boolean `true` if the node is whitespace
90
+ * @returns `true` if the node is a `JSXFragment` or a `Fragment` element
116
91
  */
117
- declare function isWhiteSpace(node: TSESTree.JSXText | TSESTree.Literal): boolean;
118
- /**
119
- * Check if a Literal or JSXText node is a line break
120
- * @param node The AST node to check
121
- * @returns boolean
122
- */
123
- declare function isLineBreak(node: TSESTree.Node): boolean;
92
+ declare function isJsxFragment(node: TSESTree.Node | null | _): boolean;
93
+
124
94
  /**
125
- * Check if a Literal or JSXText node is padding spaces
95
+ * Check if a node is a `JSXText` or a `Literal` node
126
96
  * @param node The AST node to check
127
- * @returns boolean
97
+ * @returns `true` if the node is a `JSXText` or a `Literal` node
128
98
  */
129
- declare function isPaddingSpaces(node: TSESTree.Node): boolean;
99
+ declare function isJsxText(node: TSESTree.Node | null | _): node is TSESTree.JSXText | TSESTree.Literal;
130
100
 
131
101
  /**
132
102
  * Get the stringified representation of a JSX node
@@ -135,4 +105,4 @@ declare function isPaddingSpaces(node: TSESTree.Node): boolean;
135
105
  */
136
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;
137
107
 
138
- export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isFragmentElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, toString };
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,7 +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
- declare const JSXValueHint: {
53
+ type JSXDetectionHint = bigint;
54
+ declare const JSXDetectionHint: {
54
55
  readonly None: 0n;
55
56
  readonly SkipUndefined: bigint;
56
57
  readonly SkipNullLiteral: bigint;
@@ -64,69 +65,38 @@ declare const JSXValueHint: {
64
65
  readonly StrictLogical: bigint;
65
66
  readonly StrictConditional: bigint;
66
67
  };
67
- declare const DEFAULT_JSX_VALUE_HINT: bigint;
68
+ declare const DEFAULT_JSX_DETECTION_HINT: bigint;
69
+
68
70
  /**
69
- * Heuristic decision to determine if a node is a JSX value
71
+ * Heuristic decision to determine if a node is a JSX-like node.
70
72
  * @param node The AST node to check
71
73
  * @param jsxCtx The requirements for the check
72
74
  * @param jsxCtx.getScope The function to get the scope of a node
73
- * @param hint The `JSXValueHint` to use
75
+ * @param hint The `JSXDetectionHint` to use
74
76
  * @returns boolean
75
77
  */
76
- declare function isJSXValue(node: TSESTree$1.Node | _ | null, jsxCtx: {
78
+ declare function isJSXLike(node: TSESTree$1.Node | _ | null, jsxCtx: {
77
79
  getScope: (node: TSESTree$1.Node) => Scope;
78
- }, hint?: bigint): boolean;
80
+ }, hint?: JSXDetectionHint): boolean;
79
81
 
80
- /**
81
- * Check if a node is a Fragment element
82
- * @param node The AST node to check
83
- * @returns `true` if the node is a `JSXElement` of `Fragment` type
84
- */
85
- declare function isFragmentElement(node: TSESTree.Node): boolean;
86
- /**
87
- * Check if a node has a `key` prop
88
- * @param node The AST node to check
89
- * @param initialScope The initial scope to start searching for the `key` attribute
90
- * @returns `true` if the node is a `JSXElement` of `Keyed Component` type
91
- */
92
- declare function isKeyedElement(node: TSESTree.Node, initialScope?: Scope): boolean;
93
- /**
94
- * Check if a node is a `JSXFragment` of `Built-in Component` type
95
- * @param node The AST node to check
96
- * @returns `true` if the node is a `JSXFragment` of `Built-in Component` type
97
- */
98
- declare function isBuiltInElement(node: TSESTree.Node): boolean;
99
- /**
100
- * Check if a node is a `JSXElement` of `User-Defined Component` type
101
- * @param node The AST node to check
102
- * @returns `true` if the node is a `JSXElement` of `User-Defined Component` type
103
- */
104
- declare function isUserDefinedElement(node: TSESTree.Node): boolean;
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;
105
86
 
106
87
  /**
107
- * Check if a node is a Literal or JSXText
108
- * @param node The AST node to check
109
- * @returns boolean `true` if the node is a Literal or JSXText
110
- */
111
- declare const isLiteral: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXText | TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral;
112
- /**
113
- * Check if a Literal or JSXText node is whitespace
88
+ * Check if a node is a `JSXFragment` or a `Fragment` element
114
89
  * @param node The AST node to check
115
- * @returns boolean `true` if the node is whitespace
90
+ * @returns `true` if the node is a `JSXFragment` or a `Fragment` element
116
91
  */
117
- declare function isWhiteSpace(node: TSESTree.JSXText | TSESTree.Literal): boolean;
118
- /**
119
- * Check if a Literal or JSXText node is a line break
120
- * @param node The AST node to check
121
- * @returns boolean
122
- */
123
- declare function isLineBreak(node: TSESTree.Node): boolean;
92
+ declare function isJsxFragment(node: TSESTree.Node | null | _): boolean;
93
+
124
94
  /**
125
- * Check if a Literal or JSXText node is padding spaces
95
+ * Check if a node is a `JSXText` or a `Literal` node
126
96
  * @param node The AST node to check
127
- * @returns boolean
97
+ * @returns `true` if the node is a `JSXText` or a `Literal` node
128
98
  */
129
- declare function isPaddingSpaces(node: TSESTree.Node): boolean;
99
+ declare function isJsxText(node: TSESTree.Node | null | _): node is TSESTree.JSXText | TSESTree.Literal;
130
100
 
131
101
  /**
132
102
  * Get the stringified representation of a JSX node
@@ -135,4 +105,4 @@ declare function isPaddingSpaces(node: TSESTree.Node): boolean;
135
105
  */
136
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;
137
107
 
138
- export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isFragmentElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, toString };
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
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var AST3 = require('@eslint-react/ast');
3
+ var AST = require('@eslint-react/ast');
4
4
  var eff = require('@eslint-react/eff');
5
5
  var types = require('@typescript-eslint/types');
6
6
  var VAR = require('@eslint-react/var');
@@ -24,7 +24,7 @@ function _interopNamespace(e) {
24
24
  return Object.freeze(n);
25
25
  }
26
26
 
27
- var AST3__namespace = /*#__PURE__*/_interopNamespace(AST3);
27
+ var AST__namespace = /*#__PURE__*/_interopNamespace(AST);
28
28
  var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
29
29
 
30
30
  // src/find-parent-attribute.ts
@@ -32,7 +32,7 @@ function findParentAttribute(node, test = eff.constTrue) {
32
32
  const guard = (node2) => {
33
33
  return node2.type === types.AST_NODE_TYPES.JSXAttribute && test(node2);
34
34
  };
35
- return AST3__namespace.findParentNode(node, guard);
35
+ return AST__namespace.findParentNode(node, guard);
36
36
  }
37
37
  function toString(node) {
38
38
  switch (node.type) {
@@ -138,7 +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
- var JSXValueHint = {
141
+
142
+ // src/jsx-detection-hint.ts
143
+ var JSXDetectionHint = {
142
144
  None: 0n,
143
145
  SkipUndefined: 1n << 0n,
144
146
  SkipNullLiteral: 1n << 1n,
@@ -152,72 +154,85 @@ var JSXValueHint = {
152
154
  StrictLogical: 1n << 9n,
153
155
  StrictConditional: 1n << 10n
154
156
  };
155
- var DEFAULT_JSX_VALUE_HINT = 0n | JSXValueHint.SkipUndefined | JSXValueHint.SkipBooleanLiteral;
156
- 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) {
157
161
  switch (node?.type) {
162
+ case types.AST_NODE_TYPES.JSXText:
158
163
  case types.AST_NODE_TYPES.JSXElement:
159
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:
160
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:
161
176
  case types.AST_NODE_TYPES.JSXNamespacedName: {
162
177
  return true;
163
178
  }
164
179
  case types.AST_NODE_TYPES.Literal: {
165
180
  switch (typeof node.value) {
166
181
  case "boolean":
167
- return !(hint & JSXValueHint.SkipBooleanLiteral);
182
+ return !(hint & JSXDetectionHint.SkipBooleanLiteral);
168
183
  case "string":
169
- return !(hint & JSXValueHint.SkipStringLiteral);
184
+ return !(hint & JSXDetectionHint.SkipStringLiteral);
170
185
  case "number":
171
- return !(hint & JSXValueHint.SkipNumberLiteral);
186
+ return !(hint & JSXDetectionHint.SkipNumberLiteral);
172
187
  case "bigint":
173
- return !(hint & JSXValueHint.SkipBigIntLiteral);
188
+ return !(hint & JSXDetectionHint.SkipBigIntLiteral);
174
189
  }
175
190
  if (node.value == null) {
176
- return !(hint & JSXValueHint.SkipNullLiteral);
191
+ return !(hint & JSXDetectionHint.SkipNullLiteral);
177
192
  }
178
193
  return false;
179
194
  }
180
195
  case types.AST_NODE_TYPES.TemplateLiteral: {
181
- return !(hint & JSXValueHint.SkipStringLiteral);
196
+ return !(hint & JSXDetectionHint.SkipStringLiteral);
182
197
  }
183
198
  case types.AST_NODE_TYPES.ArrayExpression: {
184
- if (hint & JSXValueHint.StrictArray) {
185
- return node.elements.every((n) => isJSXValue(n, jsxCtx, hint));
199
+ if (hint & JSXDetectionHint.StrictArray) {
200
+ return node.elements.every((n) => isJSXLike(n, jsxCtx, hint));
186
201
  }
187
- return node.elements.some((n) => isJSXValue(n, jsxCtx, hint));
202
+ return node.elements.some((n) => isJSXLike(n, jsxCtx, hint));
188
203
  }
189
204
  case types.AST_NODE_TYPES.LogicalExpression: {
190
- if (hint & JSXValueHint.StrictLogical) {
191
- 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);
192
207
  }
193
- return isJSXValue(node.left, jsxCtx, hint) || isJSXValue(node.right, jsxCtx, hint);
208
+ return isJSXLike(node.left, jsxCtx, hint) || isJSXLike(node.right, jsxCtx, hint);
194
209
  }
195
210
  case types.AST_NODE_TYPES.ConditionalExpression: {
196
211
  let leftHasJSX2 = function(node2) {
197
212
  if (Array.isArray(node2.consequent)) {
198
213
  if (node2.consequent.length === 0) {
199
- return !(hint & JSXValueHint.SkipEmptyArray);
214
+ return !(hint & JSXDetectionHint.SkipEmptyArray);
200
215
  }
201
- if (hint & JSXValueHint.StrictArray) {
202
- return node2.consequent.every((n) => isJSXValue(n, jsxCtx, hint));
216
+ if (hint & JSXDetectionHint.StrictArray) {
217
+ return node2.consequent.every((n) => isJSXLike(n, jsxCtx, hint));
203
218
  }
204
- return node2.consequent.some((n) => isJSXValue(n, jsxCtx, hint));
219
+ return node2.consequent.some((n) => isJSXLike(n, jsxCtx, hint));
205
220
  }
206
- return isJSXValue(node2.consequent, jsxCtx, hint);
221
+ return isJSXLike(node2.consequent, jsxCtx, hint);
207
222
  }, rightHasJSX2 = function(node2) {
208
- return isJSXValue(node2.alternate, jsxCtx, hint);
223
+ return isJSXLike(node2.alternate, jsxCtx, hint);
209
224
  };
210
- if (hint & JSXValueHint.StrictConditional) {
225
+ if (hint & JSXDetectionHint.StrictConditional) {
211
226
  return leftHasJSX2(node) && rightHasJSX2(node);
212
227
  }
213
228
  return leftHasJSX2(node) || rightHasJSX2(node);
214
229
  }
215
230
  case types.AST_NODE_TYPES.SequenceExpression: {
216
231
  const exp = node.expressions.at(-1);
217
- return isJSXValue(exp, jsxCtx, hint);
232
+ return isJSXLike(exp, jsxCtx, hint);
218
233
  }
219
234
  case types.AST_NODE_TYPES.CallExpression: {
220
- if (hint & JSXValueHint.SkipCreateElement) {
235
+ if (hint & JSXDetectionHint.SkipCreateElement) {
221
236
  return false;
222
237
  }
223
238
  switch (node.callee.type) {
@@ -231,44 +246,42 @@ function isJSXValue(node, jsxCtx, hint = DEFAULT_JSX_VALUE_HINT) {
231
246
  case types.AST_NODE_TYPES.Identifier: {
232
247
  const { name } = node;
233
248
  if (name === "undefined") {
234
- return !(hint & JSXValueHint.SkipUndefined);
249
+ return !(hint & JSXDetectionHint.SkipUndefined);
235
250
  }
236
- if (AST3__namespace.isJSXTagNameExpression(node)) {
251
+ if (AST__namespace.isJSXTagNameExpression(node)) {
237
252
  return true;
238
253
  }
239
254
  const variable = VAR__namespace.findVariable(name, jsxCtx.getScope(node));
240
255
  const variableNode = variable && VAR__namespace.getVariableInitNode(variable, 0);
241
- return !!variableNode && isJSXValue(variableNode, jsxCtx, hint);
256
+ return !!variableNode && isJSXLike(variableNode, jsxCtx, hint);
242
257
  }
243
258
  }
244
259
  return false;
245
260
  }
246
- function isFragmentElement(node) {
261
+ function isJsxFragmentElement(node) {
247
262
  if (node.type !== types.AST_NODE_TYPES.JSXElement) return false;
248
263
  return getElementType(node).split(".").at(-1) === "Fragment";
249
264
  }
250
- function isKeyedElement(node, initialScope) {
265
+ function isJsxKeyedElement(node, initialScope) {
251
266
  return node.type === types.AST_NODE_TYPES.JSXElement && hasAttribute("key", node.openingElement.attributes, initialScope);
252
267
  }
253
- function isBuiltInElement(node) {
254
- 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);
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);
255
270
  }
256
- function isUserDefinedElement(node) {
271
+ function isJsxUserDefinedElement(node) {
257
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);
258
273
  }
259
- var isLiteral = AST3__namespace.isOneOf([types.AST_NODE_TYPES.Literal, types.AST_NODE_TYPES.JSXText]);
260
- function isWhiteSpace(node) {
261
- return typeof node.value === "string" && node.value.trim() === "";
262
- }
263
- function isLineBreak(node) {
264
- return isLiteral(node) && isWhiteSpace(node) && AST3__namespace.isMultiLine(node);
274
+ function isJsxFragment(node) {
275
+ if (node == null) return false;
276
+ return node.type === types.AST_NODE_TYPES.JSXFragment || isJsxFragmentElement(node);
265
277
  }
266
- function isPaddingSpaces(node) {
267
- return isLiteral(node) && isWhiteSpace(node) && node.raw.includes("\n");
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;
268
281
  }
269
282
 
270
- exports.DEFAULT_JSX_VALUE_HINT = DEFAULT_JSX_VALUE_HINT;
271
- exports.JSXValueHint = JSXValueHint;
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,13 +290,11 @@ exports.getElementType = getElementType;
277
290
  exports.hasAnyAttribute = hasAnyAttribute;
278
291
  exports.hasAttribute = hasAttribute;
279
292
  exports.hasEveryAttribute = hasEveryAttribute;
280
- exports.isBuiltInElement = isBuiltInElement;
281
- exports.isFragmentElement = isFragmentElement;
282
- exports.isJSXValue = isJSXValue;
283
- exports.isKeyedElement = isKeyedElement;
284
- exports.isLineBreak = isLineBreak;
285
- exports.isLiteral = isLiteral;
286
- exports.isPaddingSpaces = isPaddingSpaces;
287
- exports.isUserDefinedElement = isUserDefinedElement;
288
- exports.isWhiteSpace = isWhiteSpace;
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;
289
300
  exports.toString = toString;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import * as AST3 from '@eslint-react/ast';
1
+ import * as AST from '@eslint-react/ast';
2
2
  import { constTrue } from '@eslint-react/eff';
3
3
  import { AST_NODE_TYPES } from '@typescript-eslint/types';
4
4
  import * as VAR from '@eslint-react/var';
@@ -9,7 +9,7 @@ function findParentAttribute(node, test = constTrue) {
9
9
  const guard = (node2) => {
10
10
  return node2.type === AST_NODE_TYPES.JSXAttribute && test(node2);
11
11
  };
12
- return AST3.findParentNode(node, guard);
12
+ return AST.findParentNode(node, guard);
13
13
  }
14
14
  function toString(node) {
15
15
  switch (node.type) {
@@ -115,7 +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
- var JSXValueHint = {
118
+
119
+ // src/jsx-detection-hint.ts
120
+ var JSXDetectionHint = {
119
121
  None: 0n,
120
122
  SkipUndefined: 1n << 0n,
121
123
  SkipNullLiteral: 1n << 1n,
@@ -129,72 +131,85 @@ var JSXValueHint = {
129
131
  StrictLogical: 1n << 9n,
130
132
  StrictConditional: 1n << 10n
131
133
  };
132
- var DEFAULT_JSX_VALUE_HINT = 0n | JSXValueHint.SkipUndefined | JSXValueHint.SkipBooleanLiteral;
133
- 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) {
134
138
  switch (node?.type) {
139
+ case AST_NODE_TYPES.JSXText:
135
140
  case AST_NODE_TYPES.JSXElement:
136
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:
137
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:
138
153
  case AST_NODE_TYPES.JSXNamespacedName: {
139
154
  return true;
140
155
  }
141
156
  case AST_NODE_TYPES.Literal: {
142
157
  switch (typeof node.value) {
143
158
  case "boolean":
144
- return !(hint & JSXValueHint.SkipBooleanLiteral);
159
+ return !(hint & JSXDetectionHint.SkipBooleanLiteral);
145
160
  case "string":
146
- return !(hint & JSXValueHint.SkipStringLiteral);
161
+ return !(hint & JSXDetectionHint.SkipStringLiteral);
147
162
  case "number":
148
- return !(hint & JSXValueHint.SkipNumberLiteral);
163
+ return !(hint & JSXDetectionHint.SkipNumberLiteral);
149
164
  case "bigint":
150
- return !(hint & JSXValueHint.SkipBigIntLiteral);
165
+ return !(hint & JSXDetectionHint.SkipBigIntLiteral);
151
166
  }
152
167
  if (node.value == null) {
153
- return !(hint & JSXValueHint.SkipNullLiteral);
168
+ return !(hint & JSXDetectionHint.SkipNullLiteral);
154
169
  }
155
170
  return false;
156
171
  }
157
172
  case AST_NODE_TYPES.TemplateLiteral: {
158
- return !(hint & JSXValueHint.SkipStringLiteral);
173
+ return !(hint & JSXDetectionHint.SkipStringLiteral);
159
174
  }
160
175
  case AST_NODE_TYPES.ArrayExpression: {
161
- if (hint & JSXValueHint.StrictArray) {
162
- return node.elements.every((n) => isJSXValue(n, jsxCtx, hint));
176
+ if (hint & JSXDetectionHint.StrictArray) {
177
+ return node.elements.every((n) => isJSXLike(n, jsxCtx, hint));
163
178
  }
164
- return node.elements.some((n) => isJSXValue(n, jsxCtx, hint));
179
+ return node.elements.some((n) => isJSXLike(n, jsxCtx, hint));
165
180
  }
166
181
  case AST_NODE_TYPES.LogicalExpression: {
167
- if (hint & JSXValueHint.StrictLogical) {
168
- 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);
169
184
  }
170
- return isJSXValue(node.left, jsxCtx, hint) || isJSXValue(node.right, jsxCtx, hint);
185
+ return isJSXLike(node.left, jsxCtx, hint) || isJSXLike(node.right, jsxCtx, hint);
171
186
  }
172
187
  case AST_NODE_TYPES.ConditionalExpression: {
173
188
  let leftHasJSX2 = function(node2) {
174
189
  if (Array.isArray(node2.consequent)) {
175
190
  if (node2.consequent.length === 0) {
176
- return !(hint & JSXValueHint.SkipEmptyArray);
191
+ return !(hint & JSXDetectionHint.SkipEmptyArray);
177
192
  }
178
- if (hint & JSXValueHint.StrictArray) {
179
- return node2.consequent.every((n) => isJSXValue(n, jsxCtx, hint));
193
+ if (hint & JSXDetectionHint.StrictArray) {
194
+ return node2.consequent.every((n) => isJSXLike(n, jsxCtx, hint));
180
195
  }
181
- return node2.consequent.some((n) => isJSXValue(n, jsxCtx, hint));
196
+ return node2.consequent.some((n) => isJSXLike(n, jsxCtx, hint));
182
197
  }
183
- return isJSXValue(node2.consequent, jsxCtx, hint);
198
+ return isJSXLike(node2.consequent, jsxCtx, hint);
184
199
  }, rightHasJSX2 = function(node2) {
185
- return isJSXValue(node2.alternate, jsxCtx, hint);
200
+ return isJSXLike(node2.alternate, jsxCtx, hint);
186
201
  };
187
- if (hint & JSXValueHint.StrictConditional) {
202
+ if (hint & JSXDetectionHint.StrictConditional) {
188
203
  return leftHasJSX2(node) && rightHasJSX2(node);
189
204
  }
190
205
  return leftHasJSX2(node) || rightHasJSX2(node);
191
206
  }
192
207
  case AST_NODE_TYPES.SequenceExpression: {
193
208
  const exp = node.expressions.at(-1);
194
- return isJSXValue(exp, jsxCtx, hint);
209
+ return isJSXLike(exp, jsxCtx, hint);
195
210
  }
196
211
  case AST_NODE_TYPES.CallExpression: {
197
- if (hint & JSXValueHint.SkipCreateElement) {
212
+ if (hint & JSXDetectionHint.SkipCreateElement) {
198
213
  return false;
199
214
  }
200
215
  switch (node.callee.type) {
@@ -208,40 +223,38 @@ function isJSXValue(node, jsxCtx, hint = DEFAULT_JSX_VALUE_HINT) {
208
223
  case AST_NODE_TYPES.Identifier: {
209
224
  const { name } = node;
210
225
  if (name === "undefined") {
211
- return !(hint & JSXValueHint.SkipUndefined);
226
+ return !(hint & JSXDetectionHint.SkipUndefined);
212
227
  }
213
- if (AST3.isJSXTagNameExpression(node)) {
228
+ if (AST.isJSXTagNameExpression(node)) {
214
229
  return true;
215
230
  }
216
231
  const variable = VAR.findVariable(name, jsxCtx.getScope(node));
217
232
  const variableNode = variable && VAR.getVariableInitNode(variable, 0);
218
- return !!variableNode && isJSXValue(variableNode, jsxCtx, hint);
233
+ return !!variableNode && isJSXLike(variableNode, jsxCtx, hint);
219
234
  }
220
235
  }
221
236
  return false;
222
237
  }
223
- function isFragmentElement(node) {
238
+ function isJsxFragmentElement(node) {
224
239
  if (node.type !== AST_NODE_TYPES.JSXElement) return false;
225
240
  return getElementType(node).split(".").at(-1) === "Fragment";
226
241
  }
227
- function isKeyedElement(node, initialScope) {
242
+ function isJsxKeyedElement(node, initialScope) {
228
243
  return node.type === AST_NODE_TYPES.JSXElement && hasAttribute("key", node.openingElement.attributes, initialScope);
229
244
  }
230
- function isBuiltInElement(node) {
231
- 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);
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);
232
247
  }
233
- function isUserDefinedElement(node) {
248
+ function isJsxUserDefinedElement(node) {
234
249
  return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && /^[A-Z]/u.test(node.openingElement.name.name);
235
250
  }
236
- var isLiteral = AST3.isOneOf([AST_NODE_TYPES.Literal, AST_NODE_TYPES.JSXText]);
237
- function isWhiteSpace(node) {
238
- return typeof node.value === "string" && node.value.trim() === "";
239
- }
240
- function isLineBreak(node) {
241
- return isLiteral(node) && isWhiteSpace(node) && AST3.isMultiLine(node);
251
+ function isJsxFragment(node) {
252
+ if (node == null) return false;
253
+ return node.type === AST_NODE_TYPES.JSXFragment || isJsxFragmentElement(node);
242
254
  }
243
- function isPaddingSpaces(node) {
244
- return isLiteral(node) && isWhiteSpace(node) && node.raw.includes("\n");
255
+ function isJsxText(node) {
256
+ if (node == null) return false;
257
+ return node.type === AST_NODE_TYPES.JSXText || node.type === AST_NODE_TYPES.Literal;
245
258
  }
246
259
 
247
- export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getElementType, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isFragmentElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, toString };
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.2",
3
+ "version": "1.40.3-beta.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.2",
43
- "@eslint-react/eff": "1.40.2",
44
- "@eslint-react/var": "1.40.2"
42
+ "@eslint-react/eff": "1.40.3-beta.1",
43
+ "@eslint-react/ast": "1.40.3-beta.1",
44
+ "@eslint-react/var": "1.40.3-beta.1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "tsup": "^8.4.0",