{"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 = Array.isArray(paths) ? paths : [paths];\n\n  const hasInjectedAttributes = openingElements.reduce(\n    (prev, openingElement) =>\n      prev ||\n      applyAttributes(\n        context,\n        openingElement as Babel.NodePath<Babel.types.JSXOpeningElement>,\n        context.componentName\n      ),\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\ninterface AnnotationOpts {\n  native?: boolean;\n  \"annotate-fragments\"?: 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  /** 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}\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  };\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\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\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\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;AACjC,QAAO,EACL,SAAS;EACP,SAAS,EACP,MAAM,MAAM,OAAO;AAEjB,SAAM,wBADkBA,yBAAuB,KAAK;KAGvD;EACD,oBAAoB,MAAM,OAAO;AAC/B,OAAI,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,KAAK,GAAG,KACjC;AAIF,gCADgBC,6BAA2B,OAAO,GAAG,KAAK,KAAK,GAAG,KAAK,EACnC,KAAK;;EAE3C,wBAAwB,MAAM,OAAO;GAEnC,MAAM,SAAS,KAAK;AAEpB,OACE,CAAC,UACD,EAAE,QAAQ,WACV,CAAC,OAAO,MACR,EAAE,UAAU,OAAO,OACnB,CAAC,OAAO,GAAG,KAEX;AAIF,gCADgBA,6BAA2B,OAAO,GAAG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"}