@eslint-react/ast 5.2.1-next.1 → 5.2.1-next.3

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +45 -303
  2. package/dist/index.js +155 -659
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,121 +1,5 @@
1
- import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types";
1
+ import { TSESTree } from "@typescript-eslint/types";
2
2
 
3
- //#region src/node-types.d.ts
4
- /**
5
- * Represents function expressions and declarations in TSESTree
6
- */
7
- type TSESTreeFunction = TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression;
8
- /**
9
- * Represents all function-related types including TypeScript function types
10
- */
11
- type TSESTreeFunctionType = TSESTree.TSCallSignatureDeclaration | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSDeclareFunction | TSESTree.TSEmptyBodyFunctionExpression | TSESTree.TSFunctionType | TSESTree.TSMethodSignature | TSESTreeFunction;
12
- /**
13
- * Represents class declarations and expressions in TSESTree
14
- */
15
- type TSESTreeClass = TSESTree.ClassDeclaration | TSESTree.ClassExpression;
16
- /**
17
- * Represents method definitions and property definitions in classes
18
- */
19
- type TSESTreeMethodOrProperty = TSESTree.PropertyDefinition | TSESTree.MethodDefinition;
20
- /**
21
- * Represents loop statements in TSESTree
22
- */
23
- type TSESTreeLoop = TSESTree.DoWhileStatement | TSESTree.ForInStatement | TSESTree.ForOfStatement | TSESTree.ForStatement | TSESTree.WhileStatement;
24
- /**
25
- * Represents TypeScript array and tuple types
26
- */
27
- type TSESTreeArrayTupleType = TSESTree.TSArrayType | TSESTree.TSTupleType;
28
- /**
29
- * Represents property-like nodes in TSESTree
30
- */
31
- type TSESTreeProperty = TSESTree.PropertyDefinition | TSESTree.TSIndexSignature | TSESTree.TSParameterProperty | TSESTree.TSPropertySignature;
32
- /**
33
- * Represents all JSX-related nodes in TSESTree
34
- * Note: This type is for type-level operations. The isJSX() runtime guard in node-is.ts
35
- * has a slightly different set of nodes as it includes JSXExpressionContainer which is
36
- * commonly needed for runtime checks but not included in this type union.
37
- */
38
- type TSESTreeJSX = TSESTree.JSXAttribute | TSESTree.JSXChild | TSESTree.JSXClosingElement | TSESTree.JSXClosingFragment | TSESTree.JSXEmptyExpression | TSESTree.JSXIdentifierToken | TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment | TSESTree.JSXSpreadAttribute | TSESTree.JSXTagNameExpression | TSESTree.JSXTextToken;
39
- type TSESTreeJSXElementLike = TSESTree.JSXElement | TSESTree.JSXFragment;
40
- /**
41
- * Represents JSX attribute-like nodes (attributes and spread attributes)
42
- */
43
- type TSESTreeJSXAttributeLike = TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute;
44
- /**
45
- * Represents destructuring patterns in variable declarations
46
- */
47
- type TSESTreeDestructuringPattern = TSESTree.ArrayPattern | TSESTree.AssignmentPattern | TSESTree.ObjectPattern | TSESTree.RestElement;
48
- /**
49
- * Represents TypeScript type declaration nodes
50
- */
51
- type TSESTreeTypeDeclaration = TSESTree.TSInterfaceDeclaration | TSESTree.TSTypeAliasDeclaration;
52
- /**
53
- * Represents TypeScript type expression nodes (type assertions, non-null expressions, etc.)
54
- */
55
- type TSESTreeTypeExpression = TSESTree.TSAsExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion | TSESTree.TSInstantiationExpression;
56
- /**
57
- * Represents TypeScript type assertion expressions (excluding instantiation expressions)
58
- */
59
- type TSESTreeTypeAssertionExpression = TSESTree.TSAsExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion;
60
- /**
61
- * Represents a directive expression statement in TSESTree (ex: "use strict";)
62
- */
63
- type TSESTreeDirective = TSESTree.ExpressionStatement & {
64
- directive: string;
65
- expression: TSESTree.StringLiteral;
66
- };
67
- /**
68
- * Represents a directive-like expression statement in TSESTree
69
- */
70
- type TSESTreeDirectiveLike = TSESTree.ExpressionStatement & {
71
- expression: TSESTree.StringLiteral;
72
- };
73
- //#endregion
74
- //#region src/class-id.d.ts
75
- /**
76
- * Get the class identifier of a class node
77
- * @param node The class node to get the identifier from
78
- * @returns The class identifier or null if not found
79
- */
80
- declare function getClassId(node: TSESTreeClass): TSESTree.BindingName | null;
81
- //#endregion
82
- //#region src/directive-is.d.ts
83
- /**
84
- * Check if a node is a directive expression statement
85
- * @param node The node to check
86
- * @returns True if the node is a directive, false otherwise
87
- */
88
- declare function isDirective(node: TSESTree.Node): node is TSESTreeDirective;
89
- /**
90
- * Check if a node is a directive-like expression statement
91
- * @param node The node to check
92
- * @returns True if the node is a directive, false otherwise
93
- */
94
- declare function isDirectiveLike(node: TSESTree.Node): node is TSESTreeDirectiveLike;
95
- //#endregion
96
- //#region src/directive-kind.d.ts
97
- /**
98
- * Known directive kinds in React
99
- */
100
- type DirectiveKind = "use client" | "use server" | "use memo" | "use no memo";
101
- /**
102
- * Check if a node is a directive kind
103
- * @param kind The kind to check
104
- * @returns True if the kind is a directive kind, false otherwise
105
- */
106
- declare function isDirectiveKind(kind: string): kind is DirectiveKind;
107
- //#endregion
108
- //#region src/directive-name.d.ts
109
- /**
110
- * Check if a string is a directive name (heuristic check)
111
- * Note: This is a broad check that matches any string starting with "use ".
112
- * For strict validation against known directives, use isDirectiveKind.
113
- * @param name The string to check
114
- * @returns True if the string looks like a directive name, false otherwise
115
- * @see isDirectiveKind
116
- */
117
- declare function isDirectiveName(name: string): boolean;
118
- //#endregion
119
3
  //#region src/expression-is.d.ts
120
4
  /**
121
5
  * Check if the given expression is a 'this' expression
@@ -126,122 +10,14 @@ declare function isDirectiveName(name: string): boolean;
126
10
  */
127
11
  declare function isThisExpressionLoose(node: TSESTree.Expression): boolean;
128
12
  //#endregion
129
- //#region src/expression-nested.d.ts
130
- /**
131
- * Get all nested identifiers in a expression like node
132
- * @param node The node to get the nested identifiers from
133
- * @returns All nested identifiers
134
- */
135
- declare function getNestedIdentifiers(node: TSESTree.Node): readonly TSESTree.Identifier[];
136
- /**
137
- * Gets the nested return statements in the node that are within the same function
138
- * @param node The AST node
139
- * @returns The nested return statements in the node
140
- */
141
- declare function getNestedReturnStatements(node: TSESTree.Node): readonly TSESTree.ReturnStatement[];
142
- /**
143
- * Get all nested expressions of type T in an expression like node
144
- * @param type The type of the expression to retrieve within the node
145
- * @returns A partially applied function bound to a predicate of type AST. The returned function can be called passing a
146
- * node, and it will return an array of all nested expressions of type AST.
147
- */
148
- declare function getNestedExpressionsOfType<TNodeType extends AST_NODE_TYPES>(type: TNodeType): (node: TSESTree.Node) => Extract<TSESTree.Node, {
149
- type: TNodeType;
150
- }>[];
151
- /**
152
- * Get all nested new expressions in an expression like node
153
- * @param node The node to get the nested new expressions from
154
- * @returns All nested new expressions
155
- */
156
- declare const getNestedNewExpressions: (node: TSESTree.Node) => TSESTree.NewExpression[];
157
- /**
158
- * Get all nested call expressions in a expression like node
159
- * @param node The node to get the nested call expressions from
160
- * @returns All nested call expressions
161
- */
162
- declare const getNestedCallExpressions: (node: TSESTree.Node) => TSESTree.CallExpression[];
163
- //#endregion
164
- //#region src/file-directive.d.ts
165
- /**
166
- * Get all directive expression statements from the top of a program AST node
167
- * @param node The program AST node
168
- * @returns The array of directive string literals (ex: "use strict")
169
- */
170
- declare function getFileDirectives(node: TSESTree.Program): TSESTreeDirective[];
13
+ //#region src/file.d.ts
171
14
  /**
172
15
  * Check if a directive with the given name exists in the file directives
173
16
  * @param node The program AST node
174
17
  * @param name The directive name to check (ex: "use strict", "use memo", "use no memo")
175
18
  * @returns True if the directive exists, false otherwise
176
19
  */
177
- declare function isDirectiveInFile(node: TSESTree.Program, name: string): boolean;
178
- //#endregion
179
- //#region src/function-directive.d.ts
180
- /**
181
- * Get all directive expression statements from the top of a function AST node
182
- * @param node The function AST node
183
- * @returns The array of directive string literals (ex: "use memo", "use no memo")
184
- */
185
- declare function getFunctionDirectives(node: TSESTreeFunction): TSESTreeDirective[];
186
- /**
187
- * Check if a directive with the given name exists in the function directives
188
- * @param node The function AST node
189
- * @param name The directive name to check (ex: "use memo", "use no memo")
190
- * @returns True if the directive exists, false otherwise
191
- */
192
- declare function isDirectiveInFunction(node: TSESTreeFunction, name: string): boolean;
193
- //#endregion
194
- //#region src/function-id.d.ts
195
- /**
196
- * Gets the static name of a function AST node. For function declarations it is
197
- * easy. For anonymous function expressions it is much harder. If you search for
198
- * `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places
199
- * where JS gives anonymous function expressions names. We roughly detect the
200
- * same AST nodes with some exceptions to better fit our use case.
201
- */
202
- 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;
203
- /**
204
- * Type representing the return type of getFunctionId
205
- */
206
- type FunctionID = ReturnType<typeof getFunctionId>;
207
- //#endregion
208
- //#region src/function-init-path.d.ts
209
- /**
210
- * Represents various AST paths for React component function declarations
211
- * Each tuple type represents a specific component definition pattern
212
- */
213
- type FunctionInitPath = readonly [TSESTree.FunctionDeclaration] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.CallExpression, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.CallExpression, TSESTree.CallExpression, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTree.CallExpression, TSESTreeFunction] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTree.CallExpression, TSESTree.CallExpression, TSESTreeFunction] | readonly [TSESTree.ClassDeclaration | TSESTree.ClassExpression, TSESTree.ClassBody, TSESTree.MethodDefinition, TSESTreeFunction] | readonly [TSESTree.ClassDeclaration | TSESTree.ClassExpression, TSESTree.ClassBody, TSESTree.PropertyDefinition, TSESTreeFunction];
214
- /**
215
- * Identifies the initialization path of a function node in the ast.
216
- * Determine what kind of component declaration pattern the function belongs to.
217
- *
218
- * @param node The function node to analyze
219
- * @returns The function initialization path or null if not identifiable
220
- */
221
- declare function getFunctionInitPath(node: TSESTreeFunction): null | FunctionInitPath;
222
- /**
223
- * Check if a specific function call exists in the function initialization path.
224
- * Useful for detecting HOCs like React.memo, React.forwardRef, etc.
225
- *
226
- * @param callName The name of the call to check for (ex: "memo", "forwardRef")
227
- * @param initPath The function initialization path to search in
228
- * @returns True if the call exists in the path, false otherwise
229
- */
230
- declare function hasCallInFunctionInitPath(callName: string, initPath: FunctionInitPath): boolean;
231
- //#endregion
232
- //#region src/function-is.d.ts
233
- /**
234
- * Check if a function is empty
235
- * @param node The function node to check
236
- * @returns True if the function is empty, false otherwise
237
- */
238
- declare function isFunctionEmpty(node: TSESTreeFunction): boolean;
239
- /**
240
- * Check if a function is immediately invoked
241
- * @param node The function node to check
242
- * @returns True if the function is immediately invoked, false otherwise
243
- */
244
- declare function isFunctionImmediatelyInvoked(node: TSESTreeFunction): boolean;
20
+ declare function isFileHasDirective(node: TSESTree.Program, name: string): boolean;
245
21
  //#endregion
246
22
  //#region src/identifier-is.d.ts
247
23
  /**
@@ -252,16 +28,6 @@ declare function isFunctionImmediatelyInvoked(node: TSESTreeFunction): boolean;
252
28
  */
253
29
  declare function isIdentifier(node: TSESTree.Node | null, name?: string): node is TSESTree.Identifier;
254
30
  //#endregion
255
- //#region src/identifier-name.d.ts
256
- /**
257
- * Check if a string is a valid JavaScript identifier name
258
- * Note: This only checks for ASCII identifiers. Unicode identifiers (e.g., `const 变量 = 1`)
259
- * are not supported by this simple regex check.
260
- * @param name The string to check
261
- * @returns True if the string is a valid ASCII identifier name
262
- */
263
- declare function isIdentifierName(name: string): boolean;
264
- //#endregion
265
31
  //#region src/identifier-traverse.d.ts
266
32
  /**
267
33
  * Get the root identifier of a (possibly nested) member expression.
@@ -297,6 +63,40 @@ declare const isNodeEqual: {
297
63
  (a: TSESTree.Node, b: TSESTree.Node): boolean;
298
64
  };
299
65
  //#endregion
66
+ //#region src/node-types.d.ts
67
+ /**
68
+ * Represents function expressions and declarations in TSESTree
69
+ */
70
+ type TSESTreeFunction = TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression;
71
+ /**
72
+ * Represents class declarations and expressions in TSESTree
73
+ */
74
+ type TSESTreeClass = TSESTree.ClassDeclaration | TSESTree.ClassExpression;
75
+ /**
76
+ * Represents method definitions and property definitions in classes
77
+ */
78
+ type TSESTreeMethodOrProperty = TSESTree.PropertyDefinition | TSESTree.MethodDefinition;
79
+ /**
80
+ * Represents all JSX-related nodes in TSESTree
81
+ * Note: This type is for type-level operations. The isJSX() runtime guard in node-is.ts
82
+ * has a slightly different set of nodes as it includes JSXExpressionContainer which is
83
+ * commonly needed for runtime checks but not included in this type union.
84
+ */
85
+ type TSESTreeJSX = TSESTree.JSXAttribute | TSESTree.JSXChild | TSESTree.JSXClosingElement | TSESTree.JSXClosingFragment | TSESTree.JSXEmptyExpression | TSESTree.JSXIdentifierToken | TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment | TSESTree.JSXSpreadAttribute | TSESTree.JSXTagNameExpression | TSESTree.JSXTextToken;
86
+ type TSESTreeJSXElementLike = TSESTree.JSXElement | TSESTree.JSXFragment;
87
+ /**
88
+ * Represents JSX attribute-like nodes (attributes and spread attributes)
89
+ */
90
+ type TSESTreeJSXAttributeLike = TSESTree.JSXAttribute | TSESTree.JSXSpreadAttribute;
91
+ /**
92
+ * Represents a directive expression statement in TSESTree (ex: "use strict";)
93
+ */
94
+ type TSESTreeDirective = TSESTree.ExpressionStatement & {
95
+ directive: string;
96
+ expression: TSESTree.StringLiteral;
97
+ };
98
+ type TSESTreeTypeExpression = TSESTree.TSAsExpression | TSESTree.TSTypeAssertion | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSInstantiationExpression;
99
+ //#endregion
300
100
  //#region src/node-is.d.ts
301
101
  /**
302
102
  * Type guard to check if a node is of a specific AST node type
@@ -320,12 +120,6 @@ declare const isOneOf: <NodeTypes extends readonly TSESTree.AST_NODE_TYPES[]>(no
320
120
  * @returns True if the node is a function
321
121
  */
322
122
  declare const isFunction: (node: TSESTree.Node | null | undefined) => node is TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclarationWithName | TSESTree.FunctionDeclarationWithOptionalName | TSESTree.FunctionExpression;
323
- /**
324
- * Check if a node is a function type (including TypeScript function types)
325
- * @param node The node to check
326
- * @returns True if the node is a function type
327
- */
328
- declare const isFunctionType: (node: TSESTree.Node | null | undefined) => node is TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclarationWithName | TSESTree.FunctionDeclarationWithOptionalName | TSESTree.FunctionExpression | TSESTree.TSCallSignatureDeclaration | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSDeclareFunctionNoDeclare | TSESTree.TSDeclareFunctionWithDeclare | TSESTree.TSEmptyBodyFunctionExpression | TSESTree.TSFunctionType | TSESTree.TSMethodSignatureComputedName | TSESTree.TSMethodSignatureNonComputedName;
329
123
  /**
330
124
  * Check if a node is a class declaration or expression
331
125
  * @param node The node to check
@@ -350,16 +144,10 @@ declare const isProperty: (node: TSESTree.Node | null | undefined) => node is TS
350
144
  * @returns True if the node is a JSX element
351
145
  */
352
146
  declare const isJSXElement: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXElement;
353
- /**
354
- * Check if a node is a JSX fragment
355
- * @param node The node to check
356
- * @returns True if the node is a JSX fragment
357
- */
358
- declare const isJSXFragment: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXFragment;
359
147
  /**
360
148
  * Check if a node is a JSX element or JSX fragment
361
149
  */
362
- declare const isJSXElementLike: (data: TSESTree.Node | null | undefined) => data is TSESTree.JSXElement | TSESTree.JSXFragment;
150
+ declare const isJSXElementLike: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXElement | TSESTree.JSXFragment;
363
151
  /**
364
152
  * Check if a node is a JSX tag name expression (identifier, member expression, or namespaced name)
365
153
  * @param node The node to check
@@ -375,24 +163,6 @@ declare const isJSXTagNameExpression: (node: TSESTree.Node | null | undefined) =
375
163
  * @see TSESTreeJSX
376
164
  */
377
165
  declare const isJSX: (node: TSESTree.Node | null | undefined) => node is TSESTree.JSXAttribute | TSESTree.JSXClosingElement | TSESTree.JSXClosingFragment | TSESTree.JSXElement | TSESTree.JSXEmptyExpression | TSESTree.JSXExpressionContainer | TSESTree.JSXFragment | TSESTree.JSXIdentifier | TSESTree.JSXMemberExpression | TSESTree.JSXNamespacedName | TSESTree.JSXOpeningElement | TSESTree.JSXOpeningFragment | TSESTree.JSXSpreadAttribute | TSESTree.JSXSpreadChild | TSESTree.JSXText;
378
- /**
379
- * Check if a node is a loop statement
380
- * @param node The node to check
381
- * @returns True if the node is a loop
382
- */
383
- declare const isLoop: (node: TSESTree.Node | null | undefined) => node is TSESTree.DoWhileStatement | TSESTree.ForInStatement | TSESTree.ForOfStatement | TSESTree.ForStatement | TSESTree.WhileStatement;
384
- /**
385
- * Check if a node is a control flow statement (loop, if, or switch)
386
- * @param node The node to check
387
- * @returns True if the node is a control flow statement
388
- */
389
- declare const isControlFlow: (data: TSESTree.Node | null | undefined) => data is TSESTree.DoWhileStatement | TSESTree.ForInStatement | TSESTree.ForOfStatement | TSESTree.ForStatement | TSESTree.IfStatement | TSESTree.SwitchStatement | TSESTree.WhileStatement;
390
- /**
391
- * Check if a node is a conditional expression or control flow statement
392
- * @param node The node to check
393
- * @returns True if the node is conditional
394
- */
395
- declare const isConditional: (data: TSESTree.Node | null | undefined) => data is TSESTree.ConditionalExpression | TSESTree.DoWhileStatement | TSESTree.ForInStatement | TSESTree.ForOfStatement | TSESTree.ForStatement | TSESTree.IfStatement | TSESTree.LogicalExpression | TSESTree.SwitchStatement | TSESTree.WhileStatement;
396
166
  /**
397
167
  * Check if a node is a TypeScript type expression
398
168
  * @param node The node to check
@@ -405,24 +175,20 @@ declare const isTypeExpression: (node: TSESTree.Node | null | undefined) => node
405
175
  * @returns True if the node is a type assertion expression
406
176
  */
407
177
  declare const isTypeAssertionExpression: (node: TSESTree.Node | null | undefined) => node is TSESTree.TSAsExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion;
178
+ /**
179
+ * Check if a node is a directive expression statement
180
+ * @param node The node to check
181
+ * @returns True if the node is a directive, false otherwise
182
+ */
183
+ declare function isDirective(node: TSESTree.Node): node is TSESTreeDirective;
408
184
  //#endregion
409
185
  //#region src/node-kind.d.ts
410
186
  declare function getHumanReadableKind(node: TSESTree.Node, delimiter?: string): "RegExp literal" | Lowercase<string> | `JSX ${Lowercase<string>}`;
411
187
  //#endregion
412
- //#region src/node-line.d.ts
413
- declare function isMultiLine(node: TSESTree.Node): boolean;
414
- declare function isLineBreak(node: TSESTree.Node): boolean;
415
- //#endregion
416
188
  //#region src/node-name.d.ts
417
189
  declare function getFullyQualifiedName(node: TSESTree.Node, getText: (node: TSESTree.Node) => string): string;
418
190
  //#endregion
419
191
  //#region src/node-selectors.d.ts
420
- /**
421
- * Represents an arrow function expression with an implicit return
422
- */
423
- type ImplicitReturnArrowFunctionExpression = TSESTree.ArrowFunctionExpression & {
424
- body: TSESTree.Expression;
425
- };
426
192
  /**
427
193
  * Represents a variable declarator with object destructuring and an identifier initializer
428
194
  */
@@ -442,10 +208,6 @@ type DisplayNameAssignmentExpression = TSESTree.AssignmentExpression & {
442
208
  operator: "=";
443
209
  right: TSESTree.Literal;
444
210
  };
445
- /**
446
- * Selector for arrow function expressions with implicit return
447
- */
448
- declare const SEL_IMPLICIT_RETURN_ARROW_FUNCTION_EXPRESSION = "ArrowFunctionExpression[body.type!='BlockStatement']";
449
211
  /**
450
212
  * Selector for variable declarators with object destructuring
451
213
  */
@@ -480,26 +242,6 @@ declare function findParent(node: TSESTree.Node | null, test: (node: TSESTree.No
480
242
  */
481
243
  declare function getUnderlyingExpression(node: TSESTree.Node): Exclude<TSESTree.Node, TSESTreeTypeExpression>;
482
244
  //#endregion
483
- //#region src/pattern-process-env-node-env.d.ts
484
- /**
485
- * Check if the given node is a member expression that accesses `process.env.NODE_ENV`
486
- * @param node The AST node
487
- * @returns True if the node is a member expression that accesses `process.env.NODE_ENV`, false otherwise
488
- */
489
- declare function isProcessEnvNodeEnv(node: TSESTree.Node | null): node is TSESTree.MemberExpression;
490
- /**
491
- * Check if the given node is a binary expression that compares `process.env.NODE_ENV` with a string literal.
492
- * @param node The AST node
493
- * @param operator The operator used in the comparison
494
- * @param value The string literal value to compare against
495
- * @returns True if the node is a binary expression that compares `process.env.NODE_ENV` with the specified value, false otherwise
496
- */
497
- declare function isProcessEnvNodeEnvCompare(node: TSESTree.Node | null, operator: "===" | "!==", value: "development" | "production"): node is TSESTree.BinaryExpression;
498
- //#endregion
499
- //#region src/pattern-test-mock.d.ts
500
- declare function isTestMock(node: TSESTree.Node | null): node is TSESTree.MemberExpression;
501
- declare function isTestMockCallback(node: TSESTree.Node | null): boolean;
502
- //#endregion
503
245
  //#region src/property-name.d.ts
504
246
  /**
505
247
  * Get the name of a property from a node
@@ -520,4 +262,4 @@ declare function getPropertyName(node: TSESTree.Node): string | null;
520
262
  */
521
263
  declare function findProperty(properties: TSESTree.ObjectLiteralElement[], name: string): TSESTree.Property | null;
522
264
  //#endregion
523
- 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, TSESTreeJSXElementLike, TSESTreeLoop, TSESTreeMethodOrProperty, TSESTreeProperty, TSESTreeTypeAssertionExpression, TSESTreeTypeDeclaration, TSESTreeTypeExpression, findParent, 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, isJSXElementLike, isJSXFragment, isJSXTagNameExpression, isLineBreak, isLiteral, isLoop, isMethodOrProperty, isMultiLine, isNodeEqual, isOneOf, isProcessEnvNodeEnv, isProcessEnvNodeEnvCompare, isProperty, isTestMock, isTestMockCallback, isThisExpressionLoose, isTypeAssertionExpression, isTypeExpression };
265
+ export { DisplayNameAssignmentExpression, ObjectDestructuringVariableDeclarator, SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION, SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR, TSESTreeClass, TSESTreeDirective, TSESTreeFunction, TSESTreeJSX, TSESTreeJSXAttributeLike, TSESTreeJSXElementLike, TSESTreeMethodOrProperty, TSESTreeTypeExpression, findParent, findProperty, getFullyQualifiedName, getHumanReadableKind, getPropertyName, getRootIdentifier, getUnderlyingExpression, is, isClass, isDirective, isFileHasDirective, isFunction, isIdentifier, isJSX, isJSXElement, isJSXElementLike, isJSXTagNameExpression, isLiteral, isMethodOrProperty, isNodeEqual, isOneOf, isProperty, isThisExpressionLoose, isTypeAssertionExpression, isTypeExpression };
package/dist/index.js CHANGED
@@ -1,200 +1,7 @@
1
1
  import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/types";
2
2
  import { ASTUtils } from "@typescript-eslint/utils";
3
- import { simpleTraverse } from "@typescript-eslint/typescript-estree";
4
3
  import { delimiterCase, replace, toLowerCase } from "string-ts";
5
4
 
6
- //#region src/class-id.ts
7
- /**
8
- * Get the class identifier of a class node
9
- * @param node The class node to get the identifier from
10
- * @returns The class identifier or null if not found
11
- */
12
- function getClassId(node) {
13
- if (node.id != null) return node.id;
14
- if (node.parent.type === AST_NODE_TYPES.VariableDeclarator) return node.parent.id;
15
- return null;
16
- }
17
-
18
- //#endregion
19
- //#region src/directive-name.ts
20
- /**
21
- * Check if a string is a directive name (heuristic check)
22
- * Note: This is a broad check that matches any string starting with "use ".
23
- * For strict validation against known directives, use isDirectiveKind.
24
- * @param name The string to check
25
- * @returns True if the string looks like a directive name, false otherwise
26
- * @see isDirectiveKind
27
- */
28
- function isDirectiveName(name) {
29
- return name.startsWith("use ") && name.length > 4;
30
- }
31
-
32
- //#endregion
33
- //#region src/literal-is.ts
34
- function isLiteral(node, type) {
35
- if (node.type !== AST_NODE_TYPES.Literal) return false;
36
- if (type == null) return true;
37
- switch (type) {
38
- case "boolean": return typeof node.value === "boolean";
39
- case "null": return node.value === null;
40
- case "number": return typeof node.value === "number";
41
- case "regexp": return "regex" in node;
42
- case "string": return typeof node.value === "string";
43
- }
44
- }
45
-
46
- //#endregion
47
- //#region src/directive-is.ts
48
- /**
49
- * Check if a node is a directive expression statement
50
- * @param node The node to check
51
- * @returns True if the node is a directive, false otherwise
52
- */
53
- function isDirective(node) {
54
- return node.type === AST_NODE_TYPES.ExpressionStatement && node.directive != null;
55
- }
56
- /**
57
- * Check if a node is a directive-like expression statement
58
- * @param node The node to check
59
- * @returns True if the node is a directive, false otherwise
60
- */
61
- function isDirectiveLike(node) {
62
- return node.type === AST_NODE_TYPES.ExpressionStatement && isLiteral(node.expression, "string") && isDirectiveName(node.expression.value);
63
- }
64
-
65
- //#endregion
66
- //#region src/directive-kind.ts
67
- /**
68
- * Check if a node is a directive kind
69
- * @param kind The kind to check
70
- * @returns True if the kind is a directive kind, false otherwise
71
- */
72
- function isDirectiveKind(kind) {
73
- return kind === "use client" || kind === "use server" || kind === "use memo" || kind === "use no memo";
74
- }
75
-
76
- //#endregion
77
- //#region ../../.pkgs/eff/dist/index.js
78
- function or(a, b) {
79
- return (data) => a(data) || b(data);
80
- }
81
- /**
82
- * Creates a function that can be used in a data-last (aka `pipe`able) or
83
- * data-first style.
84
- *
85
- * The first parameter to `dual` is either the arity of the uncurried function
86
- * or a predicate that determines if the function is being used in a data-first
87
- * or data-last style.
88
- *
89
- * Using the arity is the most common use case, but there are some cases where
90
- * you may want to use a predicate. For example, if you have a function that
91
- * takes an optional argument, you can use a predicate to determine if the
92
- * function is being used in a data-first or data-last style.
93
- *
94
- * You can pass either the arity of the uncurried function or a predicate
95
- * which determines if the function is being used in a data-first or
96
- * data-last style.
97
- *
98
- * **Example** (Using arity to determine data-first or data-last style)
99
- *
100
- * ```ts
101
- * import { dual, pipe } from "effect/Function"
102
- *
103
- * const sum = dual<
104
- * (that: number) => (self: number) => number,
105
- * (self: number, that: number) => number
106
- * >(2, (self, that) => self + that)
107
- *
108
- * console.log(sum(2, 3)) // 5
109
- * console.log(pipe(2, sum(3))) // 5
110
- * ```
111
- *
112
- * **Example** (Using call signatures to define the overloads)
113
- *
114
- * ```ts
115
- * import { dual, pipe } from "effect/Function"
116
- *
117
- * const sum: {
118
- * (that: number): (self: number) => number
119
- * (self: number, that: number): number
120
- * } = dual(2, (self: number, that: number): number => self + that)
121
- *
122
- * console.log(sum(2, 3)) // 5
123
- * console.log(pipe(2, sum(3))) // 5
124
- * ```
125
- *
126
- * **Example** (Using a predicate to determine data-first or data-last style)
127
- *
128
- * ```ts
129
- * import { dual, pipe } from "effect/Function"
130
- *
131
- * const sum = dual<
132
- * (that: number) => (self: number) => number,
133
- * (self: number, that: number) => number
134
- * >(
135
- * (args) => args.length === 2,
136
- * (self, that) => self + that
137
- * )
138
- *
139
- * console.log(sum(2, 3)) // 5
140
- * console.log(pipe(2, sum(3))) // 5
141
- * ```
142
- *
143
- * @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.
144
- * @param body - The function to be curried.
145
- * @since 1.0.0
146
- */
147
- const dual = function(arity, body) {
148
- if (typeof arity === "function") return function() {
149
- return arity(arguments) ? body.apply(this, arguments) : ((self) => body(self, ...arguments));
150
- };
151
- switch (arity) {
152
- case 0:
153
- case 1: throw new RangeError(`Invalid arity ${arity}`);
154
- case 2: return function(a, b) {
155
- if (arguments.length >= 2) return body(a, b);
156
- return function(self) {
157
- return body(self, a);
158
- };
159
- };
160
- case 3: return function(a, b, c) {
161
- if (arguments.length >= 3) return body(a, b, c);
162
- return function(self) {
163
- return body(self, a, b);
164
- };
165
- };
166
- default: return function() {
167
- if (arguments.length >= arity) return body.apply(this, arguments);
168
- const args = arguments;
169
- return function(self) {
170
- return body(self, ...args);
171
- };
172
- };
173
- }
174
- };
175
- /**
176
- * 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`.
177
- * The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
178
- *
179
- * @param self - The first function to apply (or the composed function in data-last style).
180
- * @param bc - The second function to apply.
181
- * @returns A composed function that applies both functions in sequence.
182
- * @example
183
- * ```ts
184
- * import * as assert from "node:assert"
185
- * import { compose } from "effect/Function"
186
- *
187
- * const increment = (n: number) => n + 1;
188
- * const square = (n: number) => n * n;
189
- *
190
- * assert.strictEqual(compose(increment, square)(2), 9);
191
- * ```
192
- *
193
- * @since 1.0.0
194
- */
195
- const compose = dual(2, (ab, bc) => (a) => bc(ab(a)));
196
-
197
- //#endregion
198
5
  //#region src/node-is.ts
199
6
  /**
200
7
  * Type guard to check if a node is of a specific AST node type
@@ -219,22 +26,6 @@ const isFunction = isOneOf([
219
26
  AST_NODE_TYPES.FunctionExpression
220
27
  ]);
221
28
  /**
222
- * Check if a node is a function type (including TypeScript function types)
223
- * @param node The node to check
224
- * @returns True if the node is a function type
225
- */
226
- const isFunctionType = isOneOf([
227
- AST_NODE_TYPES.ArrowFunctionExpression,
228
- AST_NODE_TYPES.FunctionDeclaration,
229
- AST_NODE_TYPES.FunctionExpression,
230
- AST_NODE_TYPES.TSCallSignatureDeclaration,
231
- AST_NODE_TYPES.TSConstructSignatureDeclaration,
232
- AST_NODE_TYPES.TSDeclareFunction,
233
- AST_NODE_TYPES.TSEmptyBodyFunctionExpression,
234
- AST_NODE_TYPES.TSFunctionType,
235
- AST_NODE_TYPES.TSMethodSignature
236
- ]);
237
- /**
238
29
  * Check if a node is a class declaration or expression
239
30
  * @param node The node to check
240
31
  * @returns True if the node is a class
@@ -264,15 +55,9 @@ const isProperty = isOneOf([
264
55
  */
265
56
  const isJSXElement = is(AST_NODE_TYPES.JSXElement);
266
57
  /**
267
- * Check if a node is a JSX fragment
268
- * @param node The node to check
269
- * @returns True if the node is a JSX fragment
270
- */
271
- const isJSXFragment = is(AST_NODE_TYPES.JSXFragment);
272
- /**
273
58
  * Check if a node is a JSX element or JSX fragment
274
59
  */
275
- const isJSXElementLike = or(isJSXElement, isJSXFragment);
60
+ const isJSXElementLike = isOneOf([AST_NODE_TYPES.JSXElement, AST_NODE_TYPES.JSXFragment]);
276
61
  /**
277
62
  * Check if a node is a JSX tag name expression (identifier, member expression, or namespaced name)
278
63
  * @param node The node to check
@@ -309,30 +94,6 @@ const isJSX = isOneOf([
309
94
  AST_NODE_TYPES.JSXText
310
95
  ]);
311
96
  /**
312
- * Check if a node is a loop statement
313
- * @param node The node to check
314
- * @returns True if the node is a loop
315
- */
316
- const isLoop = isOneOf([
317
- AST_NODE_TYPES.DoWhileStatement,
318
- AST_NODE_TYPES.ForInStatement,
319
- AST_NODE_TYPES.ForOfStatement,
320
- AST_NODE_TYPES.ForStatement,
321
- AST_NODE_TYPES.WhileStatement
322
- ]);
323
- /**
324
- * Check if a node is a control flow statement (loop, if, or switch)
325
- * @param node The node to check
326
- * @returns True if the node is a control flow statement
327
- */
328
- const isControlFlow = or(isLoop, isOneOf([AST_NODE_TYPES.IfStatement, AST_NODE_TYPES.SwitchStatement]));
329
- /**
330
- * Check if a node is a conditional expression or control flow statement
331
- * @param node The node to check
332
- * @returns True if the node is conditional
333
- */
334
- const isConditional = or(isControlFlow, isOneOf([AST_NODE_TYPES.LogicalExpression, AST_NODE_TYPES.ConditionalExpression]));
335
- /**
336
97
  * Check if a node is a TypeScript type expression
337
98
  * @param node The node to check
338
99
  * @returns True if the node is a type expression
@@ -355,6 +116,14 @@ const isTypeAssertionExpression = isOneOf([
355
116
  AST_NODE_TYPES.TSNonNullExpression,
356
117
  AST_NODE_TYPES.TSSatisfiesExpression
357
118
  ]);
119
+ /**
120
+ * Check if a node is a directive expression statement
121
+ * @param node The node to check
122
+ * @returns True if the node is a directive, false otherwise
123
+ */
124
+ function isDirective(node) {
125
+ return node.type === AST_NODE_TYPES.ExpressionStatement && node.directive != null;
126
+ }
358
127
 
359
128
  //#endregion
360
129
  //#region src/node-unwrap.ts
@@ -383,372 +152,16 @@ function isThisExpressionLoose(node) {
383
152
  }
384
153
 
385
154
  //#endregion
386
- //#region src/node-traverse.ts
387
- function findParent(node, test) {
388
- if (node == null) return null;
389
- let parent = node.parent;
390
- while (parent != null && parent.type !== AST_NODE_TYPES.Program) {
391
- if (test(parent)) return parent;
392
- parent = parent.parent;
393
- }
394
- return null;
395
- }
396
-
397
- //#endregion
398
- //#region src/expression-nested.ts
399
- /**
400
- * Get all nested identifiers in a expression like node
401
- * @param node The node to get the nested identifiers from
402
- * @returns All nested identifiers
403
- */
404
- function getNestedIdentifiers(node) {
405
- const identifiers = [];
406
- if (node.type === AST_NODE_TYPES.Identifier) identifiers.push(node);
407
- if ("arguments" in node) {
408
- const chunk = node.arguments.flatMap(getNestedIdentifiers);
409
- identifiers.push(...chunk);
410
- }
411
- if ("elements" in node) {
412
- const chunk = node.elements.filter((x) => x != null).flatMap(getNestedIdentifiers);
413
- identifiers.push(...chunk);
414
- }
415
- if ("properties" in node) {
416
- const chunk = node.properties.flatMap(getNestedIdentifiers);
417
- identifiers.push(...chunk);
418
- }
419
- if ("expressions" in node) {
420
- const chunk = node.expressions.flatMap(getNestedIdentifiers);
421
- identifiers.push(...chunk);
422
- }
423
- if ("left" in node) {
424
- const chunk = getNestedIdentifiers(node.left);
425
- identifiers.push(...chunk);
426
- }
427
- if ("right" in node) {
428
- const chunk = getNestedIdentifiers(node.right);
429
- identifiers.push(...chunk);
430
- }
431
- if (node.type === AST_NODE_TYPES.Property) {
432
- const chunk = getNestedIdentifiers(node.value);
433
- identifiers.push(...chunk);
434
- }
435
- if (node.type === AST_NODE_TYPES.SpreadElement) {
436
- const chunk = getNestedIdentifiers(node.argument);
437
- identifiers.push(...chunk);
438
- }
439
- if (node.type === AST_NODE_TYPES.MemberExpression) {
440
- identifiers.push(...getNestedIdentifiers(node.object));
441
- if (node.computed) identifiers.push(...getNestedIdentifiers(node.property));
442
- }
443
- if (node.type === AST_NODE_TYPES.UnaryExpression) {
444
- const chunk = getNestedIdentifiers(node.argument);
445
- identifiers.push(...chunk);
446
- }
447
- if (node.type === AST_NODE_TYPES.ChainExpression) {
448
- const chunk = getNestedIdentifiers(node.expression);
449
- identifiers.push(...chunk);
450
- }
451
- if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
452
- const chunk = getNestedIdentifiers(node.expression);
453
- identifiers.push(...chunk);
454
- }
455
- if (node.type === AST_NODE_TYPES.TSAsExpression) {
456
- const chunk = getNestedIdentifiers(node.expression);
457
- identifiers.push(...chunk);
458
- }
459
- if (node.type === AST_NODE_TYPES.TSSatisfiesExpression) {
460
- const chunk = getNestedIdentifiers(node.expression);
461
- identifiers.push(...chunk);
462
- }
463
- if (node.type === AST_NODE_TYPES.ConditionalExpression) {
464
- identifiers.push(...getNestedIdentifiers(node.test));
465
- identifiers.push(...getNestedIdentifiers(node.consequent));
466
- identifiers.push(...getNestedIdentifiers(node.alternate));
467
- }
468
- if (node.type === AST_NODE_TYPES.AwaitExpression) identifiers.push(...getNestedIdentifiers(node.argument));
469
- if (node.type === AST_NODE_TYPES.YieldExpression && node.argument != null) identifiers.push(...getNestedIdentifiers(node.argument));
470
- if (node.type === AST_NODE_TYPES.UpdateExpression) identifiers.push(...getNestedIdentifiers(node.argument));
471
- if (node.type === AST_NODE_TYPES.CallExpression || node.type === AST_NODE_TYPES.NewExpression) identifiers.push(...getNestedIdentifiers(node.callee));
472
- if (node.type === AST_NODE_TYPES.TaggedTemplateExpression) {
473
- identifiers.push(...getNestedIdentifiers(node.tag));
474
- identifiers.push(...getNestedIdentifiers(node.quasi));
475
- }
476
- if (node.type === AST_NODE_TYPES.ImportExpression) identifiers.push(...getNestedIdentifiers(node.source));
477
- if (node.type === AST_NODE_TYPES.TSTypeAssertion) identifiers.push(...getNestedIdentifiers(node.expression));
478
- if (node.type === AST_NODE_TYPES.TSInstantiationExpression) identifiers.push(...getNestedIdentifiers(node.expression));
479
- return identifiers;
480
- }
481
- /**
482
- * Gets the nested return statements in the node that are within the same function
483
- * @param node The AST node
484
- * @returns The nested return statements in the node
485
- */
486
- function getNestedReturnStatements(node) {
487
- const statements = [];
488
- const boundaryNode = isFunction(node) ? node : findParent(node, isFunction);
489
- simpleTraverse(node, { enter(node) {
490
- if (node.type !== AST_NODE_TYPES.ReturnStatement) return;
491
- if (findParent(node, isFunction) !== boundaryNode) return;
492
- statements.push(node);
493
- } });
494
- return statements;
495
- }
496
- /**
497
- * Get all nested expressions of type T in an expression like node
498
- * @param type The type of the expression to retrieve within the node
499
- * @returns A partially applied function bound to a predicate of type AST. The returned function can be called passing a
500
- * node, and it will return an array of all nested expressions of type AST.
501
- */
502
- function getNestedExpressionsOfType(type) {
503
- const isNodeOfType = is(type);
504
- const recurse = (node) => {
505
- const expressions = [];
506
- if (isNodeOfType(node)) expressions.push(node);
507
- if ("arguments" in node) {
508
- const chunk = node.arguments.flatMap(recurse);
509
- expressions.push(...chunk);
510
- }
511
- if ("expression" in node && node.expression !== true && node.expression !== false) {
512
- const chunk = recurse(node.expression);
513
- expressions.push(...chunk);
514
- }
515
- if ("left" in node) {
516
- const chunk = recurse(node.left);
517
- expressions.push(...chunk);
518
- }
519
- if ("right" in node) {
520
- const chunk = recurse(node.right);
521
- expressions.push(...chunk);
522
- }
523
- if ("test" in node && node.test != null) {
524
- const chunk = recurse(node.test);
525
- expressions.push(...chunk);
526
- }
527
- if ("consequent" in node) {
528
- const chunk = Array.isArray(node.consequent) ? node.consequent.flatMap(recurse) : recurse(node.consequent);
529
- expressions.push(...chunk);
530
- }
531
- if ("alternate" in node && node.alternate != null) {
532
- const chunk = Array.isArray(node.alternate) ? node.alternate.flatMap(recurse) : recurse(node.alternate);
533
- expressions.push(...chunk);
534
- }
535
- if ("elements" in node) {
536
- const chunk = node.elements.filter((x) => x != null).flatMap(recurse);
537
- expressions.push(...chunk);
538
- }
539
- if ("properties" in node) {
540
- const chunk = node.properties.flatMap(recurse);
541
- expressions.push(...chunk);
542
- }
543
- if ("expressions" in node) {
544
- const chunk = node.expressions.flatMap(recurse);
545
- expressions.push(...chunk);
546
- }
547
- if (node.type === AST_NODE_TYPES.Property) {
548
- const chunk = recurse(node.value);
549
- expressions.push(...chunk);
550
- }
551
- if (node.type === AST_NODE_TYPES.SpreadElement) {
552
- const chunk = recurse(node.argument);
553
- expressions.push(...chunk);
554
- }
555
- if (node.type === AST_NODE_TYPES.MemberExpression) {
556
- expressions.push(...recurse(node.object));
557
- if (node.computed) expressions.push(...recurse(node.property));
558
- }
559
- if (node.type === AST_NODE_TYPES.UnaryExpression) {
560
- const chunk = recurse(node.argument);
561
- expressions.push(...chunk);
562
- }
563
- if (node.type === AST_NODE_TYPES.AwaitExpression) expressions.push(...recurse(node.argument));
564
- if (node.type === AST_NODE_TYPES.YieldExpression && node.argument != null) expressions.push(...recurse(node.argument));
565
- if (node.type === AST_NODE_TYPES.UpdateExpression) expressions.push(...recurse(node.argument));
566
- if (node.type === AST_NODE_TYPES.CallExpression || node.type === AST_NODE_TYPES.NewExpression) expressions.push(...recurse(node.callee));
567
- if (node.type === AST_NODE_TYPES.TaggedTemplateExpression) {
568
- expressions.push(...recurse(node.tag));
569
- expressions.push(...recurse(node.quasi));
570
- }
571
- if (node.type === AST_NODE_TYPES.ImportExpression) expressions.push(...recurse(node.source));
572
- return expressions;
573
- };
574
- return recurse;
575
- }
576
- /**
577
- * Get all nested new expressions in an expression like node
578
- * @param node The node to get the nested new expressions from
579
- * @returns All nested new expressions
580
- */
581
- const getNestedNewExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.NewExpression);
582
- /**
583
- * Get all nested call expressions in a expression like node
584
- * @param node The node to get the nested call expressions from
585
- * @returns All nested call expressions
586
- */
587
- const getNestedCallExpressions = getNestedExpressionsOfType(AST_NODE_TYPES.CallExpression);
588
-
589
- //#endregion
590
- //#region src/file-directive.ts
591
- /**
592
- * Get all directive expression statements from the top of a program AST node
593
- * @param node The program AST node
594
- * @returns The array of directive string literals (ex: "use strict")
595
- */
596
- function getFileDirectives(node) {
597
- const directives = [];
598
- for (const stmt of node.body) {
599
- if (!isDirective(stmt)) continue;
600
- directives.push(stmt);
601
- }
602
- return directives;
603
- }
155
+ //#region src/file.ts
604
156
  /**
605
157
  * Check if a directive with the given name exists in the file directives
606
158
  * @param node The program AST node
607
159
  * @param name The directive name to check (ex: "use strict", "use memo", "use no memo")
608
160
  * @returns True if the directive exists, false otherwise
609
161
  */
610
- function isDirectiveInFile(node, name) {
611
- return getFileDirectives(node).some((d) => d.directive === name);
612
- }
613
-
614
- //#endregion
615
- //#region src/function-directive.ts
616
- /**
617
- * Get all directive expression statements from the top of a function AST node
618
- * @param node The function AST node
619
- * @returns The array of directive string literals (ex: "use memo", "use no memo")
620
- */
621
- function getFunctionDirectives(node) {
622
- const directives = [];
623
- if (node.body.type !== AST_NODE_TYPES.BlockStatement) return directives;
624
- for (const stmt of node.body.body) {
625
- if (!isDirective(stmt)) continue;
626
- directives.push(stmt);
627
- }
628
- return directives;
629
- }
630
- /**
631
- * Check if a directive with the given name exists in the function directives
632
- * @param node The function AST node
633
- * @param name The directive name to check (ex: "use memo", "use no memo")
634
- * @returns True if the directive exists, false otherwise
635
- */
636
- function isDirectiveInFunction(node, name) {
637
- return getFunctionDirectives(node).some((d) => d.directive === name);
638
- }
639
-
640
- //#endregion
641
- //#region src/function-id.ts
642
- /**
643
- * Gets the static name of a function AST node. For function declarations it is
644
- * easy. For anonymous function expressions it is much harder. If you search for
645
- * `IsAnonymousFunctionDefinition()` in the ECMAScript spec you'll find places
646
- * where JS gives anonymous function expressions names. We roughly detect the
647
- * same AST nodes with some exceptions to better fit our use case.
648
- */
649
- function getFunctionId(node) {
650
- switch (true) {
651
- case "id" in node && node.id != null: return node.id;
652
- case node.parent.type === AST_NODE_TYPES.VariableDeclarator && node.parent.init === node: return node.parent.id;
653
- case node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.right === node && node.parent.operator === "=": return node.parent.left;
654
- case node.parent.type === AST_NODE_TYPES.Property && node.parent.value === node && !node.parent.computed: return node.parent.key;
655
- case isMethodOrProperty(node.parent) && node.parent.value === node: return node.parent.key;
656
- case node.parent.type === AST_NODE_TYPES.AssignmentPattern && node.parent.right === node: return node.parent.left;
657
- case node.parent.type === AST_NODE_TYPES.ConditionalExpression: return getFunctionId(node.parent);
658
- case isTypeAssertionExpression(node.parent): return getFunctionId(node.parent);
659
- }
660
- return null;
661
- }
662
-
663
- //#endregion
664
- //#region src/function-init-path.ts
665
- /**
666
- * Identifies the initialization path of a function node in the ast.
667
- * Determine what kind of component declaration pattern the function belongs to.
668
- *
669
- * @param node The function node to analyze
670
- * @returns The function initialization path or null if not identifiable
671
- */
672
- function getFunctionInitPath(node) {
673
- if (node.type === AST_NODE_TYPES.FunctionDeclaration) return [node];
674
- let parent = node.parent;
675
- while (isTypeExpression(parent)) parent = parent.parent;
676
- switch (true) {
677
- case parent.type === AST_NODE_TYPES.VariableDeclarator: return [
678
- parent.parent,
679
- parent,
680
- node
681
- ];
682
- case parent.type === AST_NODE_TYPES.CallExpression && parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
683
- parent.parent.parent,
684
- parent.parent,
685
- parent,
686
- node
687
- ];
688
- case parent.type === AST_NODE_TYPES.CallExpression && parent.parent.type === AST_NODE_TYPES.CallExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
689
- parent.parent.parent.parent,
690
- parent.parent.parent,
691
- parent.parent,
692
- parent,
693
- node
694
- ];
695
- case parent.type === AST_NODE_TYPES.Property && parent.parent.type === AST_NODE_TYPES.ObjectExpression && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator: return [
696
- parent.parent.parent.parent,
697
- parent.parent.parent,
698
- parent.parent,
699
- parent,
700
- node
701
- ];
702
- case parent.type === AST_NODE_TYPES.MethodDefinition: return [
703
- parent.parent.parent,
704
- parent.parent,
705
- parent,
706
- node
707
- ];
708
- case parent.type === AST_NODE_TYPES.PropertyDefinition: return [
709
- parent.parent.parent,
710
- parent.parent,
711
- parent,
712
- node
713
- ];
714
- }
715
- return null;
716
- }
717
- /**
718
- * Check if a specific function call exists in the function initialization path.
719
- * Useful for detecting HOCs like React.memo, React.forwardRef, etc.
720
- *
721
- * @param callName The name of the call to check for (ex: "memo", "forwardRef")
722
- * @param initPath The function initialization path to search in
723
- * @returns True if the call exists in the path, false otherwise
724
- */
725
- function hasCallInFunctionInitPath(callName, initPath) {
726
- return initPath.some((node) => {
727
- if (node.type !== AST_NODE_TYPES.CallExpression) return false;
728
- const { callee } = node;
729
- if (callee.type === AST_NODE_TYPES.Identifier) return callee.name === callName;
730
- if (callee.type === AST_NODE_TYPES.MemberExpression && "name" in callee.property) return callee.property.name === callName;
731
- return false;
732
- });
733
- }
734
-
735
- //#endregion
736
- //#region src/function-is.ts
737
- /**
738
- * Check if a function is empty
739
- * @param node The function node to check
740
- * @returns True if the function is empty, false otherwise
741
- */
742
- function isFunctionEmpty(node) {
743
- return node.body.type === AST_NODE_TYPES.BlockStatement && node.body.body.length === 0;
744
- }
745
- /**
746
- * Check if a function is immediately invoked
747
- * @param node The function node to check
748
- * @returns True if the function is immediately invoked, false otherwise
749
- */
750
- function isFunctionImmediatelyInvoked(node) {
751
- return node.type !== AST_NODE_TYPES.FunctionDeclaration && node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
162
+ function isFileHasDirective(node, name) {
163
+ for (const stmt of node.body) if (isDirective(stmt) && stmt.directive === name) return true;
164
+ return false;
752
165
  }
753
166
 
754
167
  //#endregion
@@ -763,19 +176,6 @@ function isIdentifier(node, name) {
763
176
  return node != null && node.type === AST_NODE_TYPES.Identifier && (name == null || node.name === name);
764
177
  }
765
178
 
766
- //#endregion
767
- //#region src/identifier-name.ts
768
- /**
769
- * Check if a string is a valid JavaScript identifier name
770
- * Note: This only checks for ASCII identifiers. Unicode identifiers (e.g., `const 变量 = 1`)
771
- * are not supported by this simple regex check.
772
- * @param name The string to check
773
- * @returns True if the string is a valid ASCII identifier name
774
- */
775
- function isIdentifierName(name) {
776
- return /^[A-Z$_][\w$]*$/i.test(name);
777
- }
778
-
779
179
  //#endregion
780
180
  //#region src/identifier-traverse.ts
781
181
  /**
@@ -793,6 +193,138 @@ function getRootIdentifier(node) {
793
193
  }
794
194
  }
795
195
 
196
+ //#endregion
197
+ //#region src/literal-is.ts
198
+ function isLiteral(node, type) {
199
+ if (node.type !== AST_NODE_TYPES.Literal) return false;
200
+ if (type == null) return true;
201
+ switch (type) {
202
+ case "boolean": return typeof node.value === "boolean";
203
+ case "null": return node.value === null;
204
+ case "number": return typeof node.value === "number";
205
+ case "regexp": return "regex" in node;
206
+ case "string": return typeof node.value === "string";
207
+ }
208
+ }
209
+
210
+ //#endregion
211
+ //#region ../../.pkgs/eff/dist/index.js
212
+ /**
213
+ * Creates a function that can be used in a data-last (aka `pipe`able) or
214
+ * data-first style.
215
+ *
216
+ * The first parameter to `dual` is either the arity of the uncurried function
217
+ * or a predicate that determines if the function is being used in a data-first
218
+ * or data-last style.
219
+ *
220
+ * Using the arity is the most common use case, but there are some cases where
221
+ * you may want to use a predicate. For example, if you have a function that
222
+ * takes an optional argument, you can use a predicate to determine if the
223
+ * function is being used in a data-first or data-last style.
224
+ *
225
+ * You can pass either the arity of the uncurried function or a predicate
226
+ * which determines if the function is being used in a data-first or
227
+ * data-last style.
228
+ *
229
+ * **Example** (Using arity to determine data-first or data-last style)
230
+ *
231
+ * ```ts
232
+ * import { dual, pipe } from "effect/Function"
233
+ *
234
+ * const sum = dual<
235
+ * (that: number) => (self: number) => number,
236
+ * (self: number, that: number) => number
237
+ * >(2, (self, that) => self + that)
238
+ *
239
+ * console.log(sum(2, 3)) // 5
240
+ * console.log(pipe(2, sum(3))) // 5
241
+ * ```
242
+ *
243
+ * **Example** (Using call signatures to define the overloads)
244
+ *
245
+ * ```ts
246
+ * import { dual, pipe } from "effect/Function"
247
+ *
248
+ * const sum: {
249
+ * (that: number): (self: number) => number
250
+ * (self: number, that: number): number
251
+ * } = dual(2, (self: number, that: number): number => self + that)
252
+ *
253
+ * console.log(sum(2, 3)) // 5
254
+ * console.log(pipe(2, sum(3))) // 5
255
+ * ```
256
+ *
257
+ * **Example** (Using a predicate to determine data-first or data-last style)
258
+ *
259
+ * ```ts
260
+ * import { dual, pipe } from "effect/Function"
261
+ *
262
+ * const sum = dual<
263
+ * (that: number) => (self: number) => number,
264
+ * (self: number, that: number) => number
265
+ * >(
266
+ * (args) => args.length === 2,
267
+ * (self, that) => self + that
268
+ * )
269
+ *
270
+ * console.log(sum(2, 3)) // 5
271
+ * console.log(pipe(2, sum(3))) // 5
272
+ * ```
273
+ *
274
+ * @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.
275
+ * @param body - The function to be curried.
276
+ * @since 1.0.0
277
+ */
278
+ const dual = function(arity, body) {
279
+ if (typeof arity === "function") return function() {
280
+ return arity(arguments) ? body.apply(this, arguments) : ((self) => body(self, ...arguments));
281
+ };
282
+ switch (arity) {
283
+ case 0:
284
+ case 1: throw new RangeError(`Invalid arity ${arity}`);
285
+ case 2: return function(a, b) {
286
+ if (arguments.length >= 2) return body(a, b);
287
+ return function(self) {
288
+ return body(self, a);
289
+ };
290
+ };
291
+ case 3: return function(a, b, c) {
292
+ if (arguments.length >= 3) return body(a, b, c);
293
+ return function(self) {
294
+ return body(self, a, b);
295
+ };
296
+ };
297
+ default: return function() {
298
+ if (arguments.length >= arity) return body.apply(this, arguments);
299
+ const args = arguments;
300
+ return function(self) {
301
+ return body(self, ...args);
302
+ };
303
+ };
304
+ }
305
+ };
306
+ /**
307
+ * 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`.
308
+ * The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
309
+ *
310
+ * @param self - The first function to apply (or the composed function in data-last style).
311
+ * @param bc - The second function to apply.
312
+ * @returns A composed function that applies both functions in sequence.
313
+ * @example
314
+ * ```ts
315
+ * import * as assert from "node:assert"
316
+ * import { compose } from "effect/Function"
317
+ *
318
+ * const increment = (n: number) => n + 1;
319
+ * const square = (n: number) => n * n;
320
+ *
321
+ * assert.strictEqual(compose(increment, square)(2), 9);
322
+ * ```
323
+ *
324
+ * @since 1.0.0
325
+ */
326
+ const compose = dual(2, (ab, bc) => (a) => bc(ab(a)));
327
+
796
328
  //#endregion
797
329
  //#region src/node-equality.ts
798
330
  /**
@@ -849,15 +381,6 @@ function getHumanReadableKind(node, delimiter = " ") {
849
381
  return toLowerCase(delimiterCase(node.type, delimiter));
850
382
  }
851
383
 
852
- //#endregion
853
- //#region src/node-line.ts
854
- function isMultiLine(node) {
855
- return node.loc.start.line !== node.loc.end.line;
856
- }
857
- function isLineBreak(node) {
858
- return isOneOf([AST_NODE_TYPES.Literal, AST_NODE_TYPES.JSXText])(node) && typeof node.value === "string" && node.value.trim() === "" && isMultiLine(node);
859
- }
860
-
861
384
  //#endregion
862
385
  //#region src/node-name.ts
863
386
  function getFullyQualifiedName(node, getText) {
@@ -877,10 +400,6 @@ function getFullyQualifiedName(node, getText) {
877
400
  //#endregion
878
401
  //#region src/node-selectors.ts
879
402
  /**
880
- * Selector for arrow function expressions with implicit return
881
- */
882
- const SEL_IMPLICIT_RETURN_ARROW_FUNCTION_EXPRESSION = "ArrowFunctionExpression[body.type!='BlockStatement']";
883
- /**
884
403
  * Selector for variable declarators with object destructuring
885
404
  */
886
405
  const SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR = [
@@ -899,38 +418,15 @@ const SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION = [
899
418
  ].join("");
900
419
 
901
420
  //#endregion
902
- //#region src/pattern-process-env-node-env.ts
903
- /**
904
- * Check if the given node is a member expression that accesses `process.env.NODE_ENV`
905
- * @param node The AST node
906
- * @returns True if the node is a member expression that accesses `process.env.NODE_ENV`, false otherwise
907
- */
908
- function isProcessEnvNodeEnv(node) {
909
- return node != null && node.type === AST_NODE_TYPES.MemberExpression && node.object.type === AST_NODE_TYPES.MemberExpression && node.object.object.type === AST_NODE_TYPES.Identifier && node.object.object.name === "process" && node.object.property.type === AST_NODE_TYPES.Identifier && node.object.property.name === "env" && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === "NODE_ENV";
910
- }
911
- /**
912
- * Check if the given node is a binary expression that compares `process.env.NODE_ENV` with a string literal.
913
- * @param node The AST node
914
- * @param operator The operator used in the comparison
915
- * @param value The string literal value to compare against
916
- * @returns True if the node is a binary expression that compares `process.env.NODE_ENV` with the specified value, false otherwise
917
- */
918
- function isProcessEnvNodeEnvCompare(node, operator, value) {
919
- if (node == null) return false;
920
- if (node.type !== AST_NODE_TYPES.BinaryExpression) return false;
921
- if (node.operator !== operator) return false;
922
- if (isProcessEnvNodeEnv(node.left) && isLiteral(node.right, "string")) return node.right.value === value;
923
- if (isLiteral(node.left, "string") && isProcessEnvNodeEnv(node.right)) return node.left.value === value;
924
- return false;
925
- }
926
-
927
- //#endregion
928
- //#region src/pattern-test-mock.ts
929
- function isTestMock(node) {
930
- return node != null && node.type === AST_NODE_TYPES.MemberExpression && node.object.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === "mock";
931
- }
932
- function isTestMockCallback(node) {
933
- return node != null && isFunction(node) && node.parent.type === AST_NODE_TYPES.CallExpression && isTestMock(node.parent.callee) && node.parent.arguments[1] === node;
421
+ //#region src/node-traverse.ts
422
+ function findParent(node, test) {
423
+ if (node == null) return null;
424
+ let parent = node.parent;
425
+ while (parent != null && parent.type !== AST_NODE_TYPES.Program) {
426
+ if (test(parent)) return parent;
427
+ parent = parent.parent;
428
+ }
429
+ return null;
934
430
  }
935
431
 
936
432
  //#endregion
@@ -971,4 +467,4 @@ function findProperty(properties, name) {
971
467
  }
972
468
 
973
469
  //#endregion
974
- export { SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION, SEL_IMPLICIT_RETURN_ARROW_FUNCTION_EXPRESSION, SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR, findParent, 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, isJSXElementLike, isJSXFragment, isJSXTagNameExpression, isLineBreak, isLiteral, isLoop, isMethodOrProperty, isMultiLine, isNodeEqual, isOneOf, isProcessEnvNodeEnv, isProcessEnvNodeEnvCompare, isProperty, isTestMock, isTestMockCallback, isThisExpressionLoose, isTypeAssertionExpression, isTypeExpression };
470
+ export { SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION, SEL_OBJECT_DESTRUCTURING_VARIABLE_DECLARATOR, findParent, findProperty, getFullyQualifiedName, getHumanReadableKind, getPropertyName, getRootIdentifier, getUnderlyingExpression, is, isClass, isDirective, isFileHasDirective, isFunction, isIdentifier, isJSX, isJSXElement, isJSXElementLike, isJSXTagNameExpression, isLiteral, isMethodOrProperty, isNodeEqual, isOneOf, isProperty, isThisExpressionLoose, isTypeAssertionExpression, isTypeExpression };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/ast",
3
- "version": "5.2.1-next.1",
3
+ "version": "5.2.1-next.3",
4
4
  "description": "ESLint React's TSESTree AST utility module.",
5
5
  "homepage": "https://github.com/Rel1cx/eslint-react",
6
6
  "bugs": {