@eslint-react/jsx 1.9.1 → 1.9.2-next.2
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/LICENSE +1 -1
- package/dist/index.d.mts +20 -23
- package/dist/index.d.ts +20 -23
- package/dist/index.js +72 -82
- package/dist/index.mjs +73 -82
- package/package.json +5 -5
package/LICENSE
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { TSESTree } from '@typescript-eslint/types';
|
|
2
|
-
import { RuleContext } from '@eslint-react/types';
|
|
3
|
-
import { O } from '@eslint-react/tools';
|
|
4
2
|
import { Scope } from '@typescript-eslint/scope-manager';
|
|
3
|
+
import { O } from '@eslint-react/tools';
|
|
5
4
|
import { TSESTree as TSESTree$1 } from '@typescript-eslint/utils';
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -11,9 +10,9 @@ import { TSESTree as TSESTree$1 } from '@typescript-eslint/utils';
|
|
|
11
10
|
*/
|
|
12
11
|
declare function getElementName(node: TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment): string;
|
|
13
12
|
|
|
14
|
-
declare function getElementType(
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
declare function getElementType(ctx: {
|
|
14
|
+
getScope: (node: TSESTree.Node) => Scope;
|
|
15
|
+
}, components?: Map<string, string>, polymorphicPropName?: string): (node: TSESTree.JSXOpeningElement) => string;
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Get the name of a JSX attribute with namespace
|
|
@@ -21,63 +20,58 @@ declare function getJSXPragma(context: RuleContext): O.Option<string>;
|
|
|
21
20
|
* @returns string
|
|
22
21
|
*/
|
|
23
22
|
declare function getPropName(node: TSESTree$1.JSXAttribute): string;
|
|
24
|
-
declare function getProp(props: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[], propName: string,
|
|
23
|
+
declare function getProp(props: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[], propName: string, initialScope: Scope): O.Option<TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute>;
|
|
25
24
|
/**
|
|
26
25
|
* Gets and resolves the static value of a JSX attribute
|
|
27
26
|
* @param attribute The JSX attribute to get the value of
|
|
28
|
-
* @param
|
|
27
|
+
* @param initialScope The initial scope to start from
|
|
29
28
|
* @returns The static value of the given JSX attribute
|
|
30
29
|
*/
|
|
31
|
-
declare function getPropValue(attribute: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute,
|
|
30
|
+
declare function getPropValue(attribute: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute, initialScope: Scope): O.None<{
|
|
32
31
|
value: unknown;
|
|
33
32
|
} | null> | O.Some<{
|
|
34
33
|
value: unknown;
|
|
35
34
|
} | null>;
|
|
36
35
|
/**
|
|
37
36
|
* @param properties The properties to search in
|
|
38
|
-
* @param context The rule context
|
|
39
37
|
* @param initialScope The initial scope to start from
|
|
40
38
|
* @param seenProps The properties that have already been seen
|
|
41
39
|
* @returns A function that searches for a property in the given properties
|
|
42
40
|
*/
|
|
43
|
-
declare function findPropInProperties(properties: (TSESTree$1.Property | TSESTree$1.RestElement | TSESTree$1.SpreadElement)[],
|
|
41
|
+
declare function findPropInProperties(properties: (TSESTree$1.Property | TSESTree$1.RestElement | TSESTree$1.SpreadElement)[], initialScope: Scope, seenProps?: string[]): (propName: string) => O.Option<(typeof properties)[number]>;
|
|
44
42
|
/**
|
|
45
43
|
* @param attributes The attributes to search in
|
|
46
|
-
* @param context The rule context
|
|
47
44
|
* @param initialScope The initial scope to start from
|
|
48
45
|
* @returns A function that searches for a property in the given attributes
|
|
49
46
|
*/
|
|
50
|
-
declare function findPropInAttributes(attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[],
|
|
47
|
+
declare function findPropInAttributes(attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[], initialScope: Scope): (propName: string) => O.Option<NonNullable<TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | undefined>>;
|
|
51
48
|
|
|
52
49
|
/**
|
|
53
50
|
* Check if the given prop name is present in the given attributes
|
|
54
51
|
* @param attributes The attributes to search in
|
|
55
52
|
* @param propName The prop name to search for
|
|
56
|
-
* @param context The rule context
|
|
57
53
|
* @param initialScope The initial scope to start from
|
|
58
54
|
* @returns `true` if the given prop name is present in the given properties
|
|
59
55
|
*/
|
|
60
|
-
declare function hasProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propName: string,
|
|
56
|
+
declare function hasProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propName: string, initialScope: Scope): boolean;
|
|
61
57
|
/**
|
|
62
58
|
* Check if any of the given prop names are present in the given attributes
|
|
63
59
|
* @param attributes The attributes to search in
|
|
64
60
|
* @param propNames The prop names to search for
|
|
65
|
-
* @param context The rule context
|
|
66
61
|
* @param initialScope The initial scope to start from
|
|
67
62
|
* @returns `true` if any of the given prop names are present in the given attributes
|
|
68
63
|
*/
|
|
69
|
-
declare function hasAnyProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[],
|
|
64
|
+
declare function hasAnyProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[], initialScope: Scope): boolean;
|
|
70
65
|
/**
|
|
71
66
|
* Check if all of the given prop names are present in the given attributes
|
|
72
67
|
* @param attributes The attributes to search in
|
|
73
68
|
* @param propNames The prop names to search for
|
|
74
|
-
* @param context The rule context
|
|
75
69
|
* @param initialScope The initial scope to start from
|
|
76
70
|
* @returns `true` if all of the given prop names are present in the given attributes
|
|
77
71
|
*/
|
|
78
|
-
declare function hasEveryProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[],
|
|
72
|
+
declare function hasEveryProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[], initialScope: Scope): boolean;
|
|
79
73
|
|
|
80
|
-
declare function isKeyedElement(node: TSESTree.Node,
|
|
74
|
+
declare function isKeyedElement(node: TSESTree.Node, initialScope: Scope): boolean;
|
|
81
75
|
/**
|
|
82
76
|
* Check if a node is a `JSXElement` of `User-Defined Component` type
|
|
83
77
|
* @param node The AST node to check
|
|
@@ -108,18 +102,21 @@ declare const DEFAULT_JSX_VALUE_HINT: bigint;
|
|
|
108
102
|
/**
|
|
109
103
|
* Check if a node is a JSX value
|
|
110
104
|
* @param node The AST node to check
|
|
111
|
-
* @param
|
|
105
|
+
* @param ctx The requirements for the check
|
|
106
|
+
* @param ctx.getScope The function to get the scope of a node
|
|
112
107
|
* @param hint The `JSXValueHint` to use
|
|
113
108
|
* @returns boolean
|
|
114
109
|
*/
|
|
115
|
-
declare function isJSXValue(node: TSESTree$1.Node | null | undefined,
|
|
110
|
+
declare function isJSXValue(node: TSESTree$1.Node | null | undefined, ctx: {
|
|
111
|
+
getScope: (node: TSESTree$1.Node) => Scope;
|
|
112
|
+
}, hint?: bigint): boolean;
|
|
116
113
|
|
|
117
114
|
/**
|
|
118
115
|
* Check if a node is a Literal or JSXText
|
|
119
116
|
* @param node The AST node to check
|
|
120
117
|
* @returns boolean `true` if the node is a Literal or JSXText
|
|
121
118
|
*/
|
|
122
|
-
declare const isLiteral: (node: TSESTree.Node | null | undefined) => node is TSESTree.
|
|
119
|
+
declare const isLiteral: (node: TSESTree.Node | null | undefined) => node is TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral | TSESTree.JSXText;
|
|
123
120
|
/**
|
|
124
121
|
* Check if a Literal or JSXText node is whitespace
|
|
125
122
|
* @param node The AST node to check
|
|
@@ -147,4 +144,4 @@ declare function isPaddingSpaces(node: TSESTree.Node): boolean;
|
|
|
147
144
|
*/
|
|
148
145
|
declare function traverseUpProp(node: TSESTree.Node, predicate?: (node: TSESTree.JSXAttribute) => boolean): O.Option<TSESTree.JSXAttribute>;
|
|
149
146
|
|
|
150
|
-
export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findPropInAttributes, findPropInProperties, getElementName, getElementType,
|
|
147
|
+
export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findPropInAttributes, findPropInProperties, getElementName, getElementType, getProp, getPropName, getPropValue, hasAnyProp, hasEveryProp, hasProp, isBuiltInElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, traverseUpProp };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { TSESTree } from '@typescript-eslint/types';
|
|
2
|
-
import { RuleContext } from '@eslint-react/types';
|
|
3
|
-
import { O } from '@eslint-react/tools';
|
|
4
2
|
import { Scope } from '@typescript-eslint/scope-manager';
|
|
3
|
+
import { O } from '@eslint-react/tools';
|
|
5
4
|
import { TSESTree as TSESTree$1 } from '@typescript-eslint/utils';
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -11,9 +10,9 @@ import { TSESTree as TSESTree$1 } from '@typescript-eslint/utils';
|
|
|
11
10
|
*/
|
|
12
11
|
declare function getElementName(node: TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment): string;
|
|
13
12
|
|
|
14
|
-
declare function getElementType(
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
declare function getElementType(ctx: {
|
|
14
|
+
getScope: (node: TSESTree.Node) => Scope;
|
|
15
|
+
}, components?: Map<string, string>, polymorphicPropName?: string): (node: TSESTree.JSXOpeningElement) => string;
|
|
17
16
|
|
|
18
17
|
/**
|
|
19
18
|
* Get the name of a JSX attribute with namespace
|
|
@@ -21,63 +20,58 @@ declare function getJSXPragma(context: RuleContext): O.Option<string>;
|
|
|
21
20
|
* @returns string
|
|
22
21
|
*/
|
|
23
22
|
declare function getPropName(node: TSESTree$1.JSXAttribute): string;
|
|
24
|
-
declare function getProp(props: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[], propName: string,
|
|
23
|
+
declare function getProp(props: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[], propName: string, initialScope: Scope): O.Option<TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute>;
|
|
25
24
|
/**
|
|
26
25
|
* Gets and resolves the static value of a JSX attribute
|
|
27
26
|
* @param attribute The JSX attribute to get the value of
|
|
28
|
-
* @param
|
|
27
|
+
* @param initialScope The initial scope to start from
|
|
29
28
|
* @returns The static value of the given JSX attribute
|
|
30
29
|
*/
|
|
31
|
-
declare function getPropValue(attribute: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute,
|
|
30
|
+
declare function getPropValue(attribute: TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute, initialScope: Scope): O.None<{
|
|
32
31
|
value: unknown;
|
|
33
32
|
} | null> | O.Some<{
|
|
34
33
|
value: unknown;
|
|
35
34
|
} | null>;
|
|
36
35
|
/**
|
|
37
36
|
* @param properties The properties to search in
|
|
38
|
-
* @param context The rule context
|
|
39
37
|
* @param initialScope The initial scope to start from
|
|
40
38
|
* @param seenProps The properties that have already been seen
|
|
41
39
|
* @returns A function that searches for a property in the given properties
|
|
42
40
|
*/
|
|
43
|
-
declare function findPropInProperties(properties: (TSESTree$1.Property | TSESTree$1.RestElement | TSESTree$1.SpreadElement)[],
|
|
41
|
+
declare function findPropInProperties(properties: (TSESTree$1.Property | TSESTree$1.RestElement | TSESTree$1.SpreadElement)[], initialScope: Scope, seenProps?: string[]): (propName: string) => O.Option<(typeof properties)[number]>;
|
|
44
42
|
/**
|
|
45
43
|
* @param attributes The attributes to search in
|
|
46
|
-
* @param context The rule context
|
|
47
44
|
* @param initialScope The initial scope to start from
|
|
48
45
|
* @returns A function that searches for a property in the given attributes
|
|
49
46
|
*/
|
|
50
|
-
declare function findPropInAttributes(attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[],
|
|
47
|
+
declare function findPropInAttributes(attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[], initialScope: Scope): (propName: string) => O.Option<NonNullable<TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | undefined>>;
|
|
51
48
|
|
|
52
49
|
/**
|
|
53
50
|
* Check if the given prop name is present in the given attributes
|
|
54
51
|
* @param attributes The attributes to search in
|
|
55
52
|
* @param propName The prop name to search for
|
|
56
|
-
* @param context The rule context
|
|
57
53
|
* @param initialScope The initial scope to start from
|
|
58
54
|
* @returns `true` if the given prop name is present in the given properties
|
|
59
55
|
*/
|
|
60
|
-
declare function hasProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propName: string,
|
|
56
|
+
declare function hasProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propName: string, initialScope: Scope): boolean;
|
|
61
57
|
/**
|
|
62
58
|
* Check if any of the given prop names are present in the given attributes
|
|
63
59
|
* @param attributes The attributes to search in
|
|
64
60
|
* @param propNames The prop names to search for
|
|
65
|
-
* @param context The rule context
|
|
66
61
|
* @param initialScope The initial scope to start from
|
|
67
62
|
* @returns `true` if any of the given prop names are present in the given attributes
|
|
68
63
|
*/
|
|
69
|
-
declare function hasAnyProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[],
|
|
64
|
+
declare function hasAnyProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[], initialScope: Scope): boolean;
|
|
70
65
|
/**
|
|
71
66
|
* Check if all of the given prop names are present in the given attributes
|
|
72
67
|
* @param attributes The attributes to search in
|
|
73
68
|
* @param propNames The prop names to search for
|
|
74
|
-
* @param context The rule context
|
|
75
69
|
* @param initialScope The initial scope to start from
|
|
76
70
|
* @returns `true` if all of the given prop names are present in the given attributes
|
|
77
71
|
*/
|
|
78
|
-
declare function hasEveryProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[],
|
|
72
|
+
declare function hasEveryProp(attributes: (TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute)[], propNames: string[], initialScope: Scope): boolean;
|
|
79
73
|
|
|
80
|
-
declare function isKeyedElement(node: TSESTree.Node,
|
|
74
|
+
declare function isKeyedElement(node: TSESTree.Node, initialScope: Scope): boolean;
|
|
81
75
|
/**
|
|
82
76
|
* Check if a node is a `JSXElement` of `User-Defined Component` type
|
|
83
77
|
* @param node The AST node to check
|
|
@@ -108,18 +102,21 @@ declare const DEFAULT_JSX_VALUE_HINT: bigint;
|
|
|
108
102
|
/**
|
|
109
103
|
* Check if a node is a JSX value
|
|
110
104
|
* @param node The AST node to check
|
|
111
|
-
* @param
|
|
105
|
+
* @param ctx The requirements for the check
|
|
106
|
+
* @param ctx.getScope The function to get the scope of a node
|
|
112
107
|
* @param hint The `JSXValueHint` to use
|
|
113
108
|
* @returns boolean
|
|
114
109
|
*/
|
|
115
|
-
declare function isJSXValue(node: TSESTree$1.Node | null | undefined,
|
|
110
|
+
declare function isJSXValue(node: TSESTree$1.Node | null | undefined, ctx: {
|
|
111
|
+
getScope: (node: TSESTree$1.Node) => Scope;
|
|
112
|
+
}, hint?: bigint): boolean;
|
|
116
113
|
|
|
117
114
|
/**
|
|
118
115
|
* Check if a node is a Literal or JSXText
|
|
119
116
|
* @param node The AST node to check
|
|
120
117
|
* @returns boolean `true` if the node is a Literal or JSXText
|
|
121
118
|
*/
|
|
122
|
-
declare const isLiteral: (node: TSESTree.Node | null | undefined) => node is TSESTree.
|
|
119
|
+
declare const isLiteral: (node: TSESTree.Node | null | undefined) => node is TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral | TSESTree.JSXText;
|
|
123
120
|
/**
|
|
124
121
|
* Check if a Literal or JSXText node is whitespace
|
|
125
122
|
* @param node The AST node to check
|
|
@@ -147,4 +144,4 @@ declare function isPaddingSpaces(node: TSESTree.Node): boolean;
|
|
|
147
144
|
*/
|
|
148
145
|
declare function traverseUpProp(node: TSESTree.Node, predicate?: (node: TSESTree.JSXAttribute) => boolean): O.Option<TSESTree.JSXAttribute>;
|
|
149
146
|
|
|
150
|
-
export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findPropInAttributes, findPropInProperties, getElementName, getElementType,
|
|
147
|
+
export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findPropInAttributes, findPropInProperties, getElementName, getElementType, getProp, getPropName, getPropValue, hasAnyProp, hasEveryProp, hasProp, isBuiltInElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, traverseUpProp };
|
package/dist/index.js
CHANGED
|
@@ -1,68 +1,70 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var types = require('@typescript-eslint/types');
|
|
4
4
|
var tools = require('@eslint-react/tools');
|
|
5
|
+
var ast = require('@eslint-react/ast');
|
|
5
6
|
var _var = require('@eslint-react/var');
|
|
6
7
|
var astUtils = require('@typescript-eslint/utils/ast-utils');
|
|
7
8
|
var tsPattern = require('ts-pattern');
|
|
8
9
|
|
|
9
10
|
// src/get-element-name.ts
|
|
10
11
|
function resolveJSXMemberExpressions(object, property) {
|
|
11
|
-
if (object.type ===
|
|
12
|
+
if (object.type === types.AST_NODE_TYPES.JSXMemberExpression) {
|
|
12
13
|
return `${resolveJSXMemberExpressions(object.object, object.property)}.${property.name}`;
|
|
13
14
|
}
|
|
14
|
-
if (object.type ===
|
|
15
|
+
if (object.type === types.AST_NODE_TYPES.JSXNamespacedName) {
|
|
15
16
|
return `${object.namespace.name}:${object.name.name}.${property.name}`;
|
|
16
17
|
}
|
|
17
18
|
return `${object.name}.${property.name}`;
|
|
18
19
|
}
|
|
19
20
|
function getElementName(node) {
|
|
20
|
-
if (node.type ===
|
|
21
|
+
if (node.type === types.AST_NODE_TYPES.JSXOpeningFragment) {
|
|
21
22
|
return "<>";
|
|
22
23
|
}
|
|
23
24
|
const { name } = node;
|
|
24
|
-
if (name.type ===
|
|
25
|
+
if (name.type === types.AST_NODE_TYPES.JSXMemberExpression) {
|
|
25
26
|
const { object, property } = name;
|
|
26
27
|
return resolveJSXMemberExpressions(object, property);
|
|
27
28
|
}
|
|
28
|
-
if (name.type ===
|
|
29
|
+
if (name.type === types.AST_NODE_TYPES.JSXNamespacedName) {
|
|
29
30
|
return `${name.namespace.name}:${name.name.name}`;
|
|
30
31
|
}
|
|
31
32
|
return name.name;
|
|
32
33
|
}
|
|
33
34
|
function getPropName(node) {
|
|
34
35
|
switch (node.name.type) {
|
|
35
|
-
case
|
|
36
|
+
case types.AST_NODE_TYPES.JSXIdentifier:
|
|
36
37
|
return node.name.name;
|
|
37
|
-
case
|
|
38
|
+
case types.AST_NODE_TYPES.JSXNamespacedName:
|
|
38
39
|
return `${node.name.namespace.name}:${node.name.name.name}`;
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
|
-
function getProp(props, propName,
|
|
42
|
-
return findPropInAttributes(props,
|
|
42
|
+
function getProp(props, propName, initialScope) {
|
|
43
|
+
return findPropInAttributes(props, initialScope)(propName);
|
|
43
44
|
}
|
|
44
|
-
function getPropValue(attribute,
|
|
45
|
-
|
|
46
|
-
if (attribute.type === ast.NodeType.JSXAttribute && "value" in attribute) {
|
|
45
|
+
function getPropValue(attribute, initialScope) {
|
|
46
|
+
if (attribute.type === types.AST_NODE_TYPES.JSXAttribute && "value" in attribute) {
|
|
47
47
|
const { value } = attribute;
|
|
48
48
|
if (value === null) return tools.O.none();
|
|
49
|
-
if (value.type ===
|
|
50
|
-
if (value.type ===
|
|
49
|
+
if (value.type === types.AST_NODE_TYPES.Literal) return tools.O.some(astUtils.getStaticValue(value, initialScope));
|
|
50
|
+
if (value.type === types.AST_NODE_TYPES.JSXExpressionContainer) {
|
|
51
|
+
return tools.O.some(astUtils.getStaticValue(value.expression, initialScope));
|
|
52
|
+
}
|
|
51
53
|
return tools.O.none();
|
|
52
54
|
}
|
|
53
55
|
const { argument } = attribute;
|
|
54
56
|
return tools.O.some(astUtils.getStaticValue(argument, initialScope));
|
|
55
57
|
}
|
|
56
|
-
function findPropInProperties(properties,
|
|
58
|
+
function findPropInProperties(properties, initialScope, seenProps = []) {
|
|
57
59
|
return (propName) => {
|
|
58
60
|
return tools.O.fromNullable(
|
|
59
61
|
properties.findLast((prop) => {
|
|
60
62
|
switch (true) {
|
|
61
|
-
case (prop.type ===
|
|
63
|
+
case (prop.type === types.AST_NODE_TYPES.Property && "name" in prop.key && prop.key.name === propName):
|
|
62
64
|
return true;
|
|
63
|
-
case prop.type ===
|
|
65
|
+
case prop.type === types.AST_NODE_TYPES.SpreadElement:
|
|
64
66
|
switch (true) {
|
|
65
|
-
case prop.argument.type ===
|
|
67
|
+
case prop.argument.type === types.AST_NODE_TYPES.Identifier: {
|
|
66
68
|
const { name } = prop.argument;
|
|
67
69
|
const maybeInit = tools.O.flatMap(
|
|
68
70
|
_var.findVariable(name, initialScope),
|
|
@@ -70,22 +72,22 @@ function findPropInProperties(properties, context, initialScope, seenProps = [])
|
|
|
70
72
|
);
|
|
71
73
|
if (tools.O.isNone(maybeInit)) return false;
|
|
72
74
|
const init = maybeInit.value;
|
|
73
|
-
if (!ast.is(
|
|
75
|
+
if (!ast.is(types.AST_NODE_TYPES.ObjectExpression)(init)) return false;
|
|
74
76
|
if (seenProps.includes(name)) return false;
|
|
75
77
|
return tools.O.isSome(
|
|
76
|
-
findPropInProperties(init.properties,
|
|
78
|
+
findPropInProperties(init.properties, initialScope, [...seenProps, name])(propName)
|
|
77
79
|
);
|
|
78
80
|
}
|
|
79
|
-
case prop.argument.type ===
|
|
81
|
+
case prop.argument.type === types.AST_NODE_TYPES.ObjectExpression: {
|
|
80
82
|
return tools.O.isSome(
|
|
81
|
-
findPropInProperties(prop.argument.properties,
|
|
83
|
+
findPropInProperties(prop.argument.properties, initialScope, seenProps)(propName)
|
|
82
84
|
);
|
|
83
85
|
}
|
|
84
86
|
default: {
|
|
85
87
|
return false;
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
|
-
case prop.type ===
|
|
90
|
+
case prop.type === types.AST_NODE_TYPES.RestElement:
|
|
89
91
|
return false;
|
|
90
92
|
default:
|
|
91
93
|
return false;
|
|
@@ -94,16 +96,16 @@ function findPropInProperties(properties, context, initialScope, seenProps = [])
|
|
|
94
96
|
);
|
|
95
97
|
};
|
|
96
98
|
}
|
|
97
|
-
function findPropInAttributes(attributes,
|
|
99
|
+
function findPropInAttributes(attributes, initialScope) {
|
|
98
100
|
return (propName) => {
|
|
99
101
|
return tools.O.fromNullable(
|
|
100
102
|
attributes.findLast((attr) => {
|
|
101
103
|
switch (attr.type) {
|
|
102
|
-
case
|
|
104
|
+
case types.AST_NODE_TYPES.JSXAttribute:
|
|
103
105
|
return getPropName(attr) === propName;
|
|
104
|
-
case
|
|
106
|
+
case types.AST_NODE_TYPES.JSXSpreadAttribute:
|
|
105
107
|
switch (attr.argument.type) {
|
|
106
|
-
case
|
|
108
|
+
case types.AST_NODE_TYPES.Identifier: {
|
|
107
109
|
const { name } = attr.argument;
|
|
108
110
|
const maybeInit = tools.O.flatMap(
|
|
109
111
|
_var.findVariable(name, initialScope),
|
|
@@ -111,14 +113,14 @@ function findPropInAttributes(attributes, context, initialScope) {
|
|
|
111
113
|
);
|
|
112
114
|
if (tools.O.isNone(maybeInit)) return false;
|
|
113
115
|
const init = maybeInit.value;
|
|
114
|
-
if (!ast.is(
|
|
115
|
-
return tools.O.isSome(findPropInProperties(init.properties,
|
|
116
|
+
if (!ast.is(types.AST_NODE_TYPES.ObjectExpression)(init)) return false;
|
|
117
|
+
return tools.O.isSome(findPropInProperties(init.properties, initialScope)(propName));
|
|
116
118
|
}
|
|
117
|
-
case
|
|
118
|
-
return tools.O.isSome(findPropInProperties(attr.argument.properties,
|
|
119
|
-
case
|
|
119
|
+
case types.AST_NODE_TYPES.ObjectExpression:
|
|
120
|
+
return tools.O.isSome(findPropInProperties(attr.argument.properties, initialScope)(propName));
|
|
121
|
+
case types.AST_NODE_TYPES.MemberExpression:
|
|
120
122
|
return false;
|
|
121
|
-
case
|
|
123
|
+
case types.AST_NODE_TYPES.CallExpression:
|
|
122
124
|
return false;
|
|
123
125
|
default:
|
|
124
126
|
return false;
|
|
@@ -132,51 +134,40 @@ function findPropInAttributes(attributes, context, initialScope) {
|
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
// src/get-element-type.ts
|
|
135
|
-
function getElementType(
|
|
137
|
+
function getElementType(ctx, components, polymorphicPropName) {
|
|
136
138
|
return (node) => {
|
|
137
139
|
const elementName = getElementName(node);
|
|
138
140
|
if (elementName === elementName.toLowerCase()) return elementName;
|
|
139
141
|
const asElementName = components?.get(elementName);
|
|
140
142
|
if (tools.isString(asElementName)) return asElementName;
|
|
141
|
-
const initialScope =
|
|
143
|
+
const initialScope = ctx.getScope(node);
|
|
142
144
|
return tools.F.pipe(
|
|
143
145
|
tools.O.fromNullable(polymorphicPropName),
|
|
144
|
-
tools.O.flatMap(findPropInAttributes(node.attributes,
|
|
145
|
-
tools.O.flatMap((attr) => getPropValue(attr,
|
|
146
|
+
tools.O.flatMap(findPropInAttributes(node.attributes, initialScope)),
|
|
147
|
+
tools.O.flatMap((attr) => getPropValue(attr, ctx.getScope(attr))),
|
|
146
148
|
tools.O.flatMapNullable((v) => v?.value),
|
|
147
149
|
tools.O.filter(tools.isString),
|
|
148
150
|
tools.O.getOrElse(() => elementName)
|
|
149
151
|
);
|
|
150
152
|
};
|
|
151
153
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
function getJSXPragma(context) {
|
|
155
|
-
const { sourceCode } = context;
|
|
156
|
-
return tools.F.pipe(
|
|
157
|
-
tools.O.fromNullable(sourceCode.getAllComments().find((node) => RE_JSX_ANNOTATION_REGEX.test(node.value))),
|
|
158
|
-
tools.O.map(({ value }) => RE_JSX_ANNOTATION_REGEX.exec(value)),
|
|
159
|
-
tools.O.flatMapNullable((matches) => matches?.[1]),
|
|
160
|
-
tools.O.filter((pragma) => RE_JS_IDENTIFIER_REGEX.test(pragma))
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
function hasProp(attributes, propName, context, initialScope) {
|
|
164
|
-
return tools.O.isSome(findPropInAttributes(attributes, context, initialScope)(propName));
|
|
154
|
+
function hasProp(attributes, propName, initialScope) {
|
|
155
|
+
return tools.O.isSome(findPropInAttributes(attributes, initialScope)(propName));
|
|
165
156
|
}
|
|
166
|
-
function hasAnyProp(attributes, propNames,
|
|
167
|
-
return propNames.some((propName) => hasProp(attributes, propName,
|
|
157
|
+
function hasAnyProp(attributes, propNames, initialScope) {
|
|
158
|
+
return propNames.some((propName) => hasProp(attributes, propName, initialScope));
|
|
168
159
|
}
|
|
169
|
-
function hasEveryProp(attributes, propNames,
|
|
170
|
-
return propNames.every((propName) => hasProp(attributes, propName,
|
|
160
|
+
function hasEveryProp(attributes, propNames, initialScope) {
|
|
161
|
+
return propNames.every((propName) => hasProp(attributes, propName, initialScope));
|
|
171
162
|
}
|
|
172
|
-
function isKeyedElement(node,
|
|
173
|
-
return node.type ===
|
|
163
|
+
function isKeyedElement(node, initialScope) {
|
|
164
|
+
return node.type === types.AST_NODE_TYPES.JSXElement && hasProp(node.openingElement.attributes, "key", initialScope);
|
|
174
165
|
}
|
|
175
166
|
function isUserDefinedElement(node) {
|
|
176
|
-
return node.type ===
|
|
167
|
+
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);
|
|
177
168
|
}
|
|
178
169
|
function isBuiltInElement(node) {
|
|
179
|
-
return node.type ===
|
|
170
|
+
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);
|
|
180
171
|
}
|
|
181
172
|
var JSXValueHint = {
|
|
182
173
|
None: 0n,
|
|
@@ -192,55 +183,55 @@ var JSXValueHint = {
|
|
|
192
183
|
StrictConditional: 1n << 9n
|
|
193
184
|
};
|
|
194
185
|
var DEFAULT_JSX_VALUE_HINT = 0n | JSXValueHint.SkipUndefinedLiteral | JSXValueHint.SkipBooleanLiteral;
|
|
195
|
-
function isJSXValue(node,
|
|
186
|
+
function isJSXValue(node, ctx, hint = DEFAULT_JSX_VALUE_HINT) {
|
|
196
187
|
if (!node) return false;
|
|
197
|
-
return tsPattern.match(node).with({ type:
|
|
188
|
+
return tsPattern.match(node).with({ type: types.AST_NODE_TYPES.JSXElement }, tools.F.constTrue).with({ type: types.AST_NODE_TYPES.JSXFragment }, tools.F.constTrue).with({ type: types.AST_NODE_TYPES.JSXMemberExpression }, tools.F.constTrue).with({ type: types.AST_NODE_TYPES.JSXNamespacedName }, tools.F.constTrue).with({ type: types.AST_NODE_TYPES.Literal }, (node2) => {
|
|
198
189
|
return tsPattern.match(node2.value).with(null, () => !(hint & JSXValueHint.SkipNullLiteral)).with(tsPattern.P.boolean, () => !(hint & JSXValueHint.SkipBooleanLiteral)).with(tsPattern.P.string, () => !(hint & JSXValueHint.SkipStringLiteral)).with(tsPattern.P.number, () => !(hint & JSXValueHint.SkipNumberLiteral)).otherwise(tools.F.constFalse);
|
|
199
|
-
}).with({ type:
|
|
200
|
-
if (hint & JSXValueHint.StrictArray) return node2.elements.every((n) => isJSXValue(n,
|
|
201
|
-
return node2.elements.some((n) => isJSXValue(n,
|
|
202
|
-
}).with({ type:
|
|
190
|
+
}).with({ type: types.AST_NODE_TYPES.TemplateLiteral }, () => !(hint & JSXValueHint.SkipStringLiteral)).with({ type: types.AST_NODE_TYPES.ArrayExpression }, (node2) => {
|
|
191
|
+
if (hint & JSXValueHint.StrictArray) return node2.elements.every((n) => isJSXValue(n, ctx, hint));
|
|
192
|
+
return node2.elements.some((n) => isJSXValue(n, ctx, hint));
|
|
193
|
+
}).with({ type: types.AST_NODE_TYPES.ConditionalExpression }, (node2) => {
|
|
203
194
|
function leftHasJSX(node3) {
|
|
204
195
|
if (Array.isArray(node3.consequent)) {
|
|
205
196
|
if (node3.consequent.length === 0) return !(hint & JSXValueHint.SkipEmptyArray);
|
|
206
197
|
if (hint & JSXValueHint.StrictArray) {
|
|
207
|
-
return node3.consequent.every((n) => isJSXValue(n,
|
|
198
|
+
return node3.consequent.every((n) => isJSXValue(n, ctx, hint));
|
|
208
199
|
}
|
|
209
|
-
return node3.consequent.some((n) => isJSXValue(n,
|
|
200
|
+
return node3.consequent.some((n) => isJSXValue(n, ctx, hint));
|
|
210
201
|
}
|
|
211
|
-
return isJSXValue(node3.consequent,
|
|
202
|
+
return isJSXValue(node3.consequent, ctx, hint);
|
|
212
203
|
}
|
|
213
204
|
function rightHasJSX(node3) {
|
|
214
|
-
return isJSXValue(node3.alternate,
|
|
205
|
+
return isJSXValue(node3.alternate, ctx, hint);
|
|
215
206
|
}
|
|
216
207
|
if (hint & JSXValueHint.StrictConditional) {
|
|
217
208
|
return leftHasJSX(node2) && rightHasJSX(node2);
|
|
218
209
|
}
|
|
219
210
|
return leftHasJSX(node2) || rightHasJSX(node2);
|
|
220
|
-
}).with({ type:
|
|
211
|
+
}).with({ type: types.AST_NODE_TYPES.LogicalExpression }, (node2) => {
|
|
221
212
|
if (hint & JSXValueHint.StrictLogical) {
|
|
222
|
-
return isJSXValue(node2.left,
|
|
213
|
+
return isJSXValue(node2.left, ctx, hint) && isJSXValue(node2.right, ctx, hint);
|
|
223
214
|
}
|
|
224
|
-
return isJSXValue(node2.left,
|
|
225
|
-
}).with({ type:
|
|
215
|
+
return isJSXValue(node2.left, ctx, hint) || isJSXValue(node2.right, ctx, hint);
|
|
216
|
+
}).with({ type: types.AST_NODE_TYPES.SequenceExpression }, (node2) => {
|
|
226
217
|
const exp = node2.expressions.at(-1);
|
|
227
|
-
return isJSXValue(exp,
|
|
228
|
-
}).with({ type:
|
|
218
|
+
return isJSXValue(exp, ctx, hint);
|
|
219
|
+
}).with({ type: types.AST_NODE_TYPES.CallExpression }, (node2) => {
|
|
229
220
|
if (hint & JSXValueHint.SkipCreateElement) return false;
|
|
230
|
-
return tsPattern.match(node2.callee).with({ type:
|
|
231
|
-
}).with({ type:
|
|
221
|
+
return tsPattern.match(node2.callee).with({ type: types.AST_NODE_TYPES.Identifier, name: "createElement" }, tools.F.constTrue).with({ type: types.AST_NODE_TYPES.MemberExpression, property: { name: "createElement" } }, tools.F.constTrue).otherwise(tools.F.constFalse);
|
|
222
|
+
}).with({ type: types.AST_NODE_TYPES.Identifier }, (node2) => {
|
|
232
223
|
const { name } = node2;
|
|
233
224
|
if (name === "undefined") return !(hint & JSXValueHint.SkipUndefinedLiteral);
|
|
234
225
|
if (ast.isJSXTagNameExpression(node2)) return true;
|
|
235
|
-
const initialScope =
|
|
226
|
+
const initialScope = ctx.getScope(node2);
|
|
236
227
|
return tools.F.pipe(
|
|
237
228
|
_var.findVariable(name, initialScope),
|
|
238
229
|
tools.O.flatMap(_var.getVariableNode(0)),
|
|
239
|
-
tools.O.exists((n) => isJSXValue(n,
|
|
230
|
+
tools.O.exists((n) => isJSXValue(n, ctx, hint))
|
|
240
231
|
);
|
|
241
232
|
}).otherwise(tools.F.constFalse);
|
|
242
233
|
}
|
|
243
|
-
var isLiteral = ast.isOneOf([
|
|
234
|
+
var isLiteral = ast.isOneOf([types.AST_NODE_TYPES.Literal, types.AST_NODE_TYPES.JSXText]);
|
|
244
235
|
function isWhiteSpace(node) {
|
|
245
236
|
return tools.isString(node.value) && node.value.trim() === "";
|
|
246
237
|
}
|
|
@@ -252,7 +243,7 @@ function isPaddingSpaces(node) {
|
|
|
252
243
|
}
|
|
253
244
|
function traverseUpProp(node, predicate = tools.F.constTrue) {
|
|
254
245
|
const guard = (node2) => {
|
|
255
|
-
return node2.type ===
|
|
246
|
+
return node2.type === types.AST_NODE_TYPES.JSXAttribute && predicate(node2);
|
|
256
247
|
};
|
|
257
248
|
return ast.traverseUpGuard(node, guard);
|
|
258
249
|
}
|
|
@@ -263,7 +254,6 @@ exports.findPropInAttributes = findPropInAttributes;
|
|
|
263
254
|
exports.findPropInProperties = findPropInProperties;
|
|
264
255
|
exports.getElementName = getElementName;
|
|
265
256
|
exports.getElementType = getElementType;
|
|
266
|
-
exports.getJSXPragma = getJSXPragma;
|
|
267
257
|
exports.getProp = getProp;
|
|
268
258
|
exports.getPropName = getPropName;
|
|
269
259
|
exports.getPropValue = getPropValue;
|
package/dist/index.mjs
CHANGED
|
@@ -1,66 +1,68 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
2
2
|
import { O, isString, F } from '@eslint-react/tools';
|
|
3
|
+
import { isOneOf, is, isJSXTagNameExpression, isMultiLine, traverseUpGuard } from '@eslint-react/ast';
|
|
3
4
|
import { findVariable, getVariableNode } from '@eslint-react/var';
|
|
4
5
|
import { getStaticValue } from '@typescript-eslint/utils/ast-utils';
|
|
5
6
|
import { match, P } from 'ts-pattern';
|
|
6
7
|
|
|
7
8
|
// src/get-element-name.ts
|
|
8
9
|
function resolveJSXMemberExpressions(object, property) {
|
|
9
|
-
if (object.type ===
|
|
10
|
+
if (object.type === AST_NODE_TYPES.JSXMemberExpression) {
|
|
10
11
|
return `${resolveJSXMemberExpressions(object.object, object.property)}.${property.name}`;
|
|
11
12
|
}
|
|
12
|
-
if (object.type ===
|
|
13
|
+
if (object.type === AST_NODE_TYPES.JSXNamespacedName) {
|
|
13
14
|
return `${object.namespace.name}:${object.name.name}.${property.name}`;
|
|
14
15
|
}
|
|
15
16
|
return `${object.name}.${property.name}`;
|
|
16
17
|
}
|
|
17
18
|
function getElementName(node) {
|
|
18
|
-
if (node.type ===
|
|
19
|
+
if (node.type === AST_NODE_TYPES.JSXOpeningFragment) {
|
|
19
20
|
return "<>";
|
|
20
21
|
}
|
|
21
22
|
const { name } = node;
|
|
22
|
-
if (name.type ===
|
|
23
|
+
if (name.type === AST_NODE_TYPES.JSXMemberExpression) {
|
|
23
24
|
const { object, property } = name;
|
|
24
25
|
return resolveJSXMemberExpressions(object, property);
|
|
25
26
|
}
|
|
26
|
-
if (name.type ===
|
|
27
|
+
if (name.type === AST_NODE_TYPES.JSXNamespacedName) {
|
|
27
28
|
return `${name.namespace.name}:${name.name.name}`;
|
|
28
29
|
}
|
|
29
30
|
return name.name;
|
|
30
31
|
}
|
|
31
32
|
function getPropName(node) {
|
|
32
33
|
switch (node.name.type) {
|
|
33
|
-
case
|
|
34
|
+
case AST_NODE_TYPES.JSXIdentifier:
|
|
34
35
|
return node.name.name;
|
|
35
|
-
case
|
|
36
|
+
case AST_NODE_TYPES.JSXNamespacedName:
|
|
36
37
|
return `${node.name.namespace.name}:${node.name.name.name}`;
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
|
-
function getProp(props, propName,
|
|
40
|
-
return findPropInAttributes(props,
|
|
40
|
+
function getProp(props, propName, initialScope) {
|
|
41
|
+
return findPropInAttributes(props, initialScope)(propName);
|
|
41
42
|
}
|
|
42
|
-
function getPropValue(attribute,
|
|
43
|
-
|
|
44
|
-
if (attribute.type === NodeType.JSXAttribute && "value" in attribute) {
|
|
43
|
+
function getPropValue(attribute, initialScope) {
|
|
44
|
+
if (attribute.type === AST_NODE_TYPES.JSXAttribute && "value" in attribute) {
|
|
45
45
|
const { value } = attribute;
|
|
46
46
|
if (value === null) return O.none();
|
|
47
|
-
if (value.type ===
|
|
48
|
-
if (value.type ===
|
|
47
|
+
if (value.type === AST_NODE_TYPES.Literal) return O.some(getStaticValue(value, initialScope));
|
|
48
|
+
if (value.type === AST_NODE_TYPES.JSXExpressionContainer) {
|
|
49
|
+
return O.some(getStaticValue(value.expression, initialScope));
|
|
50
|
+
}
|
|
49
51
|
return O.none();
|
|
50
52
|
}
|
|
51
53
|
const { argument } = attribute;
|
|
52
54
|
return O.some(getStaticValue(argument, initialScope));
|
|
53
55
|
}
|
|
54
|
-
function findPropInProperties(properties,
|
|
56
|
+
function findPropInProperties(properties, initialScope, seenProps = []) {
|
|
55
57
|
return (propName) => {
|
|
56
58
|
return O.fromNullable(
|
|
57
59
|
properties.findLast((prop) => {
|
|
58
60
|
switch (true) {
|
|
59
|
-
case (prop.type ===
|
|
61
|
+
case (prop.type === AST_NODE_TYPES.Property && "name" in prop.key && prop.key.name === propName):
|
|
60
62
|
return true;
|
|
61
|
-
case prop.type ===
|
|
63
|
+
case prop.type === AST_NODE_TYPES.SpreadElement:
|
|
62
64
|
switch (true) {
|
|
63
|
-
case prop.argument.type ===
|
|
65
|
+
case prop.argument.type === AST_NODE_TYPES.Identifier: {
|
|
64
66
|
const { name } = prop.argument;
|
|
65
67
|
const maybeInit = O.flatMap(
|
|
66
68
|
findVariable(name, initialScope),
|
|
@@ -68,22 +70,22 @@ function findPropInProperties(properties, context, initialScope, seenProps = [])
|
|
|
68
70
|
);
|
|
69
71
|
if (O.isNone(maybeInit)) return false;
|
|
70
72
|
const init = maybeInit.value;
|
|
71
|
-
if (!is(
|
|
73
|
+
if (!is(AST_NODE_TYPES.ObjectExpression)(init)) return false;
|
|
72
74
|
if (seenProps.includes(name)) return false;
|
|
73
75
|
return O.isSome(
|
|
74
|
-
findPropInProperties(init.properties,
|
|
76
|
+
findPropInProperties(init.properties, initialScope, [...seenProps, name])(propName)
|
|
75
77
|
);
|
|
76
78
|
}
|
|
77
|
-
case prop.argument.type ===
|
|
79
|
+
case prop.argument.type === AST_NODE_TYPES.ObjectExpression: {
|
|
78
80
|
return O.isSome(
|
|
79
|
-
findPropInProperties(prop.argument.properties,
|
|
81
|
+
findPropInProperties(prop.argument.properties, initialScope, seenProps)(propName)
|
|
80
82
|
);
|
|
81
83
|
}
|
|
82
84
|
default: {
|
|
83
85
|
return false;
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
|
-
case prop.type ===
|
|
88
|
+
case prop.type === AST_NODE_TYPES.RestElement:
|
|
87
89
|
return false;
|
|
88
90
|
default:
|
|
89
91
|
return false;
|
|
@@ -92,16 +94,16 @@ function findPropInProperties(properties, context, initialScope, seenProps = [])
|
|
|
92
94
|
);
|
|
93
95
|
};
|
|
94
96
|
}
|
|
95
|
-
function findPropInAttributes(attributes,
|
|
97
|
+
function findPropInAttributes(attributes, initialScope) {
|
|
96
98
|
return (propName) => {
|
|
97
99
|
return O.fromNullable(
|
|
98
100
|
attributes.findLast((attr) => {
|
|
99
101
|
switch (attr.type) {
|
|
100
|
-
case
|
|
102
|
+
case AST_NODE_TYPES.JSXAttribute:
|
|
101
103
|
return getPropName(attr) === propName;
|
|
102
|
-
case
|
|
104
|
+
case AST_NODE_TYPES.JSXSpreadAttribute:
|
|
103
105
|
switch (attr.argument.type) {
|
|
104
|
-
case
|
|
106
|
+
case AST_NODE_TYPES.Identifier: {
|
|
105
107
|
const { name } = attr.argument;
|
|
106
108
|
const maybeInit = O.flatMap(
|
|
107
109
|
findVariable(name, initialScope),
|
|
@@ -109,14 +111,14 @@ function findPropInAttributes(attributes, context, initialScope) {
|
|
|
109
111
|
);
|
|
110
112
|
if (O.isNone(maybeInit)) return false;
|
|
111
113
|
const init = maybeInit.value;
|
|
112
|
-
if (!is(
|
|
113
|
-
return O.isSome(findPropInProperties(init.properties,
|
|
114
|
+
if (!is(AST_NODE_TYPES.ObjectExpression)(init)) return false;
|
|
115
|
+
return O.isSome(findPropInProperties(init.properties, initialScope)(propName));
|
|
114
116
|
}
|
|
115
|
-
case
|
|
116
|
-
return O.isSome(findPropInProperties(attr.argument.properties,
|
|
117
|
-
case
|
|
117
|
+
case AST_NODE_TYPES.ObjectExpression:
|
|
118
|
+
return O.isSome(findPropInProperties(attr.argument.properties, initialScope)(propName));
|
|
119
|
+
case AST_NODE_TYPES.MemberExpression:
|
|
118
120
|
return false;
|
|
119
|
-
case
|
|
121
|
+
case AST_NODE_TYPES.CallExpression:
|
|
120
122
|
return false;
|
|
121
123
|
default:
|
|
122
124
|
return false;
|
|
@@ -130,51 +132,40 @@ function findPropInAttributes(attributes, context, initialScope) {
|
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
// src/get-element-type.ts
|
|
133
|
-
function getElementType(
|
|
135
|
+
function getElementType(ctx, components, polymorphicPropName) {
|
|
134
136
|
return (node) => {
|
|
135
137
|
const elementName = getElementName(node);
|
|
136
138
|
if (elementName === elementName.toLowerCase()) return elementName;
|
|
137
139
|
const asElementName = components?.get(elementName);
|
|
138
140
|
if (isString(asElementName)) return asElementName;
|
|
139
|
-
const initialScope =
|
|
141
|
+
const initialScope = ctx.getScope(node);
|
|
140
142
|
return F.pipe(
|
|
141
143
|
O.fromNullable(polymorphicPropName),
|
|
142
|
-
O.flatMap(findPropInAttributes(node.attributes,
|
|
143
|
-
O.flatMap((attr) => getPropValue(attr,
|
|
144
|
+
O.flatMap(findPropInAttributes(node.attributes, initialScope)),
|
|
145
|
+
O.flatMap((attr) => getPropValue(attr, ctx.getScope(attr))),
|
|
144
146
|
O.flatMapNullable((v) => v?.value),
|
|
145
147
|
O.filter(isString),
|
|
146
148
|
O.getOrElse(() => elementName)
|
|
147
149
|
);
|
|
148
150
|
};
|
|
149
151
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
function getJSXPragma(context) {
|
|
153
|
-
const { sourceCode } = context;
|
|
154
|
-
return F.pipe(
|
|
155
|
-
O.fromNullable(sourceCode.getAllComments().find((node) => RE_JSX_ANNOTATION_REGEX.test(node.value))),
|
|
156
|
-
O.map(({ value }) => RE_JSX_ANNOTATION_REGEX.exec(value)),
|
|
157
|
-
O.flatMapNullable((matches) => matches?.[1]),
|
|
158
|
-
O.filter((pragma) => RE_JS_IDENTIFIER_REGEX.test(pragma))
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
function hasProp(attributes, propName, context, initialScope) {
|
|
162
|
-
return O.isSome(findPropInAttributes(attributes, context, initialScope)(propName));
|
|
152
|
+
function hasProp(attributes, propName, initialScope) {
|
|
153
|
+
return O.isSome(findPropInAttributes(attributes, initialScope)(propName));
|
|
163
154
|
}
|
|
164
|
-
function hasAnyProp(attributes, propNames,
|
|
165
|
-
return propNames.some((propName) => hasProp(attributes, propName,
|
|
155
|
+
function hasAnyProp(attributes, propNames, initialScope) {
|
|
156
|
+
return propNames.some((propName) => hasProp(attributes, propName, initialScope));
|
|
166
157
|
}
|
|
167
|
-
function hasEveryProp(attributes, propNames,
|
|
168
|
-
return propNames.every((propName) => hasProp(attributes, propName,
|
|
158
|
+
function hasEveryProp(attributes, propNames, initialScope) {
|
|
159
|
+
return propNames.every((propName) => hasProp(attributes, propName, initialScope));
|
|
169
160
|
}
|
|
170
|
-
function isKeyedElement(node,
|
|
171
|
-
return node.type ===
|
|
161
|
+
function isKeyedElement(node, initialScope) {
|
|
162
|
+
return node.type === AST_NODE_TYPES.JSXElement && hasProp(node.openingElement.attributes, "key", initialScope);
|
|
172
163
|
}
|
|
173
164
|
function isUserDefinedElement(node) {
|
|
174
|
-
return node.type ===
|
|
165
|
+
return node.type === AST_NODE_TYPES.JSXElement && node.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier && /^[A-Z]/u.test(node.openingElement.name.name);
|
|
175
166
|
}
|
|
176
167
|
function isBuiltInElement(node) {
|
|
177
|
-
return node.type ===
|
|
168
|
+
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);
|
|
178
169
|
}
|
|
179
170
|
var JSXValueHint = {
|
|
180
171
|
None: 0n,
|
|
@@ -190,55 +181,55 @@ var JSXValueHint = {
|
|
|
190
181
|
StrictConditional: 1n << 9n
|
|
191
182
|
};
|
|
192
183
|
var DEFAULT_JSX_VALUE_HINT = 0n | JSXValueHint.SkipUndefinedLiteral | JSXValueHint.SkipBooleanLiteral;
|
|
193
|
-
function isJSXValue(node,
|
|
184
|
+
function isJSXValue(node, ctx, hint = DEFAULT_JSX_VALUE_HINT) {
|
|
194
185
|
if (!node) return false;
|
|
195
|
-
return match(node).with({ type:
|
|
186
|
+
return match(node).with({ type: AST_NODE_TYPES.JSXElement }, F.constTrue).with({ type: AST_NODE_TYPES.JSXFragment }, F.constTrue).with({ type: AST_NODE_TYPES.JSXMemberExpression }, F.constTrue).with({ type: AST_NODE_TYPES.JSXNamespacedName }, F.constTrue).with({ type: AST_NODE_TYPES.Literal }, (node2) => {
|
|
196
187
|
return match(node2.value).with(null, () => !(hint & JSXValueHint.SkipNullLiteral)).with(P.boolean, () => !(hint & JSXValueHint.SkipBooleanLiteral)).with(P.string, () => !(hint & JSXValueHint.SkipStringLiteral)).with(P.number, () => !(hint & JSXValueHint.SkipNumberLiteral)).otherwise(F.constFalse);
|
|
197
|
-
}).with({ type:
|
|
198
|
-
if (hint & JSXValueHint.StrictArray) return node2.elements.every((n) => isJSXValue(n,
|
|
199
|
-
return node2.elements.some((n) => isJSXValue(n,
|
|
200
|
-
}).with({ type:
|
|
188
|
+
}).with({ type: AST_NODE_TYPES.TemplateLiteral }, () => !(hint & JSXValueHint.SkipStringLiteral)).with({ type: AST_NODE_TYPES.ArrayExpression }, (node2) => {
|
|
189
|
+
if (hint & JSXValueHint.StrictArray) return node2.elements.every((n) => isJSXValue(n, ctx, hint));
|
|
190
|
+
return node2.elements.some((n) => isJSXValue(n, ctx, hint));
|
|
191
|
+
}).with({ type: AST_NODE_TYPES.ConditionalExpression }, (node2) => {
|
|
201
192
|
function leftHasJSX(node3) {
|
|
202
193
|
if (Array.isArray(node3.consequent)) {
|
|
203
194
|
if (node3.consequent.length === 0) return !(hint & JSXValueHint.SkipEmptyArray);
|
|
204
195
|
if (hint & JSXValueHint.StrictArray) {
|
|
205
|
-
return node3.consequent.every((n) => isJSXValue(n,
|
|
196
|
+
return node3.consequent.every((n) => isJSXValue(n, ctx, hint));
|
|
206
197
|
}
|
|
207
|
-
return node3.consequent.some((n) => isJSXValue(n,
|
|
198
|
+
return node3.consequent.some((n) => isJSXValue(n, ctx, hint));
|
|
208
199
|
}
|
|
209
|
-
return isJSXValue(node3.consequent,
|
|
200
|
+
return isJSXValue(node3.consequent, ctx, hint);
|
|
210
201
|
}
|
|
211
202
|
function rightHasJSX(node3) {
|
|
212
|
-
return isJSXValue(node3.alternate,
|
|
203
|
+
return isJSXValue(node3.alternate, ctx, hint);
|
|
213
204
|
}
|
|
214
205
|
if (hint & JSXValueHint.StrictConditional) {
|
|
215
206
|
return leftHasJSX(node2) && rightHasJSX(node2);
|
|
216
207
|
}
|
|
217
208
|
return leftHasJSX(node2) || rightHasJSX(node2);
|
|
218
|
-
}).with({ type:
|
|
209
|
+
}).with({ type: AST_NODE_TYPES.LogicalExpression }, (node2) => {
|
|
219
210
|
if (hint & JSXValueHint.StrictLogical) {
|
|
220
|
-
return isJSXValue(node2.left,
|
|
211
|
+
return isJSXValue(node2.left, ctx, hint) && isJSXValue(node2.right, ctx, hint);
|
|
221
212
|
}
|
|
222
|
-
return isJSXValue(node2.left,
|
|
223
|
-
}).with({ type:
|
|
213
|
+
return isJSXValue(node2.left, ctx, hint) || isJSXValue(node2.right, ctx, hint);
|
|
214
|
+
}).with({ type: AST_NODE_TYPES.SequenceExpression }, (node2) => {
|
|
224
215
|
const exp = node2.expressions.at(-1);
|
|
225
|
-
return isJSXValue(exp,
|
|
226
|
-
}).with({ type:
|
|
216
|
+
return isJSXValue(exp, ctx, hint);
|
|
217
|
+
}).with({ type: AST_NODE_TYPES.CallExpression }, (node2) => {
|
|
227
218
|
if (hint & JSXValueHint.SkipCreateElement) return false;
|
|
228
|
-
return match(node2.callee).with({ type:
|
|
229
|
-
}).with({ type:
|
|
219
|
+
return match(node2.callee).with({ type: AST_NODE_TYPES.Identifier, name: "createElement" }, F.constTrue).with({ type: AST_NODE_TYPES.MemberExpression, property: { name: "createElement" } }, F.constTrue).otherwise(F.constFalse);
|
|
220
|
+
}).with({ type: AST_NODE_TYPES.Identifier }, (node2) => {
|
|
230
221
|
const { name } = node2;
|
|
231
222
|
if (name === "undefined") return !(hint & JSXValueHint.SkipUndefinedLiteral);
|
|
232
223
|
if (isJSXTagNameExpression(node2)) return true;
|
|
233
|
-
const initialScope =
|
|
224
|
+
const initialScope = ctx.getScope(node2);
|
|
234
225
|
return F.pipe(
|
|
235
226
|
findVariable(name, initialScope),
|
|
236
227
|
O.flatMap(getVariableNode(0)),
|
|
237
|
-
O.exists((n) => isJSXValue(n,
|
|
228
|
+
O.exists((n) => isJSXValue(n, ctx, hint))
|
|
238
229
|
);
|
|
239
230
|
}).otherwise(F.constFalse);
|
|
240
231
|
}
|
|
241
|
-
var isLiteral = isOneOf([
|
|
232
|
+
var isLiteral = isOneOf([AST_NODE_TYPES.Literal, AST_NODE_TYPES.JSXText]);
|
|
242
233
|
function isWhiteSpace(node) {
|
|
243
234
|
return isString(node.value) && node.value.trim() === "";
|
|
244
235
|
}
|
|
@@ -250,9 +241,9 @@ function isPaddingSpaces(node) {
|
|
|
250
241
|
}
|
|
251
242
|
function traverseUpProp(node, predicate = F.constTrue) {
|
|
252
243
|
const guard = (node2) => {
|
|
253
|
-
return node2.type ===
|
|
244
|
+
return node2.type === AST_NODE_TYPES.JSXAttribute && predicate(node2);
|
|
254
245
|
};
|
|
255
246
|
return traverseUpGuard(node, guard);
|
|
256
247
|
}
|
|
257
248
|
|
|
258
|
-
export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findPropInAttributes, findPropInProperties, getElementName, getElementType,
|
|
249
|
+
export { DEFAULT_JSX_VALUE_HINT, JSXValueHint, findPropInAttributes, findPropInProperties, getElementName, getElementType, getProp, getPropName, getPropValue, hasAnyProp, hasEveryProp, hasProp, isBuiltInElement, isJSXValue, isKeyedElement, isLineBreak, isLiteral, isPaddingSpaces, isUserDefinedElement, isWhiteSpace, traverseUpProp };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/jsx",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.2-next.2",
|
|
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,10 +39,10 @@
|
|
|
39
39
|
"@typescript-eslint/types": "^8.0.1",
|
|
40
40
|
"@typescript-eslint/utils": "^8.0.1",
|
|
41
41
|
"ts-pattern": "^5.2.0",
|
|
42
|
-
"@eslint-react/ast": "1.9.
|
|
43
|
-
"@eslint-react/
|
|
44
|
-
"@eslint-react/tools": "1.9.
|
|
45
|
-
"@eslint-react/
|
|
42
|
+
"@eslint-react/ast": "1.9.2-next.2",
|
|
43
|
+
"@eslint-react/var": "1.9.2-next.2",
|
|
44
|
+
"@eslint-react/tools": "1.9.2-next.2",
|
|
45
|
+
"@eslint-react/types": "1.9.2-next.2"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"tsup": "^8.2.4"
|