{"version":3,"file":"index.mjs","names":["collectFragmentContext","createJSXProcessingContext","UNKNOWN_ELEMENT_NAME","attributeNamesFromState","functionBodyPushAttributes","processJSX","applyAttributes","isReactFragment","getPathName","hasAttributeWithName","getJSXMemberExpressionObjectName"],"sources":["../../src/constants.ts","../../src/experimental.ts","../../src/index.ts"],"sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2020 Engineering at FullStory\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n */\n\nexport const KNOWN_INCOMPATIBLE_PLUGINS = [\n  // This module might be causing an issue preventing clicks. For safety, we won't run on this module.\n  \"react-native-testfairy\",\n  // This module checks for unexpected property keys and throws an exception.\n  \"@react-navigation\",\n];\n\nexport const DEFAULT_IGNORED_ELEMENTS = [\n  \"a\",\n  \"abbr\",\n  \"address\",\n  \"area\",\n  \"article\",\n  \"aside\",\n  \"audio\",\n  \"b\",\n  \"base\",\n  \"bdi\",\n  \"bdo\",\n  \"blockquote\",\n  \"body\",\n  \"br\",\n  \"button\",\n  \"canvas\",\n  \"caption\",\n  \"cite\",\n  \"code\",\n  \"col\",\n  \"colgroup\",\n  \"data\",\n  \"datalist\",\n  \"dd\",\n  \"del\",\n  \"details\",\n  \"dfn\",\n  \"dialog\",\n  \"div\",\n  \"dl\",\n  \"dt\",\n  \"em\",\n  \"embed\",\n  \"fieldset\",\n  \"figure\",\n  \"footer\",\n  \"form\",\n  \"h1\",\n  \"h2\",\n  \"h3\",\n  \"h4\",\n  \"h5\",\n  \"h6\",\n  \"head\",\n  \"header\",\n  \"hgroup\",\n  \"hr\",\n  \"html\",\n  \"i\",\n  \"iframe\",\n  \"img\",\n  \"input\",\n  \"ins\",\n  \"kbd\",\n  \"keygen\",\n  \"label\",\n  \"legend\",\n  \"li\",\n  \"link\",\n  \"main\",\n  \"map\",\n  \"mark\",\n  \"menu\",\n  \"menuitem\",\n  \"meter\",\n  \"nav\",\n  \"noscript\",\n  \"object\",\n  \"ol\",\n  \"optgroup\",\n  \"option\",\n  \"output\",\n  \"p\",\n  \"param\",\n  \"pre\",\n  \"progress\",\n  \"q\",\n  \"rb\",\n  \"rp\",\n  \"rt\",\n  \"rtc\",\n  \"ruby\",\n  \"s\",\n  \"samp\",\n  \"script\",\n  \"section\",\n  \"select\",\n  \"small\",\n  \"source\",\n  \"span\",\n  \"strong\",\n  \"style\",\n  \"sub\",\n  \"summary\",\n  \"sup\",\n  \"table\",\n  \"tbody\",\n  \"td\",\n  \"template\",\n  \"textarea\",\n  \"tfoot\",\n  \"th\",\n  \"thead\",\n  \"time\",\n  \"title\",\n  \"tr\",\n  \"track\",\n  \"u\",\n  \"ul\",\n  \"var\",\n  \"video\",\n  \"wbr\",\n];\n","/**\n * MIT License\n *\n * Copyright (c) 2020 Engineering at FullStory\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n */\n\n/**\n * The following code is based on the FullStory Babel plugin, but has been modified to work\n * with Sentry products:\n *\n * - Added `sentry` to data properties, i.e `data-sentry-component`\n * - Converted to TypeScript\n * - Code cleanups\n * - Highly modified to inject the data attributes into the root HTML elements of a component.\n */\n\nimport type * as Babel from \"@babel/core\";\nimport type { PluginObj, PluginPass } from \"@babel/core\";\n\nconst REACT_NATIVE_ELEMENTS: string[] = [\n  \"Image\",\n  \"Text\",\n  \"View\",\n  \"ScrollView\",\n  \"TextInput\",\n  \"TouchableOpacity\",\n  \"TouchableHighlight\",\n  \"TouchableWithoutFeedback\",\n  \"FlatList\",\n  \"SectionList\",\n  \"ActivityIndicator\",\n  \"Button\",\n  \"Switch\",\n  \"Modal\",\n  \"SafeAreaView\",\n  \"StatusBar\",\n  \"KeyboardAvoidingView\",\n  \"RefreshControl\",\n  \"Picker\",\n  \"Slider\",\n];\n\ninterface AnnotationOpts {\n  native?: boolean;\n  ignoredComponents?: string[];\n}\n\ninterface FragmentContext {\n  fragmentAliases: Set<string>;\n  reactNamespaceAliases: Set<string>;\n}\n\ninterface AnnotationPluginPass extends PluginPass {\n  opts: AnnotationOpts;\n  sentryFragmentContext?: FragmentContext;\n}\n\ntype AnnotationPlugin = PluginObj<AnnotationPluginPass>;\n\n// Shared context object for all JSX processing functions\ninterface JSXProcessingContext {\n  /** Babel types object */\n  t: typeof Babel.types;\n  /** Name of the React component */\n  componentName: string;\n  /** AAttribute name for the component */\n  attributeName: string;\n  /** Array of component names to ignore */\n  ignoredComponents: string[];\n  /** Fragment context for identifying React fragments */\n  fragmentContext?: FragmentContext;\n}\n\n// We must export the plugin as default, otherwise the Babel loader will not be able to resolve it when configured using its string identifier\nexport function experimentalComponentNameAnnotatePlugin({\n  types: t,\n}: typeof Babel): AnnotationPlugin {\n  return {\n    visitor: {\n      Program: {\n        enter(path, state) {\n          const fragmentContext = collectFragmentContext(path);\n          state.sentryFragmentContext = fragmentContext;\n        },\n      },\n      FunctionDeclaration(path, state) {\n        if (!path.node.id || !path.node.id.name) {\n          return;\n        }\n\n        const context = createJSXProcessingContext(state, t, path.node.id.name);\n        functionBodyPushAttributes(context, path);\n      },\n      ArrowFunctionExpression(path, state) {\n        // We're expecting a `VariableDeclarator` like `const MyComponent =`\n        const parent = path.parent;\n\n        if (\n          !parent ||\n          !(\"id\" in parent) ||\n          !parent.id ||\n          !(\"name\" in parent.id) ||\n          !parent.id.name\n        ) {\n          return;\n        }\n\n        const context = createJSXProcessingContext(state, t, parent.id.name);\n        functionBodyPushAttributes(context, path);\n      },\n      ClassDeclaration(path, state) {\n        const name = path.get(\"id\");\n        const properties = path.get(\"body\").get(\"body\");\n        const render = properties.find((prop) => {\n          return prop.isClassMethod() && prop.get(\"key\").isIdentifier({ name: \"render\" });\n        });\n\n        if (!render || !render.traverse) {\n          return;\n        }\n\n        const context = createJSXProcessingContext(state, t, name.node?.name || \"\");\n\n        render.traverse({\n          ReturnStatement(returnStatement) {\n            const arg = returnStatement.get(\"argument\");\n\n            if (!arg.isJSXElement() && !arg.isJSXFragment()) {\n              return;\n            }\n\n            processJSX(context, arg);\n          },\n        });\n      },\n    },\n  };\n}\n\n/**\n * Checks if an element name represents an HTML element (as opposed to a React component).\n * HTML elements include standard lowercase HTML tags and React Native elements.\n */\nfunction isHtmlElement(elementName: string): boolean {\n  // Unknown elements are not HTML elements\n  if (elementName === UNKNOWN_ELEMENT_NAME) {\n    return false;\n  }\n\n  // Check for lowercase first letter (standard HTML elements)\n  if (elementName.length > 0 && elementName.charAt(0) === elementName.charAt(0).toLowerCase()) {\n    return true;\n  }\n\n  // React Native elements typically start with uppercase but are still \"native\" elements\n  // We consider them HTML-like elements for annotation purposes\n  if (REACT_NATIVE_ELEMENTS.includes(elementName)) {\n    return true;\n  }\n\n  // Otherwise, assume it's a React component (PascalCase)\n  return false;\n}\n\n/**\n * Creates a JSX processing context from the plugin state\n */\nfunction createJSXProcessingContext(\n  state: AnnotationPluginPass,\n  t: typeof Babel.types,\n  componentName: string\n): JSXProcessingContext {\n  return {\n    t,\n    componentName,\n    attributeName: attributeNamesFromState(state),\n    ignoredComponents: state.opts.ignoredComponents ?? [],\n    fragmentContext: state.sentryFragmentContext,\n  };\n}\n\n/**\n * Processes the body of a function to add Sentry tracking attributes to JSX elements.\n * Handles various function body structures including direct JSX returns, conditional expressions,\n * and nested JSX elements.\n */\nfunction functionBodyPushAttributes(\n  context: JSXProcessingContext,\n  path: Babel.NodePath<Babel.types.Function>\n): void {\n  let jsxNode: Babel.NodePath;\n\n  const functionBody = path.get(\"body\").get(\"body\");\n\n  if (\n    !(\"length\" in functionBody) &&\n    functionBody.parent &&\n    (functionBody.parent.type === \"JSXElement\" || functionBody.parent.type === \"JSXFragment\")\n  ) {\n    const maybeJsxNode = functionBody.find((c) => {\n      return c.type === \"JSXElement\" || c.type === \"JSXFragment\";\n    });\n\n    if (!maybeJsxNode) {\n      return;\n    }\n\n    jsxNode = maybeJsxNode;\n  } else {\n    const returnStatement = functionBody.find((c) => {\n      return c.type === \"ReturnStatement\";\n    });\n    if (!returnStatement) {\n      return;\n    }\n\n    const arg = returnStatement.get(\"argument\");\n    if (!arg) {\n      return;\n    }\n\n    if (Array.isArray(arg)) {\n      return;\n    }\n\n    // Handle the case of a function body returning a ternary operation.\n    // `return (maybeTrue ? '' : (<SubComponent />))`\n    if (arg.isConditionalExpression()) {\n      const consequent = arg.get(\"consequent\");\n      if (consequent.isJSXFragment() || consequent.isJSXElement()) {\n        processJSX(context, consequent);\n      }\n      const alternate = arg.get(\"alternate\");\n      if (alternate.isJSXFragment() || alternate.isJSXElement()) {\n        processJSX(context, alternate);\n      }\n      return;\n    }\n\n    if (!arg.isJSXFragment() && !arg.isJSXElement()) {\n      return;\n    }\n\n    jsxNode = arg;\n  }\n\n  if (!jsxNode) {\n    return;\n  }\n\n  processJSX(context, jsxNode);\n}\n\n/**\n * Recursively processes JSX elements to add Sentry tracking attributes.\n * Handles both JSX elements and fragments, applying appropriate attributes\n * based on configuration and component context.\n */\nfunction processJSX(context: JSXProcessingContext, jsxNode: Babel.NodePath): void {\n  if (!jsxNode) {\n    return;\n  }\n\n  // NOTE: I don't know of a case where `openingElement` would have more than one item,\n  // but it's safer to always iterate\n  const paths = jsxNode.get(\"openingElement\");\n  const openingElements = (\n    Array.isArray(paths) ? paths : [paths]\n  ) as Babel.NodePath<Babel.types.JSXOpeningElement>[];\n\n  const hasInjectedAttributes = openingElements.reduce(\n    (prev, openingElement) =>\n      prev || applyAttributes(context, openingElement, context.componentName),\n    false\n  );\n\n  if (hasInjectedAttributes) {\n    return;\n  }\n\n  let children = jsxNode.get(\"children\");\n  // TODO: See why `Array.isArray` doesn't have correct behaviour here\n  if (children && !(\"length\" in children)) {\n    // A single child was found, maybe a bit of static text\n    children = [children];\n  }\n\n  children.forEach((child) => {\n    // Happens for some node types like plain text\n    if (!child.node) {\n      return;\n    }\n\n    // If the current element is a fragment, children are still considered at root level\n    // Otherwise, children are not at root level\n    const openingElement = child.get(\"openingElement\");\n    // TODO: Improve this. We never expect to have multiple opening elements\n    // but if it's possible, this should work\n    if (Array.isArray(openingElement)) {\n      return;\n    }\n\n    processJSX(context, child);\n  });\n}\n\n/**\n * Applies Sentry tracking attributes to a JSX opening element.\n * Adds component name, element name, and source file attributes while\n * respecting ignore lists and fragment detection.\n */\nfunction applyAttributes(\n  context: JSXProcessingContext,\n  openingElement: Babel.NodePath<Babel.types.JSXOpeningElement>,\n  componentName: string\n): boolean {\n  const { t, attributeName: componentAttributeName, ignoredComponents, fragmentContext } = context;\n\n  // e.g., Raw JSX text like the `A` in `<h1>a</h1>`\n  if (!openingElement.node) {\n    return false;\n  }\n\n  // Check if this is a React fragment - if so, skip attribute addition entirely\n  const isFragment = isReactFragment(t, openingElement, fragmentContext);\n  if (isFragment) {\n    return false;\n  }\n\n  if (!openingElement.node.attributes) {\n    openingElement.node.attributes = [];\n  }\n\n  const elementName = getPathName(t, openingElement);\n\n  if (!isHtmlElement(elementName)) {\n    return false;\n  }\n\n  const isAnIgnoredComponent = ignoredComponents.some(\n    (ignoredComponent) => ignoredComponent === componentName || ignoredComponent === elementName\n  );\n\n  // Add a stable attribute for the component name (only for root elements)\n  if (!isAnIgnoredComponent && !hasAttributeWithName(openingElement, componentAttributeName)) {\n    if (componentAttributeName) {\n      openingElement.node.attributes.push(\n        t.jSXAttribute(t.jSXIdentifier(componentAttributeName), t.stringLiteral(componentName))\n      );\n    }\n  }\n\n  return true;\n}\n\nfunction attributeNamesFromState(state: AnnotationPluginPass): string {\n  if (state.opts.native) {\n    return \"dataSentryComponent\";\n  }\n\n  return \"data-sentry-component\";\n}\n\nfunction collectFragmentContext(programPath: Babel.NodePath): FragmentContext {\n  const fragmentAliases = new Set<string>();\n  const reactNamespaceAliases = new Set<string>([\"React\"]); // Default React namespace\n\n  programPath.traverse({\n    ImportDeclaration(importPath) {\n      const source = importPath.node.source.value;\n\n      // Handle React imports\n      if (source === \"react\" || source === \"React\") {\n        importPath.node.specifiers.forEach((spec) => {\n          if (spec.type === \"ImportSpecifier\" && spec.imported.type === \"Identifier\") {\n            // Detect aliased React.Fragment imports (e.g., `Fragment as F`)\n            // so we can later identify <F> as a fragment in JSX.\n            if (spec.imported.name === \"Fragment\") {\n              fragmentAliases.add(spec.local.name);\n            }\n          } else if (\n            spec.type === \"ImportDefaultSpecifier\" ||\n            spec.type === \"ImportNamespaceSpecifier\"\n          ) {\n            // import React from 'react' -> React OR\n            // import * as React from 'react' -> React\n            reactNamespaceAliases.add(spec.local.name);\n          }\n        });\n      }\n    },\n\n    // Handle simple variable assignments only (avoid complex cases)\n    VariableDeclarator(varPath) {\n      if (varPath.node.init) {\n        const init = varPath.node.init;\n\n        // Handle identifier assignments: const MyFragment = Fragment\n        if (varPath.node.id.type === \"Identifier\") {\n          // Handle: const MyFragment = Fragment (only if Fragment is a known alias)\n          if (init.type === \"Identifier\" && fragmentAliases.has(init.name)) {\n            fragmentAliases.add(varPath.node.id.name);\n          }\n\n          // Handle: const MyFragment = React.Fragment (only for known React namespaces)\n          if (\n            init.type === \"MemberExpression\" &&\n            init.object.type === \"Identifier\" &&\n            init.property.type === \"Identifier\" &&\n            init.property.name === \"Fragment\" &&\n            reactNamespaceAliases.has(init.object.name)\n          ) {\n            fragmentAliases.add(varPath.node.id.name);\n          }\n        }\n\n        // Handle destructuring assignments: const { Fragment } = React\n        if (varPath.node.id.type === \"ObjectPattern\") {\n          if (init.type === \"Identifier\" && reactNamespaceAliases.has(init.name)) {\n            const properties = varPath.node.id.properties;\n\n            for (const prop of properties) {\n              if (\n                prop.type === \"ObjectProperty\" &&\n                prop.key &&\n                prop.key.type === \"Identifier\" &&\n                prop.value &&\n                prop.value.type === \"Identifier\" &&\n                prop.key.name === \"Fragment\"\n              ) {\n                fragmentAliases.add(prop.value.name);\n              }\n            }\n          }\n        }\n      }\n    },\n  });\n\n  return { fragmentAliases, reactNamespaceAliases };\n}\n\nfunction isReactFragment(\n  t: typeof Babel.types,\n  openingElement: Babel.NodePath,\n  context?: FragmentContext // Add this optional parameter\n): boolean {\n  // Handle JSX fragments (<>)\n  if (openingElement.isJSXFragment()) {\n    return true;\n  }\n\n  const elementName = getPathName(t, openingElement);\n\n  // Direct fragment references\n  if (elementName === \"Fragment\" || elementName === \"React.Fragment\") {\n    return true;\n  }\n\n  // TODO: All these objects are typed as unknown, maybe an oversight in Babel types?\n\n  // Check if the element name is a known fragment alias\n  if (context && elementName && context.fragmentAliases.has(elementName)) {\n    return true;\n  }\n\n  // Handle JSXMemberExpression\n  if (\n    openingElement.node &&\n    \"name\" in openingElement.node &&\n    openingElement.node.name &&\n    typeof openingElement.node.name === \"object\" &&\n    \"type\" in openingElement.node.name &&\n    openingElement.node.name.type === \"JSXMemberExpression\"\n  ) {\n    const nodeName = openingElement.node.name;\n    if (typeof nodeName !== \"object\" || !nodeName) {\n      return false;\n    }\n\n    if (\"object\" in nodeName && \"property\" in nodeName) {\n      const nodeNameObject = nodeName.object;\n      const nodeNameProperty = nodeName.property;\n\n      if (typeof nodeNameObject !== \"object\" || typeof nodeNameProperty !== \"object\") {\n        return false;\n      }\n\n      if (!nodeNameObject || !nodeNameProperty) {\n        return false;\n      }\n\n      const objectName = \"name\" in nodeNameObject && nodeNameObject.name;\n      const propertyName = \"name\" in nodeNameProperty && nodeNameProperty.name;\n\n      // React.Fragment check\n      if (objectName === \"React\" && propertyName === \"Fragment\") {\n        return true;\n      }\n\n      // Enhanced checks using context\n      if (context) {\n        // Check React.Fragment pattern with known React namespaces\n        if (\n          context.reactNamespaceAliases.has(objectName as string) &&\n          propertyName === \"Fragment\"\n        ) {\n          return true;\n        }\n\n        // Check MyFragment.Fragment pattern\n        if (context.fragmentAliases.has(objectName as string) && propertyName === \"Fragment\") {\n          return true;\n        }\n      }\n    }\n  }\n\n  return false;\n}\n\nfunction hasAttributeWithName(\n  openingElement: Babel.NodePath<Babel.types.JSXOpeningElement>,\n  name: string | undefined | null\n): boolean {\n  if (!name) {\n    return false;\n  }\n\n  return openingElement.node.attributes.some((node) => {\n    if (node.type === \"JSXAttribute\") {\n      return node.name.name === name;\n    }\n\n    return false;\n  });\n}\n\nfunction getPathName(t: typeof Babel.types, path: Babel.NodePath): string {\n  if (!path.node) return UNKNOWN_ELEMENT_NAME;\n  if (!(\"name\" in path.node)) {\n    return UNKNOWN_ELEMENT_NAME;\n  }\n\n  const name = path.node.name;\n\n  if (typeof name === \"string\") {\n    return name;\n  }\n\n  if (t.isIdentifier(name) || t.isJSXIdentifier(name)) {\n    return name.name;\n  }\n\n  if (t.isJSXNamespacedName(name)) {\n    return name.name.name;\n  }\n\n  // Handle JSX member expressions like Tab.Group\n  if (t.isJSXMemberExpression(name)) {\n    const objectName = getJSXMemberExpressionObjectName(t, name.object);\n    const propertyName = name.property.name;\n    return `${objectName}.${propertyName}`;\n  }\n\n  return UNKNOWN_ELEMENT_NAME;\n}\n\n// Recursively handle nested member expressions (e.g. Components.UI.Header)\nfunction getJSXMemberExpressionObjectName(\n  t: typeof Babel.types,\n  object: Babel.types.JSXMemberExpression | Babel.types.JSXIdentifier\n): string {\n  if (t.isJSXIdentifier(object)) {\n    return object.name;\n  }\n  if (t.isJSXMemberExpression(object)) {\n    const objectName = getJSXMemberExpressionObjectName(t, object.object);\n    return `${objectName}.${object.property.name}`;\n  }\n\n  return UNKNOWN_ELEMENT_NAME;\n}\n\nconst UNKNOWN_ELEMENT_NAME = \"unknown\";\n","/**\n * MIT License\n *\n * Copyright (c) 2020 Engineering at FullStory\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n */\n\n/**\n * The following code is based on the FullStory Babel plugin, but has been modified to work\n * with Sentry products:\n *\n * - Added `sentry` to data properties, i.e `data-sentry-component`\n * - Converted to TypeScript\n * - Code cleanups\n */\n\nimport type * as Babel from \"@babel/core\";\nimport type { PluginObj, PluginPass } from \"@babel/core\";\n\nimport { DEFAULT_IGNORED_ELEMENTS, KNOWN_INCOMPATIBLE_PLUGINS } from \"./constants\";\n\nconst webComponentName = \"data-sentry-component\";\nconst webElementName = \"data-sentry-element\";\nconst webSourceFileName = \"data-sentry-source-file\";\n\nconst nativeComponentName = \"dataSentryComponent\";\nconst nativeElementName = \"dataSentryElement\";\nconst nativeSourceFileName = \"dataSentrySourceFile\";\n\nconst SENTRY_LABEL_ATTRIBUTE = \"sentry-label\";\nconst MAX_LABEL_LENGTH = 64;\nconst DEFAULT_TEXT_COMPONENT_NAMES = [\"Text\", \"text\"];\nconst MAX_TEXT_SEARCH_DEPTH = 3;\n\ninterface AutoInjectSentryLabelOpts {\n  textComponentNames?: string[];\n}\n\ninterface AnnotationOpts {\n  native?: boolean;\n  \"annotate-fragments\"?: boolean;\n  ignoredComponents?: string[];\n  /** @hidden */\n  autoInjectSentryLabel?: boolean | AutoInjectSentryLabelOpts;\n}\n\ninterface FragmentContext {\n  fragmentAliases: Set<string>;\n  reactNamespaceAliases: Set<string>;\n}\n\ninterface AnnotationPluginPass extends PluginPass {\n  opts: AnnotationOpts;\n  sentryFragmentContext?: FragmentContext;\n}\n\ntype AnnotationPlugin = PluginObj<AnnotationPluginPass>;\n\n// Shared context object for all JSX processing functions\ninterface JSXProcessingContext {\n  /** Whether to annotate React fragments */\n  annotateFragments: boolean;\n  /** Babel types object */\n  t: typeof Babel.types;\n  /** Name of the React component */\n  componentName: string;\n  /** Source file name (optional) */\n  sourceFileName?: string;\n  /** Array of attribute names [component, element, sourceFile] */\n  attributeNames: string[];\n  /** Array of component names to ignore */\n  ignoredComponents: string[];\n  /** Fragment context for identifying React fragments */\n  fragmentContext?: FragmentContext;\n  /** Whether to auto-inject sentry-label from static text children */\n  autoInjectSentryLabel: boolean;\n  /** Component names whose JSXText children are considered text content */\n  textComponentNames: string[];\n}\n\nexport { experimentalComponentNameAnnotatePlugin } from \"./experimental\";\n\n// We must export the plugin as default, otherwise the Babel loader will not be able to resolve it when configured using its string identifier\nexport default function componentNameAnnotatePlugin({ types: t }: typeof Babel): AnnotationPlugin {\n  return {\n    visitor: {\n      Program: {\n        enter(path, state) {\n          const fragmentContext = collectFragmentContext(path);\n          state.sentryFragmentContext = fragmentContext;\n        },\n      },\n      FunctionDeclaration(path, state) {\n        if (!path.node.id || !path.node.id.name) {\n          return;\n        }\n        if (isKnownIncompatiblePluginFromState(state)) {\n          return;\n        }\n\n        const context = createJSXProcessingContext(state, t, path.node.id.name);\n        functionBodyPushAttributes(context, path);\n      },\n      ArrowFunctionExpression(path, state) {\n        // We're expecting a `VariableDeclarator` like `const MyComponent =`\n        const parent = path.parent;\n\n        if (\n          !parent ||\n          !(\"id\" in parent) ||\n          !parent.id ||\n          !(\"name\" in parent.id) ||\n          !parent.id.name\n        ) {\n          return;\n        }\n\n        if (isKnownIncompatiblePluginFromState(state)) {\n          return;\n        }\n\n        const context = createJSXProcessingContext(state, t, parent.id.name);\n        functionBodyPushAttributes(context, path);\n      },\n      ClassDeclaration(path, state) {\n        const name = path.get(\"id\");\n        const properties = path.get(\"body\").get(\"body\");\n        const render = properties.find((prop) => {\n          return prop.isClassMethod() && prop.get(\"key\").isIdentifier({ name: \"render\" });\n        });\n\n        if (!render || !render.traverse || isKnownIncompatiblePluginFromState(state)) {\n          return;\n        }\n\n        const context = createJSXProcessingContext(state, t, name.node?.name || \"\");\n\n        render.traverse({\n          ReturnStatement(returnStatement) {\n            const arg = returnStatement.get(\"argument\");\n\n            if (!arg.isJSXElement() && !arg.isJSXFragment()) {\n              return;\n            }\n\n            processJSX(context, arg);\n          },\n        });\n      },\n    },\n  };\n}\n\n/**\n * Creates a JSX processing context from the plugin state\n */\nfunction createJSXProcessingContext(\n  state: AnnotationPluginPass,\n  t: typeof Babel.types,\n  componentName: string\n): JSXProcessingContext {\n  return {\n    annotateFragments: state.opts[\"annotate-fragments\"] === true,\n    t,\n    componentName,\n    sourceFileName: sourceFileNameFromState(state),\n    attributeNames: attributeNamesFromState(state),\n    ignoredComponents: state.opts.ignoredComponents ?? [],\n    fragmentContext: state.sentryFragmentContext,\n    autoInjectSentryLabel: !!state.opts.autoInjectSentryLabel,\n    textComponentNames:\n      (state.opts.autoInjectSentryLabel && typeof state.opts.autoInjectSentryLabel === \"object\"\n        ? state.opts.autoInjectSentryLabel.textComponentNames\n        : undefined) ?? DEFAULT_TEXT_COMPONENT_NAMES,\n  };\n}\n\n/**\n * Processes the body of a function to add Sentry tracking attributes to JSX elements.\n * Handles various function body structures including direct JSX returns, conditional expressions,\n * and nested JSX elements.\n */\nfunction functionBodyPushAttributes(\n  context: JSXProcessingContext,\n  path: Babel.NodePath<Babel.types.Function>\n): void {\n  let jsxNode: Babel.NodePath;\n\n  const functionBody = path.get(\"body\").get(\"body\");\n\n  if (\n    !(\"length\" in functionBody) &&\n    functionBody.parent &&\n    (functionBody.parent.type === \"JSXElement\" || functionBody.parent.type === \"JSXFragment\")\n  ) {\n    const maybeJsxNode = functionBody.find((c) => {\n      return c.type === \"JSXElement\" || c.type === \"JSXFragment\";\n    });\n\n    if (!maybeJsxNode) {\n      return;\n    }\n\n    jsxNode = maybeJsxNode;\n  } else {\n    const returnStatement = functionBody.find((c) => {\n      return c.type === \"ReturnStatement\";\n    });\n    if (!returnStatement) {\n      return;\n    }\n\n    const arg = returnStatement.get(\"argument\");\n    if (!arg) {\n      return;\n    }\n\n    if (Array.isArray(arg)) {\n      return;\n    }\n\n    // Handle the case of a function body returning a ternary operation.\n    // `return (maybeTrue ? '' : (<SubComponent />))`\n    if (arg.isConditionalExpression()) {\n      const consequent = arg.get(\"consequent\");\n      if (consequent.isJSXFragment() || consequent.isJSXElement()) {\n        processJSX(context, consequent);\n      }\n      const alternate = arg.get(\"alternate\");\n      if (alternate.isJSXFragment() || alternate.isJSXElement()) {\n        processJSX(context, alternate);\n      }\n      return;\n    }\n\n    if (!arg.isJSXFragment() && !arg.isJSXElement()) {\n      return;\n    }\n\n    jsxNode = arg;\n  }\n\n  if (!jsxNode) {\n    return;\n  }\n\n  processJSX(context, jsxNode);\n}\n\n/**\n * Recursively processes JSX elements to add Sentry tracking attributes.\n * Handles both JSX elements and fragments, applying appropriate attributes\n * based on configuration and component context.\n */\nfunction processJSX(\n  context: JSXProcessingContext,\n  jsxNode: Babel.NodePath,\n  componentName?: string\n): void {\n  if (!jsxNode) {\n    return;\n  }\n\n  // Use provided componentName or fall back to context componentName\n  const currentComponentName = componentName ?? context.componentName;\n  const isRootElement = componentName === undefined;\n\n  // NOTE: I don't know of a case where `openingElement` would have more than one item,\n  // but it's safer to always iterate\n  const paths = jsxNode.get(\"openingElement\");\n  const openingElements = Array.isArray(paths) ? paths : [paths];\n\n  openingElements.forEach((openingElement) => {\n    applyAttributes(\n      context,\n      openingElement as Babel.NodePath<Babel.types.JSXOpeningElement>,\n      currentComponentName\n    );\n  });\n\n  let children = jsxNode.get(\"children\");\n  // TODO: See why `Array.isArray` doesn't have correct behaviour here\n  if (children && !(\"length\" in children)) {\n    // A single child was found, maybe a bit of static text\n    children = [children];\n  }\n\n  let shouldSetComponentName = context.annotateFragments;\n\n  children.forEach((child) => {\n    // Happens for some node types like plain text\n    if (!child.node) {\n      return;\n    }\n\n    // Children don't receive the data-component attribute so we pass null for componentName unless it's the first child of a Fragment with a node and `annotateFragments` is true\n    const openingElement = child.get(\"openingElement\");\n    // TODO: Improve this. We never expect to have multiple opening elements\n    // but if it's possible, this should work\n    if (Array.isArray(openingElement)) {\n      return;\n    }\n\n    if (shouldSetComponentName && openingElement && openingElement.node) {\n      shouldSetComponentName = false;\n      processJSX(context, child, currentComponentName);\n    } else {\n      processJSX(context, child, \"\");\n    }\n  });\n\n  if (isRootElement && context.autoInjectSentryLabel) {\n    maybeInjectSentryLabel(context, jsxNode);\n  }\n}\n\n/**\n * Applies Sentry tracking attributes to a JSX opening element.\n * Adds component name, element name, and source file attributes while\n * respecting ignore lists and fragment detection.\n */\nfunction applyAttributes(\n  context: JSXProcessingContext,\n  openingElement: Babel.NodePath<Babel.types.JSXOpeningElement>,\n  componentName: string\n): void {\n  const { t, attributeNames, ignoredComponents, fragmentContext, sourceFileName } = context;\n  const [componentAttributeName, elementAttributeName, sourceFileAttributeName] = attributeNames;\n\n  // e.g., Raw JSX text like the `A` in `<h1>a</h1>`\n  if (!openingElement.node) {\n    return;\n  }\n\n  // Check if this is a React fragment - if so, skip attribute addition entirely\n  const isFragment = isReactFragment(t, openingElement, fragmentContext);\n  if (isFragment) {\n    return;\n  }\n\n  if (!openingElement.node.attributes) openingElement.node.attributes = [];\n  const elementName = getPathName(t, openingElement);\n\n  const isAnIgnoredComponent = ignoredComponents.some(\n    (ignoredComponent) => ignoredComponent === componentName || ignoredComponent === elementName\n  );\n\n  // Add a stable attribute for the element name but only for non-DOM names\n  let isAnIgnoredElement = false;\n  if (!isAnIgnoredComponent && !hasAttributeWithName(openingElement, elementAttributeName)) {\n    if (DEFAULT_IGNORED_ELEMENTS.includes(elementName)) {\n      isAnIgnoredElement = true;\n    } else {\n      // Always add element attribute for non-ignored elements\n      if (elementAttributeName) {\n        openingElement.node.attributes.push(\n          t.jSXAttribute(t.jSXIdentifier(elementAttributeName), t.stringLiteral(elementName))\n        );\n      }\n    }\n  }\n\n  // Add a stable attribute for the component name (absent for non-root elements)\n  if (\n    componentName &&\n    !isAnIgnoredComponent &&\n    !hasAttributeWithName(openingElement, componentAttributeName)\n  ) {\n    if (componentAttributeName) {\n      openingElement.node.attributes.push(\n        t.jSXAttribute(t.jSXIdentifier(componentAttributeName), t.stringLiteral(componentName))\n      );\n    }\n  }\n\n  // Add a stable attribute for the source file name\n  // Updated condition: add source file for elements that have either:\n  // 1. A component name (root elements), OR\n  // 2. An element name that's not ignored (child elements)\n  if (\n    sourceFileName &&\n    !isAnIgnoredComponent &&\n    (componentName || !isAnIgnoredElement) &&\n    !hasAttributeWithName(openingElement, sourceFileAttributeName)\n  ) {\n    if (sourceFileAttributeName) {\n      openingElement.node.attributes.push(\n        t.jSXAttribute(t.jSXIdentifier(sourceFileAttributeName), t.stringLiteral(sourceFileName))\n      );\n    }\n  }\n}\n\nfunction sourceFileNameFromState(state: AnnotationPluginPass): string | undefined {\n  const name = fullSourceFileNameFromState(state);\n  if (!name) {\n    return undefined;\n  }\n\n  if (name.indexOf(\"/\") !== -1) {\n    return name.split(\"/\").pop();\n  } else if (name.indexOf(\"\\\\\") !== -1) {\n    return name.split(\"\\\\\").pop();\n  } else {\n    return name;\n  }\n}\n\nfunction fullSourceFileNameFromState(state: AnnotationPluginPass): string | null {\n  // @ts-expect-error This type is incorrect in Babel, `sourceFileName` is the correct type\n  const name = state.file.opts.parserOpts?.sourceFileName as unknown;\n\n  if (typeof name === \"string\") {\n    return name;\n  }\n\n  return null;\n}\n\nfunction isKnownIncompatiblePluginFromState(state: AnnotationPluginPass): boolean {\n  const fullSourceFileName = fullSourceFileNameFromState(state);\n\n  if (!fullSourceFileName) {\n    return false;\n  }\n\n  return KNOWN_INCOMPATIBLE_PLUGINS.some((pluginName) => {\n    if (\n      fullSourceFileName.includes(`/node_modules/${pluginName}/`) ||\n      fullSourceFileName.includes(`\\\\node_modules\\\\${pluginName}\\\\`)\n    ) {\n      return true;\n    }\n\n    return false;\n  });\n}\n\nfunction attributeNamesFromState(state: AnnotationPluginPass): [string, string, string] {\n  if (state.opts.native) {\n    return [nativeComponentName, nativeElementName, nativeSourceFileName];\n  }\n\n  return [webComponentName, webElementName, webSourceFileName];\n}\n\nfunction collectFragmentContext(programPath: Babel.NodePath): FragmentContext {\n  const fragmentAliases = new Set<string>();\n  const reactNamespaceAliases = new Set<string>([\"React\"]); // Default React namespace\n\n  programPath.traverse({\n    ImportDeclaration(importPath) {\n      const source = importPath.node.source.value;\n\n      // Handle React imports\n      if (source === \"react\" || source === \"React\") {\n        importPath.node.specifiers.forEach((spec) => {\n          if (spec.type === \"ImportSpecifier\" && spec.imported.type === \"Identifier\") {\n            // Detect aliased React.Fragment imports (e.g., `Fragment as F`)\n            // so we can later identify <F> as a fragment in JSX.\n            if (spec.imported.name === \"Fragment\") {\n              fragmentAliases.add(spec.local.name);\n            }\n          } else if (\n            spec.type === \"ImportDefaultSpecifier\" ||\n            spec.type === \"ImportNamespaceSpecifier\"\n          ) {\n            // import React from 'react' -> React OR\n            // import * as React from 'react' -> React\n            reactNamespaceAliases.add(spec.local.name);\n          }\n        });\n      }\n    },\n\n    // Handle simple variable assignments only (avoid complex cases)\n    VariableDeclarator(varPath) {\n      if (varPath.node.init) {\n        const init = varPath.node.init;\n\n        // Handle identifier assignments: const MyFragment = Fragment\n        if (varPath.node.id.type === \"Identifier\") {\n          // Handle: const MyFragment = Fragment (only if Fragment is a known alias)\n          if (init.type === \"Identifier\" && fragmentAliases.has(init.name)) {\n            fragmentAliases.add(varPath.node.id.name);\n          }\n\n          // Handle: const MyFragment = React.Fragment (only for known React namespaces)\n          if (\n            init.type === \"MemberExpression\" &&\n            init.object.type === \"Identifier\" &&\n            init.property.type === \"Identifier\" &&\n            init.property.name === \"Fragment\" &&\n            reactNamespaceAliases.has(init.object.name)\n          ) {\n            fragmentAliases.add(varPath.node.id.name);\n          }\n        }\n\n        // Handle destructuring assignments: const { Fragment } = React\n        if (varPath.node.id.type === \"ObjectPattern\") {\n          if (init.type === \"Identifier\" && reactNamespaceAliases.has(init.name)) {\n            const properties = varPath.node.id.properties;\n\n            for (const prop of properties) {\n              if (\n                prop.type === \"ObjectProperty\" &&\n                prop.key &&\n                prop.key.type === \"Identifier\" &&\n                prop.value &&\n                prop.value.type === \"Identifier\" &&\n                prop.key.name === \"Fragment\"\n              ) {\n                fragmentAliases.add(prop.value.name);\n              }\n            }\n          }\n        }\n      }\n    },\n  });\n\n  return { fragmentAliases, reactNamespaceAliases };\n}\n\nfunction isReactFragment(\n  t: typeof Babel.types,\n  openingElement: Babel.NodePath,\n  context?: FragmentContext // Add this optional parameter\n): boolean {\n  // Handle JSX fragments (<>)\n  if (openingElement.isJSXFragment()) {\n    return true;\n  }\n\n  const elementName = getPathName(t, openingElement);\n\n  // Direct fragment references\n  if (elementName === \"Fragment\" || elementName === \"React.Fragment\") {\n    return true;\n  }\n\n  // TODO: All these objects are typed as unknown, maybe an oversight in Babel types?\n\n  // Check if the element name is a known fragment alias\n  if (context && elementName && context.fragmentAliases.has(elementName)) {\n    return true;\n  }\n\n  // Handle JSXMemberExpression\n  if (\n    openingElement.node &&\n    \"name\" in openingElement.node &&\n    openingElement.node.name &&\n    typeof openingElement.node.name === \"object\" &&\n    \"type\" in openingElement.node.name &&\n    openingElement.node.name.type === \"JSXMemberExpression\"\n  ) {\n    const nodeName = openingElement.node.name;\n    if (typeof nodeName !== \"object\" || !nodeName) {\n      return false;\n    }\n\n    if (\"object\" in nodeName && \"property\" in nodeName) {\n      const nodeNameObject = nodeName.object;\n      const nodeNameProperty = nodeName.property;\n\n      if (typeof nodeNameObject !== \"object\" || typeof nodeNameProperty !== \"object\") {\n        return false;\n      }\n\n      if (!nodeNameObject || !nodeNameProperty) {\n        return false;\n      }\n\n      const objectName = \"name\" in nodeNameObject && nodeNameObject.name;\n      const propertyName = \"name\" in nodeNameProperty && nodeNameProperty.name;\n\n      // React.Fragment check\n      if (objectName === \"React\" && propertyName === \"Fragment\") {\n        return true;\n      }\n\n      // Enhanced checks using context\n      if (context) {\n        // Check React.Fragment pattern with known React namespaces\n        if (\n          context.reactNamespaceAliases.has(objectName as string) &&\n          propertyName === \"Fragment\"\n        ) {\n          return true;\n        }\n\n        // Check MyFragment.Fragment pattern\n        if (context.fragmentAliases.has(objectName as string) && propertyName === \"Fragment\") {\n          return true;\n        }\n      }\n    }\n  }\n\n  return false;\n}\n\nfunction hasAttributeWithName(\n  openingElement: Babel.NodePath<Babel.types.JSXOpeningElement>,\n  name: string | undefined | null\n): boolean {\n  if (!name) {\n    return false;\n  }\n\n  return openingElement.node.attributes.some((node) => {\n    if (node.type === \"JSXAttribute\") {\n      return node.name.name === name;\n    }\n\n    return false;\n  });\n}\n\nfunction getPathName(t: typeof Babel.types, path: Babel.NodePath): string {\n  if (!path.node) return UNKNOWN_ELEMENT_NAME;\n  if (!(\"name\" in path.node)) {\n    return UNKNOWN_ELEMENT_NAME;\n  }\n\n  const name = path.node.name;\n\n  if (typeof name === \"string\") {\n    return name;\n  }\n\n  if (t.isIdentifier(name) || t.isJSXIdentifier(name)) {\n    return name.name;\n  }\n\n  if (t.isJSXNamespacedName(name)) {\n    return name.name.name;\n  }\n\n  // Handle JSX member expressions like Tab.Group\n  if (t.isJSXMemberExpression(name)) {\n    const objectName = getJSXMemberExpressionObjectName(t, name.object);\n    const propertyName = name.property.name;\n    return `${objectName}.${propertyName}`;\n  }\n\n  return UNKNOWN_ELEMENT_NAME;\n}\n\n// Recursively handle nested member expressions (e.g. Components.UI.Header)\nfunction getJSXMemberExpressionObjectName(\n  t: typeof Babel.types,\n  object: Babel.types.JSXMemberExpression | Babel.types.JSXIdentifier\n): string {\n  if (t.isJSXIdentifier(object)) {\n    return object.name;\n  }\n  if (t.isJSXMemberExpression(object)) {\n    const objectName = getJSXMemberExpressionObjectName(t, object.object);\n    return `${objectName}.${object.property.name}`;\n  }\n\n  return UNKNOWN_ELEMENT_NAME;\n}\n\n/**\n * Extracts static text content from JSX children, searching up to a depth limit.\n * Collects text from JSXText nodes of the root element and from recognized\n * text components (e.g. <Text>). Non-text custom components are traversed\n * but their own JSXText is not collected.\n *\n * Returns null when dynamic content is found anywhere in the subtree,\n * signaling that the entire label should be skipped.\n */\nfunction extractStaticTextFromChildren(\n  t: typeof Babel.types,\n  node: Babel.types.JSXElement | Babel.types.JSXFragment,\n  textComponentNames: string[],\n  depth: number,\n  isRoot: boolean\n): string[] | null {\n  if (depth <= 0) {\n    return [];\n  }\n\n  const texts: string[] = [];\n\n  for (const child of node.children) {\n    if (t.isJSXText(child)) {\n      if (isRoot) {\n        const trimmed = child.value.replace(/\\s+/g, \" \").trim();\n        if (trimmed) {\n          texts.push(trimmed);\n        }\n      }\n    } else if (t.isJSXElement(child)) {\n      const childName = getElementName(t, child.openingElement);\n\n      if (textComponentNames.includes(childName)) {\n        const innerTexts = extractTextFromTextComponent(t, child, textComponentNames);\n        if (innerTexts === null) {\n          return null;\n        }\n        texts.push(...innerTexts);\n      } else {\n        const result = extractStaticTextFromChildren(\n          t,\n          child,\n          textComponentNames,\n          depth - 1,\n          false\n        );\n        if (result === null) {\n          return null;\n        }\n        texts.push(...result);\n      }\n    } else if (t.isJSXFragment(child)) {\n      const result = extractStaticTextFromChildren(t, child, textComponentNames, depth, isRoot);\n      if (result === null) {\n        return null;\n      }\n      texts.push(...result);\n    } else if (t.isJSXExpressionContainer(child)) {\n      if (!t.isJSXEmptyExpression(child.expression)) {\n        return null;\n      }\n    } else if (t.isJSXSpreadChild(child)) {\n      return null;\n    }\n  }\n\n  return texts;\n}\n\n/**\n * Recursively extracts static text from within a recognized text component.\n * Handles nested text components (e.g. <Text>Hello <Text style={bold}>world</Text></Text>)\n * which is the standard React Native pattern for inline styling.\n *\n * Returns null when any dynamic content is found, signaling bail-out.\n */\nfunction extractTextFromTextComponent(\n  t: typeof Babel.types,\n  node: Babel.types.JSXElement | Babel.types.JSXFragment,\n  textComponentNames: string[]\n): string[] | null {\n  const texts: string[] = [];\n\n  for (const child of node.children) {\n    if (t.isJSXText(child)) {\n      const trimmed = child.value.replace(/\\s+/g, \" \").trim();\n      if (trimmed) {\n        texts.push(trimmed);\n      }\n    } else if (t.isJSXExpressionContainer(child)) {\n      if (!t.isJSXEmptyExpression(child.expression)) {\n        return null;\n      }\n    } else if (t.isJSXElement(child)) {\n      const childName = getElementName(t, child.openingElement);\n      if (textComponentNames.includes(childName)) {\n        const innerTexts = extractTextFromTextComponent(t, child, textComponentNames);\n        if (innerTexts === null) {\n          return null;\n        }\n        texts.push(...innerTexts);\n      } else {\n        const innerTexts = extractTextFromTextComponent(t, child, textComponentNames);\n        if (innerTexts === null) {\n          return null;\n        }\n      }\n    } else if (t.isJSXFragment(child)) {\n      const innerTexts = extractTextFromTextComponent(t, child, textComponentNames);\n      if (innerTexts === null) {\n        return null;\n      }\n      texts.push(...innerTexts);\n    } else if (t.isJSXSpreadChild(child)) {\n      return null;\n    }\n  }\n\n  return texts;\n}\n\nfunction getElementName(\n  t: typeof Babel.types,\n  openingElement: Babel.types.JSXOpeningElement\n): string {\n  const name = openingElement.name;\n  if (t.isJSXIdentifier(name)) {\n    return name.name;\n  }\n  if (t.isJSXMemberExpression(name)) {\n    return `${getJSXMemberExpressionObjectName(t, name.object)}.${name.property.name}`;\n  }\n  return \"\";\n}\n\n/**\n * Injects a sentry-label attribute on the root JSX element of a component if\n * static text content can be extracted from its children.\n *\n * When the root is a JSX fragment, the first JSXElement child is used as the\n * target for both text extraction and attribute injection (since fragments\n * cannot carry attributes).\n */\nfunction maybeInjectSentryLabel(context: JSXProcessingContext, jsxNode: Babel.NodePath): void {\n  const { t, textComponentNames, ignoredComponents, componentName } = context;\n  const node = jsxNode.node;\n\n  let targetElement: Babel.types.JSXElement;\n\n  if (t.isJSXElement(node)) {\n    targetElement = node;\n  } else if (t.isJSXFragment(node)) {\n    const firstChild = node.children.find((c): c is Babel.types.JSXElement => t.isJSXElement(c));\n    if (!firstChild) {\n      return;\n    }\n    targetElement = firstChild;\n  } else {\n    return;\n  }\n\n  const targetElementName = getElementName(t, targetElement.openingElement);\n\n  if (\n    ignoredComponents.some((ignored) => ignored === componentName || ignored === targetElementName)\n  ) {\n    return;\n  }\n\n  if (\n    targetElement.openingElement.attributes.some(\n      (attr) => t.isJSXAttribute(attr) && attr.name.name === SENTRY_LABEL_ATTRIBUTE\n    )\n  ) {\n    return;\n  }\n\n  const texts = extractStaticTextFromChildren(\n    t,\n    targetElement,\n    textComponentNames,\n    MAX_TEXT_SEARCH_DEPTH,\n    true\n  );\n\n  if (texts === null) {\n    return;\n  }\n\n  let label = texts.join(\" \").replace(/\\s+/g, \" \").trim();\n\n  if (!label) {\n    return;\n  }\n\n  if (label.length > MAX_LABEL_LENGTH) {\n    label = label.substring(0, MAX_LABEL_LENGTH - 3) + \"...\";\n  }\n\n  targetElement.openingElement.attributes.push(\n    t.jSXAttribute(t.jSXIdentifier(SENTRY_LABEL_ATTRIBUTE), t.stringLiteral(label))\n  );\n}\n\nconst UNKNOWN_ELEMENT_NAME = \"unknown\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAa,6BAA6B,CAExC,0BAEA,oBACD;AAED,MAAa,2BAA2B;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;AC3GD,MAAM,wBAAkC;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAkCD,SAAgB,wCAAwC,EACtD,OAAO,KAC0B;CACjC,OAAO,EACL,SAAS;EACP,SAAS,EACP,MAAM,MAAM,OAAO;GAEjB,MAAM,wBADkBA,yBAAuB,KACF;KAEhD;EACD,oBAAoB,MAAM,OAAO;GAC/B,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,KAAK,GAAG,MACjC;GAIF,6BADgBC,6BAA2B,OAAO,GAAG,KAAK,KAAK,GAAG,KAChC,EAAE,KAAK;;EAE3C,wBAAwB,MAAM,OAAO;GAEnC,MAAM,SAAS,KAAK;GAEpB,IACE,CAAC,UACD,EAAE,QAAQ,WACV,CAAC,OAAO,MACR,EAAE,UAAU,OAAO,OACnB,CAAC,OAAO,GAAG,MAEX;GAIF,6BADgBA,6BAA2B,OAAO,GAAG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"}