@truewatchtech/react-native-mobile-babel-plugin 0.4.3-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +185 -0
  2. package/lib/commonjs/actions/global.js +19 -0
  3. package/lib/commonjs/actions/global.js.map +1 -0
  4. package/lib/commonjs/actions/rum/components.js +81 -0
  5. package/lib/commonjs/actions/rum/components.js.map +1 -0
  6. package/lib/commonjs/actions/rum/content.js +168 -0
  7. package/lib/commonjs/actions/rum/content.js.map +1 -0
  8. package/lib/commonjs/actions/rum/index.js +68 -0
  9. package/lib/commonjs/actions/rum/index.js.map +1 -0
  10. package/lib/commonjs/actions/rum/memoization.js +88 -0
  11. package/lib/commonjs/actions/rum/memoization.js.map +1 -0
  12. package/lib/commonjs/actions/rum/metadata.js +63 -0
  13. package/lib/commonjs/actions/rum/metadata.js.map +1 -0
  14. package/lib/commonjs/actions/rum/tap.js +45 -0
  15. package/lib/commonjs/actions/rum/tap.js.map +1 -0
  16. package/lib/commonjs/constants.js +25 -0
  17. package/lib/commonjs/constants.js.map +1 -0
  18. package/lib/commonjs/index.js +48 -0
  19. package/lib/commonjs/index.js.map +1 -0
  20. package/lib/commonjs/options.js +23 -0
  21. package/lib/commonjs/options.js.map +1 -0
  22. package/lib/commonjs/state.js +32 -0
  23. package/lib/commonjs/state.js.map +1 -0
  24. package/lib/commonjs/types.js +6 -0
  25. package/lib/commonjs/types.js.map +1 -0
  26. package/lib/commonjs/utils/jsx.js +43 -0
  27. package/lib/commonjs/utils/jsx.js.map +1 -0
  28. package/lib/module/actions/global.js +13 -0
  29. package/lib/module/actions/global.js.map +1 -0
  30. package/lib/module/actions/rum/components.js +73 -0
  31. package/lib/module/actions/rum/components.js.map +1 -0
  32. package/lib/module/actions/rum/content.js +161 -0
  33. package/lib/module/actions/rum/content.js.map +1 -0
  34. package/lib/module/actions/rum/index.js +61 -0
  35. package/lib/module/actions/rum/index.js.map +1 -0
  36. package/lib/module/actions/rum/memoization.js +82 -0
  37. package/lib/module/actions/rum/memoization.js.map +1 -0
  38. package/lib/module/actions/rum/metadata.js +56 -0
  39. package/lib/module/actions/rum/metadata.js.map +1 -0
  40. package/lib/module/actions/rum/tap.js +38 -0
  41. package/lib/module/actions/rum/tap.js.map +1 -0
  42. package/lib/module/constants.js +19 -0
  43. package/lib/module/constants.js.map +1 -0
  44. package/lib/module/index.js +42 -0
  45. package/lib/module/index.js.map +1 -0
  46. package/lib/module/options.js +17 -0
  47. package/lib/module/options.js.map +1 -0
  48. package/lib/module/state.js +25 -0
  49. package/lib/module/state.js.map +1 -0
  50. package/lib/module/types.js +2 -0
  51. package/lib/module/types.js.map +1 -0
  52. package/lib/module/utils/jsx.js +36 -0
  53. package/lib/module/utils/jsx.js.map +1 -0
  54. package/lib/typescript/actions/global.d.ts +2 -0
  55. package/lib/typescript/actions/rum/components.d.ts +5 -0
  56. package/lib/typescript/actions/rum/content.d.ts +6 -0
  57. package/lib/typescript/actions/rum/index.d.ts +4 -0
  58. package/lib/typescript/actions/rum/memoization.d.ts +4 -0
  59. package/lib/typescript/actions/rum/metadata.d.ts +4 -0
  60. package/lib/typescript/actions/rum/tap.d.ts +6 -0
  61. package/lib/typescript/constants.d.ts +4 -0
  62. package/lib/typescript/index.d.ts +5 -0
  63. package/lib/typescript/options.d.ts +2 -0
  64. package/lib/typescript/state.d.ts +5 -0
  65. package/lib/typescript/types.d.ts +56 -0
  66. package/lib/typescript/utils/jsx.d.ts +4 -0
  67. package/package.json +68 -0
  68. package/src/actions/global.ts +48 -0
  69. package/src/actions/rum/components.ts +128 -0
  70. package/src/actions/rum/content.ts +274 -0
  71. package/src/actions/rum/index.ts +154 -0
  72. package/src/actions/rum/memoization.ts +136 -0
  73. package/src/actions/rum/metadata.ts +147 -0
  74. package/src/actions/rum/tap.ts +148 -0
  75. package/src/constants.ts +21 -0
  76. package/src/index.ts +50 -0
  77. package/src/options.ts +26 -0
  78. package/src/state.ts +39 -0
  79. package/src/types.ts +72 -0
  80. package/src/utils/jsx.ts +50 -0
@@ -0,0 +1,161 @@
1
+ /*
2
+ * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel
3
+ * interaction tracking implementation, licensed under Apache-2.0.
4
+ */
5
+
6
+ import { getDirectAttributePaths, getNodeName } from '../../utils/jsx';
7
+ const CONTENT_PROPS = ['trackingLabel', 'title', 'label', 'text'];
8
+ function contentCandidateNames(component) {
9
+ return component.contentProp && !CONTENT_PROPS.includes(component.contentProp) ? [...CONTENT_PROPS, component.contentProp] : CONTENT_PROPS;
10
+ }
11
+ function elementType(t, name) {
12
+ if (t.isJSXMemberExpression(name)) {
13
+ // Lowercase member receivers (e.g. ui.Text) are variables, not host tags.
14
+ const receiver = t.isJSXIdentifier(name.object) ? t.identifier(name.object.name) : elementType(t, name.object);
15
+ return t.memberExpression(receiver, t.identifier(name.property.name));
16
+ }
17
+ const value = getNodeName(t, name) || '';
18
+ return t.isJSXIdentifier(name) && !/^[a-z]/.test(value) ? t.identifier(value) : t.stringLiteral(value);
19
+ }
20
+ function effectiveAttributes(t, attributes) {
21
+ const result = new Map();
22
+ for (const attribute of attributes) {
23
+ if (t.isJSXSpreadAttribute(attribute)) {
24
+ // Do not replay spreads or trust props they may have overridden.
25
+ result.clear();
26
+ } else {
27
+ result.set(getNodeName(t, attribute.name) || '', attribute);
28
+ }
29
+ }
30
+ return result;
31
+ }
32
+ function contentSourcePaths(t, path, component) {
33
+ const candidateNames = contentCandidateNames(component);
34
+ const attributes = new Map();
35
+ for (const attributePath of getDirectAttributePaths(path)) {
36
+ if (!attributePath.isJSXAttribute()) {
37
+ attributes.clear();
38
+ continue;
39
+ }
40
+ attributes.set(getNodeName(t, attributePath.node.name) || '', attributePath);
41
+ }
42
+ const sources = [];
43
+ for (const name of candidateNames) {
44
+ const attributePath = attributes.get(name);
45
+ const valuePath = attributePath === null || attributePath === void 0 ? void 0 : attributePath.get('value');
46
+ if (valuePath && !Array.isArray(valuePath) && valuePath.node) {
47
+ sources.push(valuePath);
48
+ }
49
+ }
50
+ return sources.concat(path.get('children'));
51
+ }
52
+ function containsPath(root, candidate) {
53
+ let current = candidate;
54
+ while (current) {
55
+ if (current === root || current.node === root.node) {
56
+ return true;
57
+ }
58
+ current = current.parentPath;
59
+ }
60
+ return false;
61
+ }
62
+
63
+ /** Checks whether moving content into a memo callback preserves every binding. */
64
+ export function isContentVisibleFromScope(t, path, component, destinationScope) {
65
+ const sources = contentSourcePaths(t, path, component);
66
+ let visible = true;
67
+ const checkReference = (referencePath, name) => {
68
+ const sourceBinding = referencePath.scope.getBinding(name);
69
+ if (sourceBinding && sources.some(source => containsPath(source, sourceBinding.path))) {
70
+ return;
71
+ }
72
+ const destinationBinding = destinationScope.getBinding(name);
73
+ if ((sourceBinding === null || sourceBinding === void 0 ? void 0 : sourceBinding.identifier) !== (destinationBinding === null || destinationBinding === void 0 ? void 0 : destinationBinding.identifier)) {
74
+ visible = false;
75
+ }
76
+ };
77
+ for (const source of sources) {
78
+ source.traverse({
79
+ ReferencedIdentifier(referencePath) {
80
+ checkReference(referencePath, referencePath.node.name);
81
+ if (!visible) {
82
+ referencePath.stop();
83
+ }
84
+ },
85
+ JSXOpeningElement(openingPath) {
86
+ let name = openingPath.node.name;
87
+ let isMember = false;
88
+ while (t.isJSXMemberExpression(name)) {
89
+ isMember = true;
90
+ name = name.object;
91
+ }
92
+ if (t.isJSXIdentifier(name) && (isMember || !/^[a-z]/.test(name.name))) {
93
+ checkReference(openingPath, name.name);
94
+ }
95
+ if (!visible) {
96
+ openingPath.stop();
97
+ }
98
+ },
99
+ JSXSpreadAttribute(spreadPath) {
100
+ // Spread attributes are not copied into the content getter.
101
+ spreadPath.skip();
102
+ }
103
+ });
104
+ if (!visible) {
105
+ return false;
106
+ }
107
+ }
108
+ return true;
109
+ }
110
+
111
+ /** Converts JSX anywhere in an expression, including render functions and maps. */
112
+ function toRuntimeNode(t, node, react) {
113
+ if (t.isJSXElement(node) || t.isJSXFragment(node)) {
114
+ const properties = [];
115
+ if (t.isJSXElement(node)) {
116
+ for (const [name, attribute] of effectiveAttributes(t, node.openingElement.attributes)) {
117
+ properties.push(t.objectProperty(t.stringLiteral(name), attribute.value ? toRuntimeNode(t, attribute.value, react) : t.booleanLiteral(true)));
118
+ }
119
+ }
120
+ const children = node.children.filter(child => !(t.isJSXText(child) && !child.value.trim()) && !(t.isJSXExpressionContainer(child) && t.isJSXEmptyExpression(child.expression))).map(child => toRuntimeNode(t, child, react));
121
+ return t.callExpression(t.memberExpression(t.cloneNode(react), t.identifier('createElement')), [t.isJSXElement(node) ? elementType(t, node.openingElement.name) : t.memberExpression(t.cloneNode(react), t.identifier('Fragment')), properties.length ? t.objectExpression(properties) : t.nullLiteral(), ...children]);
122
+ }
123
+ if (t.isJSXText(node)) {
124
+ return t.stringLiteral(node.value.replace(/\s+/g, ' ').trim());
125
+ }
126
+ if (t.isJSXExpressionContainer(node)) {
127
+ return toRuntimeNode(t, node.expression, react);
128
+ }
129
+ // Recurse through all expression shapes so cloned JSX cannot survive Babel's
130
+ // JSX visitor or be instrumented a second time inside the content getter.
131
+ const cloned = t.cloneNode(node, false);
132
+ const fields = cloned;
133
+ for (const key of t.VISITOR_KEYS[node.type] || []) {
134
+ const value = fields[key];
135
+ if (Array.isArray(value)) {
136
+ fields[key] = value.map(child => child ? toRuntimeNode(t, child, react) : child);
137
+ } else if (value) {
138
+ fields[key] = toRuntimeNode(t, value, react);
139
+ }
140
+ }
141
+ return cloned;
142
+ }
143
+
144
+ /** Matches Datadog's click-time evaluation of content props and JSX children. */
145
+ export function buildContentGetter(t, path, component, state) {
146
+ if (!component.useContent) {
147
+ return null;
148
+ }
149
+ const candidateNames = contentCandidateNames(component);
150
+ const attributes = effectiveAttributes(t, path.node.openingElement.attributes);
151
+ const candidates = [];
152
+ for (const name of candidateNames) {
153
+ const attribute = attributes.get(name);
154
+ if (attribute !== null && attribute !== void 0 && attribute.value) {
155
+ candidates.push(toRuntimeNode(t, attribute.value, state._ftReactIdentifier));
156
+ }
157
+ }
158
+ const fragment = t.jsxFragment(t.jsxOpeningFragment(), t.jsxClosingFragment(), path.node.children);
159
+ return t.arrowFunctionExpression([], t.callExpression(t.cloneNode(state._ftExtractTextIdentifier), [toRuntimeNode(t, fragment, state._ftReactIdentifier), t.arrayExpression(candidates)]));
160
+ }
161
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["getDirectAttributePaths","getNodeName","CONTENT_PROPS","contentCandidateNames","component","contentProp","includes","elementType","t","name","isJSXMemberExpression","receiver","isJSXIdentifier","object","identifier","memberExpression","property","value","test","stringLiteral","effectiveAttributes","attributes","result","Map","attribute","isJSXSpreadAttribute","clear","set","contentSourcePaths","path","candidateNames","attributePath","isJSXAttribute","node","sources","get","valuePath","Array","isArray","push","concat","containsPath","root","candidate","current","parentPath","isContentVisibleFromScope","destinationScope","visible","checkReference","referencePath","sourceBinding","scope","getBinding","some","source","destinationBinding","traverse","ReferencedIdentifier","stop","JSXOpeningElement","openingPath","isMember","JSXSpreadAttribute","spreadPath","skip","toRuntimeNode","react","isJSXElement","isJSXFragment","properties","openingElement","objectProperty","booleanLiteral","children","filter","child","isJSXText","trim","isJSXExpressionContainer","isJSXEmptyExpression","expression","map","callExpression","cloneNode","length","objectExpression","nullLiteral","replace","cloned","fields","key","VISITOR_KEYS","type","buildContentGetter","state","useContent","candidates","_ftReactIdentifier","fragment","jsxFragment","jsxOpeningFragment","jsxClosingFragment","arrowFunctionExpression","_ftExtractTextIdentifier","arrayExpression"],"sources":["content.ts"],"sourcesContent":["/*\n * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel\n * interaction tracking implementation, licensed under Apache-2.0.\n */\n\nimport type * as Babel from '@babel/core';\nimport type { PluginState, TrackedComponentData } from '../../types';\nimport { getDirectAttributePaths, getNodeName } from '../../utils/jsx';\n\nconst CONTENT_PROPS = ['trackingLabel', 'title', 'label', 'text'];\n\nfunction contentCandidateNames(component: TrackedComponentData): string[] {\n return component.contentProp && !CONTENT_PROPS.includes(component.contentProp)\n ? [...CONTENT_PROPS, component.contentProp]\n : CONTENT_PROPS;\n}\n\nfunction elementType(\n t: typeof Babel.types,\n name: Babel.types.JSXOpeningElement['name']\n): Babel.types.Expression {\n if (t.isJSXMemberExpression(name)) {\n // Lowercase member receivers (e.g. ui.Text) are variables, not host tags.\n const receiver = t.isJSXIdentifier(name.object)\n ? t.identifier(name.object.name)\n : elementType(t, name.object);\n return t.memberExpression(receiver, t.identifier(name.property.name));\n }\n const value = getNodeName(t, name) || '';\n return t.isJSXIdentifier(name) && !/^[a-z]/.test(value)\n ? t.identifier(value)\n : t.stringLiteral(value);\n}\n\nfunction effectiveAttributes(\n t: typeof Babel.types,\n attributes: Babel.types.JSXOpeningElement['attributes']\n): Map<string, Babel.types.JSXAttribute> {\n const result = new Map<string, Babel.types.JSXAttribute>();\n for (const attribute of attributes) {\n if (t.isJSXSpreadAttribute(attribute)) {\n // Do not replay spreads or trust props they may have overridden.\n result.clear();\n } else {\n result.set(getNodeName(t, attribute.name) || '', attribute);\n }\n }\n return result;\n}\n\nfunction contentSourcePaths(\n t: typeof Babel.types,\n path: Babel.NodePath<Babel.types.JSXElement>,\n component: TrackedComponentData\n): Babel.NodePath[] {\n const candidateNames = contentCandidateNames(component);\n const attributes = new Map<\n string,\n Babel.NodePath<Babel.types.JSXAttribute>\n >();\n for (const attributePath of getDirectAttributePaths(path)) {\n if (!attributePath.isJSXAttribute()) {\n attributes.clear();\n continue;\n }\n attributes.set(\n getNodeName(t, attributePath.node.name) || '',\n attributePath\n );\n }\n const sources: Babel.NodePath[] = [];\n for (const name of candidateNames) {\n const attributePath = attributes.get(name);\n const valuePath = attributePath?.get('value');\n if (valuePath && !Array.isArray(valuePath) && valuePath.node) {\n sources.push(valuePath as Babel.NodePath<Babel.types.Node>);\n }\n }\n return sources.concat(path.get('children') as Babel.NodePath[]);\n}\n\nfunction containsPath(\n root: Babel.NodePath,\n candidate: Babel.NodePath\n): boolean {\n let current: Babel.NodePath | null = candidate;\n while (current) {\n if (current === root || current.node === root.node) {\n return true;\n }\n current = current.parentPath;\n }\n return false;\n}\n\n/** Checks whether moving content into a memo callback preserves every binding. */\nexport function isContentVisibleFromScope(\n t: typeof Babel.types,\n path: Babel.NodePath<Babel.types.JSXElement>,\n component: TrackedComponentData,\n destinationScope: Babel.NodePath['scope']\n): boolean {\n const sources = contentSourcePaths(t, path, component);\n let visible = true;\n const checkReference = (referencePath: Babel.NodePath, name: string) => {\n const sourceBinding = referencePath.scope.getBinding(name);\n if (\n sourceBinding &&\n sources.some((source) => containsPath(source, sourceBinding.path))\n ) {\n return;\n }\n const destinationBinding = destinationScope.getBinding(name);\n if (sourceBinding?.identifier !== destinationBinding?.identifier) {\n visible = false;\n }\n };\n\n for (const source of sources) {\n source.traverse({\n ReferencedIdentifier(referencePath) {\n checkReference(referencePath, referencePath.node.name);\n if (!visible) {\n referencePath.stop();\n }\n },\n JSXOpeningElement(openingPath) {\n let name = openingPath.node.name;\n let isMember = false;\n while (t.isJSXMemberExpression(name)) {\n isMember = true;\n name = name.object;\n }\n if (\n t.isJSXIdentifier(name) &&\n (isMember || !/^[a-z]/.test(name.name))\n ) {\n checkReference(openingPath, name.name);\n }\n if (!visible) {\n openingPath.stop();\n }\n },\n JSXSpreadAttribute(spreadPath) {\n // Spread attributes are not copied into the content getter.\n spreadPath.skip();\n },\n });\n if (!visible) {\n return false;\n }\n }\n return true;\n}\n\n/** Converts JSX anywhere in an expression, including render functions and maps. */\nfunction toRuntimeNode(\n t: typeof Babel.types,\n node: Babel.types.Node,\n react: Babel.types.Identifier\n): Babel.types.Node {\n if (t.isJSXElement(node) || t.isJSXFragment(node)) {\n const properties: Babel.types.ObjectProperty[] = [];\n if (t.isJSXElement(node)) {\n for (const [name, attribute] of effectiveAttributes(\n t,\n node.openingElement.attributes\n )) {\n properties.push(\n t.objectProperty(\n t.stringLiteral(name),\n attribute.value\n ? (toRuntimeNode(\n t,\n attribute.value,\n react\n ) as Babel.types.Expression)\n : t.booleanLiteral(true)\n )\n );\n }\n }\n const children = node.children\n .filter(\n (child) =>\n !(t.isJSXText(child) && !child.value.trim()) &&\n !(\n t.isJSXExpressionContainer(child) &&\n t.isJSXEmptyExpression(child.expression)\n )\n )\n .map((child) => toRuntimeNode(t, child, react) as Babel.types.Expression);\n return t.callExpression(\n t.memberExpression(t.cloneNode(react), t.identifier('createElement')),\n [\n t.isJSXElement(node)\n ? elementType(t, node.openingElement.name)\n : t.memberExpression(t.cloneNode(react), t.identifier('Fragment')),\n properties.length ? t.objectExpression(properties) : t.nullLiteral(),\n ...children,\n ]\n );\n }\n if (t.isJSXText(node)) {\n return t.stringLiteral(node.value.replace(/\\s+/g, ' ').trim());\n }\n if (t.isJSXExpressionContainer(node)) {\n return toRuntimeNode(t, node.expression, react);\n }\n // Recurse through all expression shapes so cloned JSX cannot survive Babel's\n // JSX visitor or be instrumented a second time inside the content getter.\n const cloned = t.cloneNode(node, false);\n const fields = cloned as unknown as Record<\n string,\n Babel.types.Node | Babel.types.Node[] | null\n >;\n for (const key of t.VISITOR_KEYS[node.type] || []) {\n const value = fields[key];\n if (Array.isArray(value)) {\n fields[key] = value.map((child) =>\n child ? toRuntimeNode(t, child, react) : child\n );\n } else if (value) {\n fields[key] = toRuntimeNode(t, value, react);\n }\n }\n return cloned;\n}\n\n/** Matches Datadog's click-time evaluation of content props and JSX children. */\nexport function buildContentGetter(\n t: typeof Babel.types,\n path: Babel.NodePath<Babel.types.JSXElement>,\n component: TrackedComponentData,\n state: PluginState\n): Babel.types.ArrowFunctionExpression | null {\n if (!component.useContent) {\n return null;\n }\n const candidateNames = contentCandidateNames(component);\n const attributes = effectiveAttributes(\n t,\n path.node.openingElement.attributes\n );\n const candidates: Babel.types.Expression[] = [];\n for (const name of candidateNames) {\n const attribute = attributes.get(name);\n if (attribute?.value) {\n candidates.push(\n toRuntimeNode(\n t,\n attribute.value,\n state._ftReactIdentifier\n ) as Babel.types.Expression\n );\n }\n }\n const fragment = t.jsxFragment(\n t.jsxOpeningFragment(),\n t.jsxClosingFragment(),\n path.node.children\n );\n return t.arrowFunctionExpression(\n [],\n t.callExpression(t.cloneNode(state._ftExtractTextIdentifier), [\n toRuntimeNode(\n t,\n fragment,\n state._ftReactIdentifier\n ) as Babel.types.Expression,\n t.arrayExpression(candidates),\n ])\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,61 @@
1
+ /*
2
+ * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel
3
+ * interaction tracking implementation, licensed under Apache-2.0.
4
+ */
5
+
6
+ import { RUNTIME_PACKAGE } from '../../constants';
7
+ import { getDirectAttributePaths, getNodeName } from '../../utils/jsx';
8
+ import { addRequiredTextInputHandler, isInsideConfiguredComponent } from './components';
9
+ import { buildMetadata } from './metadata';
10
+ import { wrapMemoizedHandler } from './memoization';
11
+ import { buildGuardedHandlerWrapper, buildHandlerWrapper } from './tap';
12
+ export function handleJSXElement(t, path, state, options) {
13
+ const componentName = getNodeName(t, path.node.openingElement.name);
14
+ const component = componentName ? state._ftTrackedComponents[componentName] : undefined;
15
+ if (!componentName || !component || isInsideConfiguredComponent(t, path, state._ftCustomNames)) {
16
+ return;
17
+ }
18
+ addRequiredTextInputHandler(t, path, component, componentName);
19
+ let metadata;
20
+ for (const attributePath of getDirectAttributePaths(path)) {
21
+ var _attributePath$node$e;
22
+ if (!attributePath.isJSXAttribute() || (_attributePath$node$e = attributePath.node.extra) !== null && _attributePath$node$e !== void 0 && _attributePath$node$e.__ftWrappedAction) {
23
+ continue;
24
+ }
25
+ const attributeName = getNodeName(t, attributePath.node.name);
26
+ const handler = component.handlers.find(item => item.event === attributeName);
27
+ if (!handler) {
28
+ continue;
29
+ }
30
+ const value = attributePath.node.value;
31
+ if (!t.isJSXExpressionContainer(value)) {
32
+ continue;
33
+ }
34
+ const expression = value.expression;
35
+ if (!t.isArrowFunctionExpression(expression) && !t.isFunctionExpression(expression) && !t.isIdentifier(expression) && !t.isMemberExpression(expression) && !t.isConditionalExpression(expression)) {
36
+ continue;
37
+ }
38
+ metadata || (metadata = buildMetadata(t, path, componentName, component, options, state));
39
+ if (!wrapMemoizedHandler(t, attributePath, expression, metadata, state, handler.mode, handler.actionType)) {
40
+ const wrappedHandler = t.isConditionalExpression(expression) ? buildGuardedHandlerWrapper(t, expression, metadata, state, attributePath.scope, handler.mode, handler.actionType) : buildHandlerWrapper(t, expression, metadata, state, attributePath.scope, handler.mode, handler.actionType);
41
+ attributePath.node.value = t.jsxExpressionContainer(wrappedHandler);
42
+ state._ftHasWrappedAction = true;
43
+ }
44
+ attributePath.node.extra = {
45
+ ...attributePath.node.extra,
46
+ __ftWrappedAction: true
47
+ };
48
+ }
49
+ }
50
+ export function insertRuntimeImports(t, programPath, state) {
51
+ if (!state._ftHasWrappedAction) {
52
+ return;
53
+ }
54
+ const imports = [t.importSpecifier(t.cloneNode(state._ftTrackingIdentifier), t.identifier('FTBabelInteractionTracking'))];
55
+ if (state._ftNeedsContentRuntime) {
56
+ imports.push(t.importSpecifier(t.cloneNode(state._ftExtractTextIdentifier), t.identifier('__ftExtractText')));
57
+ programPath.unshiftContainer('body', t.importDeclaration([t.importNamespaceSpecifier(t.cloneNode(state._ftReactIdentifier))], t.stringLiteral('react')));
58
+ }
59
+ programPath.unshiftContainer('body', t.importDeclaration(imports, t.stringLiteral(RUNTIME_PACKAGE)));
60
+ }
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["RUNTIME_PACKAGE","getDirectAttributePaths","getNodeName","addRequiredTextInputHandler","isInsideConfiguredComponent","buildMetadata","wrapMemoizedHandler","buildGuardedHandlerWrapper","buildHandlerWrapper","handleJSXElement","t","path","state","options","componentName","node","openingElement","name","component","_ftTrackedComponents","undefined","_ftCustomNames","metadata","attributePath","_attributePath$node$e","isJSXAttribute","extra","__ftWrappedAction","attributeName","handler","handlers","find","item","event","value","isJSXExpressionContainer","expression","isArrowFunctionExpression","isFunctionExpression","isIdentifier","isMemberExpression","isConditionalExpression","mode","actionType","wrappedHandler","scope","jsxExpressionContainer","_ftHasWrappedAction","insertRuntimeImports","programPath","imports","importSpecifier","cloneNode","_ftTrackingIdentifier","identifier","_ftNeedsContentRuntime","push","_ftExtractTextIdentifier","unshiftContainer","importDeclaration","importNamespaceSpecifier","_ftReactIdentifier","stringLiteral"],"sources":["index.ts"],"sourcesContent":["/*\n * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel\n * interaction tracking implementation, licensed under Apache-2.0.\n */\n\nimport type * as Babel from '@babel/core';\nimport { RUNTIME_PACKAGE } from '../../constants';\nimport type {\n ActionMetadata,\n NormalizedPluginOptions,\n PluginState,\n} from '../../types';\nimport { getDirectAttributePaths, getNodeName } from '../../utils/jsx';\nimport {\n addRequiredTextInputHandler,\n isInsideConfiguredComponent,\n} from './components';\nimport { buildMetadata } from './metadata';\nimport { wrapMemoizedHandler } from './memoization';\nimport { buildGuardedHandlerWrapper, buildHandlerWrapper } from './tap';\n\nexport function handleJSXElement(\n t: typeof Babel.types,\n path: Babel.NodePath<Babel.types.JSXElement>,\n state: PluginState,\n options: NormalizedPluginOptions\n): void {\n const componentName = getNodeName(t, path.node.openingElement.name);\n const component = componentName\n ? state._ftTrackedComponents[componentName]\n : undefined;\n if (\n !componentName ||\n !component ||\n isInsideConfiguredComponent(t, path, state._ftCustomNames)\n ) {\n return;\n }\n\n addRequiredTextInputHandler(t, path, component, componentName);\n let metadata: ActionMetadata | undefined;\n\n for (const attributePath of getDirectAttributePaths(path)) {\n if (\n !attributePath.isJSXAttribute() ||\n attributePath.node.extra?.__ftWrappedAction\n ) {\n continue;\n }\n const attributeName = getNodeName(t, attributePath.node.name);\n const handler = component.handlers.find(\n (item) => item.event === attributeName\n );\n if (!handler) {\n continue;\n }\n const value = attributePath.node.value;\n if (!t.isJSXExpressionContainer(value)) {\n continue;\n }\n const expression = value.expression;\n if (\n !t.isArrowFunctionExpression(expression) &&\n !t.isFunctionExpression(expression) &&\n !t.isIdentifier(expression) &&\n !t.isMemberExpression(expression) &&\n !t.isConditionalExpression(expression)\n ) {\n continue;\n }\n\n metadata ||= buildMetadata(\n t,\n path,\n componentName,\n component,\n options,\n state\n );\n\n if (\n !wrapMemoizedHandler(\n t,\n attributePath,\n expression,\n metadata,\n state,\n handler.mode,\n handler.actionType\n )\n ) {\n const wrappedHandler = t.isConditionalExpression(expression)\n ? buildGuardedHandlerWrapper(\n t,\n expression,\n metadata,\n state,\n attributePath.scope,\n handler.mode,\n handler.actionType\n )\n : buildHandlerWrapper(\n t,\n expression,\n metadata,\n state,\n attributePath.scope,\n handler.mode,\n handler.actionType\n );\n attributePath.node.value = t.jsxExpressionContainer(wrappedHandler);\n state._ftHasWrappedAction = true;\n }\n attributePath.node.extra = {\n ...attributePath.node.extra,\n __ftWrappedAction: true,\n };\n }\n}\n\nexport function insertRuntimeImports(\n t: typeof Babel.types,\n programPath: Babel.NodePath<Babel.types.Program>,\n state: PluginState\n): void {\n if (!state._ftHasWrappedAction) {\n return;\n }\n const imports = [\n t.importSpecifier(\n t.cloneNode(state._ftTrackingIdentifier),\n t.identifier('FTBabelInteractionTracking')\n ),\n ];\n if (state._ftNeedsContentRuntime) {\n imports.push(\n t.importSpecifier(\n t.cloneNode(state._ftExtractTextIdentifier),\n t.identifier('__ftExtractText')\n )\n );\n programPath.unshiftContainer(\n 'body',\n t.importDeclaration(\n [t.importNamespaceSpecifier(t.cloneNode(state._ftReactIdentifier))],\n t.stringLiteral('react')\n )\n );\n }\n programPath.unshiftContainer(\n 'body',\n t.importDeclaration(imports, t.stringLiteral(RUNTIME_PACKAGE))\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,82 @@
1
+ /*
2
+ * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel
3
+ * interaction tracking implementation, licensed under Apache-2.0.
4
+ */
5
+
6
+ import { isContentVisibleFromScope } from './content';
7
+ import { buildHandlerWrapper } from './tap';
8
+ function getMemoizationName(t, callee) {
9
+ if (t.isIdentifier(callee)) {
10
+ return callee.name;
11
+ }
12
+ if (t.isMemberExpression(callee) && t.isIdentifier(callee.property)) {
13
+ return callee.property.name;
14
+ }
15
+ return null;
16
+ }
17
+ function getVariableDeclaratorPath(bindingPath) {
18
+ if (bindingPath.isVariableDeclarator()) {
19
+ return bindingPath;
20
+ }
21
+ return bindingPath.findParent(parent => parent.isVariableDeclarator()) || null;
22
+ }
23
+ function isLocalFunctionReference(path, expression) {
24
+ if (!expression || expression.type !== 'Identifier') {
25
+ return true;
26
+ }
27
+ const binding = path.scope.getBinding(expression.name);
28
+ if (!binding) {
29
+ return false;
30
+ }
31
+ return !(binding.path.isImportSpecifier() || binding.path.isImportDefaultSpecifier() || binding.path.isImportNamespaceSpecifier());
32
+ }
33
+
34
+ /** Wraps the hook callback once so JSX references retain their memoized identity. */
35
+ export function wrapMemoizedHandler(t, path, expression, metadata, state, mode, actionType) {
36
+ var _path$parentPath;
37
+ if (!t.isIdentifier(expression)) {
38
+ return false;
39
+ }
40
+ const binding = path.scope.getBinding(expression.name);
41
+ if (!binding) {
42
+ return false;
43
+ }
44
+ const declaratorPath = getVariableDeclaratorPath(binding.path);
45
+ if (!declaratorPath) {
46
+ return false;
47
+ }
48
+ const initPath = declaratorPath.get('init');
49
+ if (!initPath.isCallExpression()) {
50
+ return false;
51
+ }
52
+ const memoizationName = getMemoizationName(t, initPath.node.callee);
53
+ if (!memoizationName || !['useCallback', 'useMemo'].includes(memoizationName)) {
54
+ return false;
55
+ }
56
+ if (state._ftMemoizedHandlers.has(declaratorPath.node)) {
57
+ return true;
58
+ }
59
+ const argumentPaths = initPath.get('arguments');
60
+ const callbackPath = argumentPaths[0];
61
+ if (!callbackPath || callbackPath.isSpreadElement()) {
62
+ return false;
63
+ }
64
+ const callback = callbackPath.node;
65
+ if (!t.isArrowFunctionExpression(callback) && !t.isFunctionExpression(callback) && !t.isIdentifier(callback)) {
66
+ return false;
67
+ }
68
+ if (!isLocalFunctionReference(path, callback)) {
69
+ state._ftMemoizedHandlers.add(declaratorPath.node);
70
+ return true;
71
+ }
72
+ const elementPath = (_path$parentPath = path.parentPath) === null || _path$parentPath === void 0 ? void 0 : _path$parentPath.parentPath;
73
+ const metadataAtMemoDefinition = metadata.getContent && elementPath !== null && elementPath !== void 0 && elementPath.isJSXElement() && !isContentVisibleFromScope(t, elementPath, metadata.component, initPath.scope) ? {
74
+ ...metadata,
75
+ getContent: null
76
+ } : metadata;
77
+ callbackPath.replaceWith(buildHandlerWrapper(t, callback, metadataAtMemoDefinition, state, callbackPath.scope, memoizationName === 'useMemo' ? 'delayed' : mode, actionType));
78
+ state._ftMemoizedHandlers.add(declaratorPath.node);
79
+ state._ftHasWrappedAction = true;
80
+ return true;
81
+ }
82
+ //# sourceMappingURL=memoization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["isContentVisibleFromScope","buildHandlerWrapper","getMemoizationName","t","callee","isIdentifier","name","isMemberExpression","property","getVariableDeclaratorPath","bindingPath","isVariableDeclarator","findParent","parent","isLocalFunctionReference","path","expression","type","binding","scope","getBinding","isImportSpecifier","isImportDefaultSpecifier","isImportNamespaceSpecifier","wrapMemoizedHandler","metadata","state","mode","actionType","_path$parentPath","declaratorPath","initPath","get","isCallExpression","memoizationName","node","includes","_ftMemoizedHandlers","has","argumentPaths","callbackPath","isSpreadElement","callback","isArrowFunctionExpression","isFunctionExpression","add","elementPath","parentPath","metadataAtMemoDefinition","getContent","isJSXElement","component","replaceWith","_ftHasWrappedAction"],"sources":["memoization.ts"],"sourcesContent":["/*\n * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel\n * interaction tracking implementation, licensed under Apache-2.0.\n */\n\nimport type * as Babel from '@babel/core';\nimport type { ActionMetadata, PluginState, TrackedHandler } from '../../types';\nimport { isContentVisibleFromScope } from './content';\nimport { buildHandlerWrapper } from './tap';\n\nfunction getMemoizationName(\n t: typeof Babel.types,\n callee: Babel.types.Expression | Babel.types.V8IntrinsicIdentifier\n): string | null {\n if (t.isIdentifier(callee)) {\n return callee.name;\n }\n if (t.isMemberExpression(callee) && t.isIdentifier(callee.property)) {\n return callee.property.name;\n }\n return null;\n}\n\nfunction getVariableDeclaratorPath(\n bindingPath: Babel.NodePath\n): Babel.NodePath<Babel.types.VariableDeclarator> | null {\n if (bindingPath.isVariableDeclarator()) {\n return bindingPath;\n }\n return (\n (bindingPath.findParent((parent) =>\n parent.isVariableDeclarator()\n ) as Babel.NodePath<Babel.types.VariableDeclarator> | null) || null\n );\n}\n\nfunction isLocalFunctionReference(\n path: Babel.NodePath,\n expression: Babel.types.Expression\n): boolean {\n if (!expression || expression.type !== 'Identifier') {\n return true;\n }\n const binding = path.scope.getBinding(expression.name);\n if (!binding) {\n return false;\n }\n return !(\n binding.path.isImportSpecifier() ||\n binding.path.isImportDefaultSpecifier() ||\n binding.path.isImportNamespaceSpecifier()\n );\n}\n\n/** Wraps the hook callback once so JSX references retain their memoized identity. */\nexport function wrapMemoizedHandler(\n t: typeof Babel.types,\n path: Babel.NodePath<Babel.types.JSXAttribute>,\n expression: Babel.types.Expression,\n metadata: ActionMetadata,\n state: PluginState,\n mode: TrackedHandler['mode'],\n actionType: TrackedHandler['actionType']\n): boolean {\n if (!t.isIdentifier(expression)) {\n return false;\n }\n const binding = path.scope.getBinding(expression.name);\n if (!binding) {\n return false;\n }\n const declaratorPath = getVariableDeclaratorPath(binding.path);\n if (!declaratorPath) {\n return false;\n }\n const initPath = declaratorPath.get('init');\n if (!initPath.isCallExpression()) {\n return false;\n }\n const memoizationName = getMemoizationName(t, initPath.node.callee);\n if (\n !memoizationName ||\n !['useCallback', 'useMemo'].includes(memoizationName)\n ) {\n return false;\n }\n if (state._ftMemoizedHandlers.has(declaratorPath.node)) {\n return true;\n }\n\n const argumentPaths = initPath.get('arguments');\n const callbackPath = argumentPaths[0];\n if (!callbackPath || callbackPath.isSpreadElement()) {\n return false;\n }\n const callback = callbackPath.node;\n if (\n !t.isArrowFunctionExpression(callback) &&\n !t.isFunctionExpression(callback) &&\n !t.isIdentifier(callback)\n ) {\n return false;\n }\n if (!isLocalFunctionReference(path, callback)) {\n state._ftMemoizedHandlers.add(declaratorPath.node);\n return true;\n }\n\n const elementPath = path.parentPath?.parentPath;\n const metadataAtMemoDefinition =\n metadata.getContent &&\n elementPath?.isJSXElement() &&\n !isContentVisibleFromScope(\n t,\n elementPath,\n metadata.component,\n initPath.scope\n )\n ? { ...metadata, getContent: null }\n : metadata;\n\n callbackPath.replaceWith(\n buildHandlerWrapper(\n t,\n callback,\n metadataAtMemoDefinition,\n state,\n callbackPath.scope,\n memoizationName === 'useMemo' ? 'delayed' : mode,\n actionType\n )\n );\n state._ftMemoizedHandlers.add(declaratorPath.node);\n state._ftHasWrappedAction = true;\n return true;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;;AAIA,SAASA,yBAAyB,QAAQ,WAAW;AACrD,SAASC,mBAAmB,QAAQ,OAAO;AAE3C,SAASC,kBAAkBA,CACzBC,CAAqB,EACrBC,MAAkE,EACnD;EACf,IAAID,CAAC,CAACE,YAAY,CAACD,MAAM,CAAC,EAAE;IAC1B,OAAOA,MAAM,CAACE,IAAI;EACpB;EACA,IAAIH,CAAC,CAACI,kBAAkB,CAACH,MAAM,CAAC,IAAID,CAAC,CAACE,YAAY,CAACD,MAAM,CAACI,QAAQ,CAAC,EAAE;IACnE,OAAOJ,MAAM,CAACI,QAAQ,CAACF,IAAI;EAC7B;EACA,OAAO,IAAI;AACb;AAEA,SAASG,yBAAyBA,CAChCC,WAA2B,EAC4B;EACvD,IAAIA,WAAW,CAACC,oBAAoB,CAAC,CAAC,EAAE;IACtC,OAAOD,WAAW;EACpB;EACA,OACGA,WAAW,CAACE,UAAU,CAAEC,MAAM,IAC7BA,MAAM,CAACF,oBAAoB,CAAC,CAC9B,CAAC,IAA8D,IAAI;AAEvE;AAEA,SAASG,wBAAwBA,CAC/BC,IAAoB,EACpBC,UAAkC,EACzB;EACT,IAAI,CAACA,UAAU,IAAIA,UAAU,CAACC,IAAI,KAAK,YAAY,EAAE;IACnD,OAAO,IAAI;EACb;EACA,MAAMC,OAAO,GAAGH,IAAI,CAACI,KAAK,CAACC,UAAU,CAACJ,UAAU,CAACV,IAAI,CAAC;EACtD,IAAI,CAACY,OAAO,EAAE;IACZ,OAAO,KAAK;EACd;EACA,OAAO,EACLA,OAAO,CAACH,IAAI,CAACM,iBAAiB,CAAC,CAAC,IAChCH,OAAO,CAACH,IAAI,CAACO,wBAAwB,CAAC,CAAC,IACvCJ,OAAO,CAACH,IAAI,CAACQ,0BAA0B,CAAC,CAAC,CAC1C;AACH;;AAEA;AACA,OAAO,SAASC,mBAAmBA,CACjCrB,CAAqB,EACrBY,IAA8C,EAC9CC,UAAkC,EAClCS,QAAwB,EACxBC,KAAkB,EAClBC,IAA4B,EAC5BC,UAAwC,EAC/B;EAAA,IAAAC,gBAAA;EACT,IAAI,CAAC1B,CAAC,CAACE,YAAY,CAACW,UAAU,CAAC,EAAE;IAC/B,OAAO,KAAK;EACd;EACA,MAAME,OAAO,GAAGH,IAAI,CAACI,KAAK,CAACC,UAAU,CAACJ,UAAU,CAACV,IAAI,CAAC;EACtD,IAAI,CAACY,OAAO,EAAE;IACZ,OAAO,KAAK;EACd;EACA,MAAMY,cAAc,GAAGrB,yBAAyB,CAACS,OAAO,CAACH,IAAI,CAAC;EAC9D,IAAI,CAACe,cAAc,EAAE;IACnB,OAAO,KAAK;EACd;EACA,MAAMC,QAAQ,GAAGD,cAAc,CAACE,GAAG,CAAC,MAAM,CAAC;EAC3C,IAAI,CAACD,QAAQ,CAACE,gBAAgB,CAAC,CAAC,EAAE;IAChC,OAAO,KAAK;EACd;EACA,MAAMC,eAAe,GAAGhC,kBAAkB,CAACC,CAAC,EAAE4B,QAAQ,CAACI,IAAI,CAAC/B,MAAM,CAAC;EACnE,IACE,CAAC8B,eAAe,IAChB,CAAC,CAAC,aAAa,EAAE,SAAS,CAAC,CAACE,QAAQ,CAACF,eAAe,CAAC,EACrD;IACA,OAAO,KAAK;EACd;EACA,IAAIR,KAAK,CAACW,mBAAmB,CAACC,GAAG,CAACR,cAAc,CAACK,IAAI,CAAC,EAAE;IACtD,OAAO,IAAI;EACb;EAEA,MAAMI,aAAa,GAAGR,QAAQ,CAACC,GAAG,CAAC,WAAW,CAAC;EAC/C,MAAMQ,YAAY,GAAGD,aAAa,CAAC,CAAC,CAAC;EACrC,IAAI,CAACC,YAAY,IAAIA,YAAY,CAACC,eAAe,CAAC,CAAC,EAAE;IACnD,OAAO,KAAK;EACd;EACA,MAAMC,QAAQ,GAAGF,YAAY,CAACL,IAAI;EAClC,IACE,CAAChC,CAAC,CAACwC,yBAAyB,CAACD,QAAQ,CAAC,IACtC,CAACvC,CAAC,CAACyC,oBAAoB,CAACF,QAAQ,CAAC,IACjC,CAACvC,CAAC,CAACE,YAAY,CAACqC,QAAQ,CAAC,EACzB;IACA,OAAO,KAAK;EACd;EACA,IAAI,CAAC5B,wBAAwB,CAACC,IAAI,EAAE2B,QAAQ,CAAC,EAAE;IAC7ChB,KAAK,CAACW,mBAAmB,CAACQ,GAAG,CAACf,cAAc,CAACK,IAAI,CAAC;IAClD,OAAO,IAAI;EACb;EAEA,MAAMW,WAAW,IAAAjB,gBAAA,GAAGd,IAAI,CAACgC,UAAU,cAAAlB,gBAAA,uBAAfA,gBAAA,CAAiBkB,UAAU;EAC/C,MAAMC,wBAAwB,GAC5BvB,QAAQ,CAACwB,UAAU,IACnBH,WAAW,aAAXA,WAAW,eAAXA,WAAW,CAAEI,YAAY,CAAC,CAAC,IAC3B,CAAClD,yBAAyB,CACxBG,CAAC,EACD2C,WAAW,EACXrB,QAAQ,CAAC0B,SAAS,EAClBpB,QAAQ,CAACZ,KACX,CAAC,GACG;IAAE,GAAGM,QAAQ;IAAEwB,UAAU,EAAE;EAAK,CAAC,GACjCxB,QAAQ;EAEde,YAAY,CAACY,WAAW,CACtBnD,mBAAmB,CACjBE,CAAC,EACDuC,QAAQ,EACRM,wBAAwB,EACxBtB,KAAK,EACLc,YAAY,CAACrB,KAAK,EAClBe,eAAe,KAAK,SAAS,GAAG,SAAS,GAAGP,IAAI,EAChDC,UACF,CACF,CAAC;EACDF,KAAK,CAACW,mBAAmB,CAACQ,GAAG,CAACf,cAAc,CAACK,IAAI,CAAC;EAClDT,KAAK,CAAC2B,mBAAmB,GAAG,IAAI;EAChC,OAAO,IAAI;AACb","ignoreList":[]}
@@ -0,0 +1,56 @@
1
+ /*
2
+ * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel
3
+ * interaction tracking implementation, licensed under Apache-2.0.
4
+ */
5
+
6
+ import { ACTION_NAME_ATTRIBUTE } from '../../constants';
7
+ import { getNodeName } from '../../utils/jsx';
8
+ import { buildContentGetter } from './content';
9
+ function collectStaticActionNames(t, path, customAttribute) {
10
+ const values = {
11
+ actionNames: [],
12
+ customActionNames: [],
13
+ accessibilityLabels: []
14
+ };
15
+ path.traverse({
16
+ JSXAttribute(attributePath) {
17
+ if (!t.isStringLiteral(attributePath.node.value)) {
18
+ return;
19
+ }
20
+ const name = getNodeName(t, attributePath.node.name);
21
+ const field = name === ACTION_NAME_ATTRIBUTE ? values.actionNames : name === 'accessibilityLabel' ? values.accessibilityLabels : name === customAttribute ? values.customActionNames : null;
22
+ if (field) {
23
+ field.push(t.cloneNode(attributePath.node.value, true));
24
+ }
25
+ }
26
+ });
27
+ return values;
28
+ }
29
+ export function buildMetadata(t, path, componentName, component, options, state) {
30
+ const names = collectStaticActionNames(t, path, options.actionNameAttribute);
31
+ const hasStaticName = Object.values(names).some(values => values.some(value => value.value.trim().length > 0));
32
+ return {
33
+ ...names,
34
+ component,
35
+ componentName,
36
+ getContent: hasStaticName ? null : buildContentGetter(t, path, component, state)
37
+ };
38
+ }
39
+ export function buildTargetObject(t, metadata, handlerArgsIdentifier, state) {
40
+ const properties = [t.objectProperty(t.identifier('options'), t.objectExpression([t.objectProperty(t.identifier('useContent'), t.booleanLiteral(metadata.component.useContent)), t.objectProperty(t.identifier('useNamePrefix'), t.booleanLiteral(metadata.component.useNamePrefix))])), t.objectProperty(t.identifier('handlerArgs'), t.cloneNode(handlerArgsIdentifier)), t.objectProperty(t.identifier('componentName'), t.stringLiteral(metadata.componentName))];
41
+ if (metadata.actionNames.length > 0) {
42
+ properties.push(t.objectProperty(t.stringLiteral(ACTION_NAME_ATTRIBUTE), t.arrayExpression(metadata.actionNames.map(value => t.cloneNode(value, true)))));
43
+ }
44
+ if (metadata.customActionNames.length > 0) {
45
+ properties.push(t.objectProperty(t.identifier('customActionName'), t.arrayExpression(metadata.customActionNames.map(value => t.cloneNode(value, true)))));
46
+ }
47
+ if (metadata.accessibilityLabels.length > 0) {
48
+ properties.push(t.objectProperty(t.identifier('accessibilityLabel'), t.arrayExpression(metadata.accessibilityLabels.map(value => t.cloneNode(value, true)))));
49
+ }
50
+ if (metadata.getContent) {
51
+ state._ftNeedsContentRuntime = true;
52
+ properties.push(t.objectProperty(t.identifier('getContent'), t.cloneNode(metadata.getContent, true)));
53
+ }
54
+ return t.objectExpression(properties);
55
+ }
56
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["ACTION_NAME_ATTRIBUTE","getNodeName","buildContentGetter","collectStaticActionNames","t","path","customAttribute","values","actionNames","customActionNames","accessibilityLabels","traverse","JSXAttribute","attributePath","isStringLiteral","node","value","name","field","push","cloneNode","buildMetadata","componentName","component","options","state","names","actionNameAttribute","hasStaticName","Object","some","trim","length","getContent","buildTargetObject","metadata","handlerArgsIdentifier","properties","objectProperty","identifier","objectExpression","booleanLiteral","useContent","useNamePrefix","stringLiteral","arrayExpression","map","_ftNeedsContentRuntime"],"sources":["metadata.ts"],"sourcesContent":["/*\n * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel\n * interaction tracking implementation, licensed under Apache-2.0.\n */\n\nimport type * as Babel from '@babel/core';\nimport { ACTION_NAME_ATTRIBUTE } from '../../constants';\nimport type {\n ActionMetadata,\n NormalizedPluginOptions,\n PluginState,\n TrackedComponentData,\n} from '../../types';\nimport { getNodeName } from '../../utils/jsx';\nimport { buildContentGetter } from './content';\n\nfunction collectStaticActionNames(\n t: typeof Babel.types,\n path: Babel.NodePath<Babel.types.JSXElement>,\n customAttribute: string | undefined\n): Pick<\n ActionMetadata,\n 'actionNames' | 'customActionNames' | 'accessibilityLabels'\n> {\n const values: Pick<\n ActionMetadata,\n 'actionNames' | 'customActionNames' | 'accessibilityLabels'\n > = {\n actionNames: [],\n customActionNames: [],\n accessibilityLabels: [],\n };\n path.traverse({\n JSXAttribute(attributePath) {\n if (!t.isStringLiteral(attributePath.node.value)) {\n return;\n }\n const name = getNodeName(t, attributePath.node.name);\n const field =\n name === ACTION_NAME_ATTRIBUTE\n ? values.actionNames\n : name === 'accessibilityLabel'\n ? values.accessibilityLabels\n : name === customAttribute\n ? values.customActionNames\n : null;\n if (field) {\n field.push(t.cloneNode(attributePath.node.value, true));\n }\n },\n });\n return values;\n}\n\nexport function buildMetadata(\n t: typeof Babel.types,\n path: Babel.NodePath<Babel.types.JSXElement>,\n componentName: string,\n component: TrackedComponentData,\n options: NormalizedPluginOptions,\n state: PluginState\n): ActionMetadata {\n const names = collectStaticActionNames(t, path, options.actionNameAttribute);\n const hasStaticName = Object.values(names).some((values) =>\n values.some((value) => value.value.trim().length > 0)\n );\n return {\n ...names,\n component,\n componentName,\n getContent: hasStaticName\n ? null\n : buildContentGetter(t, path, component, state),\n };\n}\n\nexport function buildTargetObject(\n t: typeof Babel.types,\n metadata: ActionMetadata,\n handlerArgsIdentifier: Babel.types.Identifier,\n state: PluginState\n): Babel.types.ObjectExpression {\n const properties: Babel.types.ObjectProperty[] = [\n t.objectProperty(\n t.identifier('options'),\n t.objectExpression([\n t.objectProperty(\n t.identifier('useContent'),\n t.booleanLiteral(metadata.component.useContent)\n ),\n t.objectProperty(\n t.identifier('useNamePrefix'),\n t.booleanLiteral(metadata.component.useNamePrefix)\n ),\n ])\n ),\n t.objectProperty(\n t.identifier('handlerArgs'),\n t.cloneNode(handlerArgsIdentifier)\n ),\n t.objectProperty(\n t.identifier('componentName'),\n t.stringLiteral(metadata.componentName)\n ),\n ];\n\n if (metadata.actionNames.length > 0) {\n properties.push(\n t.objectProperty(\n t.stringLiteral(ACTION_NAME_ATTRIBUTE),\n t.arrayExpression(\n metadata.actionNames.map((value) => t.cloneNode(value, true))\n )\n )\n );\n }\n if (metadata.customActionNames.length > 0) {\n properties.push(\n t.objectProperty(\n t.identifier('customActionName'),\n t.arrayExpression(\n metadata.customActionNames.map((value) => t.cloneNode(value, true))\n )\n )\n );\n }\n if (metadata.accessibilityLabels.length > 0) {\n properties.push(\n t.objectProperty(\n t.identifier('accessibilityLabel'),\n t.arrayExpression(\n metadata.accessibilityLabels.map((value) => t.cloneNode(value, true))\n )\n )\n );\n }\n if (metadata.getContent) {\n state._ftNeedsContentRuntime = true;\n properties.push(\n t.objectProperty(\n t.identifier('getContent'),\n t.cloneNode(metadata.getContent, true)\n )\n );\n }\n return t.objectExpression(properties);\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;;AAGA,SAASA,qBAAqB,QAAQ,iBAAiB;AAOvD,SAASC,WAAW,QAAQ,iBAAiB;AAC7C,SAASC,kBAAkB,QAAQ,WAAW;AAE9C,SAASC,wBAAwBA,CAC/BC,CAAqB,EACrBC,IAA4C,EAC5CC,eAAmC,EAInC;EACA,MAAMC,MAGL,GAAG;IACFC,WAAW,EAAE,EAAE;IACfC,iBAAiB,EAAE,EAAE;IACrBC,mBAAmB,EAAE;EACvB,CAAC;EACDL,IAAI,CAACM,QAAQ,CAAC;IACZC,YAAYA,CAACC,aAAa,EAAE;MAC1B,IAAI,CAACT,CAAC,CAACU,eAAe,CAACD,aAAa,CAACE,IAAI,CAACC,KAAK,CAAC,EAAE;QAChD;MACF;MACA,MAAMC,IAAI,GAAGhB,WAAW,CAACG,CAAC,EAAES,aAAa,CAACE,IAAI,CAACE,IAAI,CAAC;MACpD,MAAMC,KAAK,GACTD,IAAI,KAAKjB,qBAAqB,GAC1BO,MAAM,CAACC,WAAW,GAClBS,IAAI,KAAK,oBAAoB,GAC7BV,MAAM,CAACG,mBAAmB,GAC1BO,IAAI,KAAKX,eAAe,GACxBC,MAAM,CAACE,iBAAiB,GACxB,IAAI;MACV,IAAIS,KAAK,EAAE;QACTA,KAAK,CAACC,IAAI,CAACf,CAAC,CAACgB,SAAS,CAACP,aAAa,CAACE,IAAI,CAACC,KAAK,EAAE,IAAI,CAAC,CAAC;MACzD;IACF;EACF,CAAC,CAAC;EACF,OAAOT,MAAM;AACf;AAEA,OAAO,SAASc,aAAaA,CAC3BjB,CAAqB,EACrBC,IAA4C,EAC5CiB,aAAqB,EACrBC,SAA+B,EAC/BC,OAAgC,EAChCC,KAAkB,EACF;EAChB,MAAMC,KAAK,GAAGvB,wBAAwB,CAACC,CAAC,EAAEC,IAAI,EAAEmB,OAAO,CAACG,mBAAmB,CAAC;EAC5E,MAAMC,aAAa,GAAGC,MAAM,CAACtB,MAAM,CAACmB,KAAK,CAAC,CAACI,IAAI,CAAEvB,MAAM,IACrDA,MAAM,CAACuB,IAAI,CAAEd,KAAK,IAAKA,KAAK,CAACA,KAAK,CAACe,IAAI,CAAC,CAAC,CAACC,MAAM,GAAG,CAAC,CACtD,CAAC;EACD,OAAO;IACL,GAAGN,KAAK;IACRH,SAAS;IACTD,aAAa;IACbW,UAAU,EAAEL,aAAa,GACrB,IAAI,GACJ1B,kBAAkB,CAACE,CAAC,EAAEC,IAAI,EAAEkB,SAAS,EAAEE,KAAK;EAClD,CAAC;AACH;AAEA,OAAO,SAASS,iBAAiBA,CAC/B9B,CAAqB,EACrB+B,QAAwB,EACxBC,qBAA6C,EAC7CX,KAAkB,EACY;EAC9B,MAAMY,UAAwC,GAAG,CAC/CjC,CAAC,CAACkC,cAAc,CACdlC,CAAC,CAACmC,UAAU,CAAC,SAAS,CAAC,EACvBnC,CAAC,CAACoC,gBAAgB,CAAC,CACjBpC,CAAC,CAACkC,cAAc,CACdlC,CAAC,CAACmC,UAAU,CAAC,YAAY,CAAC,EAC1BnC,CAAC,CAACqC,cAAc,CAACN,QAAQ,CAACZ,SAAS,CAACmB,UAAU,CAChD,CAAC,EACDtC,CAAC,CAACkC,cAAc,CACdlC,CAAC,CAACmC,UAAU,CAAC,eAAe,CAAC,EAC7BnC,CAAC,CAACqC,cAAc,CAACN,QAAQ,CAACZ,SAAS,CAACoB,aAAa,CACnD,CAAC,CACF,CACH,CAAC,EACDvC,CAAC,CAACkC,cAAc,CACdlC,CAAC,CAACmC,UAAU,CAAC,aAAa,CAAC,EAC3BnC,CAAC,CAACgB,SAAS,CAACgB,qBAAqB,CACnC,CAAC,EACDhC,CAAC,CAACkC,cAAc,CACdlC,CAAC,CAACmC,UAAU,CAAC,eAAe,CAAC,EAC7BnC,CAAC,CAACwC,aAAa,CAACT,QAAQ,CAACb,aAAa,CACxC,CAAC,CACF;EAED,IAAIa,QAAQ,CAAC3B,WAAW,CAACwB,MAAM,GAAG,CAAC,EAAE;IACnCK,UAAU,CAAClB,IAAI,CACbf,CAAC,CAACkC,cAAc,CACdlC,CAAC,CAACwC,aAAa,CAAC5C,qBAAqB,CAAC,EACtCI,CAAC,CAACyC,eAAe,CACfV,QAAQ,CAAC3B,WAAW,CAACsC,GAAG,CAAE9B,KAAK,IAAKZ,CAAC,CAACgB,SAAS,CAACJ,KAAK,EAAE,IAAI,CAAC,CAC9D,CACF,CACF,CAAC;EACH;EACA,IAAImB,QAAQ,CAAC1B,iBAAiB,CAACuB,MAAM,GAAG,CAAC,EAAE;IACzCK,UAAU,CAAClB,IAAI,CACbf,CAAC,CAACkC,cAAc,CACdlC,CAAC,CAACmC,UAAU,CAAC,kBAAkB,CAAC,EAChCnC,CAAC,CAACyC,eAAe,CACfV,QAAQ,CAAC1B,iBAAiB,CAACqC,GAAG,CAAE9B,KAAK,IAAKZ,CAAC,CAACgB,SAAS,CAACJ,KAAK,EAAE,IAAI,CAAC,CACpE,CACF,CACF,CAAC;EACH;EACA,IAAImB,QAAQ,CAACzB,mBAAmB,CAACsB,MAAM,GAAG,CAAC,EAAE;IAC3CK,UAAU,CAAClB,IAAI,CACbf,CAAC,CAACkC,cAAc,CACdlC,CAAC,CAACmC,UAAU,CAAC,oBAAoB,CAAC,EAClCnC,CAAC,CAACyC,eAAe,CACfV,QAAQ,CAACzB,mBAAmB,CAACoC,GAAG,CAAE9B,KAAK,IAAKZ,CAAC,CAACgB,SAAS,CAACJ,KAAK,EAAE,IAAI,CAAC,CACtE,CACF,CACF,CAAC;EACH;EACA,IAAImB,QAAQ,CAACF,UAAU,EAAE;IACvBR,KAAK,CAACsB,sBAAsB,GAAG,IAAI;IACnCV,UAAU,CAAClB,IAAI,CACbf,CAAC,CAACkC,cAAc,CACdlC,CAAC,CAACmC,UAAU,CAAC,YAAY,CAAC,EAC1BnC,CAAC,CAACgB,SAAS,CAACe,QAAQ,CAACF,UAAU,EAAE,IAAI,CACvC,CACF,CAAC;EACH;EACA,OAAO7B,CAAC,CAACoC,gBAAgB,CAACH,UAAU,CAAC;AACvC","ignoreList":[]}
@@ -0,0 +1,38 @@
1
+ /*
2
+ * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel
3
+ * interaction tracking implementation, licensed under Apache-2.0.
4
+ */
5
+
6
+ import { buildTargetObject } from './metadata';
7
+ const DEFAULT_ACTION_TYPE = 'click';
8
+ function normalizeActionType(actionType) {
9
+ return typeof actionType === 'string' && actionType.trim() ? actionType.trim() : DEFAULT_ACTION_TYPE;
10
+ }
11
+ function buildOriginalInvocation(t, originalExpression, argsIdentifier) {
12
+ return t.optionalCallExpression(t.cloneNode(originalExpression, true), [t.spreadElement(t.cloneNode(argsIdentifier))], true);
13
+ }
14
+ function buildImmediateHandlerWrapper(t, originalExpression, metadata, state, scope, actionType) {
15
+ const handlerArgsIdentifier = scope.generateUidIdentifier('ftHandlerArgs');
16
+ const originalArgsIdentifier = scope.generateUidIdentifier('ftOriginalArgs');
17
+ const originalInvoker = t.arrowFunctionExpression([t.restElement(originalArgsIdentifier)], buildOriginalInvocation(t, originalExpression, originalArgsIdentifier));
18
+ const instanceCall = t.callExpression(t.memberExpression(t.cloneNode(state._ftTrackingIdentifier), t.identifier('getInstance')), []);
19
+ const wrappedHandler = t.callExpression(t.memberExpression(instanceCall, t.identifier('wrapRumAction')), [originalInvoker, t.stringLiteral(normalizeActionType(actionType)), buildTargetObject(t, metadata, handlerArgsIdentifier, state)]);
20
+ return t.arrowFunctionExpression([t.restElement(handlerArgsIdentifier)], t.callExpression(wrappedHandler, [t.spreadElement(t.cloneNode(handlerArgsIdentifier))]));
21
+ }
22
+
23
+ /** Wraps a handler, or a handler factory when delayed mode is configured. */
24
+ export function buildHandlerWrapper(t, originalExpression, metadata, state, scope, mode = 'default', actionType) {
25
+ if (mode !== 'delayed') {
26
+ return buildImmediateHandlerWrapper(t, originalExpression, metadata, state, scope, actionType);
27
+ }
28
+ const factoryArgsIdentifier = scope.generateUidIdentifier('ftFactoryArgs');
29
+ const handlerIdentifier = scope.generateUidIdentifier('ftDelayedHandler');
30
+ return t.arrowFunctionExpression([t.restElement(factoryArgsIdentifier)], t.blockStatement([t.variableDeclaration('const', [t.variableDeclarator(handlerIdentifier, buildOriginalInvocation(t, originalExpression, factoryArgsIdentifier))]), t.returnStatement(buildImmediateHandlerWrapper(t, handlerIdentifier, metadata, state, scope, actionType))]));
31
+ }
32
+
33
+ /** Resolves a conditional handler once at render time, preserving non-functions. */
34
+ export function buildGuardedHandlerWrapper(t, originalExpression, metadata, state, scope, mode = 'default', actionType) {
35
+ const resolvedHandlerIdentifier = scope.generateUidIdentifier('ftResolvedHandler');
36
+ return t.callExpression(t.arrowFunctionExpression([resolvedHandlerIdentifier], t.conditionalExpression(t.binaryExpression('===', t.unaryExpression('typeof', t.cloneNode(resolvedHandlerIdentifier)), t.stringLiteral('function')), buildHandlerWrapper(t, resolvedHandlerIdentifier, metadata, state, scope, mode, actionType), t.cloneNode(resolvedHandlerIdentifier))), [t.cloneNode(originalExpression, true)]);
37
+ }
38
+ //# sourceMappingURL=tap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["buildTargetObject","DEFAULT_ACTION_TYPE","normalizeActionType","actionType","trim","buildOriginalInvocation","t","originalExpression","argsIdentifier","optionalCallExpression","cloneNode","spreadElement","buildImmediateHandlerWrapper","metadata","state","scope","handlerArgsIdentifier","generateUidIdentifier","originalArgsIdentifier","originalInvoker","arrowFunctionExpression","restElement","instanceCall","callExpression","memberExpression","_ftTrackingIdentifier","identifier","wrappedHandler","stringLiteral","buildHandlerWrapper","mode","factoryArgsIdentifier","handlerIdentifier","blockStatement","variableDeclaration","variableDeclarator","returnStatement","buildGuardedHandlerWrapper","resolvedHandlerIdentifier","conditionalExpression","binaryExpression","unaryExpression"],"sources":["tap.ts"],"sourcesContent":["/*\n * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel\n * interaction tracking implementation, licensed under Apache-2.0.\n */\n\nimport type * as Babel from '@babel/core';\nimport type { ActionMetadata, PluginState, TrackedHandler } from '../../types';\nimport { buildTargetObject } from './metadata';\n\nconst DEFAULT_ACTION_TYPE = 'click';\n\nfunction normalizeActionType(actionType: TrackedHandler['actionType']): string {\n return typeof actionType === 'string' && actionType.trim()\n ? actionType.trim()\n : DEFAULT_ACTION_TYPE;\n}\n\nfunction buildOriginalInvocation(\n t: typeof Babel.types,\n originalExpression: Babel.types.Expression,\n argsIdentifier: Babel.types.Identifier\n): Babel.types.OptionalCallExpression {\n return t.optionalCallExpression(\n t.cloneNode(originalExpression, true),\n [t.spreadElement(t.cloneNode(argsIdentifier))],\n true\n );\n}\n\nfunction buildImmediateHandlerWrapper(\n t: typeof Babel.types,\n originalExpression: Babel.types.Expression,\n metadata: ActionMetadata,\n state: PluginState,\n scope: Babel.NodePath['scope'],\n actionType: TrackedHandler['actionType']\n): Babel.types.ArrowFunctionExpression {\n const handlerArgsIdentifier = scope.generateUidIdentifier('ftHandlerArgs');\n const originalArgsIdentifier = scope.generateUidIdentifier('ftOriginalArgs');\n const originalInvoker = t.arrowFunctionExpression(\n [t.restElement(originalArgsIdentifier)],\n buildOriginalInvocation(t, originalExpression, originalArgsIdentifier)\n );\n const instanceCall = t.callExpression(\n t.memberExpression(\n t.cloneNode(state._ftTrackingIdentifier),\n t.identifier('getInstance')\n ),\n []\n );\n const wrappedHandler = t.callExpression(\n t.memberExpression(instanceCall, t.identifier('wrapRumAction')),\n [\n originalInvoker,\n t.stringLiteral(normalizeActionType(actionType)),\n buildTargetObject(t, metadata, handlerArgsIdentifier, state),\n ]\n );\n return t.arrowFunctionExpression(\n [t.restElement(handlerArgsIdentifier)],\n t.callExpression(wrappedHandler, [\n t.spreadElement(t.cloneNode(handlerArgsIdentifier)),\n ])\n );\n}\n\n/** Wraps a handler, or a handler factory when delayed mode is configured. */\nexport function buildHandlerWrapper(\n t: typeof Babel.types,\n originalExpression: Babel.types.Expression,\n metadata: ActionMetadata,\n state: PluginState,\n scope: Babel.NodePath['scope'],\n mode: TrackedHandler['mode'] = 'default',\n actionType?: TrackedHandler['actionType']\n): Babel.types.ArrowFunctionExpression {\n if (mode !== 'delayed') {\n return buildImmediateHandlerWrapper(\n t,\n originalExpression,\n metadata,\n state,\n scope,\n actionType\n );\n }\n\n const factoryArgsIdentifier = scope.generateUidIdentifier('ftFactoryArgs');\n const handlerIdentifier = scope.generateUidIdentifier('ftDelayedHandler');\n return t.arrowFunctionExpression(\n [t.restElement(factoryArgsIdentifier)],\n t.blockStatement([\n t.variableDeclaration('const', [\n t.variableDeclarator(\n handlerIdentifier,\n buildOriginalInvocation(t, originalExpression, factoryArgsIdentifier)\n ),\n ]),\n t.returnStatement(\n buildImmediateHandlerWrapper(\n t,\n handlerIdentifier,\n metadata,\n state,\n scope,\n actionType\n )\n ),\n ])\n );\n}\n\n/** Resolves a conditional handler once at render time, preserving non-functions. */\nexport function buildGuardedHandlerWrapper(\n t: typeof Babel.types,\n originalExpression: Babel.types.Expression,\n metadata: ActionMetadata,\n state: PluginState,\n scope: Babel.NodePath['scope'],\n mode: TrackedHandler['mode'] = 'default',\n actionType?: TrackedHandler['actionType']\n): Babel.types.CallExpression {\n const resolvedHandlerIdentifier =\n scope.generateUidIdentifier('ftResolvedHandler');\n return t.callExpression(\n t.arrowFunctionExpression(\n [resolvedHandlerIdentifier],\n t.conditionalExpression(\n t.binaryExpression(\n '===',\n t.unaryExpression('typeof', t.cloneNode(resolvedHandlerIdentifier)),\n t.stringLiteral('function')\n ),\n buildHandlerWrapper(\n t,\n resolvedHandlerIdentifier,\n metadata,\n state,\n scope,\n mode,\n actionType\n ),\n t.cloneNode(resolvedHandlerIdentifier)\n )\n ),\n [t.cloneNode(originalExpression, true)]\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel
3
+ * interaction tracking implementation, licensed under Apache-2.0.
4
+ */
5
+
6
+ export const RUNTIME_PACKAGE = '@truewatchtech/react-native-mobile';
7
+ export const ACTION_NAME_ATTRIBUTE = 'ft-action-name';
8
+ export const PLUGIN_ENABLED_FLAG = '__FT_RN_BABEL_PLUGIN_ENABLED__';
9
+ export const NATIVE_COMPONENT_HANDLERS = {
10
+ Button: ['onPress'],
11
+ Pressable: ['onPress', 'onLongPress'],
12
+ TouchableOpacity: ['onPress'],
13
+ TouchableHighlight: ['onPress'],
14
+ TouchableWithoutFeedback: ['onPress'],
15
+ TouchableNativeFeedback: ['onPress'],
16
+ Switch: ['onValueChange'],
17
+ TextInput: ['onFocus']
18
+ };
19
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["RUNTIME_PACKAGE","ACTION_NAME_ATTRIBUTE","PLUGIN_ENABLED_FLAG","NATIVE_COMPONENT_HANDLERS","Button","Pressable","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","TouchableNativeFeedback","Switch","TextInput"],"sources":["constants.ts"],"sourcesContent":["/*\n * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel\n * interaction tracking implementation, licensed under Apache-2.0.\n */\n\nexport const RUNTIME_PACKAGE = '@truewatchtech/react-native-mobile';\n\nexport const ACTION_NAME_ATTRIBUTE = 'ft-action-name';\n\nexport const PLUGIN_ENABLED_FLAG = '__FT_RN_BABEL_PLUGIN_ENABLED__';\n\nexport const NATIVE_COMPONENT_HANDLERS: Record<string, string[]> = {\n Button: ['onPress'],\n Pressable: ['onPress', 'onLongPress'],\n TouchableOpacity: ['onPress'],\n TouchableHighlight: ['onPress'],\n TouchableWithoutFeedback: ['onPress'],\n TouchableNativeFeedback: ['onPress'],\n Switch: ['onValueChange'],\n TextInput: ['onFocus'],\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;;AAEA,OAAO,MAAMA,eAAe,GAAG,oCAAoC;AAEnE,OAAO,MAAMC,qBAAqB,GAAG,gBAAgB;AAErD,OAAO,MAAMC,mBAAmB,GAAG,gCAAgC;AAEnE,OAAO,MAAMC,yBAAmD,GAAG;EACjEC,MAAM,EAAE,CAAC,SAAS,CAAC;EACnBC,SAAS,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC;EACrCC,gBAAgB,EAAE,CAAC,SAAS,CAAC;EAC7BC,kBAAkB,EAAE,CAAC,SAAS,CAAC;EAC/BC,wBAAwB,EAAE,CAAC,SAAS,CAAC;EACrCC,uBAAuB,EAAE,CAAC,SAAS,CAAC;EACpCC,MAAM,EAAE,CAAC,eAAe,CAAC;EACzBC,SAAS,EAAE,CAAC,SAAS;AACvB,CAAC","ignoreList":[]}
@@ -0,0 +1,42 @@
1
+ /*
2
+ * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel
3
+ * interaction tracking implementation, licensed under Apache-2.0.
4
+ */
5
+
6
+ import { declare } from '@babel/helper-plugin-utils';
7
+ import { insertPluginEnabledFlag } from './actions/global';
8
+ import { handleJSXElement, insertRuntimeImports } from './actions/rum';
9
+ import { mergeOptions } from './options';
10
+ import { initializePluginState, isSkippedFile } from './state';
11
+ const plugin = declare((api, rawOptions) => {
12
+ api.assertVersion(7);
13
+ const t = api.types;
14
+ const options = mergeOptions(rawOptions);
15
+ return {
16
+ name: 'truewatch-react-native-action-name',
17
+ visitor: {
18
+ Program: {
19
+ enter(programPath, state) {
20
+ state._ftSkip = isSkippedFile(state);
21
+ if (state._ftSkip) {
22
+ return;
23
+ }
24
+ initializePluginState(t, programPath, state, options);
25
+ insertPluginEnabledFlag(t, programPath);
26
+ },
27
+ exit(programPath, state) {
28
+ if (!state._ftSkip) {
29
+ insertRuntimeImports(t, programPath, state);
30
+ }
31
+ }
32
+ },
33
+ JSXElement(path, state) {
34
+ if (!state._ftSkip) {
35
+ handleJSXElement(t, path, state, options);
36
+ }
37
+ }
38
+ }
39
+ };
40
+ });
41
+ export default plugin;
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["declare","insertPluginEnabledFlag","handleJSXElement","insertRuntimeImports","mergeOptions","initializePluginState","isSkippedFile","plugin","api","rawOptions","assertVersion","t","types","options","name","visitor","Program","enter","programPath","state","_ftSkip","exit","JSXElement","path"],"sources":["index.ts"],"sourcesContent":["/*\n * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel\n * interaction tracking implementation, licensed under Apache-2.0.\n */\n\nimport type * as Babel from '@babel/core';\nimport { declare } from '@babel/helper-plugin-utils';\nimport { insertPluginEnabledFlag } from './actions/global';\nimport { handleJSXElement, insertRuntimeImports } from './actions/rum';\nimport { mergeOptions } from './options';\nimport { initializePluginState, isSkippedFile } from './state';\nimport type { PluginAPI, PluginOptions, PluginState } from './types';\n\nexport type { PluginOptions, TrackedComponent, TrackedHandler } from './types';\n\nconst plugin = declare(\n (api: PluginAPI, rawOptions: PluginOptions): Babel.PluginObj<PluginState> => {\n api.assertVersion(7);\n const t = api.types;\n const options = mergeOptions(rawOptions);\n\n return {\n name: 'truewatch-react-native-action-name',\n visitor: {\n Program: {\n enter(programPath, state) {\n state._ftSkip = isSkippedFile(state);\n if (state._ftSkip) {\n return;\n }\n initializePluginState(t, programPath, state, options);\n insertPluginEnabledFlag(t, programPath);\n },\n exit(programPath, state) {\n if (!state._ftSkip) {\n insertRuntimeImports(t, programPath, state);\n }\n },\n },\n JSXElement(path, state) {\n if (!state._ftSkip) {\n handleJSXElement(t, path, state, options);\n }\n },\n },\n };\n }\n);\n\nexport default plugin;\n"],"mappings":"AAAA;AACA;AACA;AACA;;AAGA,SAASA,OAAO,QAAQ,4BAA4B;AACpD,SAASC,uBAAuB,QAAQ,kBAAkB;AAC1D,SAASC,gBAAgB,EAAEC,oBAAoB,QAAQ,eAAe;AACtE,SAASC,YAAY,QAAQ,WAAW;AACxC,SAASC,qBAAqB,EAAEC,aAAa,QAAQ,SAAS;AAK9D,MAAMC,MAAM,GAAGP,OAAO,CACpB,CAACQ,GAAc,EAAEC,UAAyB,KAAmC;EAC3ED,GAAG,CAACE,aAAa,CAAC,CAAC,CAAC;EACpB,MAAMC,CAAC,GAAGH,GAAG,CAACI,KAAK;EACnB,MAAMC,OAAO,GAAGT,YAAY,CAACK,UAAU,CAAC;EAExC,OAAO;IACLK,IAAI,EAAE,oCAAoC;IAC1CC,OAAO,EAAE;MACPC,OAAO,EAAE;QACPC,KAAKA,CAACC,WAAW,EAAEC,KAAK,EAAE;UACxBA,KAAK,CAACC,OAAO,GAAGd,aAAa,CAACa,KAAK,CAAC;UACpC,IAAIA,KAAK,CAACC,OAAO,EAAE;YACjB;UACF;UACAf,qBAAqB,CAACM,CAAC,EAAEO,WAAW,EAAEC,KAAK,EAAEN,OAAO,CAAC;UACrDZ,uBAAuB,CAACU,CAAC,EAAEO,WAAW,CAAC;QACzC,CAAC;QACDG,IAAIA,CAACH,WAAW,EAAEC,KAAK,EAAE;UACvB,IAAI,CAACA,KAAK,CAACC,OAAO,EAAE;YAClBjB,oBAAoB,CAACQ,CAAC,EAAEO,WAAW,EAAEC,KAAK,CAAC;UAC7C;QACF;MACF,CAAC;MACDG,UAAUA,CAACC,IAAI,EAAEJ,KAAK,EAAE;QACtB,IAAI,CAACA,KAAK,CAACC,OAAO,EAAE;UAClBlB,gBAAgB,CAACS,CAAC,EAAEY,IAAI,EAAEJ,KAAK,EAAEN,OAAO,CAAC;QAC3C;MACF;IACF;EACF,CAAC;AACH,CACF,CAAC;AAED,eAAeN,MAAM","ignoreList":[]}
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Portions of this file are adapted from Datadog's dd-sdk-reactnative Babel
3
+ * interaction tracking implementation, licensed under Apache-2.0.
4
+ */
5
+
6
+ export function mergeOptions(options = {}) {
7
+ const componentOptions = options.components || {};
8
+ return {
9
+ actionNameAttribute: options.actionNameAttribute,
10
+ components: {
11
+ tracked: componentOptions.tracked || [],
12
+ useContent: componentOptions.useContent === undefined ? true : componentOptions.useContent,
13
+ useNamePrefix: componentOptions.useNamePrefix === undefined ? true : componentOptions.useNamePrefix
14
+ }
15
+ };
16
+ }
17
+ //# sourceMappingURL=options.js.map