@eslint-react/ast 3.0.0-next.9 → 3.0.0-rc.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.ts +90 -68
- package/dist/index.js +283 -114
- package/package.json +11 -8
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { unit } from "@eslint-react/eff";
|
|
2
1
|
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types";
|
|
3
2
|
import { TSESTree as TSESTree$1 } from "@typescript-eslint/utils";
|
|
4
3
|
|
|
@@ -34,7 +33,7 @@ type TSESTreeProperty = TSESTree$1.PropertyDefinition | TSESTree$1.TSIndexSignat
|
|
|
34
33
|
/**
|
|
35
34
|
* Represents all JSX-related nodes in TSESTree
|
|
36
35
|
*/
|
|
37
|
-
type TSESTreeJSX = TSESTree$1.JSXAttribute | TSESTree$1.JSXChild | TSESTree$1.JSXClosingElement | TSESTree$1.JSXClosingFragment | TSESTree$1.
|
|
36
|
+
type TSESTreeJSX = TSESTree$1.JSXAttribute | TSESTree$1.JSXChild | TSESTree$1.JSXClosingElement | TSESTree$1.JSXClosingFragment | TSESTree$1.JSXEmptyExpression | TSESTree$1.JSXIdentifierToken | TSESTree$1.JSXOpeningElement | TSESTree$1.JSXOpeningFragment | TSESTree$1.JSXSpreadAttribute | TSESTree$1.JSXTagNameExpression | TSESTree$1.JSXTextToken;
|
|
38
37
|
/**
|
|
39
38
|
* Represents JSX attribute-like nodes (attributes and spread attributes)
|
|
40
39
|
*/
|
|
@@ -56,7 +55,7 @@ type TSESTreeTypeExpression = TSESTree$1.TSAsExpression | TSESTree$1.TSNonNullEx
|
|
|
56
55
|
*/
|
|
57
56
|
type TSESTreeTypeAssertionExpression = TSESTree$1.TSAsExpression | TSESTree$1.TSNonNullExpression | TSESTree$1.TSSatisfiesExpression | TSESTree$1.TSTypeAssertion;
|
|
58
57
|
/**
|
|
59
|
-
* Represents a directive expression statement in TSESTree (
|
|
58
|
+
* Represents a directive expression statement in TSESTree (ex: "use strict";)
|
|
60
59
|
*/
|
|
61
60
|
type TSESTreeDirective = TSESTree$1.ExpressionStatement & {
|
|
62
61
|
directive: string;
|
|
@@ -73,37 +72,9 @@ type TSESTreeDirectiveLike = TSESTree$1.ExpressionStatement & {
|
|
|
73
72
|
/**
|
|
74
73
|
* Get the class identifier of a class node
|
|
75
74
|
* @param node The class node to get the identifier from
|
|
76
|
-
* @returns The class identifier or
|
|
75
|
+
* @returns The class identifier or null if not found
|
|
77
76
|
*/
|
|
78
|
-
declare function getClassId(node: TSESTreeClass): TSESTree.BindingName |
|
|
79
|
-
//#endregion
|
|
80
|
-
//#region src/directive-helper.d.ts
|
|
81
|
-
/**
|
|
82
|
-
* Get all directive expression statements from the top of a program AST node
|
|
83
|
-
* @param node The program AST node
|
|
84
|
-
* @returns The array of directive string literals (e.g., "use strict")
|
|
85
|
-
*/
|
|
86
|
-
declare function getFileDirectives(node: TSESTree.Program): TSESTreeDirective[];
|
|
87
|
-
/**
|
|
88
|
-
* Get all directive expression statements from the top of a function AST node
|
|
89
|
-
* @param node The function AST node
|
|
90
|
-
* @returns The array of directive string literals (e.g., "use memo", "use no memo")
|
|
91
|
-
*/
|
|
92
|
-
declare function getFunctionDirectives(node: TSESTreeFunction): TSESTreeDirective[];
|
|
93
|
-
/**
|
|
94
|
-
* Check if a directive with the given name exists in the file or function directives
|
|
95
|
-
* @param node The program or function AST node
|
|
96
|
-
* @param name The directive name to check (e.g., "use strict", "use memo", "use no memo")
|
|
97
|
-
* @returns True if the directive exists, false otherwise
|
|
98
|
-
*/
|
|
99
|
-
declare function isDirectiveInFile(node: TSESTree.Program, name: string): boolean;
|
|
100
|
-
/**
|
|
101
|
-
* Check if a directive with the given name exists in the function directives
|
|
102
|
-
* @param node The function AST node
|
|
103
|
-
* @param name The directive name to check (e.g., "use memo", "use no memo")
|
|
104
|
-
* @returns True if the directive exists, false otherwise
|
|
105
|
-
*/
|
|
106
|
-
declare function isDirectiveInFunction(node: TSESTreeFunction, name: string): boolean;
|
|
77
|
+
declare function getClassId(node: TSESTreeClass): TSESTree.BindingName | null;
|
|
107
78
|
//#endregion
|
|
108
79
|
//#region src/directive-is.d.ts
|
|
109
80
|
/**
|
|
@@ -120,6 +91,9 @@ declare function isDirective(node: TSESTree.Node): node is TSESTreeDirective;
|
|
|
120
91
|
declare function isDirectiveLike(node: TSESTree.Node): node is TSESTreeDirectiveLike;
|
|
121
92
|
//#endregion
|
|
122
93
|
//#region src/directive-kind.d.ts
|
|
94
|
+
/**
|
|
95
|
+
* Known directive kinds in React
|
|
96
|
+
*/
|
|
123
97
|
type DirectiveKind = "use client" | "use server" | "use memo" | "use no memo";
|
|
124
98
|
/**
|
|
125
99
|
* Check if a node is a directive kind
|
|
@@ -136,15 +110,6 @@ declare function isDirectiveKind(kind: string): kind is DirectiveKind;
|
|
|
136
110
|
*/
|
|
137
111
|
declare function isDirectiveName(name: string): boolean;
|
|
138
112
|
//#endregion
|
|
139
|
-
//#region src/expression-base.d.ts
|
|
140
|
-
/**
|
|
141
|
-
* Unwraps any type expressions to get the underlying JavaScript expression node.
|
|
142
|
-
* Recursively processes nodes until a non-type expression is found.
|
|
143
|
-
* @param node The AST node to unwrap
|
|
144
|
-
* @returns The underlying JavaScript expression node
|
|
145
|
-
*/
|
|
146
|
-
declare function getUnderlyingExpression(node: TSESTree.Node): Exclude<TSESTree.Node, TSESTreeTypeExpression>;
|
|
147
|
-
//#endregion
|
|
148
113
|
//#region src/expression-is.d.ts
|
|
149
114
|
/**
|
|
150
115
|
* Check if the given expression is a 'this' expression
|
|
@@ -190,6 +155,36 @@ declare const getNestedNewExpressions: (node: TSESTree.Node) => TSESTree.NewExpr
|
|
|
190
155
|
*/
|
|
191
156
|
declare const getNestedCallExpressions: (node: TSESTree.Node) => TSESTree.CallExpression[];
|
|
192
157
|
//#endregion
|
|
158
|
+
//#region src/file-directive.d.ts
|
|
159
|
+
/**
|
|
160
|
+
* Get all directive expression statements from the top of a program AST node
|
|
161
|
+
* @param node The program AST node
|
|
162
|
+
* @returns The array of directive string literals (ex: "use strict")
|
|
163
|
+
*/
|
|
164
|
+
declare function getFileDirectives(node: TSESTree.Program): TSESTreeDirective[];
|
|
165
|
+
/**
|
|
166
|
+
* Check if a directive with the given name exists in the file or function directives
|
|
167
|
+
* @param node The program or function AST node
|
|
168
|
+
* @param name The directive name to check (ex: "use strict", "use memo", "use no memo")
|
|
169
|
+
* @returns True if the directive exists, false otherwise
|
|
170
|
+
*/
|
|
171
|
+
declare function isDirectiveInFile(node: TSESTree.Program, name: string): boolean;
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/function-directive.d.ts
|
|
174
|
+
/**
|
|
175
|
+
* Get all directive expression statements from the top of a function AST node
|
|
176
|
+
* @param node The function AST node
|
|
177
|
+
* @returns The array of directive string literals (ex: "use memo", "use no memo")
|
|
178
|
+
*/
|
|
179
|
+
declare function getFunctionDirectives(node: TSESTreeFunction): TSESTreeDirective[];
|
|
180
|
+
/**
|
|
181
|
+
* Check if a directive with the given name exists in the function directives
|
|
182
|
+
* @param node The function AST node
|
|
183
|
+
* @param name The directive name to check (ex: "use memo", "use no memo")
|
|
184
|
+
* @returns True if the directive exists, false otherwise
|
|
185
|
+
*/
|
|
186
|
+
declare function isDirectiveInFunction(node: TSESTreeFunction, name: string): boolean;
|
|
187
|
+
//#endregion
|
|
193
188
|
//#region src/function-id.d.ts
|
|
194
189
|
/**
|
|
195
190
|
* Gets the static name of a function AST node. For function declarations it is
|
|
@@ -198,7 +193,7 @@ declare const getNestedCallExpressions: (node: TSESTree.Node) => TSESTree.CallEx
|
|
|
198
193
|
* where JS gives anonymous function expressions names. We roughly detect the
|
|
199
194
|
* same AST nodes with some exceptions to better fit our use case.
|
|
200
195
|
*/
|
|
201
|
-
declare function getFunctionId(node: TSESTree.Expression | TSESTreeFunction): TSESTree.ArrayExpression | TSESTree.ArrayPattern | TSESTree.ArrowFunctionExpression | TSESTree.AssignmentExpression | TSESTree.AwaitExpression | TSESTree.PrivateInExpression | TSESTree.SymmetricBinaryExpression | TSESTree.CallExpression | TSESTree.ChainExpression | TSESTree.ClassExpression | TSESTree.ConditionalExpression | TSESTree.FunctionExpression | TSESTree.Identifier | TSESTree.ImportExpression | TSESTree.JSXElement | TSESTree.JSXFragment | TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral | TSESTree.LogicalExpression | TSESTree.MemberExpressionComputedName | TSESTree.MemberExpressionNonComputedName | TSESTree.MetaProperty | TSESTree.NewExpression | TSESTree.ObjectExpression | TSESTree.ObjectPattern | TSESTree.PrivateIdentifier | TSESTree.SequenceExpression | TSESTree.Super | TSESTree.TaggedTemplateExpression | TSESTree.TemplateLiteral | TSESTree.ThisExpression | TSESTree.TSAsExpression | TSESTree.TSInstantiationExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion | TSESTree.UnaryExpressionBitwiseNot | TSESTree.UnaryExpressionDelete | TSESTree.UnaryExpressionMinus | TSESTree.UnaryExpressionNot | TSESTree.UnaryExpressionPlus | TSESTree.UnaryExpressionTypeof | TSESTree.UnaryExpressionVoid | TSESTree.UpdateExpression | TSESTree.YieldExpression |
|
|
196
|
+
declare function getFunctionId(node: TSESTree.Expression | TSESTreeFunction): TSESTree.ArrayExpression | TSESTree.ArrayPattern | TSESTree.ArrowFunctionExpression | TSESTree.AssignmentExpression | TSESTree.AwaitExpression | TSESTree.PrivateInExpression | TSESTree.SymmetricBinaryExpression | TSESTree.CallExpression | TSESTree.ChainExpression | TSESTree.ClassExpression | TSESTree.ConditionalExpression | TSESTree.FunctionExpression | TSESTree.Identifier | TSESTree.ImportExpression | TSESTree.JSXElement | TSESTree.JSXFragment | TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral | TSESTree.LogicalExpression | TSESTree.MemberExpressionComputedName | TSESTree.MemberExpressionNonComputedName | TSESTree.MetaProperty | TSESTree.NewExpression | TSESTree.ObjectExpression | TSESTree.ObjectPattern | TSESTree.PrivateIdentifier | TSESTree.SequenceExpression | TSESTree.Super | TSESTree.TaggedTemplateExpression | TSESTree.TemplateLiteral | TSESTree.ThisExpression | TSESTree.TSAsExpression | TSESTree.TSInstantiationExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion | TSESTree.UnaryExpressionBitwiseNot | TSESTree.UnaryExpressionDelete | TSESTree.UnaryExpressionMinus | TSESTree.UnaryExpressionNot | TSESTree.UnaryExpressionPlus | TSESTree.UnaryExpressionTypeof | TSESTree.UnaryExpressionVoid | TSESTree.UpdateExpression | TSESTree.YieldExpression | null;
|
|
202
197
|
/**
|
|
203
198
|
* Type representing the return type of getFunctionId
|
|
204
199
|
*/
|
|
@@ -215,14 +210,14 @@ type FunctionInitPath = readonly [TSESTree.FunctionDeclaration] | readonly [TSES
|
|
|
215
210
|
* Determine what kind of component declaration pattern the function belongs to.
|
|
216
211
|
*
|
|
217
212
|
* @param node The function node to analyze
|
|
218
|
-
* @returns The function initialization path or
|
|
213
|
+
* @returns The function initialization path or null if not identifiable
|
|
219
214
|
*/
|
|
220
|
-
declare function getFunctionInitPath(node: TSESTreeFunction):
|
|
215
|
+
declare function getFunctionInitPath(node: TSESTreeFunction): null | FunctionInitPath;
|
|
221
216
|
/**
|
|
222
217
|
* Check if a specific function call exists in the function initialization path.
|
|
223
218
|
* Useful for detecting HOCs like React.memo, React.forwardRef, etc.
|
|
224
219
|
*
|
|
225
|
-
* @param callName The name of the call to check for (
|
|
220
|
+
* @param callName The name of the call to check for (ex: "memo", "forwardRef")
|
|
226
221
|
* @param initPath The function initialization path to search in
|
|
227
222
|
* @returns True if the call exists in the path, false otherwise
|
|
228
223
|
*/
|
|
@@ -249,7 +244,7 @@ declare function isFunctionImmediatelyInvoked(node: TSESTreeFunction): boolean;
|
|
|
249
244
|
* @param name The name to check
|
|
250
245
|
* @returns True if the node is an identifier, false otherwise
|
|
251
246
|
*/
|
|
252
|
-
declare function isIdentifier(node: TSESTree.Node | null
|
|
247
|
+
declare function isIdentifier(node: TSESTree.Node | null, name?: string): node is TSESTree.Identifier;
|
|
253
248
|
//#endregion
|
|
254
249
|
//#region src/identifier-name.d.ts
|
|
255
250
|
/**
|
|
@@ -259,6 +254,15 @@ declare function isIdentifier(node: TSESTree.Node | null | unit, name?: string):
|
|
|
259
254
|
*/
|
|
260
255
|
declare function isIdentifierName(name: string): boolean;
|
|
261
256
|
//#endregion
|
|
257
|
+
//#region src/identifier-traverse.d.ts
|
|
258
|
+
/**
|
|
259
|
+
* Get the root identifier of a (possibly nested) member expression.
|
|
260
|
+
* For `a.b.c`, returns the `a` Identifier node.
|
|
261
|
+
* @param node The expression to analyze
|
|
262
|
+
* @returns The root Identifier node, or null if it cannot be determined (ex: non-identifier root)
|
|
263
|
+
*/
|
|
264
|
+
declare function getRootIdentifier(node: TSESTree.Expression | TSESTree.PrivateIdentifier): TSESTree.Identifier | null;
|
|
265
|
+
//#endregion
|
|
262
266
|
//#region src/literal-is.d.ts
|
|
263
267
|
/**
|
|
264
268
|
* Check if a node is a literal value
|
|
@@ -272,7 +276,7 @@ declare function isLiteral(node: TSESTree.Node, type: "number"): node is TSESTre
|
|
|
272
276
|
declare function isLiteral(node: TSESTree.Node, type: "regexp"): node is TSESTree.RegExpLiteral;
|
|
273
277
|
declare function isLiteral(node: TSESTree.Node, type: "string"): node is TSESTree.StringLiteral;
|
|
274
278
|
//#endregion
|
|
275
|
-
//#region src/node-
|
|
279
|
+
//#region src/node-equality.d.ts
|
|
276
280
|
/**
|
|
277
281
|
* Check if two nodes are equal
|
|
278
282
|
* @param a node to compare
|
|
@@ -442,24 +446,33 @@ declare const SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION: string;
|
|
|
442
446
|
* Find the parent node that satisfies the test function
|
|
443
447
|
* @param node The AST node
|
|
444
448
|
* @param test The test function
|
|
445
|
-
* @returns The parent node that satisfies the test function or `
|
|
449
|
+
* @returns The parent node that satisfies the test function or `null` if not found
|
|
446
450
|
*/
|
|
447
|
-
declare function findParentNode<A extends TSESTree.Node>(node: TSESTree.Node |
|
|
451
|
+
declare function findParentNode<A extends TSESTree.Node>(node: TSESTree.Node | null, test: (n: TSESTree.Node) => n is A): A | null;
|
|
448
452
|
/**
|
|
449
|
-
* Find the parent node that satisfies the test function or `
|
|
453
|
+
* Find the parent node that satisfies the test function or `null` if not found
|
|
450
454
|
* @param node The AST node
|
|
451
455
|
* @param test The test function
|
|
452
456
|
* @returns The parent node that satisfies the test function
|
|
453
457
|
*/
|
|
454
|
-
declare function findParentNode(node: TSESTree.Node |
|
|
458
|
+
declare function findParentNode(node: TSESTree.Node | null, test: (node: TSESTree.Node) => boolean): TSESTree.Node | null;
|
|
459
|
+
//#endregion
|
|
460
|
+
//#region src/node-unwrap.d.ts
|
|
461
|
+
/**
|
|
462
|
+
* Unwraps any type expressions to get the underlying JavaScript expression node.
|
|
463
|
+
* Recursively processes nodes until a non-type expression is found.
|
|
464
|
+
* @param node The AST node to unwrap
|
|
465
|
+
* @returns The underlying JavaScript expression node
|
|
466
|
+
*/
|
|
467
|
+
declare function getUnderlyingExpression(node: TSESTree.Node): Exclude<TSESTree.Node, TSESTreeTypeExpression>;
|
|
455
468
|
//#endregion
|
|
456
|
-
//#region src/process-env-node-env.d.ts
|
|
469
|
+
//#region src/pattern-process-env-node-env.d.ts
|
|
457
470
|
/**
|
|
458
471
|
* Check if the given node is a member expression that accesses `process.env.NODE_ENV`
|
|
459
472
|
* @param node The AST node
|
|
460
473
|
* @returns True if the node is a member expression that accesses `process.env.NODE_ENV`, false otherwise
|
|
461
474
|
*/
|
|
462
|
-
declare function isProcessEnvNodeEnv(node: TSESTree.Node | null
|
|
475
|
+
declare function isProcessEnvNodeEnv(node: TSESTree.Node | null): node is TSESTree.MemberExpression;
|
|
463
476
|
/**
|
|
464
477
|
* Check if the given node is a binary expression that compares `process.env.NODE_ENV` with a string literal.
|
|
465
478
|
* @param node The AST node
|
|
@@ -467,31 +480,40 @@ declare function isProcessEnvNodeEnv(node: TSESTree.Node | null | unit): node is
|
|
|
467
480
|
* @param value The string literal value to compare against
|
|
468
481
|
* @returns True if the node is a binary expression that compares `process.env.NODE_ENV` with the specified value, false otherwise
|
|
469
482
|
*/
|
|
470
|
-
declare function isProcessEnvNodeEnvCompare(node: TSESTree.Node | null
|
|
471
|
-
//#endregion
|
|
472
|
-
//#region src/property-name.d.ts
|
|
473
|
-
/**
|
|
474
|
-
* Get the name of a property from a node
|
|
475
|
-
* Handles identifiers, private identifiers, literals, and template literals
|
|
476
|
-
* @param node The node to get the property name from
|
|
477
|
-
* @returns The property name or unit if not determinable
|
|
478
|
-
*/
|
|
479
|
-
declare function getPropertyName(node: TSESTree.Node): string | unit;
|
|
483
|
+
declare function isProcessEnvNodeEnvCompare(node: TSESTree.Node | null, operator: "===" | "!==", value: "development" | "production"): node is TSESTree.BinaryExpression;
|
|
480
484
|
//#endregion
|
|
481
|
-
//#region src/vitest-mock.d.ts
|
|
485
|
+
//#region src/pattern-vitest-mock.d.ts
|
|
482
486
|
/**
|
|
483
487
|
* Check if the given node is a `vi.mock`.
|
|
484
488
|
* @param node The node to check
|
|
485
489
|
* @returns `true` if the node is a `vi.mock`, otherwise `false`.
|
|
486
490
|
* @internal
|
|
487
491
|
*/
|
|
488
|
-
declare function isViMock(node: TSESTree.Node | null
|
|
492
|
+
declare function isViMock(node: TSESTree.Node | null): node is TSESTree.MemberExpression;
|
|
489
493
|
/**
|
|
490
494
|
* Check if the given node is a `vi.mock` callback.
|
|
491
495
|
* @param node The node to check
|
|
492
496
|
* @returns `true` if the node is a `vi.mock` callback, otherwise `false`.
|
|
493
497
|
* @internal
|
|
494
498
|
*/
|
|
495
|
-
declare function isViMockCallback(node: TSESTree.Node | null
|
|
499
|
+
declare function isViMockCallback(node: TSESTree.Node | null): boolean;
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region src/property-name.d.ts
|
|
502
|
+
/**
|
|
503
|
+
* Get the name of a property from a node
|
|
504
|
+
* Handles identifiers, private identifiers, literals, and template literals
|
|
505
|
+
* @param node The node to get the property name from
|
|
506
|
+
* @returns The property name or null if not determinable
|
|
507
|
+
*/
|
|
508
|
+
declare function getPropertyName(node: TSESTree.Node): string | null;
|
|
509
|
+
//#endregion
|
|
510
|
+
//#region src/property-traverse.d.ts
|
|
511
|
+
/**
|
|
512
|
+
* Recursively traverses an object expression's properties to find a property with the specified name
|
|
513
|
+
* @param properties The properties of the object expression to traverse
|
|
514
|
+
* @param name The name of the property to find
|
|
515
|
+
* @returns The matching property node, or null if not found
|
|
516
|
+
*/
|
|
517
|
+
declare function findProperty(properties: TSESTree.ObjectLiteralElement[], name: string): TSESTree.Property | null;
|
|
496
518
|
//#endregion
|
|
497
|
-
export { DirectiveKind, DisplayNameAssignmentExpression, FunctionID, FunctionInitPath, ImplicitReturnArrowFunctionExpression, ObjectDestructuringVariableDeclarator, SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION, SEL_IMPLICIT_RETURN_ARROW_FUNCTION_EXPRESSION, SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR, TSESTreeArrayTupleType, TSESTreeClass, TSESTreeDestructuringPattern, TSESTreeDirective, TSESTreeDirectiveLike, TSESTreeFunction, TSESTreeFunctionType, TSESTreeJSX, TSESTreeJSXAttributeLike, TSESTreeLoop, TSESTreeMethodOrProperty, TSESTreeProperty, TSESTreeTypeAssertionExpression, TSESTreeTypeDeclaration, TSESTreeTypeExpression, findParentNode, getClassId, getFileDirectives, getFullyQualifiedName, getFunctionDirectives, getFunctionId, getFunctionInitPath, getHumanReadableKind, getNestedCallExpressions, getNestedExpressionsOfType, getNestedIdentifiers, getNestedNewExpressions, getNestedReturnStatements, getPropertyName, getUnderlyingExpression, hasCallInFunctionInitPath, is, isClass, isConditional, isControlFlow, isDirective, isDirectiveInFile, isDirectiveInFunction, isDirectiveKind, isDirectiveLike, isDirectiveName, isFunction, isFunctionEmpty, isFunctionImmediatelyInvoked, isFunctionType, isIdentifier, isIdentifierName, isJSX, isJSXElement, isJSXFragment, isJSXTagNameExpression, isLineBreak, isLiteral, isLoop, isMethodOrProperty, isMultiLine, isNodeEqual, isOneOf, isProcessEnvNodeEnv, isProcessEnvNodeEnvCompare, isProperty, isThisExpressionLoose, isTypeAssertionExpression, isTypeExpression, isViMock, isViMockCallback };
|
|
519
|
+
export { DirectiveKind, DisplayNameAssignmentExpression, FunctionID, FunctionInitPath, ImplicitReturnArrowFunctionExpression, ObjectDestructuringVariableDeclarator, SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION, SEL_IMPLICIT_RETURN_ARROW_FUNCTION_EXPRESSION, SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR, TSESTreeArrayTupleType, TSESTreeClass, TSESTreeDestructuringPattern, TSESTreeDirective, TSESTreeDirectiveLike, TSESTreeFunction, TSESTreeFunctionType, TSESTreeJSX, TSESTreeJSXAttributeLike, TSESTreeLoop, TSESTreeMethodOrProperty, TSESTreeProperty, TSESTreeTypeAssertionExpression, TSESTreeTypeDeclaration, TSESTreeTypeExpression, findParentNode, findProperty, getClassId, getFileDirectives, getFullyQualifiedName, getFunctionDirectives, getFunctionId, getFunctionInitPath, getHumanReadableKind, getNestedCallExpressions, getNestedExpressionsOfType, getNestedIdentifiers, getNestedNewExpressions, getNestedReturnStatements, getPropertyName, getRootIdentifier, getUnderlyingExpression, hasCallInFunctionInitPath, is, isClass, isConditional, isControlFlow, isDirective, isDirectiveInFile, isDirectiveInFunction, isDirectiveKind, isDirectiveLike, isDirectiveName, isFunction, isFunctionEmpty, isFunctionImmediatelyInvoked, isFunctionType, isIdentifier, isIdentifierName, isJSX, isJSXElement, isJSXFragment, isJSXTagNameExpression, isLineBreak, isLiteral, isLoop, isMethodOrProperty, isMultiLine, isNodeEqual, isOneOf, isProcessEnvNodeEnv, isProcessEnvNodeEnvCompare, isProperty, isThisExpressionLoose, isTypeAssertionExpression, isTypeExpression, isViMock, isViMockCallback };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
1
|
+
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types";
|
|
3
2
|
import { ASTUtils } from "@typescript-eslint/utils";
|
|
4
3
|
import { simpleTraverse } from "@typescript-eslint/typescript-estree";
|
|
5
4
|
import { delimiterCase, replace, toLowerCase } from "string-ts";
|
|
@@ -8,12 +7,12 @@ import { delimiterCase, replace, toLowerCase } from "string-ts";
|
|
|
8
7
|
/**
|
|
9
8
|
* Get the class identifier of a class node
|
|
10
9
|
* @param node The class node to get the identifier from
|
|
11
|
-
* @returns The class identifier or
|
|
10
|
+
* @returns The class identifier or null if not found
|
|
12
11
|
*/
|
|
13
12
|
function getClassId(node) {
|
|
14
13
|
if (node.id != null) return node.id;
|
|
15
14
|
if (node.parent.type === AST_NODE_TYPES.VariableDeclarator) return node.parent.id;
|
|
16
|
-
return
|
|
15
|
+
return null;
|
|
17
16
|
}
|
|
18
17
|
|
|
19
18
|
//#endregion
|
|
@@ -60,54 +59,6 @@ function isDirectiveLike(node) {
|
|
|
60
59
|
return node.type === AST_NODE_TYPES.ExpressionStatement && isLiteral(node.expression, "string") && isDirectiveName(node.expression.value);
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
//#endregion
|
|
64
|
-
//#region src/directive-helper.ts
|
|
65
|
-
/**
|
|
66
|
-
* Get all directive expression statements from the top of a program AST node
|
|
67
|
-
* @param node The program AST node
|
|
68
|
-
* @returns The array of directive string literals (e.g., "use strict")
|
|
69
|
-
*/
|
|
70
|
-
function getFileDirectives(node) {
|
|
71
|
-
const directives = [];
|
|
72
|
-
for (const stmt of node.body) {
|
|
73
|
-
if (!isDirective(stmt)) continue;
|
|
74
|
-
directives.push(stmt);
|
|
75
|
-
}
|
|
76
|
-
return directives;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Get all directive expression statements from the top of a function AST node
|
|
80
|
-
* @param node The function AST node
|
|
81
|
-
* @returns The array of directive string literals (e.g., "use memo", "use no memo")
|
|
82
|
-
*/
|
|
83
|
-
function getFunctionDirectives(node) {
|
|
84
|
-
const directives = [];
|
|
85
|
-
if (node.body.type !== AST_NODE_TYPES.BlockStatement) return directives;
|
|
86
|
-
for (const stmt of node.body.body) {
|
|
87
|
-
if (!isDirective(stmt)) continue;
|
|
88
|
-
directives.push(stmt);
|
|
89
|
-
}
|
|
90
|
-
return directives;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Check if a directive with the given name exists in the file or function directives
|
|
94
|
-
* @param node The program or function AST node
|
|
95
|
-
* @param name The directive name to check (e.g., "use strict", "use memo", "use no memo")
|
|
96
|
-
* @returns True if the directive exists, false otherwise
|
|
97
|
-
*/
|
|
98
|
-
function isDirectiveInFile(node, name) {
|
|
99
|
-
return getFileDirectives(node).some((d) => d.directive === name);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Check if a directive with the given name exists in the function directives
|
|
103
|
-
* @param node The function AST node
|
|
104
|
-
* @param name The directive name to check (e.g., "use memo", "use no memo")
|
|
105
|
-
* @returns True if the directive exists, false otherwise
|
|
106
|
-
*/
|
|
107
|
-
function isDirectiveInFunction(node, name) {
|
|
108
|
-
return getFunctionDirectives(node).some((d) => d.directive === name);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
62
|
//#endregion
|
|
112
63
|
//#region src/directive-kind.ts
|
|
113
64
|
/**
|
|
@@ -119,6 +70,127 @@ function isDirectiveKind(kind) {
|
|
|
119
70
|
return kind === "use client" || kind === "use server" || kind === "use memo" || kind === "use no memo";
|
|
120
71
|
}
|
|
121
72
|
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region ../../../.pkgs/eff/dist/index.js
|
|
75
|
+
function or(a, b) {
|
|
76
|
+
return (data) => a(data) || b(data);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Creates a function that can be used in a data-last (aka `pipe`able) or
|
|
80
|
+
* data-first style.
|
|
81
|
+
*
|
|
82
|
+
* The first parameter to `dual` is either the arity of the uncurried function
|
|
83
|
+
* or a predicate that determines if the function is being used in a data-first
|
|
84
|
+
* or data-last style.
|
|
85
|
+
*
|
|
86
|
+
* Using the arity is the most common use case, but there are some cases where
|
|
87
|
+
* you may want to use a predicate. For example, if you have a function that
|
|
88
|
+
* takes an optional argument, you can use a predicate to determine if the
|
|
89
|
+
* function is being used in a data-first or data-last style.
|
|
90
|
+
*
|
|
91
|
+
* You can pass either the arity of the uncurried function or a predicate
|
|
92
|
+
* which determines if the function is being used in a data-first or
|
|
93
|
+
* data-last style.
|
|
94
|
+
*
|
|
95
|
+
* **Example** (Using arity to determine data-first or data-last style)
|
|
96
|
+
*
|
|
97
|
+
* ```ts
|
|
98
|
+
* import { dual, pipe } from "effect/Function"
|
|
99
|
+
*
|
|
100
|
+
* const sum = dual<
|
|
101
|
+
* (that: number) => (self: number) => number,
|
|
102
|
+
* (self: number, that: number) => number
|
|
103
|
+
* >(2, (self, that) => self + that)
|
|
104
|
+
*
|
|
105
|
+
* console.log(sum(2, 3)) // 5
|
|
106
|
+
* console.log(pipe(2, sum(3))) // 5
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* **Example** (Using call signatures to define the overloads)
|
|
110
|
+
*
|
|
111
|
+
* ```ts
|
|
112
|
+
* import { dual, pipe } from "effect/Function"
|
|
113
|
+
*
|
|
114
|
+
* const sum: {
|
|
115
|
+
* (that: number): (self: number) => number
|
|
116
|
+
* (self: number, that: number): number
|
|
117
|
+
* } = dual(2, (self: number, that: number): number => self + that)
|
|
118
|
+
*
|
|
119
|
+
* console.log(sum(2, 3)) // 5
|
|
120
|
+
* console.log(pipe(2, sum(3))) // 5
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* **Example** (Using a predicate to determine data-first or data-last style)
|
|
124
|
+
*
|
|
125
|
+
* ```ts
|
|
126
|
+
* import { dual, pipe } from "effect/Function"
|
|
127
|
+
*
|
|
128
|
+
* const sum = dual<
|
|
129
|
+
* (that: number) => (self: number) => number,
|
|
130
|
+
* (self: number, that: number) => number
|
|
131
|
+
* >(
|
|
132
|
+
* (args) => args.length === 2,
|
|
133
|
+
* (self, that) => self + that
|
|
134
|
+
* )
|
|
135
|
+
*
|
|
136
|
+
* console.log(sum(2, 3)) // 5
|
|
137
|
+
* console.log(pipe(2, sum(3))) // 5
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* @param arity - The arity of the uncurried function or a predicate that determines if the function is being used in a data-first or data-last style.
|
|
141
|
+
* @param body - The function to be curried.
|
|
142
|
+
* @since 1.0.0
|
|
143
|
+
*/
|
|
144
|
+
const dual = function(arity, body) {
|
|
145
|
+
if (typeof arity === "function") return function() {
|
|
146
|
+
return arity(arguments) ? body.apply(this, arguments) : ((self) => body(self, ...arguments));
|
|
147
|
+
};
|
|
148
|
+
switch (arity) {
|
|
149
|
+
case 0:
|
|
150
|
+
case 1: throw new RangeError(`Invalid arity ${arity}`);
|
|
151
|
+
case 2: return function(a, b) {
|
|
152
|
+
if (arguments.length >= 2) return body(a, b);
|
|
153
|
+
return function(self) {
|
|
154
|
+
return body(self, a);
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
case 3: return function(a, b, c) {
|
|
158
|
+
if (arguments.length >= 3) return body(a, b, c);
|
|
159
|
+
return function(self) {
|
|
160
|
+
return body(self, a, b);
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
default: return function() {
|
|
164
|
+
if (arguments.length >= arity) return body.apply(this, arguments);
|
|
165
|
+
const args = arguments;
|
|
166
|
+
return function(self) {
|
|
167
|
+
return body(self, ...args);
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Composes two functions, `ab` and `bc` into a single function that takes in an argument `a` of type `A` and returns a result of type `C`.
|
|
174
|
+
* The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
|
|
175
|
+
*
|
|
176
|
+
* @param self - The first function to apply (or the composed function in data-last style).
|
|
177
|
+
* @param bc - The second function to apply.
|
|
178
|
+
* @returns A composed function that applies both functions in sequence.
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* import * as assert from "node:assert"
|
|
182
|
+
* import { compose } from "effect/Function"
|
|
183
|
+
*
|
|
184
|
+
* const increment = (n: number) => n + 1;
|
|
185
|
+
* const square = (n: number) => n * n;
|
|
186
|
+
*
|
|
187
|
+
* assert.strictEqual(compose(increment, square)(2), 9);
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @since 1.0.0
|
|
191
|
+
*/
|
|
192
|
+
const compose = dual(2, (ab, bc) => (a) => bc(ab(a)));
|
|
193
|
+
|
|
122
194
|
//#endregion
|
|
123
195
|
//#region src/node-is.ts
|
|
124
196
|
/**
|
|
@@ -275,7 +347,7 @@ const isTypeAssertionExpression = isOneOf([
|
|
|
275
347
|
]);
|
|
276
348
|
|
|
277
349
|
//#endregion
|
|
278
|
-
//#region src/
|
|
350
|
+
//#region src/node-unwrap.ts
|
|
279
351
|
/**
|
|
280
352
|
* Unwraps any type expressions to get the underlying JavaScript expression node.
|
|
281
353
|
* Recursively processes nodes until a non-type expression is found.
|
|
@@ -303,13 +375,13 @@ function isThisExpressionLoose(node) {
|
|
|
303
375
|
//#endregion
|
|
304
376
|
//#region src/node-traverse.ts
|
|
305
377
|
function findParentNode(node, test) {
|
|
306
|
-
if (node == null) return
|
|
378
|
+
if (node == null) return null;
|
|
307
379
|
let parent = node.parent;
|
|
308
380
|
while (parent != null && parent.type !== AST_NODE_TYPES.Program) {
|
|
309
381
|
if (test(parent)) return parent;
|
|
310
382
|
parent = parent.parent;
|
|
311
383
|
}
|
|
312
|
-
return
|
|
384
|
+
return null;
|
|
313
385
|
}
|
|
314
386
|
|
|
315
387
|
//#endregion
|
|
@@ -355,8 +427,8 @@ function getNestedIdentifiers(node) {
|
|
|
355
427
|
identifiers.push(...chunk);
|
|
356
428
|
}
|
|
357
429
|
if (node.type === AST_NODE_TYPES.MemberExpression) {
|
|
358
|
-
|
|
359
|
-
identifiers.push(...
|
|
430
|
+
identifiers.push(...getNestedIdentifiers(node.object));
|
|
431
|
+
if (node.computed) identifiers.push(...getNestedIdentifiers(node.property));
|
|
360
432
|
}
|
|
361
433
|
if (node.type === AST_NODE_TYPES.UnaryExpression) {
|
|
362
434
|
const chunk = getNestedIdentifiers(node.argument);
|
|
@@ -378,6 +450,22 @@ function getNestedIdentifiers(node) {
|
|
|
378
450
|
const chunk = getNestedIdentifiers(node.expression);
|
|
379
451
|
identifiers.push(...chunk);
|
|
380
452
|
}
|
|
453
|
+
if (node.type === AST_NODE_TYPES.ConditionalExpression) {
|
|
454
|
+
identifiers.push(...getNestedIdentifiers(node.test));
|
|
455
|
+
identifiers.push(...getNestedIdentifiers(node.consequent));
|
|
456
|
+
identifiers.push(...getNestedIdentifiers(node.alternate));
|
|
457
|
+
}
|
|
458
|
+
if (node.type === AST_NODE_TYPES.AwaitExpression) identifiers.push(...getNestedIdentifiers(node.argument));
|
|
459
|
+
if (node.type === AST_NODE_TYPES.YieldExpression && node.argument != null) identifiers.push(...getNestedIdentifiers(node.argument));
|
|
460
|
+
if (node.type === AST_NODE_TYPES.UpdateExpression) identifiers.push(...getNestedIdentifiers(node.argument));
|
|
461
|
+
if (node.type === AST_NODE_TYPES.CallExpression || node.type === AST_NODE_TYPES.NewExpression) identifiers.push(...getNestedIdentifiers(node.callee));
|
|
462
|
+
if (node.type === AST_NODE_TYPES.TaggedTemplateExpression) {
|
|
463
|
+
identifiers.push(...getNestedIdentifiers(node.tag));
|
|
464
|
+
identifiers.push(...getNestedIdentifiers(node.quasi));
|
|
465
|
+
}
|
|
466
|
+
if (node.type === AST_NODE_TYPES.ImportExpression) identifiers.push(...getNestedIdentifiers(node.source));
|
|
467
|
+
if (node.type === AST_NODE_TYPES.TSTypeAssertion) identifiers.push(...getNestedIdentifiers(node.expression));
|
|
468
|
+
if (node.type === AST_NODE_TYPES.TSInstantiationExpression) identifiers.push(...getNestedIdentifiers(node.expression));
|
|
381
469
|
return identifiers;
|
|
382
470
|
}
|
|
383
471
|
/**
|
|
@@ -403,84 +491,77 @@ function getNestedReturnStatements(node) {
|
|
|
403
491
|
*/
|
|
404
492
|
function getNestedExpressionsOfType(type) {
|
|
405
493
|
const isNodeOfType = is(type);
|
|
406
|
-
|
|
407
|
-
const boundGetNestedExpressionsOfType = getNestedExpressionsOfType(type);
|
|
494
|
+
const recurse = (node) => {
|
|
408
495
|
const expressions = [];
|
|
409
496
|
if (isNodeOfType(node)) expressions.push(node);
|
|
410
497
|
if ("arguments" in node) {
|
|
411
|
-
const chunk = node.arguments.flatMap(
|
|
498
|
+
const chunk = node.arguments.flatMap(recurse);
|
|
412
499
|
expressions.push(...chunk);
|
|
413
500
|
}
|
|
414
501
|
if ("expression" in node && node.expression !== true && node.expression !== false) {
|
|
415
|
-
const chunk =
|
|
502
|
+
const chunk = recurse(node.expression);
|
|
416
503
|
expressions.push(...chunk);
|
|
417
504
|
}
|
|
418
505
|
if ("left" in node) {
|
|
419
|
-
const chunk =
|
|
506
|
+
const chunk = recurse(node.left);
|
|
420
507
|
expressions.push(...chunk);
|
|
421
508
|
}
|
|
422
509
|
if ("right" in node) {
|
|
423
|
-
const chunk =
|
|
510
|
+
const chunk = recurse(node.right);
|
|
424
511
|
expressions.push(...chunk);
|
|
425
512
|
}
|
|
426
513
|
if ("test" in node && node.test != null) {
|
|
427
|
-
const chunk =
|
|
514
|
+
const chunk = recurse(node.test);
|
|
428
515
|
expressions.push(...chunk);
|
|
429
516
|
}
|
|
430
517
|
if ("consequent" in node) {
|
|
431
|
-
const chunk = Array.isArray(node.consequent) ? node.consequent.flatMap(
|
|
518
|
+
const chunk = Array.isArray(node.consequent) ? node.consequent.flatMap(recurse) : recurse(node.consequent);
|
|
432
519
|
expressions.push(...chunk);
|
|
433
520
|
}
|
|
434
521
|
if ("alternate" in node && node.alternate != null) {
|
|
435
|
-
const chunk = Array.isArray(node.alternate) ? node.alternate.flatMap(
|
|
522
|
+
const chunk = Array.isArray(node.alternate) ? node.alternate.flatMap(recurse) : recurse(node.alternate);
|
|
436
523
|
expressions.push(...chunk);
|
|
437
524
|
}
|
|
438
525
|
if ("elements" in node) {
|
|
439
|
-
const chunk = node.elements.filter((x) => x != null).flatMap(
|
|
526
|
+
const chunk = node.elements.filter((x) => x != null).flatMap(recurse);
|
|
440
527
|
expressions.push(...chunk);
|
|
441
528
|
}
|
|
442
529
|
if ("properties" in node) {
|
|
443
|
-
const chunk = node.properties.flatMap(
|
|
530
|
+
const chunk = node.properties.flatMap(recurse);
|
|
444
531
|
expressions.push(...chunk);
|
|
445
532
|
}
|
|
446
533
|
if ("expressions" in node) {
|
|
447
|
-
const chunk = node.expressions.flatMap(
|
|
534
|
+
const chunk = node.expressions.flatMap(recurse);
|
|
448
535
|
expressions.push(...chunk);
|
|
449
536
|
}
|
|
450
537
|
if (node.type === AST_NODE_TYPES.Property) {
|
|
451
|
-
const chunk =
|
|
538
|
+
const chunk = recurse(node.value);
|
|
452
539
|
expressions.push(...chunk);
|
|
453
540
|
}
|
|
454
541
|
if (node.type === AST_NODE_TYPES.SpreadElement) {
|
|
455
|
-
const chunk =
|
|
542
|
+
const chunk = recurse(node.argument);
|
|
456
543
|
expressions.push(...chunk);
|
|
457
544
|
}
|
|
458
545
|
if (node.type === AST_NODE_TYPES.MemberExpression) {
|
|
459
|
-
|
|
460
|
-
expressions.push(...
|
|
546
|
+
expressions.push(...recurse(node.object));
|
|
547
|
+
if (node.computed) expressions.push(...recurse(node.property));
|
|
461
548
|
}
|
|
462
549
|
if (node.type === AST_NODE_TYPES.UnaryExpression) {
|
|
463
|
-
const chunk =
|
|
464
|
-
expressions.push(...chunk);
|
|
465
|
-
}
|
|
466
|
-
if (node.type === AST_NODE_TYPES.ChainExpression) {
|
|
467
|
-
const chunk = boundGetNestedExpressionsOfType(node.expression);
|
|
468
|
-
expressions.push(...chunk);
|
|
469
|
-
}
|
|
470
|
-
if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
|
|
471
|
-
const chunk = boundGetNestedExpressionsOfType(node.expression);
|
|
472
|
-
expressions.push(...chunk);
|
|
473
|
-
}
|
|
474
|
-
if (node.type === AST_NODE_TYPES.TSAsExpression) {
|
|
475
|
-
const chunk = boundGetNestedExpressionsOfType(node.expression);
|
|
550
|
+
const chunk = recurse(node.argument);
|
|
476
551
|
expressions.push(...chunk);
|
|
477
552
|
}
|
|
478
|
-
if (node.type === AST_NODE_TYPES.
|
|
479
|
-
|
|
480
|
-
|
|
553
|
+
if (node.type === AST_NODE_TYPES.AwaitExpression) expressions.push(...recurse(node.argument));
|
|
554
|
+
if (node.type === AST_NODE_TYPES.YieldExpression && node.argument != null) expressions.push(...recurse(node.argument));
|
|
555
|
+
if (node.type === AST_NODE_TYPES.UpdateExpression) expressions.push(...recurse(node.argument));
|
|
556
|
+
if (node.type === AST_NODE_TYPES.CallExpression || node.type === AST_NODE_TYPES.NewExpression) expressions.push(...recurse(node.callee));
|
|
557
|
+
if (node.type === AST_NODE_TYPES.TaggedTemplateExpression) {
|
|
558
|
+
expressions.push(...recurse(node.tag));
|
|
559
|
+
expressions.push(...recurse(node.quasi));
|
|
481
560
|
}
|
|
561
|
+
if (node.type === AST_NODE_TYPES.ImportExpression) expressions.push(...recurse(node.source));
|
|
482
562
|
return expressions;
|
|
483
563
|
};
|
|
564
|
+
return recurse;
|
|
484
565
|
}
|
|
485
566
|
/**
|
|
486
567
|
* Get all nested new expressions in an expression like node
|
|
@@ -495,6 +576,57 @@ const getNestedNewExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.NewExp
|
|
|
495
576
|
*/
|
|
496
577
|
const getNestedCallExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.CallExpression);
|
|
497
578
|
|
|
579
|
+
//#endregion
|
|
580
|
+
//#region src/file-directive.ts
|
|
581
|
+
/**
|
|
582
|
+
* Get all directive expression statements from the top of a program AST node
|
|
583
|
+
* @param node The program AST node
|
|
584
|
+
* @returns The array of directive string literals (ex: "use strict")
|
|
585
|
+
*/
|
|
586
|
+
function getFileDirectives(node) {
|
|
587
|
+
const directives = [];
|
|
588
|
+
for (const stmt of node.body) {
|
|
589
|
+
if (!isDirective(stmt)) continue;
|
|
590
|
+
directives.push(stmt);
|
|
591
|
+
}
|
|
592
|
+
return directives;
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Check if a directive with the given name exists in the file or function directives
|
|
596
|
+
* @param node The program or function AST node
|
|
597
|
+
* @param name The directive name to check (ex: "use strict", "use memo", "use no memo")
|
|
598
|
+
* @returns True if the directive exists, false otherwise
|
|
599
|
+
*/
|
|
600
|
+
function isDirectiveInFile(node, name) {
|
|
601
|
+
return getFileDirectives(node).some((d) => d.directive === name);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
//#endregion
|
|
605
|
+
//#region src/function-directive.ts
|
|
606
|
+
/**
|
|
607
|
+
* Get all directive expression statements from the top of a function AST node
|
|
608
|
+
* @param node The function AST node
|
|
609
|
+
* @returns The array of directive string literals (ex: "use memo", "use no memo")
|
|
610
|
+
*/
|
|
611
|
+
function getFunctionDirectives(node) {
|
|
612
|
+
const directives = [];
|
|
613
|
+
if (node.body.type !== AST_NODE_TYPES.BlockStatement) return directives;
|
|
614
|
+
for (const stmt of node.body.body) {
|
|
615
|
+
if (!isDirective(stmt)) continue;
|
|
616
|
+
directives.push(stmt);
|
|
617
|
+
}
|
|
618
|
+
return directives;
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Check if a directive with the given name exists in the function directives
|
|
622
|
+
* @param node The function AST node
|
|
623
|
+
* @param name The directive name to check (ex: "use memo", "use no memo")
|
|
624
|
+
* @returns True if the directive exists, false otherwise
|
|
625
|
+
*/
|
|
626
|
+
function isDirectiveInFunction(node, name) {
|
|
627
|
+
return getFunctionDirectives(node).some((d) => d.directive === name);
|
|
628
|
+
}
|
|
629
|
+
|
|
498
630
|
//#endregion
|
|
499
631
|
//#region src/function-id.ts
|
|
500
632
|
/**
|
|
@@ -515,7 +647,7 @@ function getFunctionId(node) {
|
|
|
515
647
|
case node.parent.type === AST_NODE_TYPES.ConditionalExpression: return getFunctionId(node.parent);
|
|
516
648
|
case isTypeAssertionExpression(node.parent): return getFunctionId(node.parent);
|
|
517
649
|
}
|
|
518
|
-
return
|
|
650
|
+
return null;
|
|
519
651
|
}
|
|
520
652
|
|
|
521
653
|
//#endregion
|
|
@@ -525,11 +657,12 @@ function getFunctionId(node) {
|
|
|
525
657
|
* Determine what kind of component declaration pattern the function belongs to.
|
|
526
658
|
*
|
|
527
659
|
* @param node The function node to analyze
|
|
528
|
-
* @returns The function initialization path or
|
|
660
|
+
* @returns The function initialization path or null if not identifiable
|
|
529
661
|
*/
|
|
530
662
|
function getFunctionInitPath(node) {
|
|
531
663
|
if (node.type === AST_NODE_TYPES.FunctionDeclaration) return [node];
|
|
532
|
-
|
|
664
|
+
let parent = node.parent;
|
|
665
|
+
while (isTypeExpression(parent)) parent = parent.parent;
|
|
533
666
|
switch (true) {
|
|
534
667
|
case parent.type === AST_NODE_TYPES.VariableDeclarator: return [
|
|
535
668
|
parent.parent,
|
|
@@ -569,13 +702,13 @@ function getFunctionInitPath(node) {
|
|
|
569
702
|
node
|
|
570
703
|
];
|
|
571
704
|
}
|
|
572
|
-
return
|
|
705
|
+
return null;
|
|
573
706
|
}
|
|
574
707
|
/**
|
|
575
708
|
* Check if a specific function call exists in the function initialization path.
|
|
576
709
|
* Useful for detecting HOCs like React.memo, React.forwardRef, etc.
|
|
577
710
|
*
|
|
578
|
-
* @param callName The name of the call to check for (
|
|
711
|
+
* @param callName The name of the call to check for (ex: "memo", "forwardRef")
|
|
579
712
|
* @param initPath The function initialization path to search in
|
|
580
713
|
* @returns True if the call exists in the path, false otherwise
|
|
581
714
|
*/
|
|
@@ -632,7 +765,24 @@ function isIdentifierName(name) {
|
|
|
632
765
|
}
|
|
633
766
|
|
|
634
767
|
//#endregion
|
|
635
|
-
//#region src/
|
|
768
|
+
//#region src/identifier-traverse.ts
|
|
769
|
+
/**
|
|
770
|
+
* Get the root identifier of a (possibly nested) member expression.
|
|
771
|
+
* For `a.b.c`, returns the `a` Identifier node.
|
|
772
|
+
* @param node The expression to analyze
|
|
773
|
+
* @returns The root Identifier node, or null if it cannot be determined (ex: non-identifier root)
|
|
774
|
+
*/
|
|
775
|
+
function getRootIdentifier(node) {
|
|
776
|
+
const expr = getUnderlyingExpression(node);
|
|
777
|
+
switch (expr.type) {
|
|
778
|
+
case AST_NODE_TYPES.Identifier: return expr;
|
|
779
|
+
case AST_NODE_TYPES.MemberExpression: return getRootIdentifier(expr.object);
|
|
780
|
+
default: return null;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
//#endregion
|
|
785
|
+
//#region src/node-equality.ts
|
|
636
786
|
/**
|
|
637
787
|
* Check if two nodes are equal
|
|
638
788
|
* @param a node to compare
|
|
@@ -734,7 +884,7 @@ const SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION = [
|
|
|
734
884
|
].join("");
|
|
735
885
|
|
|
736
886
|
//#endregion
|
|
737
|
-
//#region src/process-env-node-env.ts
|
|
887
|
+
//#region src/pattern-process-env-node-env.ts
|
|
738
888
|
/**
|
|
739
889
|
* Check if the given node is a member expression that accesses `process.env.NODE_ENV`
|
|
740
890
|
* @param node The AST node
|
|
@@ -760,23 +910,7 @@ function isProcessEnvNodeEnvCompare(node, operator, value) {
|
|
|
760
910
|
}
|
|
761
911
|
|
|
762
912
|
//#endregion
|
|
763
|
-
//#region src/
|
|
764
|
-
/**
|
|
765
|
-
* Get the name of a property from a node
|
|
766
|
-
* Handles identifiers, private identifiers, literals, and template literals
|
|
767
|
-
* @param node The node to get the property name from
|
|
768
|
-
* @returns The property name or unit if not determinable
|
|
769
|
-
*/
|
|
770
|
-
function getPropertyName(node) {
|
|
771
|
-
if (isTypeExpression(node)) return getPropertyName(getUnderlyingExpression(node));
|
|
772
|
-
if (node.type === AST_NODE_TYPES.Identifier || node.type === AST_NODE_TYPES.PrivateIdentifier) return node.name;
|
|
773
|
-
if (node.type === AST_NODE_TYPES.Literal) return String(node.value);
|
|
774
|
-
if (node.type === AST_NODE_TYPES.TemplateLiteral && node.expressions.length === 0) return node.quasis[0]?.value.raw;
|
|
775
|
-
return unit;
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
//#endregion
|
|
779
|
-
//#region src/vitest-mock.ts
|
|
913
|
+
//#region src/pattern-vitest-mock.ts
|
|
780
914
|
/**
|
|
781
915
|
* Check if the given node is a `vi.mock`.
|
|
782
916
|
* @param node The node to check
|
|
@@ -797,4 +931,39 @@ function isViMockCallback(node) {
|
|
|
797
931
|
}
|
|
798
932
|
|
|
799
933
|
//#endregion
|
|
800
|
-
|
|
934
|
+
//#region src/property-name.ts
|
|
935
|
+
/**
|
|
936
|
+
* Get the name of a property from a node
|
|
937
|
+
* Handles identifiers, private identifiers, literals, and template literals
|
|
938
|
+
* @param node The node to get the property name from
|
|
939
|
+
* @returns The property name or null if not determinable
|
|
940
|
+
*/
|
|
941
|
+
function getPropertyName(node) {
|
|
942
|
+
if (isTypeExpression(node)) return getPropertyName(getUnderlyingExpression(node));
|
|
943
|
+
if (node.type === AST_NODE_TYPES.Identifier || node.type === AST_NODE_TYPES.PrivateIdentifier) return node.name;
|
|
944
|
+
if (node.type === AST_NODE_TYPES.Literal) return String(node.value);
|
|
945
|
+
if (node.type === AST_NODE_TYPES.TemplateLiteral && node.expressions.length === 0) return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? null;
|
|
946
|
+
return null;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
//#endregion
|
|
950
|
+
//#region src/property-traverse.ts
|
|
951
|
+
/**
|
|
952
|
+
* Recursively traverses an object expression's properties to find a property with the specified name
|
|
953
|
+
* @param properties The properties of the object expression to traverse
|
|
954
|
+
* @param name The name of the property to find
|
|
955
|
+
* @returns The matching property node, or null if not found
|
|
956
|
+
*/
|
|
957
|
+
function findProperty(properties, name) {
|
|
958
|
+
for (const prop of properties) {
|
|
959
|
+
if (prop.type === AST_NODE_TYPES.Property && getPropertyName(prop.key) === name) return prop;
|
|
960
|
+
if (prop.type === AST_NODE_TYPES.SpreadElement && prop.argument.type === AST_NODE_TYPES.ObjectExpression) {
|
|
961
|
+
const found = findProperty(prop.argument.properties, name);
|
|
962
|
+
if (found != null) return found;
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
return null;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
//#endregion
|
|
969
|
+
export { SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION, SEL_IMPLICIT_RETURN_ARROW_FUNCTION_EXPRESSION, SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR, findParentNode, findProperty, getClassId, getFileDirectives, getFullyQualifiedName, getFunctionDirectives, getFunctionId, getFunctionInitPath, getHumanReadableKind, getNestedCallExpressions, getNestedExpressionsOfType, getNestedIdentifiers, getNestedNewExpressions, getNestedReturnStatements, getPropertyName, getRootIdentifier, getUnderlyingExpression, hasCallInFunctionInitPath, is, isClass, isConditional, isControlFlow, isDirective, isDirectiveInFile, isDirectiveInFunction, isDirectiveKind, isDirectiveLike, isDirectiveName, isFunction, isFunctionEmpty, isFunctionImmediatelyInvoked, isFunctionType, isIdentifier, isIdentifierName, isJSX, isJSXElement, isJSXFragment, isJSXTagNameExpression, isLineBreak, isLiteral, isLoop, isMethodOrProperty, isMultiLine, isNodeEqual, isOneOf, isProcessEnvNodeEnv, isProcessEnvNodeEnvCompare, isProperty, isThisExpressionLoose, isTypeAssertionExpression, isTypeExpression, isViMock, isViMockCallback };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/ast",
|
|
3
|
-
"version": "3.0.0-
|
|
3
|
+
"version": "3.0.0-rc.1",
|
|
4
4
|
"description": "ESLint React's TSESTree AST utility module.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -33,23 +33,26 @@
|
|
|
33
33
|
"@typescript-eslint/types": "canary",
|
|
34
34
|
"@typescript-eslint/typescript-estree": "canary",
|
|
35
35
|
"@typescript-eslint/utils": "canary",
|
|
36
|
-
"string-ts": "^2.3.1"
|
|
37
|
-
"@eslint-react/eff": "3.0.0-next.9"
|
|
36
|
+
"string-ts": "^2.3.1"
|
|
38
37
|
},
|
|
39
38
|
"devDependencies": {
|
|
40
|
-
"tsdown": "^0.
|
|
41
|
-
"@local/configs": "0.0.0"
|
|
39
|
+
"tsdown": "^0.21.2",
|
|
40
|
+
"@local/configs": "0.0.0",
|
|
41
|
+
"@local/eff": "3.0.0-beta.72"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"eslint": "^
|
|
45
|
-
"typescript": "
|
|
44
|
+
"eslint": "^10.0.0",
|
|
45
|
+
"typescript": "*"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=22.0.0"
|
|
49
49
|
},
|
|
50
|
+
"inlinedDependencies": {
|
|
51
|
+
"@local/eff": "workspace:*"
|
|
52
|
+
},
|
|
50
53
|
"scripts": {
|
|
51
54
|
"build": "tsdown --dts-resolve",
|
|
52
55
|
"lint:publish": "publint",
|
|
53
|
-
"lint:ts": "
|
|
56
|
+
"lint:ts": "tsl"
|
|
54
57
|
}
|
|
55
58
|
}
|