{"version":3,"file":"experimental.js","sources":["../../../src/babel-plugin/experimental.ts"],"sourcesContent":["/* oxlint-disable max-lines */\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;\n reactNamespaceAliases: Set;\n}\n\ninterface AnnotationPluginPass extends PluginPass {\n opts: AnnotationOpts;\n sentryFragmentContext?: FragmentContext;\n}\n\ntype AnnotationPlugin = PluginObj;\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({ 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?.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 (!parent || !('id' in parent) || !parent.id || !('name' in parent.id) || !parent.id.name) {\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?.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(context: JSXProcessingContext, path: Babel.NodePath): 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 ? '' : ())`\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]) as Babel.NodePath[];\n\n const hasInjectedAttributes = openingElements.reduce(\n (prev, openingElement) => 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,\n componentName: string,\n): boolean {\n const { t, attributeName: componentAttributeName, ignoredComponents, fragmentContext } = context;\n\n // e.g., Raw JSX text like the `A` in `

a

`\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();\n const reactNamespaceAliases = new Set(['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 as a fragment in JSX.\n if (spec.imported.name === 'Fragment') {\n fragmentAliases.add(spec.local.name);\n }\n } else if (spec.type === 'ImportDefaultSpecifier' || spec.type === 'ImportNamespaceSpecifier') {\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?.type === 'Identifier' &&\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 (context.reactNamespaceAliases.has(objectName as string) && propertyName === 'Fragment') {\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,\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"],"names":[],"mappings":"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"}