@eslint-react/core 2.0.0-next.168 → 2.0.0-next.169
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 +53 -22
- package/dist/index.js +72 -70
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { TSESTree } from "@typescript-eslint/types";
|
|
|
2
2
|
import * as AST from "@eslint-react/ast";
|
|
3
3
|
import { unit } from "@eslint-react/eff";
|
|
4
4
|
import { RuleContext } from "@eslint-react/kit";
|
|
5
|
-
import * as VAR from "@eslint-react/var";
|
|
6
5
|
import * as birecord0 from "birecord";
|
|
7
6
|
import { isFalseLiteralType, isTrueLiteralType } from "ts-api-utils";
|
|
8
7
|
import ts from "typescript";
|
|
@@ -430,17 +429,7 @@ declare const REACT_BUILTIN_HOOK_NAMES: readonly ["use", "useActionState", "useC
|
|
|
430
429
|
declare function isReactHookName(name: string): boolean;
|
|
431
430
|
//#endregion
|
|
432
431
|
//#region src/jsx/jsx-attribute.d.ts
|
|
433
|
-
|
|
434
|
-
* Searches for a specific JSX attribute by name in a list of attributes
|
|
435
|
-
* Returns the last matching attribute (rightmost in JSX)
|
|
436
|
-
*
|
|
437
|
-
* @param context - ESLint rule context
|
|
438
|
-
* @param name - The name of the attribute to find
|
|
439
|
-
* @param attributes - Array of JSX attributes to search through
|
|
440
|
-
* @param initialScope - Optional scope for resolving variables
|
|
441
|
-
* @returns The found attribute or undefined
|
|
442
|
-
*/
|
|
443
|
-
declare function getAttribute(context: RuleContext, name: string, attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[], initialScope?: Scope): TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | unit;
|
|
432
|
+
declare function getAttribute(context: RuleContext, attributes: AST.TSESTreeJSXAttributeLike[], initialScope?: Scope): (name: string) => AST.TSESTreeJSXAttributeLike | undefined;
|
|
444
433
|
//#endregion
|
|
445
434
|
//#region src/jsx/jsx-attribute-name.d.ts
|
|
446
435
|
/**
|
|
@@ -453,15 +442,57 @@ declare function getAttributeName(context: RuleContext, node: TSESTree$1.JSXAttr
|
|
|
453
442
|
//#endregion
|
|
454
443
|
//#region src/jsx/jsx-attribute-value.d.ts
|
|
455
444
|
/**
|
|
456
|
-
*
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
445
|
+
* Represents possible JSX attribute value types that can be resolved
|
|
446
|
+
*/
|
|
447
|
+
type AttributeValue = {
|
|
448
|
+
kind: "boolean";
|
|
449
|
+
toStatic(): true;
|
|
450
|
+
} | {
|
|
451
|
+
kind: "element";
|
|
452
|
+
node: TSESTree.JSXElement;
|
|
453
|
+
toStatic(): unknown;
|
|
454
|
+
} | {
|
|
455
|
+
kind: "literal";
|
|
456
|
+
node: TSESTree.Literal;
|
|
457
|
+
toStatic(): TSESTree.Literal["value"];
|
|
458
|
+
} | {
|
|
459
|
+
kind: "expression";
|
|
460
|
+
node: TSESTree.JSXExpressionContainer["expression"];
|
|
461
|
+
toStatic(): unknown;
|
|
462
|
+
} | {
|
|
463
|
+
kind: "spreadProps";
|
|
464
|
+
node: TSESTree.JSXSpreadAttribute["argument"];
|
|
465
|
+
toStatic(name?: string): unknown;
|
|
466
|
+
} | {
|
|
467
|
+
kind: "spreadChild";
|
|
468
|
+
node: TSESTree.JSXSpreadChild["expression"];
|
|
469
|
+
toStatic(): unknown;
|
|
470
|
+
};
|
|
471
|
+
declare function resolveAttributeValue(context: RuleContext, attribute: AST.TSESTreeJSXAttributeLike): {
|
|
472
|
+
readonly kind: "boolean";
|
|
473
|
+
readonly toStatic: () => true;
|
|
474
|
+
readonly node?: never;
|
|
475
|
+
} | {
|
|
476
|
+
readonly kind: "literal";
|
|
477
|
+
readonly node: TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral;
|
|
478
|
+
readonly toStatic: () => string | number | bigint | boolean | RegExp | null;
|
|
479
|
+
} | {
|
|
480
|
+
readonly kind: "expression";
|
|
481
|
+
readonly node: TSESTree.JSXEmptyExpression | TSESTree.Expression;
|
|
482
|
+
readonly toStatic: () => unknown;
|
|
483
|
+
} | {
|
|
484
|
+
readonly kind: "element";
|
|
485
|
+
readonly node: TSESTree.JSXElement;
|
|
486
|
+
readonly toStatic: () => undefined;
|
|
487
|
+
} | {
|
|
488
|
+
readonly kind: "spreadChild";
|
|
489
|
+
readonly node: TSESTree.JSXEmptyExpression | TSESTree.Expression;
|
|
490
|
+
readonly toStatic: () => undefined;
|
|
491
|
+
} | {
|
|
492
|
+
readonly kind: "spreadProps";
|
|
493
|
+
readonly node: TSESTree.Expression;
|
|
494
|
+
readonly toStatic: (name?: string) => unknown;
|
|
495
|
+
};
|
|
465
496
|
//#endregion
|
|
466
497
|
//#region src/jsx/jsx-detection.d.ts
|
|
467
498
|
/**
|
|
@@ -776,4 +807,4 @@ declare const isForwardRefCall: isReactAPICall.ReturnType;
|
|
|
776
807
|
declare const isMemoCall: isReactAPICall.ReturnType;
|
|
777
808
|
declare const isLazyCall: isReactAPICall.ReturnType;
|
|
778
809
|
//#endregion
|
|
779
|
-
export { ClassComponent, Component, ComponentDetectionHint, ComponentEffectPhaseKind, ComponentFlag, ComponentKind, ComponentLifecyclePhaseKind, ComponentPhaseKind, ComponentPhaseRelevance, ComponentStateKind, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, EffectKind, FunctionComponent, Hook, JSXDetectionHint, REACT_BUILTIN_HOOK_NAMES, SemanticEntry, SemanticNode, TypeVariant, findParentAttribute, getAttribute, getAttributeName,
|
|
810
|
+
export { AttributeValue, ClassComponent, Component, ComponentDetectionHint, ComponentEffectPhaseKind, ComponentFlag, ComponentKind, ComponentLifecyclePhaseKind, ComponentPhaseKind, ComponentPhaseRelevance, ComponentStateKind, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, EffectKind, FunctionComponent, Hook, JSXDetectionHint, REACT_BUILTIN_HOOK_NAMES, SemanticEntry, SemanticNode, TypeVariant, findParentAttribute, getAttribute, getAttributeName, getComponentFlagFromInitPath, getComponentNameFromId, getElementType, getFunctionComponentId, getInstanceId, getTypeVariants, hasAnyAttribute, hasAttribute, hasEveryAttribute, hasNoneOrLooseComponentName, isAnyType, isAssignmentToThisState, isBigIntType, isBooleanType, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isEnumType, isFalseLiteralType, isFalsyBigIntType, isFalsyNumberType, isFalsyStringType, isForwardRef, isForwardRefCall, isFragmentElement, isFunctionOfRenderMethod, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHostElement, isInitializedFromReact, isInstanceIdEqual, isInversePhase, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isNeverType, isNullishType, isNumberType, isObjectType, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookId, isReactHookName, isRender, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isStringType, isThisSetState, isTrueLiteralType, isTruthyBigIntType, isTruthyNumberType, isTruthyStringType, isUnknownType, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, resolveAttributeValue, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { RegExp, Selector } from "@eslint-react/kit";
|
|
|
5
5
|
import { DEFAULT_ESLINT_REACT_SETTINGS, coerceSettings, getId } from "@eslint-react/shared";
|
|
6
6
|
import * as VAR from "@eslint-react/var";
|
|
7
7
|
import { P, isMatching, match } from "ts-pattern";
|
|
8
|
+
import { getStaticValue } from "@typescript-eslint/utils/ast-utils";
|
|
8
9
|
import birecord from "birecord";
|
|
9
10
|
import { isFalseLiteralType, isTrueLiteralType, isTypeFlagSet } from "ts-api-utils";
|
|
10
11
|
import ts from "typescript";
|
|
@@ -387,86 +388,87 @@ function getAttributeName(context, node) {
|
|
|
387
388
|
|
|
388
389
|
//#endregion
|
|
389
390
|
//#region src/jsx/jsx-attribute.ts
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
if (initialScope == null) return false;
|
|
404
|
-
switch (attr.argument.type) {
|
|
405
|
-
case AST_NODE_TYPES.Identifier: {
|
|
406
|
-
const variable = VAR.findVariable(attr.argument.name, initialScope);
|
|
407
|
-
const variableNode = VAR.getVariableDefinitionNode(variable, 0);
|
|
408
|
-
if (variableNode?.type === AST_NODE_TYPES.ObjectExpression) return VAR.findProperty(name, variableNode.properties, initialScope) != null;
|
|
409
|
-
return false;
|
|
391
|
+
function getAttribute(context, attributes, initialScope) {
|
|
392
|
+
return (name) => {
|
|
393
|
+
return attributes.findLast((attr) => {
|
|
394
|
+
if (attr.type === AST_NODE_TYPES.JSXAttribute) return getAttributeName(context, attr) === name;
|
|
395
|
+
if (initialScope == null) return false;
|
|
396
|
+
switch (attr.argument.type) {
|
|
397
|
+
case AST_NODE_TYPES.Identifier: {
|
|
398
|
+
const variable = VAR.findVariable(attr.argument.name, initialScope);
|
|
399
|
+
const variableNode = VAR.getVariableDefinitionNode(variable, 0);
|
|
400
|
+
if (variableNode?.type === AST_NODE_TYPES.ObjectExpression) return VAR.findProperty(name, variableNode.properties, initialScope) != null;
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
case AST_NODE_TYPES.ObjectExpression: return VAR.findProperty(name, attr.argument.properties, initialScope) != null;
|
|
410
404
|
}
|
|
411
|
-
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
});
|
|
405
|
+
return false;
|
|
406
|
+
});
|
|
407
|
+
};
|
|
415
408
|
}
|
|
416
409
|
|
|
417
410
|
//#endregion
|
|
418
411
|
//#region src/jsx/jsx-attribute-value.ts
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
412
|
+
function resolveAttributeValue(context, attribute) {
|
|
413
|
+
const initialScope = context.sourceCode.getScope(attribute);
|
|
414
|
+
function handleJsxAttribute(node) {
|
|
415
|
+
if (node.value == null) return {
|
|
416
|
+
kind: "boolean",
|
|
417
|
+
toStatic() {
|
|
418
|
+
return true;
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
switch (node.value.type) {
|
|
422
|
+
case AST_NODE_TYPES.Literal: {
|
|
423
|
+
const staticValue = node.value.value;
|
|
424
|
+
return {
|
|
425
|
+
kind: "literal",
|
|
426
|
+
node: node.value,
|
|
427
|
+
toStatic() {
|
|
428
|
+
return staticValue;
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
case AST_NODE_TYPES.JSXExpressionContainer: {
|
|
433
|
+
const expr = node.value.expression;
|
|
434
|
+
return {
|
|
435
|
+
kind: "expression",
|
|
436
|
+
node: expr,
|
|
437
|
+
toStatic() {
|
|
438
|
+
return getStaticValue(expr, initialScope)?.value;
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
case AST_NODE_TYPES.JSXElement: return {
|
|
443
|
+
kind: "element",
|
|
432
444
|
node: node.value,
|
|
433
|
-
|
|
434
|
-
|
|
445
|
+
toStatic() {
|
|
446
|
+
return unit;
|
|
447
|
+
}
|
|
435
448
|
};
|
|
436
|
-
|
|
437
|
-
kind: "
|
|
449
|
+
case AST_NODE_TYPES.JSXSpreadChild: return {
|
|
450
|
+
kind: "spreadChild",
|
|
438
451
|
node: node.value.expression,
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
kind: "none",
|
|
443
|
-
node,
|
|
444
|
-
initialScope
|
|
452
|
+
toStatic() {
|
|
453
|
+
return unit;
|
|
454
|
+
}
|
|
445
455
|
};
|
|
446
|
-
case AST_NODE_TYPES.JSXSpreadAttribute: {
|
|
447
|
-
const staticValue = VAR.toStaticValue({
|
|
448
|
-
kind: "lazy",
|
|
449
|
-
node: node.argument,
|
|
450
|
-
initialScope
|
|
451
|
-
});
|
|
452
|
-
if (staticValue.kind === "none") return staticValue;
|
|
453
|
-
return match(staticValue.value).with({ [name]: P.select(P.any) }, (value) => ({
|
|
454
|
-
kind: "some",
|
|
455
|
-
node: node.argument,
|
|
456
|
-
initialScope,
|
|
457
|
-
value
|
|
458
|
-
})).otherwise(() => ({
|
|
459
|
-
kind: "none",
|
|
460
|
-
node,
|
|
461
|
-
initialScope
|
|
462
|
-
}));
|
|
463
456
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
457
|
+
}
|
|
458
|
+
function handleJsxSpreadAttribute(node) {
|
|
459
|
+
return {
|
|
460
|
+
kind: "spreadProps",
|
|
461
|
+
node: node.argument,
|
|
462
|
+
toStatic(name) {
|
|
463
|
+
if (name == null) return unit;
|
|
464
|
+
return match(getStaticValue(node.argument, initialScope)?.value).with({ [name]: P.select(P.any) }, identity).otherwise(() => unit);
|
|
465
|
+
}
|
|
468
466
|
};
|
|
469
467
|
}
|
|
468
|
+
switch (attribute.type) {
|
|
469
|
+
case AST_NODE_TYPES.JSXAttribute: return handleJsxAttribute(attribute);
|
|
470
|
+
case AST_NODE_TYPES.JSXSpreadAttribute: return handleJsxSpreadAttribute(attribute);
|
|
471
|
+
}
|
|
470
472
|
}
|
|
471
473
|
|
|
472
474
|
//#endregion
|
|
@@ -627,7 +629,7 @@ function isFragmentElement(context, node) {
|
|
|
627
629
|
* @returns boolean indicating whether the attribute exists
|
|
628
630
|
*/
|
|
629
631
|
function hasAttribute(context, name, attributes, initialScope) {
|
|
630
|
-
return getAttribute(context,
|
|
632
|
+
return getAttribute(context, attributes, initialScope)(name) != null;
|
|
631
633
|
}
|
|
632
634
|
/**
|
|
633
635
|
* Checks if a JSX element has at least one of the specified attributes
|
|
@@ -1237,4 +1239,4 @@ function getTypeVariants(types) {
|
|
|
1237
1239
|
}
|
|
1238
1240
|
|
|
1239
1241
|
//#endregion
|
|
1240
|
-
export { ComponentDetectionHint, ComponentFlag, ComponentPhaseRelevance, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, REACT_BUILTIN_HOOK_NAMES, findParentAttribute, getAttribute, getAttributeName,
|
|
1242
|
+
export { ComponentDetectionHint, ComponentFlag, ComponentPhaseRelevance, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, REACT_BUILTIN_HOOK_NAMES, findParentAttribute, getAttribute, getAttributeName, getComponentFlagFromInitPath, getComponentNameFromId, getElementType, getFunctionComponentId, getInstanceId, getTypeVariants, hasAnyAttribute, hasAttribute, hasEveryAttribute, hasNoneOrLooseComponentName, isAnyType, isAssignmentToThisState, isBigIntType, isBooleanType, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isEnumType, isFalseLiteralType, isFalsyBigIntType, isFalsyNumberType, isFalsyStringType, isForwardRef, isForwardRefCall, isFragmentElement, isFunctionOfRenderMethod, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHostElement, isInitializedFromReact, isInstanceIdEqual, isInversePhase, isJsxLike, isJsxText, isLazy, isLazyCall, isMemo, isMemoCall, isNeverType, isNullishType, isNumberType, isObjectType, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookId, isReactHookName, isRender, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isStringType, isThisSetState, isTrueLiteralType, isTruthyBigIntType, isTruthyNumberType, isTruthyStringType, isUnknownType, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, resolveAttributeValue, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.169",
|
|
4
4
|
"description": "ESLint React's ESLint utility module for static analysis of React core APIs and patterns.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"birecord": "^0.1.1",
|
|
35
35
|
"ts-api-utils": "^2.1.0",
|
|
36
36
|
"ts-pattern": "^5.8.0",
|
|
37
|
-
"@eslint-react/ast": "2.0.0-next.
|
|
38
|
-
"@eslint-react/
|
|
39
|
-
"@eslint-react/
|
|
40
|
-
"@eslint-react/
|
|
41
|
-
"@eslint-react/
|
|
37
|
+
"@eslint-react/ast": "2.0.0-next.169",
|
|
38
|
+
"@eslint-react/eff": "2.0.0-next.169",
|
|
39
|
+
"@eslint-react/kit": "2.0.0-next.169",
|
|
40
|
+
"@eslint-react/shared": "2.0.0-next.169",
|
|
41
|
+
"@eslint-react/var": "2.0.0-next.169"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"tsdown": "^0.14.2",
|