{"version":3,"file":"index.mjs","names":["RULE_NAME","RULE_NAME","RULE_NAME","packageJson.name","packageJson.version","preferDestructuredOptionals","validEventListener","noInlineInterfaces","noRedundantJsxPropUsage"],"sources":["../package.json","../src/utils.ts","../src/rules/no-inline-interfaces.ts","../src/rules/no-redundant-jsx-prop-usage.ts","../src/rules/prefer-destructured-optionals.ts","../src/rules/valid-event-listener.ts","../src/index.ts"],"sourcesContent":["","import { ESLintUtils } from \"@typescript-eslint/utils\";\nimport type { FsecondDocs } from \"./types\";\n\nexport const createEslintRule = ESLintUtils.RuleCreator<FsecondDocs>(\n  (ruleName) => ruleName,\n);\n","/* eslint-disable @typescript-eslint/switch-exhaustiveness-check */\n/* eslint-disable fsecond/prefer-destructured-optionals */\nimport {\n  AST_NODE_TYPES,\n  ASTUtils,\n  type TSESTree,\n} from \"@typescript-eslint/utils\";\nimport { createEslintRule } from \"../utils\";\n\nconst RULE_NAME = \"no-inline-interfaces\";\n\nconst isStatementParent = ASTUtils.isNodeOfTypes([\n  AST_NODE_TYPES.Program,\n  AST_NODE_TYPES.BlockStatement,\n  AST_NODE_TYPES.TSModuleBlock,\n] as const);\n\nconst findStatementAncestor = (node: TSESTree.Node): TSESTree.Node | null => {\n  if (!node.parent) {\n    return null;\n  }\n  if (isStatementParent(node.parent)) {\n    return node;\n  }\n\n  return findStatementAncestor(node.parent);\n};\n\ntype MessageIds = \"noInlineInterfaces\";\ntype Options = [\n  {\n    checkGenericTypes?: boolean;\n    checkReturnTypes?: boolean;\n  }?,\n];\n\n/**\n * Recursively find all TSTypeLiteral nodes in a type annotation.\n * Returns all inline object type literals that should be reported.\n */\nconst findTypeLiterals = (\n  type: TSESTree.TypeNode | undefined,\n  results: TSESTree.TSTypeLiteral[] = [],\n  checkGenericTypes = false,\n): TSESTree.TSTypeLiteral[] => {\n  if (!type) {\n    return results;\n  }\n\n  switch (type.type) {\n    case AST_NODE_TYPES.TSTypeLiteral: {\n      results.push(type);\n      // Also check for nested type literals inside the members\n      type.members.forEach((member) => {\n        if (\n          member.type === AST_NODE_TYPES.TSPropertySignature &&\n          member.typeAnnotation\n        ) {\n          findTypeLiterals(\n            member.typeAnnotation.typeAnnotation,\n            results,\n            checkGenericTypes,\n          );\n        }\n      });\n\n      return results;\n    }\n\n    case AST_NODE_TYPES.TSUnionType:\n    case AST_NODE_TYPES.TSIntersectionType: {\n      for (const typeNode of type.types) {\n        findTypeLiterals(typeNode, results, checkGenericTypes);\n      }\n      break;\n    }\n\n    case AST_NODE_TYPES.TSTypeReference: {\n      // Only check generic type arguments if checkGenericTypes is true\n      if (checkGenericTypes && type.typeArguments) {\n        type.typeArguments.params.forEach((param) => {\n          findTypeLiterals(param, results, checkGenericTypes);\n        });\n      }\n      break;\n    }\n\n    case AST_NODE_TYPES.TSArrayType: {\n      findTypeLiterals(type.elementType, results, checkGenericTypes);\n      break;\n    }\n\n    case AST_NODE_TYPES.TSTupleType: {\n      type.elementTypes.forEach((elementType) => {\n        findTypeLiterals(elementType, results, checkGenericTypes);\n      });\n      break;\n    }\n\n    case AST_NODE_TYPES.TSOptionalType: {\n      findTypeLiterals(type.typeAnnotation, results, checkGenericTypes);\n      break;\n    }\n\n    case AST_NODE_TYPES.TSRestType: {\n      findTypeLiterals(type.typeAnnotation, results, checkGenericTypes);\n      break;\n    }\n\n    case AST_NODE_TYPES.TSTypeOperator: {\n      findTypeLiterals(type.typeAnnotation, results, checkGenericTypes);\n      break;\n    }\n\n    case AST_NODE_TYPES.TSIndexedAccessType: {\n      findTypeLiterals(type.objectType, results, checkGenericTypes);\n      findTypeLiterals(type.indexType, results, checkGenericTypes);\n      break;\n    }\n\n    case AST_NODE_TYPES.TSConditionalType: {\n      // Check the true and false branches of conditional types\n      findTypeLiterals(type.trueType, results, checkGenericTypes);\n      findTypeLiterals(type.falseType, results, checkGenericTypes);\n      findTypeLiterals(type.checkType, results, checkGenericTypes);\n      findTypeLiterals(type.extendsType, results, checkGenericTypes);\n      break;\n    }\n    case AST_NODE_TYPES.TSConstructorType:\n    case AST_NODE_TYPES.TSFunctionType: {\n      // Check parameter types and return type\n      type.params.forEach((param) => {\n        if (param.type === AST_NODE_TYPES.TSParameterProperty) {\n          findTypeLiterals(\n            param.parameter.typeAnnotation?.typeAnnotation,\n            results,\n            checkGenericTypes,\n          );\n        } else if (param.typeAnnotation) {\n          findTypeLiterals(\n            param.typeAnnotation.typeAnnotation,\n            results,\n            checkGenericTypes,\n          );\n        }\n      });\n      findTypeLiterals(\n        type.returnType?.typeAnnotation,\n        results,\n        checkGenericTypes,\n      );\n      break;\n    }\n    case AST_NODE_TYPES.TSImportType: {\n      // Check type arguments if present\n      if (type.typeArguments) {\n        type.typeArguments.params.forEach((param) => {\n          findTypeLiterals(param, results, checkGenericTypes);\n        });\n      }\n      break;\n    }\n    case AST_NODE_TYPES.TSMappedType: {\n      // Check the mapped type's type annotation\n      findTypeLiterals(type.typeAnnotation, results, checkGenericTypes);\n      if (type.nameType) {\n        findTypeLiterals(type.nameType, results, checkGenericTypes);\n      }\n      break;\n    }\n    case AST_NODE_TYPES.TSNamedTupleMember: {\n      // Check the element type of the named tuple member\n      findTypeLiterals(type.elementType, results, checkGenericTypes);\n      break;\n    }\n    case AST_NODE_TYPES.TSTypePredicate: {\n      // Check the parameter name type and type annotation\n      if (type.typeAnnotation) {\n        findTypeLiterals(\n          type.typeAnnotation.typeAnnotation,\n          results,\n          checkGenericTypes,\n        );\n      }\n      break;\n    }\n    default: {\n      // Ignore other type nodes (primitives, etc.)\n      break;\n    }\n  }\n\n  return results;\n};\n\nconst isClassNode = ASTUtils.isNodeOfTypes([\n  AST_NODE_TYPES.ClassDeclaration,\n  AST_NODE_TYPES.ClassExpression,\n] as const);\n\n/**\n * Check if a node is inside a class.\n */\nconst isInsideClass = (node: TSESTree.Node): boolean => {\n  if (!node.parent) {\n    return false;\n  }\n  if (isClassNode(node.parent)) {\n    return true;\n  }\n\n  return isInsideClass(node.parent);\n};\n\nexport default createEslintRule<Options, MessageIds>({\n  name: RULE_NAME,\n  meta: {\n    type: \"suggestion\",\n    docs: {\n      description:\n        \"disallow inline object type literals in variable and function annotations; extract to a named interface or type alias.\",\n      url: \"https://github.com/AndreaPontrandolfo/eslint-plugin-fsecond/blob/master/docs/rules/no-inline-interfaces.md\",\n      recommended: true,\n    },\n    fixable: \"code\",\n    schema: [\n      {\n        type: \"object\",\n        properties: {\n          checkGenericTypes: {\n            type: \"boolean\",\n            description:\n              \"Check inline object types within generic type arguments (e.g., Array<{ a: string }>)\",\n          },\n          checkReturnTypes: {\n            type: \"boolean\",\n            description:\n              \"Check inline object types in function return type annotations\",\n          },\n        },\n        additionalProperties: false,\n      },\n    ],\n    defaultOptions: [\n      {\n        checkGenericTypes: false,\n        checkReturnTypes: false,\n      },\n    ],\n    messages: {\n      noInlineInterfaces:\n        \"Extract this inline object type into a named interface or type alias and reference it here.\",\n    },\n  },\n  defaultOptions: [\n    {\n      checkGenericTypes: false,\n      checkReturnTypes: false,\n    },\n  ],\n  create(context) {\n    const options = context.options[0] ?? {};\n    const checkGenericTypes = options.checkGenericTypes ?? false;\n    const checkReturnTypes = options.checkReturnTypes ?? false;\n    let interfaceCounter = 0;\n\n    /**\n     * Report all inline object type literals found in a type annotation.\n     */\n    const reportTypeAnnotation = (\n      typeAnnotation: TSESTree.TypeNode | undefined,\n    ) => {\n      const literals = findTypeLiterals(typeAnnotation, [], checkGenericTypes);\n\n      for (const literal of literals) {\n        interfaceCounter = interfaceCounter + 1;\n        const interfaceName =\n          interfaceCounter === 1\n            ? \"InlineInterface\"\n            : `InlineInterface${String(interfaceCounter)}`;\n\n        context.report({\n          node: literal,\n          messageId: \"noInlineInterfaces\",\n          fix(fixer) {\n            const statementNode = findStatementAncestor(literal);\n\n            if (!statementNode) {\n              return null;\n            }\n\n            const { sourceCode } = context;\n            const openBrace = sourceCode.getFirstToken(literal);\n            const closeBrace = sourceCode.getLastToken(literal);\n\n            if (!openBrace || !closeBrace) {\n              return null;\n            }\n\n            const bodyText = sourceCode\n              .getText()\n              .slice(openBrace.range[1], closeBrace.range[0]);\n\n            return [\n              fixer.insertTextBefore(\n                statementNode,\n                `interface ${interfaceName} {${bodyText}}\\n`,\n              ),\n              fixer.replaceText(literal, interfaceName),\n            ];\n          },\n        });\n      }\n    };\n\n    /**\n     * Check a parameter node for type annotations\n     * Handles both direct parameters and parameters with default values (AssignmentPattern).\n     */\n    const checkParameter = (param: TSESTree.Parameter) => {\n      let nodeToCheck: TSESTree.Node = param;\n\n      // If parameter has a default value, it's wrapped in AssignmentPattern\n      // The type annotation is on the 'left' side\n      if (param.type === AST_NODE_TYPES.AssignmentPattern) {\n        nodeToCheck = param.left;\n      }\n\n      // Check for node types that can have type annotations\n      if (\n        (nodeToCheck.type === AST_NODE_TYPES.Identifier ||\n          nodeToCheck.type === AST_NODE_TYPES.ArrayPattern ||\n          nodeToCheck.type === AST_NODE_TYPES.ObjectPattern ||\n          nodeToCheck.type === AST_NODE_TYPES.RestElement) &&\n        nodeToCheck.typeAnnotation\n      ) {\n        reportTypeAnnotation(nodeToCheck.typeAnnotation.typeAnnotation);\n      }\n    };\n\n    return {\n      VariableDeclarator(node) {\n        // Skip if inside a class\n        if (isInsideClass(node)) {\n          return;\n        }\n\n        // Check variable type annotation\n        if (node.id.typeAnnotation) {\n          reportTypeAnnotation(node.id.typeAnnotation.typeAnnotation);\n        }\n      },\n\n      FunctionDeclaration(node) {\n        // Skip if inside a class\n        if (isInsideClass(node)) {\n          return;\n        }\n\n        // Check each parameter's type annotation\n        node.params.forEach((param) => {\n          checkParameter(param);\n        });\n\n        // Check return type annotation if enabled\n        if (checkReturnTypes && node.returnType) {\n          reportTypeAnnotation(node.returnType.typeAnnotation);\n        }\n      },\n\n      FunctionExpression(node) {\n        // Skip if inside a class\n        if (isInsideClass(node)) {\n          return;\n        }\n\n        // Check each parameter's type annotation\n        node.params.forEach((param) => {\n          checkParameter(param);\n        });\n\n        // Check return type annotation if enabled\n        if (checkReturnTypes && node.returnType) {\n          reportTypeAnnotation(node.returnType.typeAnnotation);\n        }\n      },\n\n      ArrowFunctionExpression(node) {\n        // Skip if inside a class\n        if (isInsideClass(node)) {\n          return;\n        }\n\n        // Check each parameter's type annotation\n        node.params.forEach((param) => {\n          checkParameter(param);\n        });\n\n        // Check return type annotation if enabled\n        if (checkReturnTypes && node.returnType) {\n          reportTypeAnnotation(node.returnType.typeAnnotation);\n        }\n      },\n    };\n  },\n});\n","import * as ts from \"typescript\";\nimport {\n  AST_NODE_TYPES,\n  ESLintUtils,\n  type TSESTree,\n} from \"@typescript-eslint/utils\";\nimport { createEslintRule } from \"../utils\";\n\nconst RULE_NAME = \"no-redundant-jsx-prop-usage\";\n\ntype MessageIds = \"noRedundantJsxPropUsage\";\ntype Options = [];\n\n// Sentinel value to distinguish \"not a comparable primitive\" from a real value\nconst SKIP = Symbol(\"SKIP\");\n\ntype PrimitiveValue = string | number | boolean | null | undefined;\n\n/**\n * Extracts a primitive literal value from a TypeScript AST expression node.\n * Returns SKIP if the expression is not a primitive literal we can compare.\n */\nconst extractPrimitiveLiteral = (\n  node: ts.Expression,\n): PrimitiveValue | typeof SKIP => {\n  if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {\n    return node.text;\n  }\n  if (ts.isNumericLiteral(node)) {\n    return Number(node.text);\n  }\n  if (node.kind === ts.SyntaxKind.TrueKeyword) {\n    return true;\n  }\n  if (node.kind === ts.SyntaxKind.FalseKeyword) {\n    return false;\n  }\n  if (node.kind === ts.SyntaxKind.NullKeyword) {\n    return null;\n  }\n  if (ts.isIdentifier(node) && node.text === \"undefined\") {\n    return undefined;\n  }\n  // Negative numbers: -42\n  if (\n    ts.isPrefixUnaryExpression(node) &&\n    node.operator === ts.SyntaxKind.MinusToken &&\n    ts.isNumericLiteral(node.operand)\n  ) {\n    return -Number(node.operand.text);\n  }\n\n  return SKIP;\n};\n\n/**\n * If the call expression is React.forwardRef(...) or forwardRef(...),\n * returns the inner function (the actual component). Otherwise returns undefined.\n */\nconst unwrapForwardRef = (\n  callExpr: ts.CallExpression,\n): ts.ArrowFunction | ts.FunctionExpression | undefined => {\n  const callee = callExpr.expression;\n  let funcName: string | undefined;\n\n  if (ts.isIdentifier(callee)) {\n    funcName = callee.text;\n  } else if (\n    ts.isPropertyAccessExpression(callee) &&\n    ts.isIdentifier(callee.name)\n  ) {\n    funcName = callee.name.text;\n  }\n\n  if (funcName === \"forwardRef\") {\n    const firstArg = callExpr.arguments[0];\n\n    if (ts.isArrowFunction(firstArg) || ts.isFunctionExpression(firstArg)) {\n      return firstArg;\n    }\n  }\n\n  return undefined;\n};\n\n/**\n * Given a TypeScript declaration node, attempts to find the function-like node\n * that represents the React component. Returns a Map of prop name -\\> default value,\n * or null if the declaration cannot be analyzed.\n */\nconst extractDefaultsFromDeclaration = (\n  decl: ts.Declaration,\n): Map<string, PrimitiveValue> | null => {\n  let functionNode: ts.FunctionLikeDeclaration | undefined;\n\n  if (\n    ts.isFunctionDeclaration(decl) ||\n    ts.isFunctionExpression(decl) ||\n    ts.isArrowFunction(decl)\n  ) {\n    functionNode = decl;\n  } else if (ts.isVariableDeclaration(decl)) {\n    const init = decl.initializer;\n\n    if (!init) {\n      return null;\n    }\n    if (ts.isArrowFunction(init) || ts.isFunctionExpression(init)) {\n      functionNode = init;\n    } else if (ts.isCallExpression(init)) {\n      // Handle React.forwardRef(...)\n      const inner = unwrapForwardRef(init);\n\n      if (inner) {\n        functionNode = inner;\n      }\n    }\n  }\n\n  if (!functionNode) {\n    return null;\n  }\n\n  const firstParam = functionNode.parameters[0];\n\n  // Parameters array can be empty for zero-argument functions\n  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n  if (!firstParam) {\n    return null;\n  }\n\n  const bindingPattern = firstParam.name;\n\n  if (!ts.isObjectBindingPattern(bindingPattern)) {\n    return null;\n  }\n\n  const defaults = new Map<string, PrimitiveValue>();\n\n  for (const element of bindingPattern.elements) {\n    if (!element.initializer) {\n      continue;\n    }\n\n    // The prop name is either the property name (for renamed bindings: { foo: bar = \"x\" })\n    // or the element name itself (for simple bindings: { foo = \"x\" })\n    let propName: string | undefined;\n\n    if (element.propertyName) {\n      if (ts.isIdentifier(element.propertyName)) {\n        propName = element.propertyName.text;\n      }\n    } else if (ts.isIdentifier(element.name)) {\n      propName = element.name.text;\n    }\n\n    if (!propName) {\n      continue;\n    }\n\n    const defaultValue = extractPrimitiveLiteral(element.initializer);\n\n    if (defaultValue !== SKIP) {\n      defaults.set(propName, defaultValue);\n    }\n  }\n\n  return defaults;\n};\n\n/**\n * Extracts a primitive value from a JSX attribute value (ESTree side).\n * Returns SKIP if the value is not a comparable primitive literal.\n */\nconst getJSXAttributePrimitiveValue = (\n  attr: TSESTree.JSXAttribute,\n): PrimitiveValue | typeof SKIP => {\n  const { value } = attr;\n\n  // Boolean shorthand: <Button disabled /> means disabled={true}\n  if (value === null) {\n    return true;\n  }\n\n  // String literal: <Button variant=\"primary\" />\n  if (value.type === AST_NODE_TYPES.Literal) {\n    const v = value.value;\n\n    if (\n      typeof v === \"string\" ||\n      typeof v === \"number\" ||\n      typeof v === \"boolean\" ||\n      v === null\n    ) {\n      return v;\n    }\n\n    return SKIP;\n  }\n\n  // JSX expression container: <Button count={42} />\n  if (value.type === AST_NODE_TYPES.JSXExpressionContainer) {\n    const expr = value.expression;\n\n    if (expr.type === AST_NODE_TYPES.Literal) {\n      const v = expr.value;\n\n      if (\n        typeof v === \"string\" ||\n        typeof v === \"number\" ||\n        typeof v === \"boolean\" ||\n        v === null\n      ) {\n        return v;\n      }\n    }\n\n    // {undefined}\n    if (expr.type === AST_NODE_TYPES.Identifier && expr.name === \"undefined\") {\n      return undefined;\n    }\n\n    // Negative numbers: {-42}\n    if (\n      expr.type === AST_NODE_TYPES.UnaryExpression &&\n      expr.operator === \"-\" &&\n      expr.argument.type === AST_NODE_TYPES.Literal &&\n      typeof expr.argument.value === \"number\"\n    ) {\n      return -expr.argument.value;\n    }\n  }\n\n  return SKIP;\n};\n\nexport default createEslintRule<Options, MessageIds>({\n  name: RULE_NAME,\n  meta: {\n    type: \"suggestion\",\n    docs: {\n      description:\n        \"disallow passing a JSX prop whose value matches the component's destructuring default for that prop\",\n      url: \"https://github.com/AndreaPontrandolfo/eslint-plugin-fsecond/blob/master/docs/rules/no-redundant-jsx-prop-usage.md\",\n      recommended: false,\n      requiresTypeChecking: true,\n    },\n    fixable: \"code\",\n    schema: [],\n    messages: {\n      noRedundantJsxPropUsage:\n        'Prop \"{{propName}}\" is redundant — it matches the default value ({{defaultValue}}).',\n    },\n  },\n  defaultOptions: [],\n  create(context) {\n    const services = ESLintUtils.getParserServices(context);\n    const checker = services.program.getTypeChecker();\n\n    // Cache defaults per resolved symbol to avoid redundant work within a file\n    const defaultsCache = new Map<\n      ts.Symbol,\n      Map<string, PrimitiveValue> | null\n    >();\n\n    const getDefaultsForSymbol = (\n      symbol: ts.Symbol,\n    ): Map<string, PrimitiveValue> | null => {\n      if (defaultsCache.has(symbol)) {\n        return defaultsCache.get(symbol) ?? null;\n      }\n\n      const { declarations } = symbol;\n\n      if (!declarations || declarations.length === 0) {\n        defaultsCache.set(symbol, null);\n\n        return null;\n      }\n\n      for (const declaration of declarations) {\n        const defaults = extractDefaultsFromDeclaration(declaration);\n\n        if (defaults !== null) {\n          defaultsCache.set(symbol, defaults);\n\n          return defaults;\n        }\n      }\n\n      defaultsCache.set(symbol, null);\n\n      return null;\n    };\n\n    return {\n      JSXOpeningElement(node) {\n        // Skip intrinsic HTML elements (lowercase names like \"div\", \"span\")\n        const nameNode = node.name;\n\n        // Skip intrinsic HTML elements: lowercase or empty names\n        if (\n          nameNode.type === AST_NODE_TYPES.JSXIdentifier &&\n          (nameNode.name.length === 0 ||\n            nameNode.name.startsWith(nameNode.name[0].toLowerCase()))\n        ) {\n          return;\n        }\n\n        // Resolve the component symbol via type checker\n        const symbol = services.getSymbolAtLocation(nameNode);\n\n        if (!symbol) {\n          return;\n        }\n\n        // Follow import aliases to reach the original declaration\n        const resolvedSymbol =\n          symbol.flags & ts.SymbolFlags.Alias\n            ? checker.getAliasedSymbol(symbol)\n            : symbol;\n\n        const defaults = getDefaultsForSymbol(resolvedSymbol);\n\n        if (!defaults || defaults.size === 0) {\n          return;\n        }\n\n        // Check each JSX attribute against the defaults\n        for (const attr of node.attributes) {\n          if (attr.type !== AST_NODE_TYPES.JSXAttribute) {\n            continue;\n          }\n\n          const propNameNode = attr.name;\n\n          if (propNameNode.type !== AST_NODE_TYPES.JSXIdentifier) {\n            continue;\n          }\n          const propName = propNameNode.name;\n\n          if (!defaults.has(propName)) {\n            continue;\n          }\n\n          const attrValue = getJSXAttributePrimitiveValue(attr);\n\n          if (attrValue === SKIP) {\n            continue;\n          }\n\n          const defaultValue = defaults.get(propName);\n\n          if (attrValue === defaultValue) {\n            context.report({\n              node: attr,\n              messageId: \"noRedundantJsxPropUsage\",\n              data: {\n                propName,\n                defaultValue: String(defaultValue),\n              },\n              fix(fixer) {\n                const tokenBefore = context.sourceCode.getTokenBefore(attr);\n\n                // Remove the attribute along with the preceding whitespace/token gap\n                const start = tokenBefore\n                  ? tokenBefore.range[1]\n                  : attr.range[0];\n\n                return fixer.removeRange([start, attr.range[1]]);\n              },\n            });\n          }\n        }\n      },\n    };\n  },\n});\n","import { AST_NODE_TYPES, type TSESTree } from \"@typescript-eslint/utils\";\nimport { createEslintRule } from \"../utils\";\n\nconst RULE_NAME = \"prefer-destructured-optionals\";\n\ntype MessageIds = \"noNonDestructuredOptional\";\ntype Options = [];\n\nexport default createEslintRule<Options, MessageIds>({\n  name: RULE_NAME,\n  meta: {\n    type: \"suggestion\",\n    docs: {\n      description:\n        \"enforce placing optional parameters on a destructured object instead of the function signature itself\",\n      recommended: true,\n      url: \"https://github.com/AndreaPontrandolfo/eslint-plugin-fsecond/blob/master/docs/rules/prefer-destructured-optionals.md\",\n    },\n    schema: [],\n    messages: {\n      noNonDestructuredOptional:\n        \"Convert this optional parameter to a destructured parameter.\",\n    },\n  },\n  defaultOptions: [],\n  create(context) {\n    const checkParameters = (params: TSESTree.Parameter[]) => {\n      let isParamObjectInTheMiddle = false;\n\n      params.forEach((param) => {\n        if (\n          (param.type === AST_NODE_TYPES.AssignmentPattern &&\n            param.left.type !== AST_NODE_TYPES.ObjectPattern) ||\n          (param.type === AST_NODE_TYPES.Identifier && param.optional)\n        ) {\n          context.report({\n            node: param,\n            messageId: \"noNonDestructuredOptional\",\n          });\n        }\n\n        if (\n          isParamObjectInTheMiddle &&\n          param.type !== AST_NODE_TYPES.ObjectPattern\n        ) {\n          context.report({\n            node: param,\n            messageId: \"noNonDestructuredOptional\",\n          });\n        }\n\n        if (\n          param.type === AST_NODE_TYPES.ObjectPattern ||\n          (param.type === AST_NODE_TYPES.AssignmentPattern &&\n            param.left.type === AST_NODE_TYPES.ObjectPattern)\n        ) {\n          isParamObjectInTheMiddle = true;\n        }\n      });\n    };\n\n    return {\n      FunctionDeclaration(node) {\n        checkParameters(node.params);\n      },\n      FunctionExpression(node) {\n        checkParameters(node.params);\n      },\n      ArrowFunctionExpression(node) {\n        checkParameters(node.params);\n      },\n    };\n  },\n});\n","/* eslint-disable @typescript-eslint/no-unnecessary-condition */\nimport { AST_NODE_TYPES, type TSESTree } from \"@typescript-eslint/utils\";\nimport { createEslintRule } from \"../utils\";\n\nconst RULE_NAME = \"valid-event-listener\";\n\ntype MessageIds =\n  | \"required-cleanup\"\n  | \"required-remove-eventListener\"\n  | \"no-conditional-addeventlistener\"\n  | \"require-use-event-listener-hook\";\ntype Options = [\n  {\n    requireUseEventListenerHook?: boolean;\n  }?,\n];\n\n/**\n * Helper function: Check if a node is a method call to addEventListener or removeEventListener.\n */\nconst isEventListenerMethodCall = (\n  node: unknown,\n  methodName: \"addEventListener\" | \"removeEventListener\",\n): node is TSESTree.CallExpression => {\n  // Handle ChainExpression wrapping the entire CallExpression\n  let currentNode = node;\n\n  if (\n    currentNode instanceof Object &&\n    \"type\" in currentNode &&\n    currentNode.type === AST_NODE_TYPES.ChainExpression\n  ) {\n    currentNode = (currentNode as TSESTree.ChainExpression).expression;\n  }\n\n  // Validate it's a CallExpression\n  if (\n    !(currentNode instanceof Object) ||\n    !(\"type\" in currentNode) ||\n    currentNode.type !== AST_NODE_TYPES.CallExpression ||\n    !(\"callee\" in currentNode)\n  ) {\n    return false;\n  }\n\n  const callExpression = currentNode as TSESTree.CallExpression;\n\n  // Handle ChainExpression wrapping the callee MemberExpression\n  let { callee } = callExpression;\n\n  if (\n    callee instanceof Object &&\n    callee.type === AST_NODE_TYPES.ChainExpression\n  ) {\n    callee = callee.expression;\n  }\n\n  // Check if callee is a MemberExpression with the correct method name\n  return (\n    callee instanceof Object &&\n    callee.type === AST_NODE_TYPES.MemberExpression &&\n    callee.property instanceof Object &&\n    callee.property.type === AST_NODE_TYPES.Identifier &&\n    callee.property.name === methodName\n  );\n};\n\n/**\n * Helper function: Check if node is an addEventListener call.\n */\nconst isAddEventListenerCall = (node: unknown): boolean => {\n  return isEventListenerMethodCall(node, \"addEventListener\");\n};\n\n/**\n * Helper function: Check if node is a removeEventListener call.\n */\nconst isRemoveEventListenerCall = (node: unknown): boolean => {\n  return isEventListenerMethodCall(node, \"removeEventListener\");\n};\n\n/**\n * Helper function: Check if a call expression is useEffect or useLayoutEffect.\n */\nconst isUseEffectOrUseLayoutEffectCall = (\n  node: TSESTree.CallExpression,\n): boolean => {\n  const { callee } = node;\n\n  // Direct call: useEffect() or useLayoutEffect()\n  if (callee.type === AST_NODE_TYPES.Identifier) {\n    return callee.name === \"useEffect\" || callee.name === \"useLayoutEffect\";\n  }\n\n  // Member expression call: React.useEffect() or React.useLayoutEffect()\n  if (callee.type === AST_NODE_TYPES.MemberExpression && !callee.computed) {\n    return (\n      callee.property.type === AST_NODE_TYPES.Identifier &&\n      (callee.property.name === \"useEffect\" ||\n        callee.property.name === \"useLayoutEffect\")\n    );\n  }\n\n  return false;\n};\n\n/**\n * Helper function: Check if an expression statement contains a conditional addEventListener.\n */\nconst isConditionalAddEventListener = (node: TSESTree.Statement): boolean => {\n  if (node.type !== AST_NODE_TYPES.IfStatement) {\n    return false;\n  }\n\n  // Check if statement has addEventListener in consequent block\n  if (node.consequent.type === AST_NODE_TYPES.BlockStatement) {\n    for (const statement of node.consequent.body) {\n      if (\n        statement.type === AST_NODE_TYPES.ExpressionStatement &&\n        isAddEventListenerCall(statement.expression)\n      ) {\n        return true;\n      }\n    }\n  }\n\n  // Check inline if without block\n  if (\n    node.consequent.type === AST_NODE_TYPES.ExpressionStatement &&\n    isAddEventListenerCall(node.consequent.expression)\n  ) {\n    return true;\n  }\n\n  // Check else/alternate block\n  if (node.alternate?.type === AST_NODE_TYPES.BlockStatement) {\n    for (const statement of node.alternate.body) {\n      if (\n        statement.type === AST_NODE_TYPES.ExpressionStatement &&\n        isAddEventListenerCall(statement.expression)\n      ) {\n        return true;\n      }\n    }\n  }\n\n  // Check inline else\n  return (\n    node.alternate?.type === AST_NODE_TYPES.ExpressionStatement &&\n    isAddEventListenerCall(node.alternate.expression)\n  );\n};\n\n/**\n * Helper function: Check if expression has conditional addEventListener (logical or ternary).\n */\nconst isConditionalExpression = (expression: TSESTree.Expression): boolean => {\n  // Check logical AND: x && element.addEventListener(...)\n  if (\n    expression.type === AST_NODE_TYPES.LogicalExpression &&\n    expression.operator === \"&&\" &&\n    isAddEventListenerCall(expression.right)\n  ) {\n    return true;\n  }\n\n  // Check ternary: x ? element.addEventListener(...) : ...\n  if (expression.type === AST_NODE_TYPES.ConditionalExpression) {\n    if (isAddEventListenerCall(expression.consequent)) {\n      return true;\n    }\n    if (isAddEventListenerCall(expression.alternate)) {\n      return true;\n    }\n  }\n\n  return false;\n};\n\n/**\n * Helper function: Search block for addEventListener, return true if found.\n */\nconst findAddEventListenerInBlock = (\n  statements: TSESTree.Statement[],\n): boolean => {\n  for (const statement of statements) {\n    if (statement.type === AST_NODE_TYPES.ExpressionStatement) {\n      if (isAddEventListenerCall(statement.expression)) {\n        return true;\n      }\n      if (isConditionalExpression(statement.expression)) {\n        return true;\n      }\n    }\n  }\n\n  return false;\n};\n\n/**\n * Helper function: Search block for removeEventListener, return true if found.\n */\nconst findRemoveEventListenerInBlock = (\n  statements: TSESTree.Statement[],\n): boolean => {\n  for (const statement of statements) {\n    if (\n      statement.type === AST_NODE_TYPES.ExpressionStatement &&\n      isRemoveEventListenerCall(statement.expression)\n    ) {\n      return true;\n    }\n  }\n\n  return false;\n};\n\n/**\n * Helper function: Search cleanup function (return statement) for removeEventListener.\n */\nconst findRemoveEventListenerInCleanup = (\n  statements: TSESTree.Statement[],\n): boolean => {\n  for (const statement of statements) {\n    if (statement.type !== AST_NODE_TYPES.ReturnStatement) {\n      continue;\n    }\n\n    const cleanupFunction = statement.argument;\n\n    if (\n      cleanupFunction &&\n      (cleanupFunction.type === AST_NODE_TYPES.ArrowFunctionExpression ||\n        cleanupFunction.type === AST_NODE_TYPES.FunctionExpression) &&\n      cleanupFunction.body?.type === AST_NODE_TYPES.BlockStatement &&\n      cleanupFunction.body.body &&\n      findRemoveEventListenerInBlock(cleanupFunction.body.body)\n    ) {\n      return true;\n    }\n\n    // Handle arrow expression body: () => element.removeEventListener(...)\n    if (\n      cleanupFunction?.type === AST_NODE_TYPES.ArrowFunctionExpression &&\n      cleanupFunction.body &&\n      isRemoveEventListenerCall(cleanupFunction.body)\n    ) {\n      return true;\n    }\n  }\n\n  return false;\n};\n\n/**\n * Helper function: Check if there's a return statement with a cleanup function.\n */\nconst hasReturnStatement = (statements: TSESTree.Statement[]): boolean => {\n  for (const statement of statements) {\n    if (\n      statement.type === AST_NODE_TYPES.ReturnStatement &&\n      statement.argument &&\n      (statement.argument.type === AST_NODE_TYPES.ArrowFunctionExpression ||\n        statement.argument.type === AST_NODE_TYPES.FunctionExpression)\n    ) {\n      return true;\n    }\n  }\n\n  return false;\n};\n\n/**\n * Helper function: Check if useEffect body has conditional addEventListener.\n */\nconst hasConditionalAddEventListener = (\n  statements: TSESTree.Statement[],\n): boolean => {\n  for (const statement of statements) {\n    if (isConditionalAddEventListener(statement)) {\n      return true;\n    }\n\n    if (\n      statement.type === AST_NODE_TYPES.ExpressionStatement &&\n      isConditionalExpression(statement.expression)\n    ) {\n      return true;\n    }\n  }\n\n  return false;\n};\n\n/**\n * Helper function: Unwrap ChainExpression to get the actual CallExpression.\n */\nconst unwrapToCallExpression = (\n  node: unknown,\n): TSESTree.CallExpression | null => {\n  let currentNode = node;\n\n  // Handle ChainExpression wrapping the entire CallExpression\n  if (\n    currentNode instanceof Object &&\n    \"type\" in currentNode &&\n    currentNode.type === AST_NODE_TYPES.ChainExpression\n  ) {\n    currentNode = (currentNode as TSESTree.ChainExpression).expression;\n  }\n\n  // Validate it's a CallExpression\n  if (\n    !(currentNode instanceof Object) ||\n    !(\"type\" in currentNode) ||\n    currentNode.type !== AST_NODE_TYPES.CallExpression\n  ) {\n    return null;\n  }\n\n  return currentNode as TSESTree.CallExpression;\n};\n\n/**\n * Helper function: Check if addEventListener call has \\{ once: true \\} option.\n */\nconst hasOnceOption = (call: unknown): boolean => {\n  if (!isEventListenerMethodCall(call, \"addEventListener\")) {\n    return false;\n  }\n\n  const callExpression = unwrapToCallExpression(call);\n\n  if (!callExpression) {\n    return false;\n  }\n\n  const optionsArgument = callExpression.arguments[2];\n\n  if (optionsArgument?.type === AST_NODE_TYPES.ObjectExpression) {\n    for (const property of optionsArgument.properties) {\n      if (\n        property.type === AST_NODE_TYPES.Property &&\n        property.key.type === AST_NODE_TYPES.Identifier &&\n        property.key.name === \"once\" &&\n        property.value.type === AST_NODE_TYPES.Literal &&\n        property.value.value === true\n      ) {\n        return true;\n      }\n    }\n  }\n\n  return false;\n};\n\n/**\n * Helper function: Check if there's any addEventListener in block that is not once.\n * Returns true if at least one addEventListener does NOT have \\{ once: true \\}.\n */\nconst hasNonOnceAddEventListenerInBlock = (\n  statements: TSESTree.Statement[],\n): boolean => {\n  for (const statement of statements) {\n    if (\n      statement.type === AST_NODE_TYPES.ExpressionStatement &&\n      isEventListenerMethodCall(statement.expression, \"addEventListener\") &&\n      !hasOnceOption(statement.expression)\n    ) {\n      return true;\n    }\n  }\n\n  return false;\n};\n\nexport default createEslintRule<Options, MessageIds>({\n  name: RULE_NAME,\n  meta: {\n    type: \"problem\",\n    docs: {\n      description:\n        \"enforces best practices around addEventListener method in React components.\",\n      url: \"https://github.com/AndreaPontrandolfo/eslint-plugin-fsecond/blob/master/docs/rules/valid-event-listener.md\",\n      recommended: true,\n    },\n    schema: [\n      {\n        type: \"object\",\n        additionalProperties: false,\n        properties: {\n          requireUseEventListenerHook: {\n            description: \"Require the use of a useEventListener hook\",\n            type: \"boolean\",\n          },\n        },\n      },\n    ],\n    defaultOptions: [\n      {\n        requireUseEventListenerHook: true,\n      },\n    ],\n    messages: {\n      \"required-cleanup\":\n        \"Missing a cleanup function for the addEventListener in React useEffect.\",\n      \"required-remove-eventListener\":\n        \"Missing a matching removeEventListener in the React useEffect cleanup.\",\n      \"no-conditional-addeventlistener\":\n        \"Don't wrap addEventListener in a condition in React components.\",\n      \"require-use-event-listener-hook\":\n        \"Use a useEventListener hook from a React hooks library instead of manually adding and removing event listeners.\",\n    },\n  },\n  defaultOptions: [\n    {\n      requireUseEventListenerHook: true,\n    },\n  ],\n  create(context) {\n    const providedFirstOption = context.options[0] ?? {};\n    const { requireUseEventListenerHook } = {\n      requireUseEventListenerHook: true,\n      ...providedFirstOption,\n    };\n\n    return {\n      ExpressionStatement(node) {\n        const expression = node?.expression;\n\n        if (expression.type !== AST_NODE_TYPES.CallExpression) {\n          return;\n        }\n\n        if (!isUseEffectOrUseLayoutEffectCall(expression)) {\n          return;\n        }\n\n        const firstArgument = expression.arguments[0];\n        const isFunctionExpression =\n          firstArgument?.type === AST_NODE_TYPES.ArrowFunctionExpression ||\n          firstArgument?.type === AST_NODE_TYPES.FunctionExpression;\n\n        const useEffectBodyInternalItems =\n          expression?.arguments &&\n          expression.arguments.length > 0 &&\n          isFunctionExpression &&\n          firstArgument.body?.type === AST_NODE_TYPES.BlockStatement &&\n          firstArgument.body.body;\n\n        if (\n          !useEffectBodyInternalItems ||\n          useEffectBodyInternalItems.length === 0\n        ) {\n          return;\n        }\n\n        // Check for conditional addEventListener first\n        const hasConditionalAdd = hasConditionalAddEventListener(\n          useEffectBodyInternalItems,\n        );\n\n        if (hasConditionalAdd) {\n          context.report({\n            node,\n            messageId: \"no-conditional-addeventlistener\",\n          });\n\n          return;\n        }\n\n        // Check for addEventListener in the main body\n        const hasAddEventListener = findAddEventListenerInBlock(\n          useEffectBodyInternalItems,\n        );\n\n        if (!hasAddEventListener) {\n          return;\n        }\n\n        // Check if hook is required\n        if (requireUseEventListenerHook) {\n          context.report({\n            node,\n            messageId: \"require-use-event-listener-hook\",\n          });\n\n          return;\n        }\n\n        // Check for cleanup\n        const hasReturnStmt = hasReturnStatement(useEffectBodyInternalItems);\n        const hasNonOnceAddEventListener = hasNonOnceAddEventListenerInBlock(\n          useEffectBodyInternalItems,\n        );\n\n        // If all addEventListener calls use { once: true }, no cleanup is needed\n        // This is safe for AbortSignal patterns where the event fires at most once\n        if (!hasNonOnceAddEventListener) {\n          return;\n        }\n\n        const hasRemoveEventListener = findRemoveEventListenerInCleanup(\n          useEffectBodyInternalItems,\n        );\n\n        if (!hasRemoveEventListener) {\n          if (hasReturnStmt) {\n            context.report({\n              node,\n              messageId: \"required-remove-eventListener\",\n            });\n          } else {\n            context.report({\n              node,\n              messageId: \"required-cleanup\",\n            });\n          }\n        }\n      },\n    };\n  },\n});\n","import packageJson from \"../package.json\";\nimport noInlineInterfaces from \"./rules/no-inline-interfaces\";\nimport noRedundantJsxPropUsage from \"./rules/no-redundant-jsx-prop-usage\";\n// import preferAliasedPath from \"./rules/prefer-aliased-path\";\nimport preferDestructuredOptionals from \"./rules/prefer-destructured-optionals\";\nimport validEventListener from \"./rules/valid-event-listener\";\n\nconst eslintPluginShortName = \"fsecond\";\n\nconst plugin = {\n  meta: { name: packageJson.name, version: packageJson.version },\n  configs: {},\n  rules: {\n    \"prefer-destructured-optionals\": preferDestructuredOptionals,\n    \"valid-event-listener\": validEventListener,\n    // \"prefer-aliased-path\": preferAliasedPath,\n    \"no-inline-interfaces\": noInlineInterfaces,\n    \"no-redundant-jsx-prop-usage\": noRedundantJsxPropUsage,\n  },\n};\n\nconst configs = {\n  recommended: [\n    {\n      plugins: {\n        fsecond: plugin,\n      },\n      rules: {\n        [`${eslintPluginShortName}/prefer-destructured-optionals`]: 2,\n        [`${eslintPluginShortName}/valid-event-listener`]: 2,\n        [`${eslintPluginShortName}/no-inline-interfaces`]: [\n          2,\n          { checkGenericTypes: false, checkReturnTypes: true },\n        ],\n      },\n    },\n  ],\n  recommendedTypeChecked: [\n    {\n      plugins: {\n        fsecond: plugin,\n      },\n      rules: {\n        [`${eslintPluginShortName}/prefer-destructured-optionals`]: 2,\n        [`${eslintPluginShortName}/valid-event-listener`]: 2,\n        [`${eslintPluginShortName}/no-inline-interfaces`]: [\n          2,\n          { checkGenericTypes: false, checkReturnTypes: true },\n        ],\n        [`${eslintPluginShortName}/no-redundant-jsx-prop-usage`]: 2,\n      },\n    },\n  ],\n};\n\nplugin.configs = configs;\n\ntype Plugin = typeof plugin & {\n  configs: typeof configs;\n};\n\nexport default plugin as Plugin;\n"],"mappings":"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"}