@eslint-react/jsx 1.24.0-next.6 → 1.24.0-next.8

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
@@ -4,7 +4,12 @@ import * as VAR from '@eslint-react/var';
4
4
  import { Scope } from '@typescript-eslint/scope-manager';
5
5
  import { TSESTree as TSESTree$1 } from '@typescript-eslint/utils';
6
6
 
7
- declare function findParentProp(node: TSESTree.Node, test?: (node: TSESTree.JSXAttribute) => boolean): TSESTree.JSXAttribute | _;
7
+ declare function findParentAttributeNode(node: TSESTree.Node, test?: (node: TSESTree.JSXAttribute) => boolean): TSESTree.JSXAttribute | _;
8
+
9
+ declare function getAttributeName(node: TSESTree$1.JSXAttribute): string;
10
+ declare function getAttributeNode(name: string, initialScope: Scope, attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[]): TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | _;
11
+ declare function getAttributeStaticValue(node: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute, initialScope: Scope): VAR.StaticValue;
12
+ declare function getAttributeStringValue(name: string, node: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | _, initialScope: Scope): string | undefined;
8
13
 
9
14
  /**
10
15
  * Returns the tag name associated with a JSXOpeningElement.
@@ -13,40 +18,9 @@ declare function findParentProp(node: TSESTree.Node, test?: (node: TSESTree.JSXA
13
18
  */
14
19
  declare function getElementName(node: TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment): string;
15
20
 
16
- /**
17
- * Get the name of a JSX attribute with namespace
18
- * @param node The JSX attribute node
19
- * @returns string
20
- */
21
- declare function getPropName(node: TSESTree$1.JSXAttribute): string;
22
- declare function getProp(name: string, initialScope: Scope, props: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[]): TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | _;
23
- /**
24
- * Gets and resolves the static value of a JSX attribute
25
- * @param attribute The JSX attribute to get the value of
26
- * @param initialScope The initial scope to start from
27
- * @returns The static value of the given JSX attribute
28
- */
29
- declare function getPropValue(attribute: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute, initialScope: Scope): VAR.StaticValue;
30
- declare function findPropInProperties(name: string, properties: (TSESTree$1.Property | TSESTree$1.RestElement | TSESTree$1.SpreadElement)[], initialScope: Scope, seenProps?: string[]): (typeof properties)[number] | _;
31
- declare function findPropInAttributes(name: string, initialScope: Scope, attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[]): TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | _;
32
-
33
- declare function hasProp(propName: string, initialScope: Scope, attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[]): boolean;
34
- /**
35
- * Check if any of the given prop names are present in the given attributes
36
- * @param attributes The attributes to search in
37
- * @param propNames The prop names to search for
38
- * @param initialScope The initial scope to start from
39
- * @returns `true` if any of the given prop names are present in the given attributes
40
- */
41
- declare function hasAnyProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[], initialScope: Scope): boolean;
42
- /**
43
- * Check if all of the given prop names are present in the given attributes
44
- * @param attributes The attributes to search in
45
- * @param propNames The prop names to search for
46
- * @param initialScope The initial scope to start from
47
- * @returns `true` if all of the given prop names are present in the given attributes
48
- */
49
- declare function hasEveryProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[], initialScope: Scope): boolean;
21
+ declare function hasAttribute(name: string, initialScope: Scope, attributes: TSESTree.JSXOpeningElement["attributes"]): boolean;
22
+ declare function hasAnyAttribute(names: string[], initialScope: Scope, attributes: TSESTree.JSXOpeningElement["attributes"]): boolean;
23
+ declare function hasEveryAttribute(names: string[], initialScope: Scope, attributes: TSESTree.JSXOpeningElement["attributes"]): boolean;
50
24
 
51
25
  declare function isKeyedElement(node: TSESTree.Node, initialScope: Scope): boolean;
52
26
  /**
@@ -123,4 +97,4 @@ declare function unescapeStringLiteralText(text: string): string;
123
97
 
124
98
  declare const xhtmlEntities: Record<string, string>;
125
99
 
126
- export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentProp, findPropInAttributes, findPropInProperties, getElementName, getProp, getPropName, getPropValue, hasAnyProp, hasEveryProp, hasProp, isBuiltInElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, unescapeStringLiteralText, xhtmlEntities };
100
+ export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentAttributeNode, getAttributeName, getAttributeNode, getAttributeStaticValue, getAttributeStringValue, getElementName, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, unescapeStringLiteralText, xhtmlEntities };
package/dist/index.d.ts CHANGED
@@ -4,7 +4,12 @@ import * as VAR from '@eslint-react/var';
4
4
  import { Scope } from '@typescript-eslint/scope-manager';
5
5
  import { TSESTree as TSESTree$1 } from '@typescript-eslint/utils';
6
6
 
7
- declare function findParentProp(node: TSESTree.Node, test?: (node: TSESTree.JSXAttribute) => boolean): TSESTree.JSXAttribute | _;
7
+ declare function findParentAttributeNode(node: TSESTree.Node, test?: (node: TSESTree.JSXAttribute) => boolean): TSESTree.JSXAttribute | _;
8
+
9
+ declare function getAttributeName(node: TSESTree$1.JSXAttribute): string;
10
+ declare function getAttributeNode(name: string, initialScope: Scope, attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[]): TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | _;
11
+ declare function getAttributeStaticValue(node: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute, initialScope: Scope): VAR.StaticValue;
12
+ declare function getAttributeStringValue(name: string, node: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | _, initialScope: Scope): string | undefined;
8
13
 
9
14
  /**
10
15
  * Returns the tag name associated with a JSXOpeningElement.
@@ -13,40 +18,9 @@ declare function findParentProp(node: TSESTree.Node, test?: (node: TSESTree.JSXA
13
18
  */
14
19
  declare function getElementName(node: TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment): string;
15
20
 
16
- /**
17
- * Get the name of a JSX attribute with namespace
18
- * @param node The JSX attribute node
19
- * @returns string
20
- */
21
- declare function getPropName(node: TSESTree$1.JSXAttribute): string;
22
- declare function getProp(name: string, initialScope: Scope, props: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[]): TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | _;
23
- /**
24
- * Gets and resolves the static value of a JSX attribute
25
- * @param attribute The JSX attribute to get the value of
26
- * @param initialScope The initial scope to start from
27
- * @returns The static value of the given JSX attribute
28
- */
29
- declare function getPropValue(attribute: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute, initialScope: Scope): VAR.StaticValue;
30
- declare function findPropInProperties(name: string, properties: (TSESTree$1.Property | TSESTree$1.RestElement | TSESTree$1.SpreadElement)[], initialScope: Scope, seenProps?: string[]): (typeof properties)[number] | _;
31
- declare function findPropInAttributes(name: string, initialScope: Scope, attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[]): TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | _;
32
-
33
- declare function hasProp(propName: string, initialScope: Scope, attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[]): boolean;
34
- /**
35
- * Check if any of the given prop names are present in the given attributes
36
- * @param attributes The attributes to search in
37
- * @param propNames The prop names to search for
38
- * @param initialScope The initial scope to start from
39
- * @returns `true` if any of the given prop names are present in the given attributes
40
- */
41
- declare function hasAnyProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[], initialScope: Scope): boolean;
42
- /**
43
- * Check if all of the given prop names are present in the given attributes
44
- * @param attributes The attributes to search in
45
- * @param propNames The prop names to search for
46
- * @param initialScope The initial scope to start from
47
- * @returns `true` if all of the given prop names are present in the given attributes
48
- */
49
- declare function hasEveryProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[], initialScope: Scope): boolean;
21
+ declare function hasAttribute(name: string, initialScope: Scope, attributes: TSESTree.JSXOpeningElement["attributes"]): boolean;
22
+ declare function hasAnyAttribute(names: string[], initialScope: Scope, attributes: TSESTree.JSXOpeningElement["attributes"]): boolean;
23
+ declare function hasEveryAttribute(names: string[], initialScope: Scope, attributes: TSESTree.JSXOpeningElement["attributes"]): boolean;
50
24
 
51
25
  declare function isKeyedElement(node: TSESTree.Node, initialScope: Scope): boolean;
52
26
  /**
@@ -123,4 +97,4 @@ declare function unescapeStringLiteralText(text: string): string;
123
97
 
124
98
  declare const xhtmlEntities: Record<string, string>;
125
99
 
126
- export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentProp, findPropInAttributes, findPropInProperties, getElementName, getProp, getPropName, getPropValue, hasAnyProp, hasEveryProp, hasProp, isBuiltInElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, unescapeStringLiteralText, xhtmlEntities };
100
+ export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentAttributeNode, getAttributeName, getAttributeNode, getAttributeStaticValue, getAttributeStringValue, getElementName, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, unescapeStringLiteralText, xhtmlEntities };
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ var AST3 = 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');
7
+ var tsPattern = require('ts-pattern');
7
8
 
8
9
  function _interopNamespace(e) {
9
10
  if (e && e.__esModule) return e;
@@ -26,37 +27,14 @@ function _interopNamespace(e) {
26
27
  var AST3__namespace = /*#__PURE__*/_interopNamespace(AST3);
27
28
  var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
28
29
 
29
- // src/find-parent-prop.ts
30
- function findParentProp(node, test = eff.returnTrue) {
30
+ // src/find-parent-attribute-node.ts
31
+ function findParentAttributeNode(node, test = eff.returnTrue) {
31
32
  const guard = (node2) => {
32
33
  return node2.type === types.AST_NODE_TYPES.JSXAttribute && test(node2);
33
34
  };
34
35
  return AST3__namespace.findParentNode(node, guard);
35
36
  }
36
- function resolveJSXMemberExpressions(object, property) {
37
- if (object.type === types.AST_NODE_TYPES.JSXMemberExpression) {
38
- return `${resolveJSXMemberExpressions(object.object, object.property)}.${property.name}`;
39
- }
40
- if (object.type === types.AST_NODE_TYPES.JSXNamespacedName) {
41
- return `${object.namespace.name}:${object.name.name}.${property.name}`;
42
- }
43
- return `${object.name}.${property.name}`;
44
- }
45
- function getElementName(node) {
46
- if (node.type === types.AST_NODE_TYPES.JSXOpeningFragment) {
47
- return "<>";
48
- }
49
- const { name } = node;
50
- if (name.type === types.AST_NODE_TYPES.JSXMemberExpression) {
51
- const { object, property } = name;
52
- return resolveJSXMemberExpressions(object, property);
53
- }
54
- if (name.type === types.AST_NODE_TYPES.JSXNamespacedName) {
55
- return `${name.namespace.name}:${name.name.name}`;
56
- }
57
- return name.name;
58
- }
59
- function getPropName(node) {
37
+ function getAttributeName(node) {
60
38
  switch (node.name.type) {
61
39
  case types.AST_NODE_TYPES.JSXIdentifier:
62
40
  return node.name.name;
@@ -64,108 +42,97 @@ function getPropName(node) {
64
42
  return `${node.name.namespace.name}:${node.name.name.name}`;
65
43
  }
66
44
  }
67
- function getProp(name, initialScope, props) {
68
- return findPropInAttributes(name, initialScope, props);
45
+ function getAttributeNode(name, initialScope, attributes) {
46
+ return attributes.findLast((attr) => {
47
+ if (attr.type === types.AST_NODE_TYPES.JSXAttribute) {
48
+ return getAttributeName(attr) === name;
49
+ }
50
+ switch (attr.argument.type) {
51
+ case types.AST_NODE_TYPES.Identifier: {
52
+ const variable = VAR__namespace.findVariable(attr.argument.name, initialScope);
53
+ const variableNode = VAR__namespace.getVariableNode(variable, 0);
54
+ if (variableNode?.type === types.AST_NODE_TYPES.ObjectExpression) {
55
+ return VAR__namespace.findPropertyInProperties(name, variableNode.properties, initialScope) != null;
56
+ }
57
+ return false;
58
+ }
59
+ case types.AST_NODE_TYPES.ObjectExpression:
60
+ return VAR__namespace.findPropertyInProperties(name, attr.argument.properties, initialScope) != null;
61
+ }
62
+ return false;
63
+ });
69
64
  }
70
- function getPropValue(attribute, initialScope) {
71
- switch (attribute.type) {
65
+ function getAttributeStaticValue(node, initialScope) {
66
+ switch (node.type) {
72
67
  case types.AST_NODE_TYPES.JSXAttribute:
73
- if (attribute.value?.type === types.AST_NODE_TYPES.Literal) {
68
+ if (node.value?.type === types.AST_NODE_TYPES.Literal) {
74
69
  return {
75
70
  kind: "some",
76
- node: attribute.value,
71
+ node: node.value,
77
72
  initialScope,
78
- value: attribute.value.value
73
+ value: node.value.value
79
74
  };
80
75
  }
81
- if (attribute.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer) {
76
+ if (node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer) {
82
77
  return {
83
78
  kind: "lazy",
84
- node: attribute.value.expression,
79
+ node: node.value.expression,
85
80
  initialScope
86
81
  };
87
82
  }
88
- return { kind: "none", node: attribute, initialScope };
83
+ return { kind: "none", node, initialScope };
89
84
  case types.AST_NODE_TYPES.JSXSpreadAttribute:
90
85
  return {
91
86
  kind: "lazy",
92
- node: attribute.argument,
87
+ node: node.argument,
93
88
  initialScope
94
89
  };
95
90
  default:
96
- return { kind: "none", node: attribute, initialScope };
91
+ return { kind: "none", node, initialScope };
97
92
  }
98
93
  }
99
- function findPropInProperties(name, properties, initialScope, seenProps = []) {
100
- return properties.findLast((prop) => {
101
- if (prop.type === types.AST_NODE_TYPES.Property) {
102
- return "name" in prop.key && prop.key.name === name;
103
- }
104
- if (prop.type === types.AST_NODE_TYPES.SpreadElement) {
105
- switch (prop.argument.type) {
106
- case types.AST_NODE_TYPES.Identifier: {
107
- if (seenProps.includes(prop.argument.name)) {
108
- return false;
109
- }
110
- const variable = VAR__namespace.findVariable(prop.argument.name, initialScope);
111
- const variableNode = VAR__namespace.getVariableNode(variable, 0);
112
- if (variableNode?.type === types.AST_NODE_TYPES.ObjectExpression) {
113
- return findPropInProperties(
114
- name,
115
- variableNode.properties,
116
- initialScope,
117
- [...seenProps, prop.argument.name]
118
- ) != null;
119
- }
120
- return false;
121
- }
122
- case types.AST_NODE_TYPES.ObjectExpression: {
123
- return findPropInProperties(
124
- name,
125
- prop.argument.properties,
126
- initialScope,
127
- seenProps
128
- ) != null;
129
- }
130
- }
131
- return false;
132
- }
133
- return false;
134
- });
94
+ function getAttributeStringValue(name, node, initialScope) {
95
+ if (node == null) return eff._;
96
+ const attributeValue = getAttributeStaticValue(node, initialScope);
97
+ const attributeValueResolved = VAR__namespace.toResolved(attributeValue).value;
98
+ return tsPattern.match(attributeValueResolved).with(tsPattern.P.string, eff.identity).with({ [name]: tsPattern.P.select(tsPattern.P.string) }, eff.identity).otherwise(() => eff._);
135
99
  }
136
- function findPropInAttributes(name, initialScope, attributes) {
137
- return attributes.findLast((attr) => {
138
- if (attr.type === types.AST_NODE_TYPES.JSXAttribute) {
139
- return getPropName(attr) === name;
140
- }
141
- switch (attr.argument.type) {
142
- case types.AST_NODE_TYPES.Identifier: {
143
- const variable = VAR__namespace.findVariable(attr.argument.name, initialScope);
144
- const variableNode = VAR__namespace.getVariableNode(variable, 0);
145
- if (variableNode?.type === types.AST_NODE_TYPES.ObjectExpression) {
146
- return findPropInProperties(name, variableNode.properties, initialScope) != null;
147
- }
148
- return false;
149
- }
150
- case types.AST_NODE_TYPES.ObjectExpression:
151
- return findPropInProperties(name, attr.argument.properties, initialScope) != null;
152
- }
153
- return false;
154
- });
100
+ function resolveJSXMemberExpressions(object, property) {
101
+ if (object.type === types.AST_NODE_TYPES.JSXMemberExpression) {
102
+ return `${resolveJSXMemberExpressions(object.object, object.property)}.${property.name}`;
103
+ }
104
+ if (object.type === types.AST_NODE_TYPES.JSXNamespacedName) {
105
+ return `${object.namespace.name}:${object.name.name}.${property.name}`;
106
+ }
107
+ return `${object.name}.${property.name}`;
108
+ }
109
+ function getElementName(node) {
110
+ if (node.type === types.AST_NODE_TYPES.JSXOpeningFragment) {
111
+ return "<>";
112
+ }
113
+ const { name } = node;
114
+ if (name.type === types.AST_NODE_TYPES.JSXMemberExpression) {
115
+ const { object, property } = name;
116
+ return resolveJSXMemberExpressions(object, property);
117
+ }
118
+ if (name.type === types.AST_NODE_TYPES.JSXNamespacedName) {
119
+ return `${name.namespace.name}:${name.name.name}`;
120
+ }
121
+ return name.name;
155
122
  }
156
123
 
157
- // src/has-prop.ts
158
- function hasProp(propName, initialScope, attributes) {
159
- return findPropInAttributes(propName, initialScope, attributes) != null;
124
+ // src/has-attribute.ts
125
+ function hasAttribute(name, initialScope, attributes) {
126
+ return getAttributeNode(name, initialScope, attributes) != null;
160
127
  }
161
- function hasAnyProp(attributes, propNames, initialScope) {
162
- return propNames.some((propName) => hasProp(propName, initialScope, attributes));
128
+ function hasAnyAttribute(names, initialScope, attributes) {
129
+ return names.some((n) => hasAttribute(n, initialScope, attributes));
163
130
  }
164
- function hasEveryProp(attributes, propNames, initialScope) {
165
- return propNames.every((propName) => hasProp(propName, initialScope, attributes));
131
+ function hasEveryAttribute(names, initialScope, attributes) {
132
+ return names.every((n) => hasAttribute(n, initialScope, attributes));
166
133
  }
167
134
  function isKeyedElement(node, initialScope) {
168
- return node.type === types.AST_NODE_TYPES.JSXElement && hasProp("key", initialScope, node.openingElement.attributes);
135
+ return node.type === types.AST_NODE_TYPES.JSXElement && hasAttribute("key", initialScope, node.openingElement.attributes);
169
136
  }
170
137
  function isBuiltInElement(node) {
171
138
  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);
@@ -560,16 +527,15 @@ function unescapeStringLiteralText(text) {
560
527
 
561
528
  exports.DEFAULT_JSX_VALUE_HINT = DEFAULT_JSX_VALUE_HINT;
562
529
  exports.JSXValueHint = JSXValueHint;
563
- exports.findParentProp = findParentProp;
564
- exports.findPropInAttributes = findPropInAttributes;
565
- exports.findPropInProperties = findPropInProperties;
530
+ exports.findParentAttributeNode = findParentAttributeNode;
531
+ exports.getAttributeName = getAttributeName;
532
+ exports.getAttributeNode = getAttributeNode;
533
+ exports.getAttributeStaticValue = getAttributeStaticValue;
534
+ exports.getAttributeStringValue = getAttributeStringValue;
566
535
  exports.getElementName = getElementName;
567
- exports.getProp = getProp;
568
- exports.getPropName = getPropName;
569
- exports.getPropValue = getPropValue;
570
- exports.hasAnyProp = hasAnyProp;
571
- exports.hasEveryProp = hasEveryProp;
572
- exports.hasProp = hasProp;
536
+ exports.hasAnyAttribute = hasAnyAttribute;
537
+ exports.hasAttribute = hasAttribute;
538
+ exports.hasEveryAttribute = hasEveryAttribute;
573
539
  exports.isBuiltInElement = isBuiltInElement;
574
540
  exports.isJSXValue = isJSXValue;
575
541
  exports.isKeyedElement = isKeyedElement;
package/dist/index.mjs CHANGED
@@ -1,39 +1,17 @@
1
1
  import * as AST3 from '@eslint-react/ast';
2
- import { returnTrue } from '@eslint-react/eff';
2
+ import { returnTrue, _, identity } from '@eslint-react/eff';
3
3
  import { AST_NODE_TYPES } from '@typescript-eslint/types';
4
4
  import * as VAR from '@eslint-react/var';
5
+ import { match, P } from 'ts-pattern';
5
6
 
6
- // src/find-parent-prop.ts
7
- function findParentProp(node, test = returnTrue) {
7
+ // src/find-parent-attribute-node.ts
8
+ function findParentAttributeNode(node, test = returnTrue) {
8
9
  const guard = (node2) => {
9
10
  return node2.type === AST_NODE_TYPES.JSXAttribute && test(node2);
10
11
  };
11
12
  return AST3.findParentNode(node, guard);
12
13
  }
13
- function resolveJSXMemberExpressions(object, property) {
14
- if (object.type === AST_NODE_TYPES.JSXMemberExpression) {
15
- return `${resolveJSXMemberExpressions(object.object, object.property)}.${property.name}`;
16
- }
17
- if (object.type === AST_NODE_TYPES.JSXNamespacedName) {
18
- return `${object.namespace.name}:${object.name.name}.${property.name}`;
19
- }
20
- return `${object.name}.${property.name}`;
21
- }
22
- function getElementName(node) {
23
- if (node.type === AST_NODE_TYPES.JSXOpeningFragment) {
24
- return "<>";
25
- }
26
- const { name } = node;
27
- if (name.type === AST_NODE_TYPES.JSXMemberExpression) {
28
- const { object, property } = name;
29
- return resolveJSXMemberExpressions(object, property);
30
- }
31
- if (name.type === AST_NODE_TYPES.JSXNamespacedName) {
32
- return `${name.namespace.name}:${name.name.name}`;
33
- }
34
- return name.name;
35
- }
36
- function getPropName(node) {
14
+ function getAttributeName(node) {
37
15
  switch (node.name.type) {
38
16
  case AST_NODE_TYPES.JSXIdentifier:
39
17
  return node.name.name;
@@ -41,108 +19,97 @@ function getPropName(node) {
41
19
  return `${node.name.namespace.name}:${node.name.name.name}`;
42
20
  }
43
21
  }
44
- function getProp(name, initialScope, props) {
45
- return findPropInAttributes(name, initialScope, props);
22
+ function getAttributeNode(name, initialScope, attributes) {
23
+ return attributes.findLast((attr) => {
24
+ if (attr.type === AST_NODE_TYPES.JSXAttribute) {
25
+ return getAttributeName(attr) === name;
26
+ }
27
+ switch (attr.argument.type) {
28
+ case AST_NODE_TYPES.Identifier: {
29
+ const variable = VAR.findVariable(attr.argument.name, initialScope);
30
+ const variableNode = VAR.getVariableNode(variable, 0);
31
+ if (variableNode?.type === AST_NODE_TYPES.ObjectExpression) {
32
+ return VAR.findPropertyInProperties(name, variableNode.properties, initialScope) != null;
33
+ }
34
+ return false;
35
+ }
36
+ case AST_NODE_TYPES.ObjectExpression:
37
+ return VAR.findPropertyInProperties(name, attr.argument.properties, initialScope) != null;
38
+ }
39
+ return false;
40
+ });
46
41
  }
47
- function getPropValue(attribute, initialScope) {
48
- switch (attribute.type) {
42
+ function getAttributeStaticValue(node, initialScope) {
43
+ switch (node.type) {
49
44
  case AST_NODE_TYPES.JSXAttribute:
50
- if (attribute.value?.type === AST_NODE_TYPES.Literal) {
45
+ if (node.value?.type === AST_NODE_TYPES.Literal) {
51
46
  return {
52
47
  kind: "some",
53
- node: attribute.value,
48
+ node: node.value,
54
49
  initialScope,
55
- value: attribute.value.value
50
+ value: node.value.value
56
51
  };
57
52
  }
58
- if (attribute.value?.type === AST_NODE_TYPES.JSXExpressionContainer) {
53
+ if (node.value?.type === AST_NODE_TYPES.JSXExpressionContainer) {
59
54
  return {
60
55
  kind: "lazy",
61
- node: attribute.value.expression,
56
+ node: node.value.expression,
62
57
  initialScope
63
58
  };
64
59
  }
65
- return { kind: "none", node: attribute, initialScope };
60
+ return { kind: "none", node, initialScope };
66
61
  case AST_NODE_TYPES.JSXSpreadAttribute:
67
62
  return {
68
63
  kind: "lazy",
69
- node: attribute.argument,
64
+ node: node.argument,
70
65
  initialScope
71
66
  };
72
67
  default:
73
- return { kind: "none", node: attribute, initialScope };
68
+ return { kind: "none", node, initialScope };
74
69
  }
75
70
  }
76
- function findPropInProperties(name, properties, initialScope, seenProps = []) {
77
- return properties.findLast((prop) => {
78
- if (prop.type === AST_NODE_TYPES.Property) {
79
- return "name" in prop.key && prop.key.name === name;
80
- }
81
- if (prop.type === AST_NODE_TYPES.SpreadElement) {
82
- switch (prop.argument.type) {
83
- case AST_NODE_TYPES.Identifier: {
84
- if (seenProps.includes(prop.argument.name)) {
85
- return false;
86
- }
87
- const variable = VAR.findVariable(prop.argument.name, initialScope);
88
- const variableNode = VAR.getVariableNode(variable, 0);
89
- if (variableNode?.type === AST_NODE_TYPES.ObjectExpression) {
90
- return findPropInProperties(
91
- name,
92
- variableNode.properties,
93
- initialScope,
94
- [...seenProps, prop.argument.name]
95
- ) != null;
96
- }
97
- return false;
98
- }
99
- case AST_NODE_TYPES.ObjectExpression: {
100
- return findPropInProperties(
101
- name,
102
- prop.argument.properties,
103
- initialScope,
104
- seenProps
105
- ) != null;
106
- }
107
- }
108
- return false;
109
- }
110
- return false;
111
- });
71
+ function getAttributeStringValue(name, node, initialScope) {
72
+ if (node == null) return _;
73
+ const attributeValue = getAttributeStaticValue(node, initialScope);
74
+ const attributeValueResolved = VAR.toResolved(attributeValue).value;
75
+ return match(attributeValueResolved).with(P.string, identity).with({ [name]: P.select(P.string) }, identity).otherwise(() => _);
112
76
  }
113
- function findPropInAttributes(name, initialScope, attributes) {
114
- return attributes.findLast((attr) => {
115
- if (attr.type === AST_NODE_TYPES.JSXAttribute) {
116
- return getPropName(attr) === name;
117
- }
118
- switch (attr.argument.type) {
119
- case AST_NODE_TYPES.Identifier: {
120
- const variable = VAR.findVariable(attr.argument.name, initialScope);
121
- const variableNode = VAR.getVariableNode(variable, 0);
122
- if (variableNode?.type === AST_NODE_TYPES.ObjectExpression) {
123
- return findPropInProperties(name, variableNode.properties, initialScope) != null;
124
- }
125
- return false;
126
- }
127
- case AST_NODE_TYPES.ObjectExpression:
128
- return findPropInProperties(name, attr.argument.properties, initialScope) != null;
129
- }
130
- return false;
131
- });
77
+ function resolveJSXMemberExpressions(object, property) {
78
+ if (object.type === AST_NODE_TYPES.JSXMemberExpression) {
79
+ return `${resolveJSXMemberExpressions(object.object, object.property)}.${property.name}`;
80
+ }
81
+ if (object.type === AST_NODE_TYPES.JSXNamespacedName) {
82
+ return `${object.namespace.name}:${object.name.name}.${property.name}`;
83
+ }
84
+ return `${object.name}.${property.name}`;
85
+ }
86
+ function getElementName(node) {
87
+ if (node.type === AST_NODE_TYPES.JSXOpeningFragment) {
88
+ return "<>";
89
+ }
90
+ const { name } = node;
91
+ if (name.type === AST_NODE_TYPES.JSXMemberExpression) {
92
+ const { object, property } = name;
93
+ return resolveJSXMemberExpressions(object, property);
94
+ }
95
+ if (name.type === AST_NODE_TYPES.JSXNamespacedName) {
96
+ return `${name.namespace.name}:${name.name.name}`;
97
+ }
98
+ return name.name;
132
99
  }
133
100
 
134
- // src/has-prop.ts
135
- function hasProp(propName, initialScope, attributes) {
136
- return findPropInAttributes(propName, initialScope, attributes) != null;
101
+ // src/has-attribute.ts
102
+ function hasAttribute(name, initialScope, attributes) {
103
+ return getAttributeNode(name, initialScope, attributes) != null;
137
104
  }
138
- function hasAnyProp(attributes, propNames, initialScope) {
139
- return propNames.some((propName) => hasProp(propName, initialScope, attributes));
105
+ function hasAnyAttribute(names, initialScope, attributes) {
106
+ return names.some((n) => hasAttribute(n, initialScope, attributes));
140
107
  }
141
- function hasEveryProp(attributes, propNames, initialScope) {
142
- return propNames.every((propName) => hasProp(propName, initialScope, attributes));
108
+ function hasEveryAttribute(names, initialScope, attributes) {
109
+ return names.every((n) => hasAttribute(n, initialScope, attributes));
143
110
  }
144
111
  function isKeyedElement(node, initialScope) {
145
- return node.type === AST_NODE_TYPES.JSXElement && hasProp("key", initialScope, node.openingElement.attributes);
112
+ return node.type === AST_NODE_TYPES.JSXElement && hasAttribute("key", initialScope, node.openingElement.attributes);
146
113
  }
147
114
  function isBuiltInElement(node) {
148
115
  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);
@@ -535,4 +502,4 @@ function unescapeStringLiteralText(text) {
535
502
  });
536
503
  }
537
504
 
538
- export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentProp, findPropInAttributes, findPropInProperties, getElementName, getProp, getPropName, getPropValue, hasAnyProp, hasEveryProp, hasProp, isBuiltInElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, unescapeStringLiteralText, xhtmlEntities };
505
+ export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findParentAttributeNode, getAttributeName, getAttributeNode, getAttributeStaticValue, getAttributeStringValue, getElementName, hasAnyAttribute, hasAttribute, hasEveryAttribute, isBuiltInElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, unescapeStringLiteralText, xhtmlEntities };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/jsx",
3
- "version": "1.24.0-next.6",
3
+ "version": "1.24.0-next.8",
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": {
@@ -33,13 +33,13 @@
33
33
  "./package.json"
34
34
  ],
35
35
  "dependencies": {
36
- "@typescript-eslint/scope-manager": "^8.19.1",
37
- "@typescript-eslint/types": "^8.19.1",
38
- "@typescript-eslint/utils": "^8.19.1",
36
+ "@typescript-eslint/scope-manager": "^8.20.0",
37
+ "@typescript-eslint/types": "^8.20.0",
38
+ "@typescript-eslint/utils": "^8.20.0",
39
39
  "ts-pattern": "^5.6.0",
40
- "@eslint-react/ast": "1.24.0-next.6",
41
- "@eslint-react/eff": "1.24.0-next.6",
42
- "@eslint-react/var": "1.24.0-next.6"
40
+ "@eslint-react/ast": "1.24.0-next.8",
41
+ "@eslint-react/var": "1.24.0-next.8",
42
+ "@eslint-react/eff": "1.24.0-next.8"
43
43
  },
44
44
  "devDependencies": {
45
45
  "tsup": "^8.3.5",