@trackunit/eslint-plugin-trackunit 0.4.66 → 0.5.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/CHANGELOG.md +25 -0
- package/README.md +2 -0
- package/package.json +1 -1
- package/src/lib/config/fragments/react-rules.js +15 -0
- package/src/lib/config/index.d.ts +60 -3
- package/src/lib/config/plugins.d.ts +14 -1
- package/src/lib/config/presets/base.d.ts +28 -2
- package/src/lib/config/presets/react.d.ts +32 -1
- package/src/lib/config/presets/react.js +9 -0
- package/src/lib/rules/component-name-matches-filename/component-name-matches-filename.d.ts +34 -0
- package/src/lib/rules/component-name-matches-filename/component-name-matches-filename.js +108 -0
- package/src/lib/rules/one-component-per-file/one-component-per-file.d.ts +29 -0
- package/src/lib/rules/one-component-per-file/one-component-per-file.js +73 -0
- package/src/lib/rules/require-component-prop-contracts/require-component-prop-contracts.d.ts +1 -2
- package/src/lib/rules/require-component-prop-contracts/require-component-prop-contracts.js +30 -27
- package/src/lib/rules-map.d.ts +14 -1
- package/src/lib/rules-map.js +4 -0
- package/src/lib/utils/ast-utils.d.ts +4 -0
- package/src/lib/utils/ast-utils.js +74 -21
- package/src/lib/utils/component-utils.d.ts +36 -0
- package/src/lib/utils/component-utils.js +192 -0
- package/src/index.js.map +0 -1
- package/src/lib/config/fragments/ignores.js.map +0 -1
- package/src/lib/config/fragments/import-rules.js.map +0 -1
- package/src/lib/config/fragments/jest-overrides.js.map +0 -1
- package/src/lib/config/fragments/jsdoc-rules.js.map +0 -1
- package/src/lib/config/fragments/module-boundaries.js.map +0 -1
- package/src/lib/config/fragments/react-rules.js.map +0 -1
- package/src/lib/config/fragments/restricted-imports.js.map +0 -1
- package/src/lib/config/fragments/testing-library.js.map +0 -1
- package/src/lib/config/fragments/typescript-rules.js.map +0 -1
- package/src/lib/config/index.js.map +0 -1
- package/src/lib/config/plugins.js.map +0 -1
- package/src/lib/config/presets/base.js.map +0 -1
- package/src/lib/config/presets/e2e.js.map +0 -1
- package/src/lib/config/presets/react.js.map +0 -1
- package/src/lib/config/presets/server.js.map +0 -1
- package/src/lib/config/utils.js.map +0 -1
- package/src/lib/config-helpers/create-skip-when.js.map +0 -1
- package/src/lib/rules/cva-merge-base-classes-as-array/cva-merge-base-classes-as-array.js.map +0 -1
- package/src/lib/rules/design-guideline-button-icon-size-match/design-guideline-button-icon-size-match.js.map +0 -1
- package/src/lib/rules/no-internal-barrel-files/no-internal-barrel-files.js.map +0 -1
- package/src/lib/rules/no-internal-graphql-when-tagged-with-gql-public/no-internal-graphql-when-tagged-with-gql-public.js.map +0 -1
- package/src/lib/rules/no-jest-mock-trackunit-react-core-hooks/no-jest-mock-trackunit-react-core-hooks.js.map +0 -1
- package/src/lib/rules/no-template-strings-in-classname-prop/no-template-strings-in-classname-prop.js.map +0 -1
- package/src/lib/rules/no-typescript-assertion/no-typescript-assertion.js.map +0 -1
- package/src/lib/rules/prefer-destructured-imports/prefer-destructured-imports.js.map +0 -1
- package/src/lib/rules/prefer-event-specific-callback-naming/name-suggestion-strategies.js.map +0 -1
- package/src/lib/rules/prefer-event-specific-callback-naming/prefer-event-specific-callback-naming.js.map +0 -1
- package/src/lib/rules/prefer-event-specific-callback-naming/strategies/string-based.js.map +0 -1
- package/src/lib/rules/prefer-event-specific-callback-naming/strategies/type-based.js.map +0 -1
- package/src/lib/rules/prefer-event-specific-callback-naming/utils.js.map +0 -1
- package/src/lib/rules/prefer-field-components/prefer-field-components.js.map +0 -1
- package/src/lib/rules/prefer-mouse-event-handler-in-react-props/prefer-mouse-event-handler-in-react-props.js.map +0 -1
- package/src/lib/rules/require-classname-alternatives/require-classname-alternatives.js.map +0 -1
- package/src/lib/rules/require-component-prop-contracts/require-component-prop-contracts.js.map +0 -1
- package/src/lib/rules/require-list-item-virtualization-props/require-list-item-virtualization-props.js.map +0 -1
- package/src/lib/rules/require-optional-prop-initialization/require-optional-prop-initialization.js.map +0 -1
- package/src/lib/rules/require-optional-prop-initialization/suggestion-utils.js.map +0 -1
- package/src/lib/rules-map.js.map +0 -1
- package/src/lib/utils/ast-utils.js.map +0 -1
- package/src/lib/utils/classname-utils.js.map +0 -1
- package/src/lib/utils/file-utils.js.map +0 -1
- package/src/lib/utils/import-utils.js.map +0 -1
- package/src/lib/utils/nx-utils.js.map +0 -1
- package/src/lib/utils/package-utils.js.map +0 -1
- package/src/lib/utils/typescript-utils.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-mouse-event-handler-in-react-props.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/prefer-mouse-event-handler-in-react-props/prefer-mouse-event-handler-in-react-props.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * ESLint rule: prefer-mouse-event-handler-in-react-props\n *\n * Enforces using MouseEventHandler<T> instead of () => void or (e: MouseEvent) => void\n * for onClick* props in React components. This ensures proper React typing and consistency.\n *\n * Only flags properties in actual React component props, not in hook options or other interfaces.\n *\n * Uses ESLint suggestions (not autofix) to let users choose the appropriate element type.\n */\n\nimport { AST_NODE_TYPES, ESLintUtils, TSESLint, TSESTree } from \"@typescript-eslint/utils\";\nimport * as ts from \"typescript\";\nimport { isReactComponent } from \"../../utils/ast-utils\";\n\ntype SuggestionResult = {\n messageId: \"suggestMouseEventHandler\";\n data: { elementType: string };\n fix: (fixer: TSESLint.RuleFixer) => TSESLint.RuleFix;\n};\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}/${name}.ts`\n);\n\ntype Options = [\n {\n /**\n * Prop names to exempt from this rule.\n *\n * @example [\"onClick\"]\n */\n allowedNames?: ReadonlyArray<string>;\n },\n];\n\ntype MessageIds = \"preferMouseEventHandler\" | \"suggestMouseEventHandler\";\n\n/**\n * Checks if a property name starts with \"onClick\" (case-sensitive).\n */\nconst isOnClickProp = (name: string): boolean => {\n return name.startsWith(\"onClick\");\n};\n\n/**\n * Extracts the element type from a MouseEvent generic type annotation.\n * Returns null if not a MouseEvent type or no generic provided.\n *\n * Examples:\n * - MouseEvent<HTMLButtonElement> -> \"HTMLButtonElement\"\n * - React.MouseEvent<HTMLDivElement> -> \"HTMLDivElement\"\n * - MouseEvent -> null (no generic)\n */\nconst extractElementTypeFromMouseEvent = (typeAnnotation: TSESTree.TypeNode): string | null => {\n if (typeAnnotation.type !== AST_NODE_TYPES.TSTypeReference) {\n return null;\n }\n\n const { typeName, typeArguments } = typeAnnotation;\n\n let isMouseEvent = false;\n\n if (typeName.type === AST_NODE_TYPES.Identifier) {\n isMouseEvent = typeName.name === \"MouseEvent\";\n } else if (typeName.type === AST_NODE_TYPES.TSQualifiedName) {\n isMouseEvent =\n typeName.left.type === AST_NODE_TYPES.Identifier &&\n typeName.left.name === \"React\" &&\n typeName.right.name === \"MouseEvent\";\n }\n\n if (!isMouseEvent) {\n return null;\n }\n\n if (!typeArguments || typeArguments.params.length === 0) {\n return null;\n }\n\n const firstTypeArg = typeArguments.params[0];\n if (firstTypeArg?.type === AST_NODE_TYPES.TSTypeReference) {\n if (firstTypeArg.typeName.type === AST_NODE_TYPES.Identifier) {\n return firstTypeArg.typeName.name;\n }\n }\n\n return null;\n};\n\n/**\n * Checks if a type annotation is a MouseEvent type (with or without generics).\n */\nconst isMouseEventType = (typeAnnotation: TSESTree.TypeNode): boolean => {\n if (typeAnnotation.type !== AST_NODE_TYPES.TSTypeReference) {\n return false;\n }\n\n const { typeName } = typeAnnotation;\n\n if (typeName.type === AST_NODE_TYPES.Identifier) {\n return typeName.name === \"MouseEvent\";\n }\n\n if (typeName.type === AST_NODE_TYPES.TSQualifiedName) {\n return (\n typeName.left.type === AST_NODE_TYPES.Identifier &&\n typeName.left.name === \"React\" &&\n typeName.right.name === \"MouseEvent\"\n );\n }\n\n return false;\n};\n\n/**\n * Checks if a function type returns void.\n */\nconst hasVoidReturn = (funcType: TSESTree.TSFunctionType): boolean => {\n const { returnType } = funcType;\n\n if (!returnType) {\n return true;\n }\n\n const typeAnnotation = returnType.typeAnnotation;\n\n if (typeAnnotation.type === AST_NODE_TYPES.TSVoidKeyword) {\n return true;\n }\n\n return false;\n};\n\ntype AnalysisResult =\n | { shouldFlag: false }\n | {\n shouldFlag: true;\n inferredElementType: string | null;\n typeAnnotationNode: TSESTree.TSFunctionType;\n };\n\n/**\n * Analyzes a TSFunctionType to determine if it should be flagged.\n */\nconst analyzeFunctionType = (funcType: TSESTree.TSFunctionType): AnalysisResult => {\n if (!hasVoidReturn(funcType)) {\n return { shouldFlag: false };\n }\n\n const { params } = funcType;\n\n // Case A: No parameters - () => void\n if (params.length === 0) {\n return {\n shouldFlag: true,\n inferredElementType: null,\n typeAnnotationNode: funcType,\n };\n }\n\n // Case B: Exactly one parameter that is MouseEvent\n if (params.length === 1) {\n const param = params[0];\n\n let paramTypeAnnotation: TSESTree.TypeNode | undefined;\n\n if (param?.type === AST_NODE_TYPES.Identifier && param.typeAnnotation) {\n paramTypeAnnotation = param.typeAnnotation.typeAnnotation;\n }\n\n if (paramTypeAnnotation && isMouseEventType(paramTypeAnnotation)) {\n const elementType = extractElementTypeFromMouseEvent(paramTypeAnnotation);\n return {\n shouldFlag: true,\n inferredElementType: elementType,\n typeAnnotationNode: funcType,\n };\n }\n }\n\n return { shouldFlag: false };\n};\n\n/**\n * Creates suggestion fixes for a given element type.\n */\nconst createSuggestion = (elementType: string, typeAnnotationNode: TSESTree.TSFunctionType): SuggestionResult => {\n return {\n messageId: \"suggestMouseEventHandler\",\n data: { elementType },\n fix: fixer => {\n return fixer.replaceText(typeAnnotationNode, `MouseEventHandler<${elementType}>`);\n },\n };\n};\n\n/**\n * Known valid HTML element types for MouseEventHandler.\n */\nconst VALID_HTML_ELEMENT_TYPES = new Set([\n \"Element\",\n \"HTMLElement\",\n \"HTMLAnchorElement\",\n \"HTMLButtonElement\",\n \"HTMLDivElement\",\n \"HTMLFormElement\",\n \"HTMLImageElement\",\n \"HTMLInputElement\",\n \"HTMLLabelElement\",\n \"HTMLLIElement\",\n \"HTMLParagraphElement\",\n \"HTMLSelectElement\",\n \"HTMLSpanElement\",\n \"HTMLTableElement\",\n \"HTMLTableRowElement\",\n \"HTMLTableCellElement\",\n \"HTMLTextAreaElement\",\n \"HTMLUListElement\",\n \"SVGElement\",\n \"SVGSVGElement\",\n]);\n\n/**\n * Extracts element type from a MouseEventHandler type string.\n */\nconst extractElementTypeFromTypeString = (typeString: string): string | null => {\n const match = typeString.match(/MouseEventHandler<([^>]+)>/);\n if (match?.[1]) {\n const elementType = match[1].trim();\n if (VALID_HTML_ELEMENT_TYPES.has(elementType)) {\n return elementType;\n }\n }\n return null;\n};\n\n/**\n * Tries to infer the element type by finding where the prop is used in JSX.\n */\nconst inferElementTypeFromUsage = (\n propName: string,\n context: TSESLint.RuleContext<MessageIds, ReadonlyArray<unknown>>\n): string | null => {\n try {\n const services = ESLintUtils.getParserServices(context);\n const checker = services.program.getTypeChecker();\n const sourceFile = services.program.getSourceFile(context.filename);\n\n if (!sourceFile) {\n return null;\n }\n\n let inferredType: string | null = null;\n\n const visit = (node: ts.Node): void => {\n if (ts.isJsxAttribute(node)) {\n const attrName = node.name.getText(sourceFile);\n\n if (attrName.startsWith(\"on\")) {\n const initializer = node.initializer;\n\n if (initializer && ts.isJsxExpression(initializer) && initializer.expression) {\n const expr = initializer.expression;\n let referencedName: string | null = null;\n\n if (ts.isIdentifier(expr) && expr.text === propName) {\n referencedName = propName;\n }\n\n if (ts.isArrowFunction(expr) && ts.isCallExpression(expr.body)) {\n const callee = expr.body.expression;\n if (ts.isIdentifier(callee) && callee.text === propName) {\n referencedName = propName;\n }\n }\n\n if (referencedName) {\n const contextualType = checker.getContextualType(expr);\n if (contextualType) {\n const typeString = checker.typeToString(contextualType);\n const elementType = extractElementTypeFromTypeString(typeString);\n if (elementType) {\n inferredType = elementType;\n }\n }\n }\n }\n }\n }\n\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return inferredType;\n } catch {\n return null;\n }\n};\n\n/**\n * Gets onClick* properties from a component's props type annotation.\n */\nconst getOnClickPropsFromType = (\n context: TSESLint.RuleContext<MessageIds, ReadonlyArray<unknown>>,\n typeAnnotation: TSESTree.TypeNode | undefined\n): Array<{ name: string; typeNode: TSESTree.TSFunctionType; propertyNode: TSESTree.Node }> => {\n if (!typeAnnotation) {\n return [];\n }\n\n const result: Array<{ name: string; typeNode: TSESTree.TSFunctionType; propertyNode: TSESTree.Node }> = [];\n\n // Handle inline type literals: ({ onClick }: { onClick: () => void }) => ...\n if (typeAnnotation.type === AST_NODE_TYPES.TSTypeLiteral) {\n for (const member of typeAnnotation.members) {\n if (\n member.type === AST_NODE_TYPES.TSPropertySignature &&\n member.key.type === AST_NODE_TYPES.Identifier &&\n isOnClickProp(member.key.name) &&\n member.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES.TSFunctionType\n ) {\n result.push({\n name: member.key.name,\n typeNode: member.typeAnnotation.typeAnnotation,\n propertyNode: member,\n });\n }\n }\n return result;\n }\n\n // Handle type references: ({ onClick }: ButtonProps) => ...\n if (typeAnnotation.type === AST_NODE_TYPES.TSTypeReference) {\n try {\n const services = ESLintUtils.getParserServices(context);\n const checker = services.program.getTypeChecker();\n const tsNode = services.esTreeNodeToTSNodeMap.get(typeAnnotation);\n const type = checker.getTypeAtLocation(tsNode);\n\n for (const prop of type.getProperties()) {\n if (isOnClickProp(prop.name)) {\n const propType = checker.getTypeOfSymbolAtLocation(prop, tsNode);\n const callSignatures = propType.getCallSignatures();\n\n if (callSignatures.length > 0) {\n // Find the corresponding ESTree node for this property\n const declarations = prop.getDeclarations();\n const decl = declarations?.[0];\n if (decl) {\n const esTreeNode = services.tsNodeToESTreeNodeMap.get(decl);\n if (\n esTreeNode.type === AST_NODE_TYPES.TSPropertySignature &&\n esTreeNode.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES.TSFunctionType\n ) {\n result.push({\n name: prop.name,\n typeNode: esTreeNode.typeAnnotation.typeAnnotation,\n propertyNode: esTreeNode,\n });\n }\n }\n }\n }\n }\n } catch {\n // Type checking failed - silently skip\n }\n }\n\n return result;\n};\n\nexport const preferMouseEventHandlerInReactProps = createRule<Options, MessageIds>({\n name: \"prefer-mouse-event-handler-in-react-props\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Enforce using MouseEventHandler<T> instead of () => void or (e: MouseEvent) => void for onClick* props in React components. \" +\n \"This ensures proper React typing and consistency across the codebase.\",\n },\n hasSuggestions: true,\n schema: [\n {\n type: \"object\",\n properties: {\n allowedNames: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Prop names to exempt from this rule\",\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n preferMouseEventHandler: \"Prop '{{propName}}' should use MouseEventHandler<T> instead of {{currentType}}.\",\n suggestMouseEventHandler: \"Use MouseEventHandler<{{elementType}}>\",\n },\n },\n defaultOptions: [\n {\n allowedNames: [],\n },\n ],\n create(context, [options]) {\n const allowedNames = options.allowedNames ?? [];\n\n // Only run on .tsx files\n const filename = context.filename;\n if (!filename.endsWith(\".tsx\")) {\n return {};\n }\n\n // Track reported property nodes to avoid duplicate reports when multiple components use the same interface\n const reportedNodes = new Set<TSESTree.Node>();\n\n const checkComponentProps = (\n _node: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression,\n propsParam: TSESTree.Parameter | undefined\n ) => {\n if (!propsParam) {\n return;\n }\n\n let typeAnnotation: TSESTree.TypeNode | undefined;\n\n // Handle both regular parameters (props: Props) and destructured parameters ({prop1, prop2}: Props)\n if (propsParam.type === AST_NODE_TYPES.Identifier || propsParam.type === AST_NODE_TYPES.ObjectPattern) {\n typeAnnotation = propsParam.typeAnnotation?.typeAnnotation;\n } else {\n return;\n }\n\n const onClickProps = getOnClickPropsFromType(context, typeAnnotation);\n\n for (const { name: propName, typeNode, propertyNode } of onClickProps) {\n // Skip if already reported (prevents duplicates when multiple components use the same interface)\n if (reportedNodes.has(propertyNode)) {\n continue;\n }\n\n // Check if it's in the allowed list\n if (allowedNames.includes(propName)) {\n continue;\n }\n\n // Analyze the function type\n const result = analyzeFunctionType(typeNode);\n\n if (!result.shouldFlag) {\n continue;\n }\n\n // Get the current type as a string for the error message\n const sourceCode = context.sourceCode;\n const currentType = sourceCode.getText(typeNode);\n\n // Build suggestions\n const suggestions: Array<SuggestionResult> = [];\n\n let inferredElementType = result.inferredElementType;\n\n if (!inferredElementType) {\n inferredElementType = inferElementTypeFromUsage(propName, context);\n }\n\n if (inferredElementType) {\n suggestions.push(createSuggestion(inferredElementType, result.typeAnnotationNode));\n } else {\n suggestions.push(createSuggestion(\"HTMLButtonElement\", result.typeAnnotationNode));\n suggestions.push(createSuggestion(\"HTMLElement\", result.typeAnnotationNode));\n suggestions.push(createSuggestion(\"HTMLDivElement\", result.typeAnnotationNode));\n }\n\n // Mark as reported to prevent duplicates\n reportedNodes.add(propertyNode);\n\n context.report({\n node: propertyNode,\n messageId: \"preferMouseEventHandler\",\n data: {\n propName,\n currentType,\n },\n suggest: suggestions,\n });\n }\n };\n\n return {\n FunctionDeclaration(node: TSESTree.FunctionDeclaration) {\n if (isReactComponent(node)) {\n checkComponentProps(node, node.params[0]);\n }\n },\n\n ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression) {\n if (isReactComponent(node)) {\n checkComponentProps(node, node.params[0]);\n }\n },\n };\n },\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"require-classname-alternatives.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/require-classname-alternatives/require-classname-alternatives.ts"],"names":[],"mappings":"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","sourcesContent":["import { AST_NODE_TYPES, ESLintUtils, TSESTree } from \"@typescript-eslint/utils\";\nimport { findClassnameStringsInAttribute, findClassnameStringsInCall } from \"../../utils/classname-utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}.ts`\n);\n\ntype MessageIds = \"bannedClassAutoFix\" | \"bannedClassSuggest\" | \"suggestReplacement\";\n\ntype RuleConfig = {\n /** Map of banned class name patterns to their allowed alternatives */\n alternatives: Record<string, Array<string>>;\n /** Optional prefixes to match (e.g., \"bg\", \"text\", \"border\"). If not provided, matches exact class names. */\n prefixes?: Array<string>;\n};\n\ntype Options = [RuleConfig?];\n\n/**\n * Replace a specific pattern in a string with its replacement.\n * Handles both prefix-based patterns (e.g., bg-red-500 -> bg-danger-500)\n * and exact matches.\n */\nfunction replacePattern(value: string, oldPattern: string, newPattern: string, hasPrefixes: boolean): string {\n if (hasPrefixes) {\n // With prefixes, replace -oldPattern- with -newPattern-\n const pattern = new RegExp(`-${oldPattern}(-|$|/)`, \"g\");\n return value.replace(pattern, `-${newPattern}$1`);\n } else {\n // Without prefixes, replace exact word boundaries\n const pattern = new RegExp(`(^|\\\\s)${oldPattern}($|\\\\s)`, \"g\");\n return value.replace(pattern, `$1${newPattern}$2`);\n }\n}\n\n/**\n * Build a regex pattern that matches class names based on configuration.\n *\n * With prefixes: Matches patterns like bg-red-500, text-blue-200, hover:border-green-400\n * Without prefixes: Matches exact class names as standalone words\n */\nfunction buildBannedPattern(bannedPatterns: Array<string>, prefixes?: Array<string>): RegExp {\n const patternList = bannedPatterns.join(\"|\");\n const variantPrefixes =\n \"(?:hover:|focus:|focus-visible:|focus-within:|active:|disabled:|group-hover:|peer-hover:|dark:|light:|sm:|md:|lg:|xl:|2xl:)*\";\n\n if (prefixes && prefixes.length > 0) {\n const prefixPattern = prefixes.join(\"|\");\n // Match: [variant:]prefix-banned[-suffix][/opacity]\n return new RegExp(\n `(?:^|\\\\s)(${variantPrefixes}(?:${prefixPattern})-(${patternList})(?:-[a-zA-Z0-9]+)?(?:\\\\/\\\\d+)?)(?=\\\\s|$|\")`,\n \"g\"\n );\n } else {\n // Exact match: standalone class name\n return new RegExp(`(?:^|\\\\s)(${variantPrefixes}(${patternList}))(?=\\\\s|$|\")`, \"g\");\n }\n}\n\nexport const requireClassnameAlternatives = createRule<Options, MessageIds>({\n name: \"require-classname-alternatives\",\n meta: {\n type: \"problem\",\n fixable: \"code\",\n hasSuggestions: true,\n docs: {\n description: \"Require specific class names to be replaced with alternatives. Configurable via rule options.\",\n },\n messages: {\n bannedClassAutoFix: '\"{{match}}\" is not allowed. Use \"{{alternative}}\" instead.',\n bannedClassSuggest: '\"{{match}}\" is not allowed. Consider using: {{alternatives}}.',\n suggestReplacement: 'Replace with \"{{replacement}}\"',\n },\n schema: [\n {\n type: \"object\",\n properties: {\n alternatives: {\n type: \"object\",\n description: \"Map of banned patterns to their allowed alternatives (array of strings)\",\n additionalProperties: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n prefixes: {\n type: \"array\",\n description: \"Prefixes to match (e.g., 'bg', 'text'). If not provided, matches exact class names.\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [],\n create(context) {\n const options = context.options[0];\n\n // Return early if no options or empty alternatives to save compute\n if (!options || Object.keys(options.alternatives).length === 0) {\n return {};\n }\n\n const { alternatives, prefixes } = options;\n const bannedPatterns = Object.keys(alternatives);\n const hasPrefixes = prefixes !== undefined && prefixes.length > 0;\n\n const isBannedPattern = (pattern: string): boolean => pattern in alternatives;\n\n const getAlternatives = (pattern: string): Array<string> => {\n return alternatives[pattern] ?? [];\n };\n\n const isAutoFixable = (pattern: string): boolean => getAlternatives(pattern).length === 1;\n\n const BANNED_PATTERN = buildBannedPattern(bannedPatterns, prefixes);\n\n /**\n * Find all banned pattern usages in a string value\n */\n function findBannedUsages(value: string): Array<{ match: string; pattern: string }> {\n const results: Array<{ match: string; pattern: string }> = [];\n BANNED_PATTERN.lastIndex = 0;\n\n let regexMatch;\n while ((regexMatch = BANNED_PATTERN.exec(value)) !== null) {\n const matchedClass = regexMatch[1];\n const matchedPattern = regexMatch[2];\n if (matchedClass !== undefined && matchedPattern !== undefined && isBannedPattern(matchedPattern)) {\n results.push({\n match: matchedClass.trim(),\n pattern: matchedPattern,\n });\n }\n }\n\n return results;\n }\n\n /**\n * Replace ALL auto-fixable patterns in a string at once\n */\n function replaceAllAutoFixablePatterns(value: string): string {\n let result = value;\n for (const [pattern, alts] of Object.entries(alternatives)) {\n const singleAlternative = alts.length === 1 ? alts[0] : undefined;\n if (singleAlternative) {\n result = replacePattern(result, pattern, singleAlternative, hasPrefixes);\n }\n }\n return result;\n }\n\n // Track which string literals have already had a fix generated\n // to avoid duplicate/conflicting fixes for the same literal\n const fixedLiterals = new WeakSet<TSESTree.Literal | TSESTree.TemplateLiteral>();\n\n /**\n * Create a fixer function that replaces all auto-fixable patterns in a string literal\n */\n function createFixer(stringLiteralNode: TSESTree.Literal | TSESTree.TemplateLiteral) {\n return (fixer: Parameters<NonNullable<Parameters<typeof context.report>[0][\"fix\"]>>[0]) => {\n switch (stringLiteralNode.type) {\n case AST_NODE_TYPES.Literal: {\n const originalValue = stringLiteralNode.value;\n if (typeof originalValue !== \"string\") {\n return null;\n }\n const fixedValue = replaceAllAutoFixablePatterns(originalValue);\n const raw = stringLiteralNode.raw;\n const quote = raw.charAt(0);\n return fixer.replaceText(stringLiteralNode, `${quote}${fixedValue}${quote}`);\n }\n case AST_NODE_TYPES.TemplateLiteral: {\n const fixes: Array<ReturnType<typeof fixer.replaceTextRange>> = [];\n const autoFixablePatterns = Object.entries(alternatives)\n .filter(([, alts]) => alts.length === 1)\n .map(([pattern]) => pattern);\n\n for (const quasi of stringLiteralNode.quasis) {\n const hasFixablePattern = autoFixablePatterns.some(pattern =>\n hasPrefixes ? quasi.value.raw.includes(`-${pattern}`) : quasi.value.raw.includes(pattern)\n );\n if (hasFixablePattern) {\n const fixedRaw = replaceAllAutoFixablePatterns(quasi.value.raw);\n const rangeStart = quasi.range[0] + (quasi.tail ? 1 : 0);\n const rangeEnd = quasi.range[1] - (quasi.tail ? 1 : 0);\n fixes.push(\n fixer.replaceTextRange(\n [rangeStart, rangeEnd],\n quasi.tail ? fixedRaw : fixedRaw + (quasi.value.raw.endsWith(\" \") ? \"\" : \"\")\n )\n );\n }\n }\n return fixes.length > 0 ? fixes : null;\n }\n default:\n return null;\n }\n };\n }\n\n /**\n * Create a suggestion fixer for a specific pattern replacement\n */\n function createSuggestionFixer(\n stringLiteralNode: TSESTree.Literal | TSESTree.TemplateLiteral,\n oldPattern: string,\n newPattern: string\n ) {\n return (fixer: Parameters<NonNullable<Parameters<typeof context.report>[0][\"fix\"]>>[0]) => {\n switch (stringLiteralNode.type) {\n case AST_NODE_TYPES.Literal: {\n const originalValue = stringLiteralNode.value;\n if (typeof originalValue !== \"string\") {\n return null;\n }\n const fixedValue = replacePattern(originalValue, oldPattern, newPattern, hasPrefixes);\n const raw = stringLiteralNode.raw;\n const quote = raw.charAt(0);\n return fixer.replaceText(stringLiteralNode, `${quote}${fixedValue}${quote}`);\n }\n case AST_NODE_TYPES.TemplateLiteral: {\n const fixes: Array<ReturnType<typeof fixer.replaceTextRange>> = [];\n for (const quasi of stringLiteralNode.quasis) {\n const containsPattern = hasPrefixes\n ? quasi.value.raw.includes(`-${oldPattern}`)\n : quasi.value.raw.includes(oldPattern);\n if (containsPattern) {\n const fixedRaw = replacePattern(quasi.value.raw, oldPattern, newPattern, hasPrefixes);\n const rangeStart = quasi.range[0] + (quasi.tail ? 1 : 0);\n const rangeEnd = quasi.range[1] - (quasi.tail ? 1 : 0);\n fixes.push(\n fixer.replaceTextRange(\n [rangeStart, rangeEnd],\n quasi.tail ? fixedRaw : fixedRaw + (quasi.value.raw.endsWith(\" \") ? \"\" : \"\")\n )\n );\n }\n }\n return fixes.length > 0 ? fixes : null;\n }\n default:\n return null;\n }\n };\n }\n\n /**\n * Report banned pattern usages for a given node and value.\n * - Auto-fixable patterns (1 alternative): applies fix automatically\n * - Multi-alternative patterns: shows suggestions in editor quick-fix menu\n */\n function checkAndReport(\n node: TSESTree.Node,\n value: string,\n stringLiteralNode?: TSESTree.Literal | TSESTree.TemplateLiteral\n ): void {\n const usages = findBannedUsages(value);\n let fixProvided = false;\n\n for (const usage of usages) {\n const patternIsAutoFixable = isAutoFixable(usage.pattern);\n const patternAlternatives = getAlternatives(usage.pattern);\n\n let fix: Parameters<typeof context.report>[0][\"fix\"];\n let suggest: Parameters<typeof context.report>[0][\"suggest\"];\n\n if (stringLiteralNode) {\n if (patternIsAutoFixable && !fixProvided && !fixedLiterals.has(stringLiteralNode)) {\n fixedLiterals.add(stringLiteralNode);\n fixProvided = true;\n fix = createFixer(stringLiteralNode);\n }\n\n if (!patternIsAutoFixable) {\n suggest = patternAlternatives.map(alternative => ({\n messageId: \"suggestReplacement\" as const,\n data: { replacement: replacePattern(usage.match, usage.pattern, alternative, hasPrefixes) },\n fix: createSuggestionFixer(stringLiteralNode, usage.pattern, alternative),\n }));\n }\n }\n\n if (patternIsAutoFixable) {\n const singleAlternative = patternAlternatives[0];\n context.report({\n node,\n messageId: \"bannedClassAutoFix\",\n data: {\n match: usage.match,\n alternative: singleAlternative ?? \"\",\n },\n fix,\n });\n } else {\n context.report({\n node,\n messageId: \"bannedClassSuggest\",\n data: {\n match: usage.match,\n alternatives: patternAlternatives.join(\", \"),\n },\n suggest,\n });\n }\n }\n }\n\n return {\n JSXAttribute(node: TSESTree.JSXAttribute) {\n const locations = findClassnameStringsInAttribute(node);\n for (const location of locations) {\n checkAndReport(location.reportNode, location.value, location.fixNode);\n }\n },\n\n CallExpression(node: TSESTree.CallExpression) {\n const locations = findClassnameStringsInCall(node);\n for (const location of locations) {\n checkAndReport(location.reportNode, location.value, location.fixNode);\n }\n },\n };\n },\n});\n"]}
|
package/src/lib/rules/require-component-prop-contracts/require-component-prop-contracts.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"require-component-prop-contracts.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/require-component-prop-contracts/require-component-prop-contracts.ts"],"names":[],"mappings":"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","sourcesContent":["import { AST_NODE_TYPES, ESLintUtils, TSESLint, TSESTree } from \"@typescript-eslint/utils\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as ts from \"typescript\";\nimport { isReactComponent } from \"../../utils/ast-utils\";\nimport { getProjectMetadata, type MatchCriteria, projectMatchesCriteria } from \"../../utils/nx-utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}/${name}.ts`\n);\n\ntype Options = [\n {\n requiredProps?: ReadonlyArray<string>;\n requiredInterfaces?: ReadonlyArray<string>;\n onlyWhenProjectMatches?: MatchCriteria;\n },\n];\n\ntype MessageIds = \"missingPropContracts\";\n\ntype ComponentCandidate = {\n componentName: string;\n node: TSESTree.Node;\n propsType: TSESTree.TypeNode | null;\n};\n\ntype TypeDeclarationMaps = {\n interfaces: Map<string, TSESTree.TSInterfaceDeclaration>;\n typeAliases: Map<string, TSESTree.TSTypeAliasDeclaration>;\n};\n\ntype TypeCheckerContext = {\n checker: ts.TypeChecker;\n services: ReturnType<typeof ESLintUtils.getParserServices>;\n};\n\nconst componentWrapperNames = new Set([\"forwardRef\", \"memo\"]);\n\nconst publicEntrypointFileNames = [\"index.ts\", \"index.tsx\"];\n\ntype TypeSymbolInfo = {\n symbolName: string | undefined;\n declarations: Array<ts.Declaration>;\n};\n\nconst getTypeSymbolInfo = (type: ts.Type): TypeSymbolInfo => {\n try {\n return {\n symbolName: type.symbol.getName(),\n declarations: type.symbol.getDeclarations() ?? [],\n };\n } catch {\n return {\n symbolName: undefined,\n declarations: [],\n };\n }\n};\n\nconst getTypeReferenceName = (typeName: TSESTree.EntityName): string | null => {\n if (typeName.type === AST_NODE_TYPES.Identifier) {\n return typeName.name;\n }\n\n if (typeName.type === AST_NODE_TYPES.TSQualifiedName) {\n return typeName.right.name;\n }\n\n return null;\n};\n\nconst getCallExpressionName = (node: TSESTree.CallExpression): string | null => {\n const { callee } = node;\n\n if (callee.type === AST_NODE_TYPES.Identifier) {\n return callee.name;\n }\n\n if (callee.type === AST_NODE_TYPES.MemberExpression && callee.property.type === AST_NODE_TYPES.Identifier) {\n return callee.property.name;\n }\n\n return null;\n};\n\nconst isPascalCaseName = (name: string): boolean => /^[A-Z]/.test(name);\n\nconst normalizeFilePath = (filePath: string): string => path.normalize(filePath);\n\nconst getProjectRoot = (projectJsonPath: string): string => path.dirname(projectJsonPath);\n\nconst getPublicEntrypointPaths = (projectRoot: string): Array<string> =>\n publicEntrypointFileNames.map(fileName => path.join(projectRoot, \"src\", fileName));\n\nconst getModulePathCandidates = (fromFilePath: string, moduleSpecifier: string): Array<string> => {\n const modulePath = path.resolve(path.dirname(fromFilePath), moduleSpecifier);\n\n return [\n modulePath,\n `${modulePath}.ts`,\n `${modulePath}.tsx`,\n path.join(modulePath, \"index.ts\"),\n path.join(modulePath, \"index.tsx\"),\n ];\n};\n\nconst moduleSpecifierTargetsFile = (fromFilePath: string, moduleSpecifier: string, targetFilePath: string): boolean => {\n if (!moduleSpecifier.startsWith(\".\")) {\n return false;\n }\n\n const normalizedTargetFilePath = normalizeFilePath(targetFilePath);\n return getModulePathCandidates(fromFilePath, moduleSpecifier).some(\n candidatePath => normalizeFilePath(candidatePath) === normalizedTargetFilePath\n );\n};\n\nconst getSourceExportName = (specifier: ts.ExportSpecifier): string => {\n if (specifier.propertyName?.text === \"default\") {\n return specifier.name.text;\n }\n\n return specifier.propertyName?.text ?? specifier.name.text;\n};\n\nconst getPublicExportedNamesForFile = (\n projectRoot: string,\n filePath: string\n): { exportsAll: boolean; names: Set<string> } => {\n const result = {\n exportsAll: false,\n names: new Set<string>(),\n };\n\n for (const entrypointPath of getPublicEntrypointPaths(projectRoot)) {\n let sourceText: string;\n try {\n sourceText = fs.readFileSync(entrypointPath, \"utf8\");\n } catch {\n continue;\n }\n\n const sourceFile = ts.createSourceFile(entrypointPath, sourceText, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);\n\n for (const statement of sourceFile.statements) {\n if (!ts.isExportDeclaration(statement) || !statement.moduleSpecifier) {\n continue;\n }\n\n if (!ts.isStringLiteral(statement.moduleSpecifier)) {\n continue;\n }\n\n if (!moduleSpecifierTargetsFile(entrypointPath, statement.moduleSpecifier.text, filePath)) {\n continue;\n }\n\n if (!statement.exportClause) {\n result.exportsAll = true;\n continue;\n }\n\n if (ts.isNamedExports(statement.exportClause)) {\n statement.exportClause.elements.forEach(specifier => {\n result.names.add(getSourceExportName(specifier));\n });\n }\n }\n }\n\n return result;\n};\n\nconst isEntrypointFile = (projectRoot: string, filePath: string): boolean => {\n const normalizedFilePath = normalizeFilePath(filePath);\n return getPublicEntrypointPaths(projectRoot).some(\n entrypointPath => normalizeFilePath(entrypointPath) === normalizedFilePath\n );\n};\n\nconst isComponentWrapperCallExpression = (node: TSESTree.CallExpression): boolean => {\n const firstArgument = node.arguments[0];\n const callExpressionName = getCallExpressionName(node);\n\n if (!callExpressionName || !componentWrapperNames.has(callExpressionName)) {\n return false;\n }\n\n return (\n firstArgument?.type === AST_NODE_TYPES.ArrowFunctionExpression ||\n firstArgument?.type === AST_NODE_TYPES.FunctionExpression\n );\n};\n\nconst getHeritageName = (heritage: TSESTree.TSInterfaceHeritage): string | null => {\n const { expression } = heritage;\n\n if (expression.type === AST_NODE_TYPES.Identifier) {\n return expression.name;\n }\n\n if (expression.type === AST_NODE_TYPES.MemberExpression && expression.property.type === AST_NODE_TYPES.Identifier) {\n return expression.property.name;\n }\n\n return null;\n};\n\nconst getParameterTypeAnnotation = (parameter: TSESTree.Parameter | undefined): TSESTree.TypeNode | null => {\n if (!parameter) {\n return null;\n }\n\n if (parameter.type === AST_NODE_TYPES.Identifier || parameter.type === AST_NODE_TYPES.ObjectPattern) {\n return parameter.typeAnnotation?.typeAnnotation ?? null;\n }\n\n if (parameter.type === AST_NODE_TYPES.AssignmentPattern) {\n const { left } = parameter;\n if (left.type === AST_NODE_TYPES.Identifier || left.type === AST_NODE_TYPES.ObjectPattern) {\n return left.typeAnnotation?.typeAnnotation ?? null;\n }\n }\n\n return null;\n};\n\nconst getFunctionPropsType = (\n node: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression\n): TSESTree.TypeNode | null => getParameterTypeAnnotation(node.params[0]);\n\nconst getPropsTypeFromCallExpression = (node: TSESTree.CallExpression): TSESTree.TypeNode | null => {\n const typeArguments = node.typeArguments?.params ?? [];\n const firstArgument = node.arguments[0];\n\n if (\n firstArgument?.type === AST_NODE_TYPES.ArrowFunctionExpression ||\n firstArgument?.type === AST_NODE_TYPES.FunctionExpression\n ) {\n const parameterType = getParameterTypeAnnotation(firstArgument.params[0]);\n if (parameterType) {\n return parameterType;\n }\n }\n\n if (getCallExpressionName(node) === \"forwardRef\") {\n return typeArguments[1] ?? null;\n }\n\n return typeArguments[0] ?? null;\n};\n\nconst getPropsTypeFromVariableDeclarator = (node: TSESTree.VariableDeclarator): TSESTree.TypeNode | null => {\n const { init } = node;\n\n if (!init) {\n return null;\n }\n\n if (init.type === AST_NODE_TYPES.ArrowFunctionExpression) {\n return getFunctionPropsType(init);\n }\n\n if (init.type === AST_NODE_TYPES.CallExpression) {\n return getPropsTypeFromCallExpression(init);\n }\n\n return null;\n};\n\nconst isExportedDeclaration = (node: TSESTree.Node): boolean => {\n const parent = node.parent;\n if (!parent) {\n return false;\n }\n\n if (\n parent.type === AST_NODE_TYPES.ExportNamedDeclaration ||\n parent.type === AST_NODE_TYPES.ExportDefaultDeclaration\n ) {\n return true;\n }\n\n const grandParent = parent.parent;\n return grandParent?.type === AST_NODE_TYPES.ExportNamedDeclaration;\n};\n\nconst typeHasRequiredInterface = (\n typeNode: TSESTree.TypeNode,\n requiredInterface: string,\n declarations: TypeDeclarationMaps,\n visitedTypeNames = new Set<string>()\n): boolean => {\n switch (typeNode.type) {\n case AST_NODE_TYPES.TSTypeReference: {\n const referenceName = getTypeReferenceName(typeNode.typeName);\n if (!referenceName) {\n return false;\n }\n\n if (referenceName === requiredInterface) {\n return true;\n }\n\n if (visitedTypeNames.has(referenceName)) {\n return false;\n }\n\n visitedTypeNames.add(referenceName);\n\n const interfaceDeclaration = declarations.interfaces.get(referenceName);\n if (interfaceDeclaration) {\n return interfaceExtendsRequiredInterface(\n interfaceDeclaration,\n requiredInterface,\n declarations,\n visitedTypeNames\n );\n }\n\n const typeAlias = declarations.typeAliases.get(referenceName);\n if (typeAlias) {\n return typeHasRequiredInterface(typeAlias.typeAnnotation, requiredInterface, declarations, visitedTypeNames);\n }\n\n return false;\n }\n\n case AST_NODE_TYPES.TSIntersectionType:\n return typeNode.types.some(part =>\n typeHasRequiredInterface(part, requiredInterface, declarations, new Set(visitedTypeNames))\n );\n\n case AST_NODE_TYPES.TSUnionType:\n return typeNode.types.every(part =>\n typeHasRequiredInterface(part, requiredInterface, declarations, new Set(visitedTypeNames))\n );\n\n default:\n return false;\n }\n};\n\nconst interfaceExtendsRequiredInterface = (\n declaration: TSESTree.TSInterfaceDeclaration,\n requiredInterface: string,\n declarations: TypeDeclarationMaps,\n visitedTypeNames: Set<string>\n): boolean => {\n return declaration.extends.some(heritage => {\n const heritageName = getHeritageName(heritage);\n if (!heritageName) {\n return false;\n }\n\n if (heritageName === requiredInterface) {\n return true;\n }\n\n if (visitedTypeNames.has(heritageName)) {\n return false;\n }\n\n visitedTypeNames.add(heritageName);\n\n const interfaceDeclaration = declarations.interfaces.get(heritageName);\n if (interfaceDeclaration) {\n return interfaceExtendsRequiredInterface(interfaceDeclaration, requiredInterface, declarations, visitedTypeNames);\n }\n\n const typeAlias = declarations.typeAliases.get(heritageName);\n if (typeAlias) {\n return typeHasRequiredInterface(typeAlias.typeAnnotation, requiredInterface, declarations, visitedTypeNames);\n }\n\n return false;\n });\n};\n\nconst interfaceHasRequiredProp = (\n declaration: TSESTree.TSInterfaceDeclaration,\n requiredProp: string,\n declarations: TypeDeclarationMaps,\n visitedTypeNames: Set<string>\n): boolean => {\n const hasOwnProp = declaration.body.body.some(member => {\n if (member.type !== AST_NODE_TYPES.TSPropertySignature) {\n return false;\n }\n\n return member.key.type === AST_NODE_TYPES.Identifier && member.key.name === requiredProp;\n });\n\n if (hasOwnProp) {\n return true;\n }\n\n return declaration.extends.some(heritage => {\n const heritageName = getHeritageName(heritage);\n if (!heritageName || visitedTypeNames.has(heritageName)) {\n return false;\n }\n\n visitedTypeNames.add(heritageName);\n\n const interfaceDeclaration = declarations.interfaces.get(heritageName);\n if (interfaceDeclaration) {\n return interfaceHasRequiredProp(interfaceDeclaration, requiredProp, declarations, visitedTypeNames);\n }\n\n const typeAlias = declarations.typeAliases.get(heritageName);\n if (typeAlias) {\n return typeHasRequiredProp(typeAlias.typeAnnotation, requiredProp, declarations, visitedTypeNames);\n }\n\n return false;\n });\n};\n\nconst typeLiteralHasRequiredProp = (typeNode: TSESTree.TSTypeLiteral, requiredProp: string): boolean => {\n return typeNode.members.some(member => {\n if (member.type !== AST_NODE_TYPES.TSPropertySignature) {\n return false;\n }\n\n return member.key.type === AST_NODE_TYPES.Identifier && member.key.name === requiredProp;\n });\n};\n\nconst typeHasRequiredProp = (\n typeNode: TSESTree.TypeNode,\n requiredProp: string,\n declarations: TypeDeclarationMaps,\n visitedTypeNames = new Set<string>()\n): boolean => {\n switch (typeNode.type) {\n case AST_NODE_TYPES.TSTypeLiteral:\n return typeLiteralHasRequiredProp(typeNode, requiredProp);\n\n case AST_NODE_TYPES.TSTypeReference: {\n const referenceName = getTypeReferenceName(typeNode.typeName);\n if (!referenceName || visitedTypeNames.has(referenceName)) {\n return false;\n }\n\n visitedTypeNames.add(referenceName);\n\n const interfaceDeclaration = declarations.interfaces.get(referenceName);\n if (interfaceDeclaration) {\n return interfaceHasRequiredProp(interfaceDeclaration, requiredProp, declarations, visitedTypeNames);\n }\n\n const typeAlias = declarations.typeAliases.get(referenceName);\n if (typeAlias) {\n return typeHasRequiredProp(typeAlias.typeAnnotation, requiredProp, declarations, visitedTypeNames);\n }\n\n return false;\n }\n\n case AST_NODE_TYPES.TSIntersectionType:\n return typeNode.types.some(part =>\n typeHasRequiredProp(part, requiredProp, declarations, new Set(visitedTypeNames))\n );\n\n case AST_NODE_TYPES.TSUnionType:\n return typeNode.types.every(part =>\n typeHasRequiredProp(part, requiredProp, declarations, new Set(visitedTypeNames))\n );\n\n default:\n return false;\n }\n};\n\nconst getTypeCheckerContext = (context: TSESLint.RuleContext<MessageIds, Options>): TypeCheckerContext | null => {\n try {\n const services = ESLintUtils.getParserServices(context);\n return {\n checker: services.program.getTypeChecker(),\n services,\n };\n } catch {\n return null;\n }\n};\n\nexport const checkerTypeHasRequiredInterface = (\n type: ts.Type,\n requiredInterface: string,\n checker: ts.TypeChecker,\n visitedTypeNames = new Set<string>()\n): boolean => {\n if (type.isUnion()) {\n return type.types.every(part => checkerTypeHasRequiredInterface(part, requiredInterface, checker, new Set()));\n }\n\n if (type.isIntersection()) {\n return type.types.some(part =>\n checkerTypeHasRequiredInterface(part, requiredInterface, checker, new Set(visitedTypeNames))\n );\n }\n\n const { symbolName, declarations } = getTypeSymbolInfo(type);\n const aliasSymbolName = type.aliasSymbol?.getName();\n\n if (symbolName === requiredInterface || aliasSymbolName === requiredInterface) {\n return true;\n }\n\n const visitKey = aliasSymbolName ?? symbolName;\n if (visitKey) {\n if (visitedTypeNames.has(visitKey)) {\n return false;\n }\n visitedTypeNames.add(visitKey);\n }\n\n if (\n type.aliasTypeArguments?.some(typeArgument =>\n checkerTypeHasRequiredInterface(typeArgument, requiredInterface, checker)\n )\n ) {\n return true;\n }\n\n if (type.isClassOrInterface()) {\n const baseTypes = checker.getBaseTypes(type);\n if (\n baseTypes.some(baseType =>\n checkerTypeHasRequiredInterface(baseType, requiredInterface, checker, visitedTypeNames)\n )\n ) {\n return true;\n }\n }\n\n return declarations.some(declaration => {\n if (!ts.isInterfaceDeclaration(declaration) || !declaration.heritageClauses) {\n return false;\n }\n\n return declaration.heritageClauses.some(heritageClause =>\n heritageClause.types.some(heritageType => {\n const heritageInterfaceType = checker.getTypeAtLocation(heritageType);\n return checkerTypeHasRequiredInterface(heritageInterfaceType, requiredInterface, checker, visitedTypeNames);\n })\n );\n });\n};\n\nconst checkerTypeHasRequiredProp = (type: ts.Type, requiredProp: string, checker: ts.TypeChecker): boolean => {\n if (type.isUnion()) {\n return type.types.every(part => checkerTypeHasRequiredProp(part, requiredProp, checker));\n }\n\n return Boolean(type.getProperty(requiredProp));\n};\n\nconst getCheckerType = (typeNode: TSESTree.TypeNode, typeCheckerContext: TypeCheckerContext | null): ts.Type | null => {\n if (!typeCheckerContext) {\n return null;\n }\n\n const tsNode = typeCheckerContext.services.esTreeNodeToTSNodeMap.get(typeNode);\n return typeCheckerContext.checker.getTypeAtLocation(tsNode);\n};\n\nexport const requireComponentPropContracts = createRule<Options, MessageIds>({\n name: \"require-component-prop-contracts\",\n meta: {\n type: \"problem\",\n docs: {\n description:\n \"Require exported React component props to include configured prop names or extend configured interfaces.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n requiredProps: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Prop names every exported component props type must include.\",\n },\n requiredInterfaces: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Interface names every exported component props type must reference or extend.\",\n },\n onlyWhenProjectMatches: {\n type: \"object\",\n properties: {\n tags: {\n type: \"array\",\n items: { type: \"string\" },\n },\n targets: {\n type: \"array\",\n items: { type: \"string\" },\n },\n tagsMatchMode: {\n type: \"string\",\n enum: [\"some\", \"every\"],\n },\n targetsMatchMode: {\n type: \"string\",\n enum: [\"some\", \"every\"],\n },\n },\n additionalProperties: false,\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n missingPropContracts:\n \"Public component '{{componentName}}' props must satisfy these contracts: {{missingContracts}}.\",\n },\n },\n defaultOptions: [\n {\n requiredProps: [],\n requiredInterfaces: [],\n onlyWhenProjectMatches: { tags: [\"publish:npm\"] },\n },\n ],\n create(context, [options]) {\n const filename = context.filename;\n if (!filename.endsWith(\".tsx\")) {\n return {};\n }\n\n const projectMetadata = getProjectMetadata(filename);\n const projectCriteria = options.onlyWhenProjectMatches ?? { tags: [\"publish:npm\"] };\n if (!projectMetadata || !projectMatchesCriteria(projectMetadata, projectCriteria)) {\n return {};\n }\n\n const requiredProps = options.requiredProps ?? [];\n const requiredInterfaces = options.requiredInterfaces ?? [];\n if (requiredProps.length === 0 && requiredInterfaces.length === 0) {\n return {};\n }\n\n const declarations: TypeDeclarationMaps = {\n interfaces: new Map(),\n typeAliases: new Map(),\n };\n const typeCheckerContext = getTypeCheckerContext(context);\n const exportedIdentifiers = new Set<string>();\n const componentCandidates: Array<ComponentCandidate> = [];\n const projectRoot = getProjectRoot(projectMetadata.projectJsonPath);\n const publicExports = getPublicExportedNamesForFile(projectRoot, filename);\n const isCurrentFileEntrypoint = isEntrypointFile(projectRoot, filename);\n\n const isExportedComponentName = (componentName: string, node: TSESTree.Node): boolean => {\n if (\n !isPascalCaseName(componentName) ||\n (!isExportedDeclaration(node) && !exportedIdentifiers.has(componentName))\n ) {\n return false;\n }\n\n return isCurrentFileEntrypoint || publicExports.exportsAll || publicExports.names.has(componentName);\n };\n\n const checkCandidate = (candidate: ComponentCandidate): void => {\n const checkerType = candidate.propsType ? getCheckerType(candidate.propsType, typeCheckerContext) : null;\n const missingProps = requiredProps.filter(\n requiredProp =>\n !candidate.propsType ||\n (checkerType && typeCheckerContext\n ? !checkerTypeHasRequiredProp(checkerType, requiredProp, typeCheckerContext.checker)\n : !typeHasRequiredProp(candidate.propsType, requiredProp, declarations, new Set()))\n );\n const missingInterfaces = requiredInterfaces.filter(\n requiredInterface =>\n !candidate.propsType ||\n (checkerType && typeCheckerContext\n ? !checkerTypeHasRequiredInterface(checkerType, requiredInterface, typeCheckerContext.checker)\n : !typeHasRequiredInterface(candidate.propsType, requiredInterface, declarations, new Set()))\n );\n const missingContracts = [...missingProps, ...missingInterfaces];\n\n if (missingContracts.length === 0) {\n return;\n }\n\n context.report({\n node: candidate.node,\n messageId: \"missingPropContracts\",\n data: {\n componentName: candidate.componentName,\n missingContracts: missingContracts.join(\", \"),\n },\n });\n };\n\n return {\n ExportNamedDeclaration(node: TSESTree.ExportNamedDeclaration) {\n for (const specifier of node.specifiers) {\n if (specifier.local.type === AST_NODE_TYPES.Identifier) {\n exportedIdentifiers.add(specifier.local.name);\n }\n }\n },\n\n ExportDefaultDeclaration(node: TSESTree.ExportDefaultDeclaration) {\n if (node.declaration.type === AST_NODE_TYPES.Identifier) {\n exportedIdentifiers.add(node.declaration.name);\n }\n },\n\n TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration) {\n declarations.interfaces.set(node.id.name, node);\n },\n\n TSTypeAliasDeclaration(node: TSESTree.TSTypeAliasDeclaration) {\n declarations.typeAliases.set(node.id.name, node);\n },\n\n FunctionDeclaration(node: TSESTree.FunctionDeclaration) {\n const componentName = node.id?.name;\n if (!componentName || !isReactComponent(node) || !isExportedComponentName(componentName, node)) {\n return;\n }\n\n componentCandidates.push({\n componentName,\n node,\n propsType: getFunctionPropsType(node),\n });\n },\n\n VariableDeclarator(node: TSESTree.VariableDeclarator) {\n if (node.id.type !== AST_NODE_TYPES.Identifier) {\n return;\n }\n\n const { init } = node;\n const isComponent =\n init?.type === AST_NODE_TYPES.ArrowFunctionExpression\n ? isReactComponent(init)\n : init?.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCallExpression(init);\n\n if (!isComponent || !isExportedComponentName(node.id.name, node)) {\n return;\n }\n\n componentCandidates.push({\n componentName: node.id.name,\n node,\n propsType: getPropsTypeFromVariableDeclarator(node),\n });\n },\n\n \"Program:exit\"() {\n componentCandidates.forEach(checkCandidate);\n },\n };\n },\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"require-list-item-virtualization-props.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/require-list-item-virtualization-props/require-list-item-virtualization-props.ts"],"names":[],"mappings":"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","sourcesContent":["import { AST_NODE_TYPES, ESLintUtils, TSESLint, TSESTree } from \"@typescript-eslint/utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}.ts`\n);\n\ntype Options = [\n {\n /**\n * Whether to allow custom components that extend VirtualizationListItemProps\n * instead of requiring explicit spreading of listItemProps\n */\n allowCustomComponents?: boolean;\n },\n];\n\ntype MessageIds = \"requireVirtualizationProps\" | \"spreadListItemProps\" | \"useSemanticListItem\";\n\n/**\n * Check if a spread attribute argument contains listItemProps\n */\nconst isListItemPropsSpread = (argument: TSESTree.Expression): boolean => {\n // Direct identifier: {...listItemProps}\n if (argument.type === AST_NODE_TYPES.Identifier) {\n return argument.name === \"listItemProps\" || argument.name.includes(\"ItemProps\");\n }\n\n // Member expression: {...params.listItemProps}\n if (argument.type === AST_NODE_TYPES.MemberExpression) {\n // Check if property is an identifier (not computed like params[\"listItemProps\"])\n if (!argument.computed && argument.property.type === AST_NODE_TYPES.Identifier) {\n const propertyName = argument.property.name;\n if (propertyName === \"listItemProps\" || propertyName.includes(\"ItemProps\")) {\n return true;\n }\n }\n }\n\n return false;\n};\n\n/**\n * Check if a JSX element has the required virtualization props\n */\nconst hasRequiredVirtualizationProps = (\n element: TSESTree.JSXElement,\n context: TSESLint.RuleContext<string, ReadonlyArray<unknown>>\n): boolean => {\n // ref is functionally required for virtualization even though TypeScript marks it optional\n const requiredProps = [\"className\", \"data-index\", \"tabIndex\", \"ref\"];\n\n const attributes = element.openingElement.attributes;\n const propNames = new Set<string>();\n let hasSpreadListItemProps = false;\n\n for (const attr of attributes) {\n if (attr.type === AST_NODE_TYPES.JSXAttribute && attr.name.type === AST_NODE_TYPES.JSXIdentifier) {\n propNames.add(attr.name.name);\n } else if (attr.type === AST_NODE_TYPES.JSXSpreadAttribute) {\n // Check if spreading listItemProps or similar\n if (isListItemPropsSpread(attr.argument)) {\n hasSpreadListItemProps = true;\n } else {\n // Fallback: check source code text for listItemProps\n // This handles edge cases where AST structure might be different\n const sourceCode = context.sourceCode.getText(attr.argument);\n const hasListItemProps = sourceCode.includes(\"listItemProps\");\n const hasItemProps = sourceCode.includes(\"ItemProps\");\n if (hasListItemProps || hasItemProps) {\n hasSpreadListItemProps = true;\n }\n }\n }\n }\n\n // If spreading listItemProps, assume it has all required props\n if (hasSpreadListItemProps) {\n return true;\n }\n\n // Check if all required props are present\n return requiredProps.every(prop => propNames.has(prop));\n};\n\n/**\n * Check if we're inside a List component's render function\n */\nconst isInsideListRenderFunction = (node: TSESTree.Node): boolean => {\n let current: TSESTree.Node | undefined = node.parent;\n\n while (current) {\n // Look for JSX element named \"List\"\n if (\n current.type === AST_NODE_TYPES.JSXElement &&\n current.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier &&\n current.openingElement.name.name === \"List\"\n ) {\n return true;\n }\n current = current.parent;\n }\n\n return false;\n};\n\n/**\n * Check if a JSX element is a direct list item (directly returned from List render function)\n */\nconst isListItemElement = (element: TSESTree.JSXElement): boolean => {\n // Check if this element is the direct return value from a List render function\n const current: TSESTree.Node | undefined = element.parent;\n\n // We need to find if this element is DIRECTLY returned from the render function\n // This means it should be the immediate child of a return statement or arrow function body\n\n // Case 1: Direct return statement - return (<li>...</li>)\n if (current.type === AST_NODE_TYPES.ReturnStatement) {\n return isInsideListRenderFunction(current);\n }\n\n // Case 2: Arrow function body - ({ key, listItemProps, item }) => (<li>...</li>)\n if (current.type === AST_NODE_TYPES.ArrowFunctionExpression) {\n return isInsideListRenderFunction(current);\n }\n\n // Case 3: Conditional expression - item ? <li>...</li> : null\n if (current.type === AST_NODE_TYPES.ConditionalExpression) {\n // Check if the conditional is directly returned or is the arrow function body\n const conditionalParent = current.parent;\n if (\n conditionalParent.type === AST_NODE_TYPES.ReturnStatement ||\n conditionalParent.type === AST_NODE_TYPES.ArrowFunctionExpression\n ) {\n return isInsideListRenderFunction(conditionalParent);\n }\n }\n\n return false;\n};\n\n/**\n * Get the name of a JSX element\n */\nconst getJSXElementName = (element: TSESTree.JSXElement): string | null => {\n if (element.openingElement.name.type === AST_NODE_TYPES.JSXIdentifier) {\n return element.openingElement.name.name;\n }\n return null;\n};\n\n/**\n * Check if element is a semantic list item element\n */\nconst isSemanticListItem = (elementName: string): boolean => {\n return elementName.toLowerCase() === \"li\";\n};\n\n/**\n * Check if element name is a built-in HTML element (vs custom React component)\n */\nconst isHTMLElement = (elementName: string): boolean => {\n // HTML elements are lowercase, React components start with uppercase\n if (elementName.length === 0) {\n return false;\n }\n const firstChar = elementName[0];\n if (!firstChar) {\n return false;\n }\n return firstChar === firstChar.toLowerCase();\n};\n\nexport const requireListItemVirtualizationProps = createRule<Options, MessageIds>({\n name: \"require-list-item-virtualization-props\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Require list items within <List> to have VirtualizationListItemProps\",\n },\n hasSuggestions: true,\n schema: [\n {\n type: \"object\",\n properties: {\n allowCustomComponents: { type: \"boolean\" },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n requireVirtualizationProps:\n \"List item '{{elementName}}' must include VirtualizationListItemProps. \" +\n \"Spread {...listItemProps} or manually specify className, data-index, tabIndex, ref props.\",\n spreadListItemProps: \"Spread {...listItemProps} on this element\",\n useSemanticListItem:\n \"Use semantic <li> elements for list items instead of '{{elementName}}'. \" +\n \"List items should be <li> elements with proper VirtualizationListItemProps.\",\n },\n },\n defaultOptions: [\n {\n allowCustomComponents: true,\n },\n ],\n create(context, options) {\n const config = options[0];\n\n return {\n JSXElement(node: TSESTree.JSXElement) {\n // Skip if not inside a List render function\n if (!isListItemElement(node)) {\n return;\n }\n\n const elementName = getJSXElementName(node);\n if (!elementName) {\n return;\n }\n\n // Check element type and apply appropriate rules\n if (isHTMLElement(elementName)) {\n // For HTML elements, enforce semantic list items\n if (!isSemanticListItem(elementName)) {\n context.report({\n node: node.openingElement,\n messageId: \"useSemanticListItem\",\n data: { elementName },\n });\n return;\n }\n\n // For <li> elements, require virtualization props\n if (!hasRequiredVirtualizationProps(node, context)) {\n context.report({\n node: node.openingElement,\n messageId: \"requireVirtualizationProps\",\n data: { elementName },\n suggest: [\n {\n messageId: \"spreadListItemProps\",\n fix(fixer) {\n // Add {...listItemProps} as the first attribute\n const openingTag = node.openingElement;\n const firstAttr = openingTag.attributes[0];\n\n if (firstAttr) {\n return fixer.insertTextBefore(firstAttr, \"{...listItemProps} \");\n } else {\n // Insert after the element name\n return fixer.insertTextAfter(openingTag.name, \" {...listItemProps}\");\n }\n },\n },\n ],\n });\n }\n } else {\n // For custom components, check allowCustomComponents setting\n if (config.allowCustomComponents === false && !hasRequiredVirtualizationProps(node, context)) {\n context.report({\n node: node.openingElement,\n messageId: \"requireVirtualizationProps\",\n data: { elementName },\n suggest: [\n {\n messageId: \"spreadListItemProps\",\n fix(fixer) {\n // Add {...listItemProps} as the first attribute\n const openingTag = node.openingElement;\n const firstAttr = openingTag.attributes[0];\n\n if (firstAttr) {\n return fixer.insertTextBefore(firstAttr, \"{...listItemProps} \");\n } else {\n // Insert after the element name\n return fixer.insertTextAfter(openingTag.name, \" {...listItemProps}\");\n }\n },\n },\n ],\n });\n }\n }\n },\n };\n },\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"require-optional-prop-initialization.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/require-optional-prop-initialization/require-optional-prop-initialization.ts"],"names":[],"mappings":";;;AAAA,oDAAiF;AACjF,qDAO+B;AAC/B,mEAAwE;AACxE,yDAA0E;AAE1E,MAAM,UAAU,GAAG,mBAAW,CAAC,WAAW,CACxC,IAAI,CAAC,EAAE,CAAC,6FAA6F,IAAI,KAAK,CAC/G,CAAC;AAcW,QAAA,iCAAiC,GAAG,UAAU,CAAsB;IAC/E,IAAI,EAAE,sCAAsC;IAC5C,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EAAE,yEAAyE;SACvF;QACD,cAAc,EAAE,IAAI;QACpB,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;oBACxC,oBAAoB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;oBACzC,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;oBACxC,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;oBACxC,iBAAiB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;oBACtC,+BAA+B,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;oBACpD,oBAAoB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;iBAC1C;gBACD,oBAAoB,EAAE,KAAK;aAC5B;SACF;QACD,QAAQ,EAAE;YACR,qBAAqB,EAAE,oDAAoD;YAC3E,cAAc,EAAE,iBAAiB;SAClC;KACF;IACD,cAAc,EAAE;QACd;YACE,mBAAmB,EAAE,IAAI;YACzB,oBAAoB,EAAE,KAAK;YAC3B,mBAAmB,EAAE,IAAI;YACzB,mBAAmB,EAAE,IAAI;YACzB,iBAAiB,EAAE,KAAK;YACxB,+BAA+B,EAAE,KAAK;YACtC,oBAAoB,EAAE,IAAI;SAC3B;KACF;IACD,MAAM,CAAC,OAAO,EAAE,OAAO;QACrB,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAE1B,2CAA2C;QAC3C,MAAM,mBAAmB,GAAG,CAC1B,YAA6E,EAC7E,UAA0C,EAC1C,EAAE;YACF,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO;YACT,CAAC;YAED,IAAI,cAA6C,CAAC;YAElD,oGAAoG;YACpG,IAAI,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,aAAa,EAAE,CAAC;gBACtG,cAAc,GAAG,UAAU,CAAC,cAAc,EAAE,cAAc,CAAC;YAC7D,CAAC;iBAAM,CAAC;gBACN,OAAO;YACT,CAAC;YAED,MAAM,aAAa,GAAG,IAAA,2CAAwB,EAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YAExE,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,OAAO;YACT,CAAC;YAED,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,KAAK,sBAAc,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAE5G,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAC3B,2EAA2E;gBAC3E,MAAM,SAAS,GACb,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,mBAAmB,KAAK,IAAI,CAAC;oBAC/D,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,oBAAoB,KAAK,IAAI,CAAC;oBACjE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,mBAAmB,KAAK,IAAI,CAAC;oBAC/D,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,mBAAmB,KAAK,IAAI,CAAC;oBAC/D,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,iBAAiB,KAAK,IAAI,CAAC;oBAC3D,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,IAAI,MAAM,CAAC,+BAA+B,KAAK,IAAI,CAAC;oBAClF,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,6BAA6B;gBAExD,IAAI,SAAS,EAAE,CAAC;oBACd,OAAO;gBACT,CAAC;gBAED,wDAAwD;gBACxD,IAAI,MAAM,CAAC,oBAAoB,KAAK,IAAI,IAAI,CAAC,IAAA,qCAAyB,EAAC,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzG,OAAO;gBACT,CAAC;gBAED,0GAA0G;gBAC1G,+EAA+E;gBAC/E,IACE,CAAC,IAAA,6CAAiC,EAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC;oBACzD,CAAC,IAAA,qCAAyB,EAAC,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,EAC5D,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,sGAAsG;gBACtG,IAAI,IAAA,oCAAwB,EAAC,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;oBACxE,OAAO;gBACT,CAAC;gBAED,8EAA8E;gBAC9E,IAAI,CAAC,IAAA,kCAAsB,EAAC,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;oBACjE,MAAM,mBAAmB,GAAG,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,aAAa,CAAC;oBAC7E,MAAM,YAAY,GAAG,IAAA,0CAA8B,EAAC,YAAY,CAAC,CAAC;oBAClE,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;oBAEjG,MAAM,WAAW,GAAG,IAAA,sCAAmB,EACrC,IAAI,EACJ,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,OAAO,CACR,CAAC;oBAEF,6DAA6D;oBAC7D,IAAI,UAAU,GAAkB,UAAU,CAAC;oBAC3C,IAAI,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,aAAa,EAAE,CAAC;wBACrD,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,CAC7C,CAAC,CAAC,EAAE,CACF,CAAC,CAAC,IAAI,KAAK,sBAAc,CAAC,QAAQ;4BAClC,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,sBAAc,CAAC,UAAU;4BACxC,CAAC,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAC3B,CAAC;wBACF,IAAI,YAAY,IAAI,YAAY,CAAC,IAAI,KAAK,sBAAc,CAAC,QAAQ,EAAE,CAAC;4BAClE,UAAU,GAAG,YAAY,CAAC;wBAC5B,CAAC;oBACH,CAAC;oBAED,OAAO,CAAC,MAAM,CAAC;wBACb,IAAI,EAAE,UAAU;wBAChB,SAAS,EAAE,uBAAuB;wBAClC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE;wBAC7B,OAAO,EAAE,WAAW;qBACrB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,OAAO;YACL,mBAAmB,CAAC,IAAkC;gBACpD,IAAI,IAAA,4BAAgB,EAAC,IAAI,CAAC,EAAE,CAAC;oBAC3B,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YAED,uBAAuB,CAAC,IAAsC;gBAC5D,IAAI,IAAA,4BAAgB,EAAC,IAAI,CAAC,EAAE,CAAC;oBAC3B,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { AST_NODE_TYPES, ESLintUtils, TSESTree } from \"@typescript-eslint/utils\";\nimport {\n hasExistingBodyInitializations,\n isParameterExplicitlyDestructured,\n isParameterInitialized,\n isParameterOnlyUsedInJSX,\n isParameterUsedInFunction,\n isReactComponent,\n} from \"../../utils/ast-utils\";\nimport { getOptionalPropsFromType } from \"../../utils/typescript-utils\";\nimport { generateSuggestions, type MessageIds } from \"./suggestion-utils\";\n\nconst createRule = ESLintUtils.RuleCreator(\n name => `https://github.com/trackunit/manager/blob/main/libs/eslint/plugin-trackunit/src/lib/rules/${name}.ts`\n);\n\ntype Options = [\n {\n allowNullableObject?: boolean;\n allowNullableBoolean?: boolean;\n allowNullableString?: boolean;\n allowNullableNumber?: boolean;\n allowNullableEnum?: boolean;\n allowNullableStringLiteralUnion?: boolean;\n onlyRequireUsedProps?: boolean;\n },\n];\n\nexport const requireOptionalPropInitialization = createRule<Options, MessageIds>({\n name: \"require-optional-prop-initialization\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Require optional component props to be initialized inside the component\",\n },\n hasSuggestions: true,\n schema: [\n {\n type: \"object\",\n properties: {\n allowNullableObject: { type: \"boolean\" },\n allowNullableBoolean: { type: \"boolean\" },\n allowNullableString: { type: \"boolean\" },\n allowNullableNumber: { type: \"boolean\" },\n allowNullableEnum: { type: \"boolean\" },\n allowNullableStringLiteralUnion: { type: \"boolean\" },\n onlyRequireUsedProps: { type: \"boolean\" },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n requireInitialization: \"Optional prop '{{propName}}' should be initialized\",\n initializeProp: \"{{description}}\",\n },\n },\n defaultOptions: [\n {\n allowNullableObject: true,\n allowNullableBoolean: false,\n allowNullableString: true,\n allowNullableNumber: true,\n allowNullableEnum: false,\n allowNullableStringLiteralUnion: false,\n onlyRequireUsedProps: true,\n },\n ],\n create(context, options) {\n const config = options[0];\n\n // Helper function to check component props\n const checkComponentProps = (\n functionNode: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression,\n propsParam: TSESTree.Parameter | undefined\n ) => {\n if (!propsParam) {\n return;\n }\n\n let typeAnnotation: TSESTree.TypeNode | undefined;\n\n // Handle both regular parameters (props: Props) and destructured parameters ({prop1, prop2}: Props)\n if (propsParam.type === AST_NODE_TYPES.Identifier || propsParam.type === AST_NODE_TYPES.ObjectPattern) {\n typeAnnotation = propsParam.typeAnnotation?.typeAnnotation;\n } else {\n return;\n }\n\n const optionalProps = getOptionalPropsFromType(context, typeAnnotation);\n\n if (optionalProps.length === 0) {\n return;\n }\n\n const functionBody = functionNode.body.type === AST_NODE_TYPES.BlockStatement ? functionNode.body.body : [];\n\n optionalProps.forEach(prop => {\n // Check if this prop type is allowed to be nullable based on configuration\n const isAllowed =\n (prop.type === \"object\" && config.allowNullableObject === true) ||\n (prop.type === \"boolean\" && config.allowNullableBoolean === true) ||\n (prop.type === \"string\" && config.allowNullableString === true) ||\n (prop.type === \"number\" && config.allowNullableNumber === true) ||\n (prop.type === \"enum\" && config.allowNullableEnum === true) ||\n (prop.type === \"stringLiteral\" && config.allowNullableStringLiteralUnion === true) ||\n prop.type === \"unknown\"; // Always allow unknown types\n\n if (isAllowed) {\n return;\n }\n\n // If onlyRequireUsedProps is enabled, skip unused props\n if (config.onlyRequireUsedProps === true && !isParameterUsedInFunction(context, functionNode, prop.name)) {\n return;\n }\n\n // Skip props that are not explicitly destructured (i.e., captured in rest parameters like ...restOptions)\n // and are not used in the component body - these are just being passed through\n if (\n !isParameterExplicitlyDestructured(propsParam, prop.name) &&\n !isParameterUsedInFunction(context, functionNode, prop.name)\n ) {\n return;\n }\n\n // Skip props that are only used for pass-through to child components (e.g., <Tag color={tagColor} />)\n if (isParameterOnlyUsedInJSX(context, functionNode, prop.name) === true) {\n return;\n }\n\n // Check if the prop is initialized in the function body or parameter defaults\n if (!isParameterInitialized(functionBody, prop.name, propsParam)) {\n const isDestructuredParam = propsParam.type === AST_NODE_TYPES.ObjectPattern;\n const hasBodyInits = hasExistingBodyInitializations(functionBody);\n const propsParamName = propsParam.type === AST_NODE_TYPES.Identifier ? propsParam.name : \"props\";\n\n const suggestions = generateSuggestions(\n prop,\n propsParamName,\n functionNode,\n isDestructuredParam,\n hasBodyInits,\n propsParam,\n context\n );\n\n // Find the specific property node for more precise reporting\n let reportNode: TSESTree.Node = propsParam;\n if (propsParam.type === AST_NODE_TYPES.ObjectPattern) {\n const propProperty = propsParam.properties.find(\n p =>\n p.type === AST_NODE_TYPES.Property &&\n p.key.type === AST_NODE_TYPES.Identifier &&\n p.key.name === prop.name\n );\n if (propProperty && propProperty.type === AST_NODE_TYPES.Property) {\n reportNode = propProperty;\n }\n }\n\n context.report({\n node: reportNode,\n messageId: \"requireInitialization\",\n data: { propName: prop.name },\n suggest: suggestions,\n });\n }\n });\n };\n\n return {\n FunctionDeclaration(node: TSESTree.FunctionDeclaration) {\n if (isReactComponent(node)) {\n checkComponentProps(node, node.params[0]);\n }\n },\n\n ArrowFunctionExpression(node: TSESTree.ArrowFunctionExpression) {\n if (isReactComponent(node)) {\n checkComponentProps(node, node.params[0]);\n }\n },\n };\n },\n});\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"suggestion-utils.js","sourceRoot":"","sources":["../../../../../../../../libs/eslint/plugin-trackunit/src/lib/rules/require-optional-prop-initialization/suggestion-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AST_NODE_TYPES, TSESLint, TSESTree } from \"@typescript-eslint/utils\";\nimport { isParameterExplicitlyDestructured } from \"../../utils/ast-utils\";\nimport { OptionalProp } from \"../../utils/typescript-utils\";\n\nexport type MessageIds = \"requireInitialization\" | \"initializeProp\";\n\nexport type SuggestionResult = {\n messageId: MessageIds;\n data?: Record<string, unknown>;\n fix: (fixer: TSESLint.RuleFixer) => TSESLint.RuleFix | Array<TSESLint.RuleFix> | null;\n};\n\n/**\n * Helper to find and replace a property in destructuring pattern\n */\nconst createParameterInitializationFix = (propName: string, value: string, propsParam: TSESTree.Parameter) => {\n return (fixer: TSESLint.RuleFixer) => {\n if (propsParam.type === AST_NODE_TYPES.ObjectPattern) {\n const property = propsParam.properties.find(\n p => p.type === AST_NODE_TYPES.Property && p.key.type === AST_NODE_TYPES.Identifier && p.key.name === propName\n );\n if (property && property.type === AST_NODE_TYPES.Property) {\n return fixer.replaceText(property, `${propName} = ${value}`);\n }\n }\n return null;\n };\n};\n\n/**\n * Helper to create body initialization fix\n */\nconst createBodyInitializationFix = (\n propName: string,\n value: string,\n propsParamName: string,\n functionBodyStart: number\n) => {\n return (fixer: TSESLint.RuleFixer) => {\n const destructuringFix = `\\n const { ${propName} = ${value} } = ${propsParamName};`;\n return fixer.insertTextAfterRange([functionBodyStart, functionBodyStart + 1], destructuringFix);\n };\n};\n\n/**\n * Helper to create a suggestion for a specific value\n */\nconst createSuggestion = (\n propName: string,\n value: string,\n displayValue: string,\n shouldUseParameterInit: boolean,\n propsParam: TSESTree.Parameter,\n propsParamName: string,\n functionBodyStart: number\n): SuggestionResult => {\n let locationSuffix = \"\";\n let fixFunction: (fixer: TSESLint.RuleFixer) => TSESLint.RuleFix | Array<TSESLint.RuleFix> | null;\n\n if (shouldUseParameterInit) {\n locationSuffix = \" in parameter\";\n fixFunction = createParameterInitializationFix(propName, value, propsParam);\n } else {\n fixFunction = createBodyInitializationFix(propName, value, propsParamName, functionBodyStart);\n }\n\n return {\n messageId: \"initializeProp\",\n data: { description: `Initialize '${propName}' to → ${displayValue}${locationSuffix}` },\n fix: fixFunction,\n };\n};\n\n/**\n * Helper to create suggestions for a set of values\n */\nconst createSuggestionsForValues = (\n propName: string,\n values: Array<{ value: string; display: string }>,\n shouldUseParameterInit: boolean,\n propsParam: TSESTree.Parameter,\n propsParamName: string,\n functionBodyStart: number\n): Array<SuggestionResult> => {\n return values.map(({ value, display }) =>\n createSuggestion(propName, value, display, shouldUseParameterInit, propsParam, propsParamName, functionBodyStart)\n );\n};\n\n/**\n * Helper function to generate suggestions for prop initialization\n */\nexport const generateSuggestions = (\n prop: OptionalProp,\n propsParamName: string,\n functionNode: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression,\n isDestructuredParam: boolean,\n hasBodyInits: boolean,\n propsParam: TSESTree.Parameter,\n _context: TSESLint.RuleContext<string, ReadonlyArray<unknown>>\n): Array<SuggestionResult> => {\n const suggestions: Array<SuggestionResult> = [];\n\n if (functionNode.body.type !== AST_NODE_TYPES.BlockStatement) {\n return suggestions; // Can't suggest for arrow functions without block body\n }\n\n // Don't offer suggestions for props captured in rest parameters (e.g., ...rest)\n // The developer should manually handle extracting these from the rest object\n if (!isParameterExplicitlyDestructured(propsParam, prop.name)) {\n return suggestions;\n }\n\n const functionBodyStart = functionNode.body.range[0];\n const MAX_SUGGESTIONS = 5; // Don't overwhelm with too many suggestions\n\n // Decide where to place the initialization:\n // Since we know the prop is explicitly destructured (early return above handles rest params),\n // we can choose between parameter initialization or body initialization\n const isAlreadyInParameterDestructuring =\n isDestructuredParam &&\n propsParam.type === AST_NODE_TYPES.ObjectPattern &&\n propsParam.properties.some(\n p => p.type === AST_NODE_TYPES.Property && p.key.type === AST_NODE_TYPES.Identifier && p.key.name === prop.name\n );\n\n const shouldUseParameterInit = isAlreadyInParameterDestructuring || (isDestructuredParam && !hasBodyInits);\n\n // Boolean suggestions: true, false, and undefined\n if (prop.type === \"boolean\") {\n const booleanValues = [\n { value: \"true\", display: \"true\" },\n { value: \"false\", display: \"false\" },\n { value: \"undefined\", display: \"undefined\" },\n ];\n suggestions.push(\n ...createSuggestionsForValues(\n prop.name,\n booleanValues,\n shouldUseParameterInit,\n propsParam,\n propsParamName,\n functionBodyStart\n )\n );\n }\n\n // String literal suggestions: each individual literal (if not too many)\n if (prop.type === \"stringLiteral\" && prop.stringLiterals.length <= MAX_SUGGESTIONS) {\n const stringLiteralValues = [\n ...prop.stringLiterals.map(literal => ({ value: `\"${literal}\"`, display: `\"${literal}\"` })),\n { value: \"undefined\", display: \"undefined\" },\n ];\n suggestions.push(\n ...createSuggestionsForValues(\n prop.name,\n stringLiteralValues,\n shouldUseParameterInit,\n propsParam,\n propsParamName,\n functionBodyStart\n )\n );\n }\n\n // Enum suggestions: each individual enum value (if not too many)\n if (prop.type === \"enum\" && prop.enumValues.length <= MAX_SUGGESTIONS) {\n const enumValues = [\n ...prop.enumValues.map(enumValue => {\n const valueStr = typeof enumValue === \"string\" ? `\"${enumValue}\"` : String(enumValue);\n return { value: valueStr, display: valueStr };\n }),\n { value: \"undefined\", display: \"undefined\" },\n ];\n suggestions.push(\n ...createSuggestionsForValues(\n prop.name,\n enumValues,\n shouldUseParameterInit,\n propsParam,\n propsParamName,\n functionBodyStart\n )\n );\n }\n\n // String type suggestions\n if (prop.type === \"string\") {\n const stringValues = [\n { value: '\"\"', display: '\"\"' },\n { value: \"undefined\", display: \"undefined\" },\n ];\n suggestions.push(\n ...createSuggestionsForValues(\n prop.name,\n stringValues,\n shouldUseParameterInit,\n propsParam,\n propsParamName,\n functionBodyStart\n )\n );\n }\n\n // Number type suggestions\n if (prop.type === \"number\") {\n const numberValues = [\n { value: \"0\", display: \"0\" },\n { value: \"undefined\", display: \"undefined\" },\n ];\n suggestions.push(\n ...createSuggestionsForValues(\n prop.name,\n numberValues,\n shouldUseParameterInit,\n propsParam,\n propsParamName,\n functionBodyStart\n )\n );\n }\n\n // Object/unknown type suggestions\n if (prop.type === \"object\" || prop.type === \"unknown\") {\n const typeDisplay = prop.type === \"unknown\" ? \"any value\" : prop.type;\n suggestions.push(\n createSuggestion(\n prop.name,\n \"undefined\",\n `undefined (${typeDisplay})`,\n shouldUseParameterInit,\n propsParam,\n propsParamName,\n functionBodyStart\n )\n );\n }\n\n return suggestions;\n};\n"]}
|
package/src/lib/rules-map.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rules-map.js","sourceRoot":"","sources":["../../../../../../libs/eslint/plugin-trackunit/src/lib/rules-map.ts"],"names":[],"mappings":";;;AACA,6HAAqH;AACrH,qJAA6I;AAC7I,wGAAkG;AAClG,6KAAmK;AACnK,qJAA4I;AAC5I,+IAAmI;AACnI,qGAAgG;AAChG,iHAA4G;AAC5G,+IAAwI;AACxI,qGAAgG;AAChG,2JAAkJ;AAClJ,0HAAqH;AACrH,gIAA0H;AAC1H,kJAA2I;AAC3I,4IAAsI;AAEzH,QAAA,QAAQ,GAAG;IACtB,iCAAiC,EAAE,4DAA0B;IAC7D,0BAA0B,EAAE,gDAAqB;IACjD,yBAAyB,EAAE,+CAAqB;IAChD,iDAAiD,EAAE,0FAAwC;IAC3F,yCAAyC,EAAE,4EAAkC;IAC7E,uCAAuC,EAAE,oEAA4B;IACrE,gCAAgC,EAAE,6DAA4B;IAC9D,yCAAyC,EAAE,2EAAiC;IAC5E,6BAA6B,EAAE,uDAAyB;IACxD,2CAA2C,EAAE,+EAAmC;IAChF,uCAAuC,EAAE,yEAAiC;IAC1E,sCAAsC,EAAE,wEAAiC;IACzE,kCAAkC,EAAE,gEAA6B;IACjE,yBAAyB,EAAE,+CAAqB;IAChD,wCAAwC,EAAE,2EAAkC;CACI,CAAC","sourcesContent":["import { ESLintUtils } from \"@typescript-eslint/utils\";\nimport { cvaMergeBaseClassesAsArray } from \"./rules/cva-merge-base-classes-as-array/cva-merge-base-classes-as-array\";\nimport { designGuidelineButtonIconSizeMatch } from \"./rules/design-guideline-button-icon-size-match/design-guideline-button-icon-size-match\";\nimport { noInternalBarrelFiles } from \"./rules/no-internal-barrel-files/no-internal-barrel-files\";\nimport { noInternalGraphqlWhenTaggedWithGqlPublic } from \"./rules/no-internal-graphql-when-tagged-with-gql-public/no-internal-graphql-when-tagged-with-gql-public\";\nimport { noJestMockTrackunitReactCoreHooks } from \"./rules/no-jest-mock-trackunit-react-core-hooks/no-jest-mock-trackunit-react-core-hooks\";\nimport { noTemplateStringsInClassName } from \"./rules/no-template-strings-in-classname-prop/no-template-strings-in-classname-prop\";\nimport { noTypescriptAssertion } from \"./rules/no-typescript-assertion/no-typescript-assertion\";\nimport { preferDestructuredImports } from \"./rules/prefer-destructured-imports/prefer-destructured-imports\";\nimport { preferEventSpecificCallbackNaming } from \"./rules/prefer-event-specific-callback-naming/prefer-event-specific-callback-naming\";\nimport { preferFieldComponents } from \"./rules/prefer-field-components/prefer-field-components\";\nimport { preferMouseEventHandlerInReactProps } from \"./rules/prefer-mouse-event-handler-in-react-props/prefer-mouse-event-handler-in-react-props\";\nimport { requireClassnameAlternatives } from \"./rules/require-classname-alternatives/require-classname-alternatives\";\nimport { requireComponentPropContracts } from \"./rules/require-component-prop-contracts/require-component-prop-contracts\";\nimport { requireListItemVirtualizationProps } from \"./rules/require-list-item-virtualization-props/require-list-item-virtualization-props\";\nimport { requireOptionalPropInitialization } from \"./rules/require-optional-prop-initialization/require-optional-prop-initialization\";\n\nexport const rulesMap = {\n \"cva-merge-base-classes-as-array\": cvaMergeBaseClassesAsArray,\n \"no-internal-barrel-files\": noInternalBarrelFiles,\n \"no-typescript-assertion\": noTypescriptAssertion,\n \"no-internal-graphql-when-tagged-with-gql-public\": noInternalGraphqlWhenTaggedWithGqlPublic,\n \"design-guideline-button-icon-size-match\": designGuidelineButtonIconSizeMatch,\n \"no-template-strings-in-classname-prop\": noTemplateStringsInClassName,\n \"require-classname-alternatives\": requireClassnameAlternatives,\n \"no-jest-mock-trackunit-react-core-hooks\": noJestMockTrackunitReactCoreHooks,\n \"prefer-destructured-imports\": preferDestructuredImports,\n \"prefer-mouse-event-handler-in-react-props\": preferMouseEventHandlerInReactProps,\n \"prefer-event-specific-callback-naming\": preferEventSpecificCallbackNaming,\n \"require-optional-prop-initialization\": requireOptionalPropInitialization,\n \"require-component-prop-contracts\": requireComponentPropContracts,\n \"prefer-field-components\": preferFieldComponents,\n \"require-list-item-virtualization-props\": requireListItemVirtualizationProps,\n} satisfies Record<string, ESLintUtils.RuleModule<string, ReadonlyArray<unknown>>>;\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../../../../../../../libs/eslint/plugin-trackunit/src/lib/utils/ast-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { ASTUtils, AST_NODE_TYPES, TSESLint, TSESTree } from \"@typescript-eslint/utils\";\n\n/**\n * Utility functions for analyzing AST nodes and function structure in ESLint rules.\n *\n * ## Core Utilities\n * - `isInParameterList()` - Check if a node is in a function's parameter list\n *\n * ## Parameter Analysis (Parameter → Usage)\n * - `isParameterExplicitlyDestructured()` - Check if parameter is explicitly destructured\n * - `isParameterInitialized()` - Check if parameter has a default value\n * - `isParameterUsedInFunction()` - Check if parameter is used in function body\n * - `getParameterRestUsage()` - Get info about parameter accessed via rest params\n * - `hasExistingBodyInitializations()` - Check for initialization patterns in function body\n *\n * ## Identifier Origin Analysis (Usage → Origin)\n * - `getIdentifierParameterOrigin()` - Trace identifier back to see if it's from a parameter (rich return)\n * - `isIdentifierFromParameter()` - Boolean helper to check if identifier is from a parameter\n * - `isIdentifierFromRenderPropCallback()` - Check if identifier is from a render prop callback parameter\n *\n * ## JSX/React Specific\n * - `isReactComponent()` - Check if function is likely a React component\n * - `isParameterOnlyUsedInJSX()` - Check if parameter is only used in JSX attributes\n */\n\n/**\n * Helper function to check if a node is in the parameter list\n */\nconst isInParameterList = (\n node: TSESTree.Node,\n functionNode: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression\n): boolean => {\n let current = node.parent;\n while (current) {\n // Check if current node is one of the function parameters\n const isParam = functionNode.params.some(param => param === current);\n if (isParam) {\n return true;\n }\n current = current.parent;\n }\n return false;\n};\n\n/**\n * Check if a parameter is explicitly destructured in the parameter list\n * (vs. captured in rest parameters like ...restOptions)\n */\nexport const isParameterExplicitlyDestructured = (parameter: TSESTree.Parameter, paramName: string): boolean => {\n if (parameter.type !== AST_NODE_TYPES.ObjectPattern) {\n return false;\n }\n\n // Check if the parameter is explicitly listed in the destructuring\n return parameter.properties.some(property => {\n if (property.type === AST_NODE_TYPES.Property && property.key.type === AST_NODE_TYPES.Identifier) {\n return property.key.name === paramName;\n }\n return false;\n });\n};\n\n/**\n * Check if there are any existing parameter initializations in the function body\n */\nexport const hasExistingBodyInitializations = (functionBody: Array<TSESTree.Statement>): boolean => {\n for (const stmt of functionBody) {\n // Check for destructuring with defaults: const { param = defaultValue } = params\n if (\n stmt.type === AST_NODE_TYPES.VariableDeclaration &&\n stmt.declarations.length === 1 &&\n stmt.declarations[0].id.type === AST_NODE_TYPES.ObjectPattern &&\n stmt.declarations[0].id.properties.some(\n prop => prop.type === AST_NODE_TYPES.Property && prop.value.type === AST_NODE_TYPES.AssignmentPattern\n )\n ) {\n return true;\n }\n\n // Check for variable declarations with defaults: const param = params.param ?? defaultValue\n if (\n stmt.type === AST_NODE_TYPES.VariableDeclaration &&\n stmt.declarations.length === 1 &&\n stmt.declarations[0].init?.type === AST_NODE_TYPES.LogicalExpression &&\n (stmt.declarations[0].init.operator === \"??\" || stmt.declarations[0].init.operator === \"||\")\n ) {\n return true;\n }\n }\n return false;\n};\n\n/**\n * Check if a parameter is initialized in the function body or parameter defaults\n */\nexport const isParameterInitialized = (\n functionBody: Array<TSESTree.Statement>,\n paramName: string,\n parameter?: TSESTree.Parameter\n): boolean => {\n // First check if the parameter has a default value in the parameter destructuring\n if (parameter && parameter.type === AST_NODE_TYPES.ObjectPattern) {\n for (const property of parameter.properties) {\n if (property.type === AST_NODE_TYPES.Property && property.value.type === AST_NODE_TYPES.AssignmentPattern) {\n // Handle both identifier keys (paramName) and string literal keys (\"param-name\")\n const keyName =\n property.key.type === AST_NODE_TYPES.Identifier\n ? property.key.name\n : property.key.type === AST_NODE_TYPES.Literal && typeof property.key.value === \"string\"\n ? property.key.value\n : null;\n\n if (keyName === paramName) {\n return true; // Found default value in parameter: {paramName = defaultValue}\n }\n }\n }\n }\n\n // Then check for initialization patterns in the function body\n for (const stmt of functionBody) {\n // Check for destructuring with defaults: const { param = defaultValue } = params\n if (\n stmt.type === AST_NODE_TYPES.VariableDeclaration &&\n stmt.declarations.length === 1 &&\n stmt.declarations[0].id.type === AST_NODE_TYPES.ObjectPattern\n ) {\n const pattern = stmt.declarations[0].id;\n for (const property of pattern.properties) {\n if (\n property.type === AST_NODE_TYPES.Property &&\n property.key.type === AST_NODE_TYPES.Identifier &&\n property.key.name === paramName &&\n property.value.type === AST_NODE_TYPES.AssignmentPattern\n ) {\n return true;\n }\n }\n }\n\n // Check for variable declarations with defaults: const param = params.param ?? defaultValue\n if (\n stmt.type === AST_NODE_TYPES.VariableDeclaration &&\n stmt.declarations.length === 1 &&\n stmt.declarations[0].id.type === AST_NODE_TYPES.Identifier &&\n stmt.declarations[0].id.name === paramName &&\n stmt.declarations[0].init?.type === AST_NODE_TYPES.LogicalExpression &&\n (stmt.declarations[0].init.operator === \"??\" || stmt.declarations[0].init.operator === \"||\")\n ) {\n return true;\n }\n }\n\n return false;\n};\n\n/**\n * Check if a parameter is used within the function body\n */\nexport const isParameterUsedInFunction = (\n context: TSESLint.RuleContext<string, ReadonlyArray<unknown>>,\n functionNode: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression,\n paramName: string\n): boolean => {\n // Use TypeScript-ESLint's built-in findVariable utility for more robust variable detection\n const scope = context.sourceCode.getScope(functionNode);\n const variable = ASTUtils.findVariable(scope, paramName);\n\n if (variable) {\n // Check if the variable has any references (excluding the parameter definition)\n const references = variable.references.filter(ref => {\n // Exclude the parameter declaration itself\n const refNode = ref.identifier;\n return !isInParameterList(refNode, functionNode);\n });\n\n // Additional check: if the variable is only referenced in object literal shorthand property names\n // (like { placement: result.placement }), it's not actually using the parameter variable\n const actualUsageReferences = references.filter(ref => {\n const parent = ref.identifier.parent;\n\n // Skip if this is just a property key in an object literal\n // Example: { placement: result.placement } - the first 'placement' is just a key, not usage\n if (\n parent.type === AST_NODE_TYPES.Property &&\n parent.key === ref.identifier &&\n parent.value !== ref.identifier &&\n !parent.shorthand\n ) {\n return false;\n }\n\n return true;\n });\n\n if (actualUsageReferences.length > 0) {\n return true;\n }\n }\n\n // If direct variable reference not found, check for member access on rest parameters\n // e.g., rest.paramName, params.paramName, etc.\n const restParameters: Array<{ name: string; param: TSESTree.Parameter }> = [];\n\n // Look for rest elements in both direct params and inside object patterns\n functionNode.params.forEach(param => {\n if (param.type === AST_NODE_TYPES.RestElement && param.argument.type === AST_NODE_TYPES.Identifier) {\n // Direct rest parameter: (...rest: Params)\n restParameters.push({ name: param.argument.name, param });\n } else if (param.type === AST_NODE_TYPES.ObjectPattern) {\n // Look for rest elements inside object patterns: ({ param1, ...rest }: Params)\n param.properties.forEach(property => {\n if (property.type === AST_NODE_TYPES.RestElement && property.argument.type === AST_NODE_TYPES.Identifier) {\n restParameters.push({ name: property.argument.name, param });\n }\n });\n }\n });\n\n if (restParameters.length === 0) {\n return false;\n }\n\n // Check if the function body contains rest.paramName patterns\n const functionText = context.sourceCode.getText(functionNode);\n\n for (const restParam of restParameters) {\n const pattern = new RegExp(`\\\\b${restParam.name}\\\\.${paramName}\\\\b`);\n if (pattern.test(functionText)) {\n return true;\n }\n }\n\n return false;\n};\n\n/**\n * Check if a parameter is accessed via rest parameters (e.g., rest.paramName)\n * and return information about the rest parameter usage\n */\nconst getParameterRestUsage = (\n context: TSESLint.RuleContext<string, ReadonlyArray<unknown>>,\n functionNode: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression,\n paramName: string\n): { isUsedViaRest: boolean; restParamName?: string; restParam?: TSESTree.Parameter } | null => {\n // Look for rest elements in both direct params and inside object patterns\n const restParameters: Array<{ name: string; param: TSESTree.Parameter }> = [];\n\n functionNode.params.forEach(param => {\n if (param.type === AST_NODE_TYPES.RestElement && param.argument.type === AST_NODE_TYPES.Identifier) {\n // Direct rest parameter: (...rest: Params)\n restParameters.push({ name: param.argument.name, param });\n } else if (param.type === AST_NODE_TYPES.ObjectPattern) {\n // Look for rest elements inside object patterns: ({ param1, ...rest }: Params)\n param.properties.forEach(property => {\n if (property.type === AST_NODE_TYPES.RestElement && property.argument.type === AST_NODE_TYPES.Identifier) {\n restParameters.push({ name: property.argument.name, param });\n }\n });\n }\n });\n\n if (restParameters.length === 0) {\n return { isUsedViaRest: false };\n }\n\n // Check if the function body contains rest.paramName patterns\n const functionText = context.sourceCode.getText(functionNode);\n\n for (const restParam of restParameters) {\n const pattern = new RegExp(`\\\\b${restParam.name}\\\\.${paramName}\\\\b`);\n if (pattern.test(functionText)) {\n return {\n isUsedViaRest: true,\n restParamName: restParam.name,\n restParam: restParam.param,\n };\n }\n }\n\n return { isUsedViaRest: false };\n};\n\n/**\n * Check if a function is likely a React component based on naming and JSX usage\n */\nexport const isReactComponent = (node: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression): boolean => {\n // Check if function name starts with uppercase (React convention)\n const functionName = node.type === AST_NODE_TYPES.FunctionDeclaration ? node.id?.name : null;\n const startsWithUppercase = /^[A-Z]/;\n if (functionName && startsWithUppercase.test(functionName)) {\n return true;\n }\n\n // Check if the function returns JSX\n const hasJSXReturn = (body: TSESTree.Node): boolean => {\n if (body.type === AST_NODE_TYPES.JSXElement || body.type === AST_NODE_TYPES.JSXFragment) {\n return true;\n }\n // Handle conditional expressions that contain JSX: condition ? <JSX /> : null\n if (body.type === AST_NODE_TYPES.ConditionalExpression) {\n return hasJSXReturn(body.consequent) || hasJSXReturn(body.alternate);\n }\n if (body.type === AST_NODE_TYPES.BlockStatement) {\n return body.body.some(stmt => {\n if (stmt.type === AST_NODE_TYPES.ReturnStatement && stmt.argument) {\n return hasJSXReturn(stmt.argument);\n }\n return false;\n });\n }\n return false;\n };\n\n return hasJSXReturn(node.body);\n};\n\n/**\n * Check if a parameter is only used in JSX attributes (pass-through to child components)\n * and nowhere else in the function body\n */\nexport const isParameterOnlyUsedInJSX = (\n context: TSESLint.RuleContext<string, ReadonlyArray<unknown>>,\n functionNode: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression,\n paramName: string\n): boolean => {\n // Use TypeScript-ESLint's built-in findVariable utility for robust variable detection\n const scope = context.sourceCode.getScope(functionNode);\n const variable = ASTUtils.findVariable(scope, paramName);\n\n if (!variable) {\n return false;\n }\n\n // Get all references to the parameter (excluding the parameter definition)\n const references = variable.references.filter(ref => {\n const refNode = ref.identifier;\n return !isInParameterList(refNode, functionNode);\n });\n\n if (references.length === 0) {\n return false;\n }\n\n // Check if all references are only in JSX attribute expressions\n const allReferencesAreJSXAttributes = references.every(ref => {\n const identifier = ref.identifier;\n let current = identifier.parent;\n\n // Walk up the AST to find if this identifier is used in a JSX attribute\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, @typescript-eslint/strict-boolean-expressions\n while (current) {\n // Check if we're in a JSX attribute expression: <Component prop={value} />\n if (current.type === AST_NODE_TYPES.JSXExpressionContainer) {\n const jsxParent = current.parent;\n if (jsxParent.type === AST_NODE_TYPES.JSXAttribute) {\n return true;\n }\n }\n\n // Check if we're in a JSX spread attribute: <Component {...props} />\n if (current.type === AST_NODE_TYPES.JSXSpreadAttribute) {\n return true;\n }\n\n // Allow dependency arrays for React hooks (useEffect, useMemo, useCallback, etc.)\n // These are acceptable for pass-through props since they're tracking the JSX usage\n if (current.type === AST_NODE_TYPES.ArrayExpression) {\n const callParent = current.parent;\n if (\n callParent.type === AST_NODE_TYPES.CallExpression &&\n callParent.callee.type === AST_NODE_TYPES.Identifier &&\n (callParent.callee.name.startsWith(\"use\") ||\n callParent.callee.name === \"useMemo\" ||\n callParent.callee.name === \"useCallback\" ||\n callParent.callee.name === \"useEffect\")\n ) {\n return true; // Allow dependency array usage\n }\n }\n\n // Stop if we reach certain node types that indicate we're not in JSX context\n if (\n current.type === AST_NODE_TYPES.VariableDeclarator ||\n current.type === AST_NODE_TYPES.AssignmentExpression ||\n current.type === AST_NODE_TYPES.CallExpression ||\n current.type === AST_NODE_TYPES.LogicalExpression ||\n current.type === AST_NODE_TYPES.ConditionalExpression ||\n current.type === AST_NODE_TYPES.BinaryExpression\n ) {\n return false;\n }\n\n if (!current.parent) {\n break;\n }\n current = current.parent;\n }\n\n return false;\n });\n\n return allReferencesAreJSXAttributes;\n};\n\n// ============================================================\n// Identifier Origin Analysis (traces usage back to definition)\n// ============================================================\n\n/**\n * Result of tracing an identifier back to its origin.\n * Used to distinguish between different ways an identifier can come from a function parameter.\n */\nexport type ParameterOriginResult =\n | {\n isFromParameter: true;\n /**\n * How the identifier relates to the parameter:\n * - \"direct-parameter\": Direct parameter, e.g., `(onClose) => ...`\n * - \"destructured-in-signature\": Destructured in function signature, e.g., `({ onClose }) => ...`\n * - \"destructured-in-body\": Destructured in function body, e.g., `const { onClose } = props`\n */\n originType: \"direct-parameter\" | \"destructured-in-signature\" | \"destructured-in-body\";\n }\n | { isFromParameter: false };\n\n/**\n * Checks if a variable is a function parameter.\n */\nconst isVariableAParameter = (variable: { defs: ReadonlyArray<{ type: string }> }): boolean => {\n return variable.defs.some(def => def.type === \"Parameter\");\n};\n\n/**\n * Traces an identifier back to determine if it originates from a function parameter.\n * Returns detailed information about how the identifier relates to the parameter.\n *\n * This is used to distinguish between:\n * - Props passed through: `({ onClose }) => <button onClick={onClose} />` - destructured-in-signature\n * - Props destructured in body: `(props) => { const { onClose } = props; }` - destructured-in-body\n * - Direct parameter: `(onClose) => ...` - direct-parameter\n * - Internal functions: `const handleClose = () => {}; <button onClick={handleClose} />` - not from parameter\n * - Hook results: `const { mutate } = useMutation(); <button onClick={mutate} />` - not from parameter\n *\n * @param identifier - The identifier node to check\n * @param context - The ESLint rule context\n * @returns ParameterOriginResult with isFromParameter and originType if applicable\n * @example\n * // Direct parameter\n * const MyComponent = (onClose) => <button onClick={onClose} />;\n * // getIdentifierParameterOrigin(onClose) => { isFromParameter: true, originType: \"direct-parameter\" }\n * @example\n * // Destructured in signature\n * const MyComponent = ({ onClose }) => <button onClick={onClose} />;\n * // getIdentifierParameterOrigin(onClose) => { isFromParameter: true, originType: \"destructured-in-signature\" }\n * @example\n * // Destructured in body\n * const MyComponent = (props) => {\n * const { onClose } = props;\n * return <button onClick={onClose} />;\n * };\n * // getIdentifierParameterOrigin(onClose) => { isFromParameter: true, originType: \"destructured-in-body\" }\n * @example\n * // Not from parameter (internal function)\n * const MyComponent = () => {\n * const handleClose = () => {};\n * return <button onClick={handleClose} />;\n * };\n * // getIdentifierParameterOrigin(handleClose) => { isFromParameter: false }\n */\nconst getIdentifierParameterOrigin = (\n identifier: TSESTree.Identifier,\n context: TSESLint.RuleContext<string, ReadonlyArray<unknown>>\n): ParameterOriginResult => {\n const scope = context.sourceCode.getScope(identifier);\n const variable = scope.references.find(ref => ref.identifier === identifier)?.resolved;\n\n if (!variable) {\n return { isFromParameter: false };\n }\n\n // Check the variable's definitions\n for (const definition of variable.defs) {\n // Check if defined as a direct function parameter\n if (definition.type === \"Parameter\") {\n // Direct parameter: (onClose) => ...\n return { isFromParameter: true, originType: \"direct-parameter\" };\n }\n\n // Check for destructured variable in body: const { onClose } = props\n // definition.type is \"Variable\" and definition.node is VariableDeclarator\n if (definition.type === \"Variable\") {\n const declarator = definition.node;\n\n // Check if the left side is an ObjectPattern (destructuring)\n if (declarator.id.type === AST_NODE_TYPES.ObjectPattern) {\n const init = declarator.init;\n\n // Check if destructured from an identifier that is a parameter\n if (init?.type === AST_NODE_TYPES.Identifier) {\n const initScope = context.sourceCode.getScope(init);\n const initVariable = initScope.references.find(ref => ref.identifier === init)?.resolved;\n\n if (initVariable && isVariableAParameter(initVariable)) {\n return { isFromParameter: true, originType: \"destructured-in-body\" };\n }\n }\n }\n }\n\n // Check if it's a destructured parameter directly in function signature\n // Pattern: ({ onClose }) => ... or ({ onClose }: Props) => ...\n if (definition.node.type === AST_NODE_TYPES.Property) {\n // Check direct parent - should be ObjectPattern for destructured props\n const objectPattern = definition.node.parent;\n if (objectPattern.type !== AST_NODE_TYPES.ObjectPattern) {\n continue;\n }\n\n // Check if this ObjectPattern is a function parameter\n const objectPatternParent = objectPattern.parent;\n\n if (\n objectPatternParent.type === AST_NODE_TYPES.ArrowFunctionExpression ||\n objectPatternParent.type === AST_NODE_TYPES.FunctionExpression ||\n objectPatternParent.type === AST_NODE_TYPES.FunctionDeclaration\n ) {\n // Check if the ObjectPattern is in the params\n const isParam = objectPatternParent.params.includes(objectPattern);\n if (isParam) {\n return { isFromParameter: true, originType: \"destructured-in-signature\" };\n }\n }\n\n // Also check for AssignmentPattern wrapper: ({ onClose = defaultFn }) => ...\n if (objectPatternParent.type === AST_NODE_TYPES.AssignmentPattern) {\n const assignmentParent = objectPatternParent.parent;\n\n if (\n assignmentParent.type === AST_NODE_TYPES.ArrowFunctionExpression ||\n assignmentParent.type === AST_NODE_TYPES.FunctionExpression ||\n assignmentParent.type === AST_NODE_TYPES.FunctionDeclaration\n ) {\n const isParam = assignmentParent.params.includes(objectPatternParent);\n if (isParam) {\n return { isFromParameter: true, originType: \"destructured-in-signature\" };\n }\n }\n }\n }\n }\n\n return { isFromParameter: false };\n};\n\n/**\n * Checks if an identifier originates from a function parameter.\n * This is a simplified boolean helper that wraps `getIdentifierParameterOrigin`.\n *\n * Use this when you only need to know if an identifier comes from a parameter,\n * without needing to know how it was destructured.\n *\n * @param identifier - The identifier node to check\n * @param context - The ESLint rule context\n * @returns true if the identifier originates from a function parameter\n * @see getIdentifierParameterOrigin for detailed origin information\n */\nexport const isIdentifierFromParameter = (\n identifier: TSESTree.Identifier,\n context: TSESLint.RuleContext<string, ReadonlyArray<unknown>>\n): boolean => getIdentifierParameterOrigin(identifier, context).isFromParameter;\n\n/**\n * Checks if an identifier's parameter comes from a render prop callback.\n *\n * Render prop pattern: `{callback => <Component onClick={callback} />}`\n *\n * The function detects when:\n * 1. The identifier comes from a parameter\n * 2. That parameter's function is inside a JSXExpressionContainer\n * 3. Which is a child of a JSXElement (render prop pattern)\n *\n * This is used to distinguish between:\n * - React component props: `const Modal = ({ onClose }) => ...` - should be flagged\n * - Render prop callbacks: `<MoreMenu>{close => <MenuItem onClick={close} />}</MoreMenu>` - should NOT be flagged\n *\n * @param identifier - The identifier node to check\n * @param context - The ESLint rule context\n * @returns true if the identifier comes from a render prop callback parameter\n * @example\n * // Render prop callback - returns true\n * <MoreMenu>\n * {close => <MenuItem onClick={close} />}\n * </MoreMenu>\n * // isIdentifierFromRenderPropCallback(close) => true\n * @example\n * // React component prop - returns false\n * const Modal = ({ onClose }) => <button onClick={onClose} />;\n * // isIdentifierFromRenderPropCallback(onClose) => false\n */\nexport const isIdentifierFromRenderPropCallback = (\n identifier: TSESTree.Identifier,\n context: TSESLint.RuleContext<string, ReadonlyArray<unknown>>\n): boolean => {\n // First check if it even comes from a parameter\n if (!isIdentifierFromParameter(identifier, context)) {\n return false;\n }\n\n // Get the variable that this identifier resolves to\n const scope = context.sourceCode.getScope(identifier);\n const variable = scope.references.find(ref => ref.identifier === identifier)?.resolved;\n\n if (!variable) {\n return false;\n }\n\n // Check each definition of this variable\n for (const definition of variable.defs) {\n if (definition.type !== \"Parameter\") {\n continue;\n }\n\n // Find the function that contains this parameter by walking up from the definition node\n let functionNode:\n | TSESTree.ArrowFunctionExpression\n | TSESTree.FunctionExpression\n | TSESTree.FunctionDeclaration\n | null = null;\n\n let current: TSESTree.Node | undefined = definition.node;\n do {\n if (\n current.type === AST_NODE_TYPES.ArrowFunctionExpression ||\n current.type === AST_NODE_TYPES.FunctionExpression ||\n current.type === AST_NODE_TYPES.FunctionDeclaration\n ) {\n functionNode = current;\n break;\n }\n current = current.parent;\n } while (current !== undefined);\n\n if (!functionNode) {\n continue;\n }\n\n // Check if the function is inside a JSXExpressionContainer (render prop pattern)\n // Pattern: <Component>{callback => ...}</Component>\n const parent = functionNode.parent;\n if (parent.type === AST_NODE_TYPES.JSXExpressionContainer) {\n // Verify the JSXExpressionContainer is a child of a JSXElement\n const jsxContainerParent = parent.parent;\n if (\n jsxContainerParent.type === AST_NODE_TYPES.JSXElement ||\n jsxContainerParent.type === AST_NODE_TYPES.JSXFragment\n ) {\n return true;\n }\n }\n }\n\n return false;\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"classname-utils.js","sourceRoot":"","sources":["../../../../../../../libs/eslint/plugin-trackunit/src/lib/utils/classname-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AST_NODE_TYPES, TSESTree } from \"@typescript-eslint/utils\";\n\n/**\n * Utility functions for finding and analyzing Tailwind CSS classnames in ESLint rules.\n *\n * This module provides a centralized way to detect classname usage patterns across:\n * - JSX `className` and `class` attributes\n * - Variables named with `...Class` or `...ClassName` suffixes\n * - Tailwind utility functions: `cvaMerge`, `twMerge`, `cva`, `tw`, `twx`, `tws`, `cn`, `clsx`, `classNames`, `twJoin`\n *\n * ## Core Concepts\n *\n * ### ClassnameLocation\n * Represents a single location where a classname string value is found.\n * Contains the string value, the AST node for reporting/fixing, and metadata.\n *\n * ### ClassnameContext\n * Describes where a classname was found (JSX attribute, function call, variable, etc.)\n *\n * ## Usage in ESLint Rules\n *\n * ```typescript\n * import { findClassnameStrings, TAILWIND_FUNCTIONS, isClassnameVariable } from \"./classname-utils\";\n *\n * // In a CallExpression handler:\n * CallExpression(node) {\n * const locations = findClassnameStrings(node);\n * for (const location of locations) {\n * // Check location.value for banned patterns\n * // Report on location.reportNode\n * // Fix using location.fixNode\n * }\n * }\n * ```\n */\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Context describing where a classname was found\n */\nexport type ClassnameContext =\n | { type: \"jsx-attribute\"; attributeName: string }\n | { type: \"function-call\"; functionName: string; argumentIndex: number }\n | { type: \"cva-variant\"; functionName: string; variantPath: Array<string> }\n | { type: \"variable\"; variableName: string }\n | { type: \"array-element\"; parentContext: ClassnameContext; elementIndex: number };\n\n/**\n * Represents a location where a classname string value is found\n */\nexport type ClassnameLocation = {\n /** The extracted string value (for template literals, only static parts) */\n value: string;\n /** The AST node to use when reporting errors */\n reportNode: TSESTree.Node;\n /** The AST node to use when creating fixes (string literal or template literal) */\n fixNode: TSESTree.Literal | TSESTree.TemplateLiteral;\n /** Context describing where this classname was found */\n context: ClassnameContext;\n};\n\n/**\n * Result of extracting a string value from a node\n */\ntype StringExtractionResult = {\n value: string;\n node: TSESTree.Literal | TSESTree.TemplateLiteral;\n} | null;\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Function names that accept Tailwind class strings as arguments.\n * These are commonly used for class merging and conditional class application.\n *\n * Corresponds to the `tailwindFunctions` config in .prettierrc for Prettier's\n * Tailwind CSS plugin.\n */\nexport const TAILWIND_FUNCTIONS = [\n \"cva\",\n \"cvaMerge\",\n \"tw\",\n \"twx\",\n \"tws\",\n \"twMerge\",\n \"twJoin\",\n \"cn\",\n \"clsx\",\n \"classNames\",\n] as const;\n\nexport type TailwindFunction = (typeof TAILWIND_FUNCTIONS)[number];\n\n/**\n * Variable name patterns that indicate a classname value.\n * Matches variables like: containerClass, buttonClassName, rootClasses\n */\nconst CLASSNAME_VARIABLE_PATTERNS = [/Class$/, /ClassName$/, /Classes$/] as const;\n\n/**\n * JSX attribute names that contain classname values\n */\nexport const CLASSNAME_ATTRIBUTES = [\"className\", \"class\"] as const;\n\n// =============================================================================\n// Detection Helpers\n// =============================================================================\n\n/**\n * Check if a function name is a known Tailwind utility function\n */\nexport const isTailwindFunction = (name: string): name is TailwindFunction => {\n return TAILWIND_FUNCTIONS.some(fn => fn === name);\n};\n\n/**\n * Check if a variable name indicates it contains classnames\n */\nexport const isClassnameVariable = (name: string): boolean => {\n return CLASSNAME_VARIABLE_PATTERNS.some(pattern => pattern.test(name));\n};\n\n/**\n * Check if a JSX attribute name is a classname attribute\n */\nexport const isClassnameAttribute = (name: string): boolean => {\n return CLASSNAME_ATTRIBUTES.some(attr => attr === name);\n};\n\n/**\n * Get the function name from a CallExpression callee\n */\nexport const getCalleeName = (callee: TSESTree.CallExpression[\"callee\"]): string | null => {\n if (callee.type === AST_NODE_TYPES.Identifier) {\n return callee.name;\n }\n if (callee.type === AST_NODE_TYPES.MemberExpression && callee.property.type === AST_NODE_TYPES.Identifier) {\n return callee.property.name;\n }\n return null;\n};\n\n// =============================================================================\n// String Extraction\n// =============================================================================\n\n/**\n * Extract a string value from a Literal node\n */\nconst extractFromLiteral = (node: TSESTree.Literal): StringExtractionResult => {\n if (typeof node.value === \"string\") {\n return { value: node.value, node };\n }\n return null;\n};\n\n/**\n * Extract the static parts of a TemplateLiteral as a single string.\n * Template expressions are replaced with a single space to preserve word boundaries.\n */\nconst extractFromTemplateLiteral = (node: TSESTree.TemplateLiteral): StringExtractionResult => {\n // Join static parts with spaces (representing where expressions would be)\n const value = node.quasis.map(quasi => quasi.value.raw).join(\" \");\n return { value, node };\n};\n\n/**\n * Extract string value from a node that might contain a classname string.\n * Handles Literal and TemplateLiteral nodes.\n */\nconst extractStringValue = (node: TSESTree.Node): StringExtractionResult => {\n switch (node.type) {\n case AST_NODE_TYPES.Literal:\n return extractFromLiteral(node);\n case AST_NODE_TYPES.TemplateLiteral:\n return extractFromTemplateLiteral(node);\n default:\n return null;\n }\n};\n\n// =============================================================================\n// Array Traversal\n// =============================================================================\n\n/**\n * Extract classname locations from an ArrayExpression.\n * Handles arrays like: [\"flex\", \"items-center\", \"bg-primary-500\"]\n */\nconst extractFromArray = (\n node: TSESTree.ArrayExpression,\n parentContext: ClassnameContext\n): Array<ClassnameLocation> => {\n const locations: Array<ClassnameLocation> = [];\n\n node.elements.forEach((element, index) => {\n if (!element || element.type === AST_NODE_TYPES.SpreadElement) {\n return;\n }\n\n const extracted = extractStringValue(element);\n if (extracted) {\n locations.push({\n value: extracted.value,\n reportNode: element,\n fixNode: extracted.node,\n context: { type: \"array-element\", parentContext, elementIndex: index },\n });\n }\n });\n\n return locations;\n};\n\n// =============================================================================\n// CVA/CVAMerge Object Traversal\n// =============================================================================\n\n/**\n * Recursively extract classname locations from a CVA options object.\n *\n * CVA structure:\n * ```\n * cva(baseClasses, {\n * variants: {\n * variantName: {\n * variantValue: \"classnames here\",\n * }\n * },\n * compoundVariants: [\n * { variantName: \"value\", className: \"classnames\" }\n * ],\n * defaultVariants: { ... }\n * })\n * ```\n */\nconst extractFromCvaObject = (\n node: TSESTree.ObjectExpression,\n functionName: string,\n currentPath: Array<string> = []\n): Array<ClassnameLocation> => {\n const locations: Array<ClassnameLocation> = [];\n\n for (const property of node.properties) {\n if (property.type !== AST_NODE_TYPES.Property) {\n continue;\n }\n\n const keyName = getPropertyKeyName(property.key);\n if (!keyName) {\n continue;\n }\n\n const propertyPath = [...currentPath, keyName];\n\n // Skip defaultVariants as it doesn't contain classnames\n if (keyName === \"defaultVariants\") {\n continue;\n }\n\n // Recurse into nested objects (variants, compoundVariants entries, etc.)\n if (property.value.type === AST_NODE_TYPES.ObjectExpression) {\n locations.push(...extractFromCvaObject(property.value, functionName, propertyPath));\n continue;\n }\n\n // Handle arrays (compoundVariants array, or array of class strings)\n if (property.value.type === AST_NODE_TYPES.ArrayExpression) {\n // Check if this is an array of objects (like compoundVariants)\n const hasObjectElements = property.value.elements.some(el => el?.type === AST_NODE_TYPES.ObjectExpression);\n\n if (hasObjectElements) {\n // Recurse into each object in the array\n property.value.elements.forEach((element, index) => {\n if (element?.type === AST_NODE_TYPES.ObjectExpression) {\n locations.push(...extractFromCvaObject(element, functionName, [...propertyPath, `[${index}]`]));\n }\n });\n } else {\n // This is an array of class strings\n const arrayContext: ClassnameContext = {\n type: \"cva-variant\",\n functionName,\n variantPath: propertyPath,\n };\n locations.push(...extractFromArray(property.value, arrayContext));\n }\n continue;\n }\n\n // Extract string values at leaf nodes\n const extracted = extractStringValue(property.value);\n if (extracted) {\n locations.push({\n value: extracted.value,\n reportNode: property.value,\n fixNode: extracted.node,\n context: {\n type: \"cva-variant\",\n functionName,\n variantPath: propertyPath,\n },\n });\n }\n }\n\n return locations;\n};\n\n/**\n * Get the name of an object property key\n */\nconst getPropertyKeyName = (key: TSESTree.Property[\"key\"]): string | null => {\n if (key.type === AST_NODE_TYPES.Identifier) {\n return key.name;\n }\n if (key.type === AST_NODE_TYPES.Literal && typeof key.value === \"string\") {\n return key.value;\n }\n return null;\n};\n\n// =============================================================================\n// Function Call Extraction\n// =============================================================================\n\n/**\n * Extract classname locations from a Tailwind function call.\n *\n * Handles various argument patterns:\n * - String literals: twMerge(\"flex items-center\")\n * - Template literals: twMerge(`flex ${condition && \"hidden\"}`)\n * - Arrays: cvaMerge([\"flex\", \"items-center\"], options)\n * - CVA options objects: cva(base, { variants: { ... } })\n */\nconst extractFromFunctionCall = (node: TSESTree.CallExpression): Array<ClassnameLocation> => {\n const calleeName = getCalleeName(node.callee);\n if (!calleeName || !isTailwindFunction(calleeName)) {\n return [];\n }\n\n const locations: Array<ClassnameLocation> = [];\n const isCvaStyle = calleeName === \"cva\" || calleeName === \"cvaMerge\";\n\n node.arguments.forEach((arg, argIndex) => {\n const baseContext: ClassnameContext = {\n type: \"function-call\",\n functionName: calleeName,\n argumentIndex: argIndex,\n };\n\n // Handle string literals\n const extracted = extractStringValue(arg);\n if (extracted) {\n locations.push({\n value: extracted.value,\n reportNode: arg,\n fixNode: extracted.node,\n context: baseContext,\n });\n return;\n }\n\n // Handle array arguments\n if (arg.type === AST_NODE_TYPES.ArrayExpression) {\n locations.push(...extractFromArray(arg, baseContext));\n return;\n }\n\n // Handle CVA options object (typically second argument)\n if (isCvaStyle && arg.type === AST_NODE_TYPES.ObjectExpression) {\n locations.push(...extractFromCvaObject(arg, calleeName));\n }\n });\n\n return locations;\n};\n\n// =============================================================================\n// JSX Attribute Extraction\n// =============================================================================\n\n/**\n * Extract classname locations from a JSX attribute (className or class).\n *\n * Handles various value patterns:\n * - String literals: className=\"flex items-center\"\n * - Expression with string: className={\"flex items-center\"}\n * - Template literals: className={`flex ${condition && \"hidden\"}`}\n */\nconst extractFromJsxAttribute = (node: TSESTree.JSXAttribute): Array<ClassnameLocation> => {\n if (node.name.type !== AST_NODE_TYPES.JSXIdentifier) {\n return [];\n }\n\n const attrName = node.name.name;\n if (!isClassnameAttribute(attrName)) {\n return [];\n }\n\n const attrValue = node.value;\n if (!attrValue) {\n return [];\n }\n\n const context: ClassnameContext = {\n type: \"jsx-attribute\",\n attributeName: attrName,\n };\n\n // Direct string literal: className=\"flex items-center\"\n if (attrValue.type === AST_NODE_TYPES.Literal) {\n const extracted = extractFromLiteral(attrValue);\n if (extracted) {\n return [\n {\n value: extracted.value,\n reportNode: node,\n fixNode: extracted.node,\n context,\n },\n ];\n }\n }\n\n // JSX Expression: className={...}\n if (attrValue.type === AST_NODE_TYPES.JSXExpressionContainer) {\n const expression = attrValue.expression;\n\n // Skip empty expressions\n if (expression.type === AST_NODE_TYPES.JSXEmptyExpression) {\n return [];\n }\n\n // String literal in expression: className={\"flex items-center\"}\n const extracted = extractStringValue(expression);\n if (extracted) {\n return [\n {\n value: extracted.value,\n reportNode: node,\n fixNode: extracted.node,\n context,\n },\n ];\n }\n\n // Note: We don't recurse into function calls here as they're handled\n // separately by the CallExpression handler in the rule\n }\n\n return [];\n};\n\n// =============================================================================\n// Variable Declaration Extraction\n// =============================================================================\n\n/**\n * Extract classname locations from a variable declaration with a classname-like name.\n *\n * Example: const buttonClass = \"flex items-center\";\n */\nconst extractFromVariableDeclarator = (node: TSESTree.VariableDeclarator): Array<ClassnameLocation> => {\n if (node.id.type !== AST_NODE_TYPES.Identifier) {\n return [];\n }\n\n const varName = node.id.name;\n if (!isClassnameVariable(varName)) {\n return [];\n }\n\n if (!node.init) {\n return [];\n }\n\n const context: ClassnameContext = {\n type: \"variable\",\n variableName: varName,\n };\n\n // Handle string literal\n const extracted = extractStringValue(node.init);\n if (extracted) {\n return [\n {\n value: extracted.value,\n reportNode: node.init,\n fixNode: extracted.node,\n context,\n },\n ];\n }\n\n // Handle array of strings\n if (node.init.type === AST_NODE_TYPES.ArrayExpression) {\n return extractFromArray(node.init, context);\n }\n\n // Note: Function calls in variable initializers are handled separately\n // by the CallExpression handler\n\n return [];\n};\n\n// =============================================================================\n// Unified Entry Points\n// =============================================================================\n\n/**\n * Find all classname string locations in a CallExpression node.\n *\n * Use this in your ESLint rule's CallExpression handler to process\n * Tailwind utility function calls like twMerge, cvaMerge, etc.\n *\n * @example\n * ```typescript\n * CallExpression(node) {\n * const locations = findClassnameStringsInCall(node);\n * for (const location of locations) {\n * if (hasBannedPattern(location.value)) {\n * context.report({ node: location.reportNode, ... });\n * }\n * }\n * }\n * ```\n */\nexport const findClassnameStringsInCall = (node: TSESTree.CallExpression): Array<ClassnameLocation> => {\n return extractFromFunctionCall(node);\n};\n\n/**\n * Find all classname string locations in a JSXAttribute node.\n *\n * Use this in your ESLint rule's JSXAttribute handler to process\n * className and class attributes.\n *\n * @example\n * ```typescript\n * JSXAttribute(node) {\n * const locations = findClassnameStringsInAttribute(node);\n * for (const location of locations) {\n * if (hasBannedPattern(location.value)) {\n * context.report({ node: location.reportNode, ... });\n * }\n * }\n * }\n * ```\n */\nexport const findClassnameStringsInAttribute = (node: TSESTree.JSXAttribute): Array<ClassnameLocation> => {\n return extractFromJsxAttribute(node);\n};\n\n/**\n * Find all classname string locations in a VariableDeclarator node.\n *\n * Use this in your ESLint rule's VariableDeclarator handler to process\n * variables with classname-like names.\n *\n * @example\n * ```typescript\n * VariableDeclarator(node) {\n * const locations = findClassnameStringsInVariable(node);\n * for (const location of locations) {\n * if (hasBannedPattern(location.value)) {\n * context.report({ node: location.reportNode, ... });\n * }\n * }\n * }\n * ```\n */\nconst findClassnameStringsInVariable = (node: TSESTree.VariableDeclarator): Array<ClassnameLocation> => {\n return extractFromVariableDeclarator(node);\n};\n\n// =============================================================================\n// Utility Helpers for Fixing\n// =============================================================================\n\n/**\n * Split a classname string into individual class names.\n * Handles whitespace-separated classes.\n */\nexport const splitClasses = (value: string): Array<string> => {\n return value.split(/\\s+/).filter(Boolean);\n};\n\n/**\n * Join class names into a single string.\n */\nexport const joinClasses = (classes: Array<string>): string => {\n return classes.join(\" \");\n};\n\n/**\n * Create a JSON-formatted array string from an array of class names.\n * Useful for auto-fix operations.\n */\nexport const formatAsArray = (classes: Array<string>): string => {\n return JSON.stringify(classes);\n};\n\n/**\n * Get the quote character used in a string literal.\n */\nconst getQuoteChar = (node: TSESTree.Literal): string => {\n if (typeof node.value === \"string\" && node.raw) {\n return node.raw.charAt(0);\n }\n return '\"';\n};\n\n/**\n * Create a quoted string with the same quote style as the original.\n */\nconst quoteString = (value: string, originalNode: TSESTree.Literal): string => {\n const quote = getQuoteChar(originalNode);\n return `${quote}${value}${quote}`;\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file-utils.js","sourceRoot":"","sources":["../../../../../../../libs/eslint/plugin-trackunit/src/lib/utils/file-utils.ts"],"names":[],"mappings":";;;;AAAA,+CAAyB;AACzB,mDAA6B;AAE7B;;;;;GAKG;AAIH;;;;;;;;;;;;GAYG;AACI,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAE,QAAgB,EAAiB,EAAE;IACnF,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;IAEzC,OAAO,UAAU,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAEnD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAfW,QAAA,eAAe,mBAe1B","sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\n\n/**\n * Utility functions for working with files in ESLint rules.\n *\n * ## Main Functions\n * - `findNearestFile()` - Find the nearest file by walking up the directory tree\n */\n\n\n\n/**\n * Find the nearest file with a given name by walking up the directory tree.\n *\n * @param filePath - The starting file path\n * @param fileName - The file name to search for (e.g., \"package.json\", \"project.json\")\n * @returns Absolute path to the file or null if not found\n * @example\n * const pkgPath = findNearestFile(\"/workspace/libs/my-lib/src/index.ts\", \"package.json\");\n * // Returns: \"/workspace/libs/my-lib/package.json\"\n * @example\n * const projectPath = findNearestFile(\"/workspace/libs/my-lib/src/index.ts\", \"project.json\");\n * // Returns: \"/workspace/libs/my-lib/project.json\"\n */\nexport const findNearestFile = (filePath: string, fileName: string): string | null => {\n let currentDir = path.dirname(filePath);\n const root = path.parse(currentDir).root;\n\n while (currentDir !== root) {\n const targetPath = path.join(currentDir, fileName);\n\n if (fs.existsSync(targetPath)) {\n return targetPath;\n }\n\n currentDir = path.dirname(currentDir);\n }\n\n return null;\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"import-utils.js","sourceRoot":"","sources":["../../../../../../../libs/eslint/plugin-trackunit/src/lib/utils/import-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { AST_NODE_TYPES, TSESLint, TSESTree } from \"@typescript-eslint/utils\";\n\n/**\n * Utility functions for manipulating import statements in TypeScript ESLint rules.\n *\n * ## Design Philosophy\n * Rules should focus on WHAT to do, not HOW to do it. This utility handles all the\n * implementation details: semicolons, newlines, alphabetical sorting, merging, etc.\n *\n * ## Main Functions\n * - `addImportSpecifiers()` - Add new imports or merge with existing ones\n * - `replaceNamespaceWithDestructured()` - Replace namespace imports (e.g., `import React from \"react\"`)\n * - `addSingleImportSpecifier()` - Convenience for adding a single import\n *\n * ## Helper Functions\n * - `findImportDeclaration()` - Find existing import for a package\n * - `hasImportSpecifier()` - Check if specific import already exists\n * - `getImportSpecifiers()` - Extract specifiers from an import\n */\n\n/**\n * Internal helper to check if an import statement ends with a semicolon\n */\nconst hasSemicolon = (sourceCode: Readonly<TSESLint.SourceCode>, node: TSESTree.ImportDeclaration): boolean => {\n const nodeText = sourceCode.getText(node);\n return nodeText.trimEnd().endsWith(\";\");\n};\n\n/**\n * Find an existing import declaration for a given package.\n *\n * @example\n * // Returns the import node if it exists:\n * // import { useState } from \"react\";\n * const reactImport = findImportDeclaration(sourceCode, \"react\");\n */\nexport const findImportDeclaration = (\n sourceCode: Readonly<TSESLint.SourceCode>,\n packageName: string\n): TSESTree.ImportDeclaration | undefined => {\n const found = sourceCode.ast.body.find(\n (node): node is TSESTree.ImportDeclaration =>\n node.type === AST_NODE_TYPES.ImportDeclaration && node.source.value === packageName\n );\n return found;\n};\n\n/**\n * Check if a specific specifier is already imported from a package.\n *\n * @example\n * // File has: import { useState, useEffect } from \"react\";\n * hasImportSpecifier(sourceCode, \"react\", \"useState\") // → true\n * hasImportSpecifier(sourceCode, \"react\", \"useRef\") // → false\n */\nconst hasImportSpecifier = (\n sourceCode: Readonly<TSESLint.SourceCode>,\n packageName: string,\n specifierName: string\n): boolean => {\n return sourceCode.ast.body.some(\n node =>\n node.type === AST_NODE_TYPES.ImportDeclaration &&\n node.source.value === packageName &&\n node.specifiers.some(\n specifier =>\n specifier.type === AST_NODE_TYPES.ImportSpecifier &&\n specifier.imported.type === AST_NODE_TYPES.Identifier &&\n specifier.imported.name === specifierName\n )\n );\n};\n\n/**\n * Get existing import specifiers from an import declaration.\n *\n * @example\n * // Given: import { useState, useEffect } from \"react\";\n * getImportSpecifiers(importNode) // → Set([\"useState\", \"useEffect\"])\n */\nexport const getImportSpecifiers = (importNode: TSESTree.ImportDeclaration): Set<string> => {\n return new Set(\n importNode.specifiers\n .filter((s): s is TSESTree.ImportSpecifier => s.type === AST_NODE_TYPES.ImportSpecifier)\n .map(s => (s.imported.type === AST_NODE_TYPES.Identifier ? s.imported.name : \"\"))\n .filter(Boolean)\n );\n};\n\ninterface AddImportSpecifiersOptions {\n sourceCode: Readonly<TSESLint.SourceCode>;\n fixer: TSESLint.RuleFixer;\n packageName: string;\n /** Specifiers to add (e.g., [\"useState\", \"useEffect\"]) */\n specifiers: Array<string>;\n /** Optional: Existing import to merge into. If not provided, creates a new import statement */\n existingImport?: TSESTree.ImportDeclaration;\n}\n\n/**\n * Internal helper to build a properly formatted import statement with sorted specifiers\n */\nconst buildImportStatement = (\n sourceCode: Readonly<TSESLint.SourceCode>,\n packageName: string,\n specifiers: Iterable<string>,\n referenceNode?: TSESTree.ImportDeclaration\n): string => {\n const sortedSpecifiers = Array.from(specifiers).sort().join(\", \");\n const semicolon = referenceNode && hasSemicolon(sourceCode, referenceNode) ? \";\" : \";\";\n return `import { ${sortedSpecifiers} } from \"${packageName}\"${semicolon}`;\n};\n\n/**\n * Add import specifiers to an existing import or create a new import statement.\n * Automatically handles merging, semicolons, newlines, alphabetical sorting, and formatting.\n *\n * @example\n * // Case 1: No existing import - creates new\n * // Before: (no imports)\n * // After: import { useEffect, useState } from \"react\";\n * @example\n * // Case 2: Merge with existing import\n * // Before: import { useState } from \"react\";\n * // After: import { useEffect, useState } from \"react\";\n */\nexport const addImportSpecifiers = (options: AddImportSpecifiersOptions): Array<TSESLint.RuleFix> => {\n const { sourceCode, fixer, packageName, specifiers, existingImport } = options;\n const fixes: Array<TSESLint.RuleFix> = [];\n\n if (existingImport) {\n // Merge with existing import\n const existingSpecifiers = getImportSpecifiers(existingImport);\n const combinedSpecifiers = new Set([...existingSpecifiers, ...specifiers]);\n const importStatement = buildImportStatement(sourceCode, packageName, combinedSpecifiers, existingImport);\n\n fixes.push(fixer.replaceText(existingImport, importStatement));\n } else {\n // Create new import statement\n const lastImport = sourceCode.ast.body.find(\n (node): node is TSESTree.ImportDeclaration => node.type === AST_NODE_TYPES.ImportDeclaration\n );\n\n if (lastImport) {\n // Add after existing imports with leading newline\n const importStatement = \"\\n\" + buildImportStatement(sourceCode, packageName, specifiers, lastImport);\n fixes.push(fixer.insertTextAfter(lastImport, importStatement));\n } else {\n // No imports exist - add at the beginning with trailing newlines\n const firstNode = sourceCode.ast.body[0];\n if (firstNode) {\n const importStatement = buildImportStatement(sourceCode, packageName, specifiers) + \"\\n\\n\";\n fixes.push(fixer.insertTextBefore(firstNode, importStatement));\n }\n }\n }\n\n return fixes;\n};\n\ninterface AddSingleImportSpecifierOptions {\n sourceCode: Readonly<TSESLint.SourceCode>;\n fixer: TSESLint.RuleFixer;\n packageName: string;\n /** The specifier to add (e.g., \"useState\") */\n specifier: string;\n}\n\n/**\n * Add a single import specifier - convenience wrapper around addImportSpecifiers.\n * Automatically finds and merges with existing imports from the same package.\n *\n * @example\n * // Before: import { useState } from \"react\";\n * // After: import { useEffect, useState } from \"react\";\n * addSingleImportSpecifier({ sourceCode, fixer, packageName: \"react\", specifier: \"useEffect\" })\n */\nconst addSingleImportSpecifier = (options: AddSingleImportSpecifierOptions): Array<TSESLint.RuleFix> => {\n const { sourceCode, packageName, specifier } = options;\n const existingImport = findImportDeclaration(sourceCode, packageName);\n\n return addImportSpecifiers({\n ...options,\n specifiers: [specifier],\n existingImport,\n });\n};\n\ninterface ReplaceNamespaceWithDestructuredOptions {\n sourceCode: Readonly<TSESLint.SourceCode>;\n fixer: TSESLint.RuleFixer;\n packageName: string;\n /** The namespace/default import statement to be replaced (e.g., `import React from \"react\"`) */\n namespaceImportToReplace: TSESTree.ImportDeclaration;\n /** Specifiers to add to the destructured import (e.g., [\"useState\", \"useEffect\"]) */\n specifiersToAdd: Iterable<string>;\n /** Optional: A separate destructured import to merge everything into (e.g., `import { FC } from \"react\"`) */\n mergeIntoImport?: TSESTree.ImportDeclaration;\n}\n\n/**\n * Replace a namespace/default import with destructured imports.\n * Automatically handles merging, semicolons, sorting, and formatting.\n *\n * ## Example 1: Replace in-place (no other import)\n * ```typescript\n * // Before:\n * import React from \"react\";\n * React.useEffect(() => {}, []);\n *\n * // After:\n * import { useEffect } from \"react\";\n * useEffect(() => {}, []);\n * ```\n *\n * ## Example 2: Merge with existing destructured import\n * ```typescript\n * // Before:\n * import React from \"react\"; // ← namespaceImportToReplace\n * import { useState } from \"react\"; // ← mergeIntoImport\n * React.useEffect(() => {}, []);\n *\n * // After:\n * import { useEffect, useState } from \"react\"; // ← Merged!\n * useEffect(() => {}, []);\n * ```\n *\n * @param namespaceImportToReplace - The namespace import to remove/replace\n * @param specifiersToAdd - New specifiers to add\n * @param mergeIntoImport - Optional separate destructured import to merge everything into\n */\nexport const replaceNamespaceWithDestructured = (\n options: ReplaceNamespaceWithDestructuredOptions\n): Array<TSESLint.RuleFix> => {\n const { sourceCode, fixer, packageName, namespaceImportToReplace, specifiersToAdd, mergeIntoImport } = options;\n const fixes: Array<TSESLint.RuleFix> = [];\n\n // Get any existing destructured specifiers from the namespace import itself\n const existingSpecifiersInNamespace = getImportSpecifiers(namespaceImportToReplace);\n const allNewSpecifiers = new Set([...existingSpecifiersInNamespace, ...specifiersToAdd]);\n\n if (mergeIntoImport && mergeIntoImport !== namespaceImportToReplace) {\n // Scenario: We have TWO imports - merge everything into the destructured one and remove the namespace one\n const existingSpecifiers = getImportSpecifiers(mergeIntoImport);\n const combinedSpecifiers = new Set([...existingSpecifiers, ...allNewSpecifiers]);\n const importStatement = buildImportStatement(sourceCode, packageName, combinedSpecifiers, mergeIntoImport);\n\n fixes.push(fixer.replaceText(mergeIntoImport, importStatement));\n fixes.push(fixer.remove(namespaceImportToReplace));\n } else {\n // Scenario: Only ONE import - replace the namespace import in-place\n const importStatement = buildImportStatement(sourceCode, packageName, allNewSpecifiers, namespaceImportToReplace);\n fixes.push(fixer.replaceText(namespaceImportToReplace, importStatement));\n }\n\n return fixes;\n};\n"]}
|