@dynatrace/react-native-plugin 2.331.1 → 2.333.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 (34) hide show
  1. package/README.md +96 -6
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +7 -1
  4. package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.kt +1 -0
  5. package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +1 -0
  6. package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +2 -1
  7. package/files/plugin.gradle +1 -1
  8. package/instrumentation/DynatraceInstrumentation.js +1 -1
  9. package/instrumentation/jsx/CreateElement.js +106 -6
  10. package/instrumentation/jsx/JsxDevRuntime.js +2 -6
  11. package/instrumentation/jsx/JsxRuntime.js +2 -6
  12. package/instrumentation/libs/withOnPressMonitoring.js +49 -3
  13. package/ios/DynatraceRNBridge.mm +8 -1
  14. package/lib/core/Application.js +2 -0
  15. package/lib/core/Dynatrace.js +2 -1
  16. package/lib/core/UserPrivacyOptions.js +8 -1
  17. package/lib/core/configuration/ConfigurationHandler.js +21 -0
  18. package/lib/features/ui-interaction/Config.js +36 -0
  19. package/lib/features/ui-interaction/IUserInteractionEvent.js +16 -0
  20. package/lib/features/ui-interaction/Plugin.js +945 -0
  21. package/lib/features/ui-interaction/RootDetection.js +51 -0
  22. package/lib/features/ui-interaction/RootWrapper.js +236 -0
  23. package/lib/features/ui-interaction/Run.js +34 -0
  24. package/lib/features/ui-interaction/Runtime.js +1494 -0
  25. package/lib/features/ui-interaction/Types.js +75 -0
  26. package/lib/next/Dynatrace.js +1 -1
  27. package/lib/next/configuration/INativeRuntimeConfiguration.js +1 -0
  28. package/lib/next/configuration/RuntimeConfigurationObserver.js +47 -12
  29. package/lib/next/events/EventPipeline.js +9 -0
  30. package/package.json +19 -10
  31. package/react-native-dynatrace.podspec +1 -1
  32. package/scripts/Config.js +1 -0
  33. package/src/lib/core/interface/NativeDynatraceBridge.ts +1 -0
  34. package/types.d.ts +22 -9
package/README.md CHANGED
@@ -13,6 +13,7 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
13
13
  * User actions for onPress and onLongPress (Touchables, Buttons, Pickers, RefreshControl, Pressable)
14
14
  * User actions for class and functional components (lifecycle events such as render(), didMount() and didUpdate())
15
15
  * Reporting React Native errors
16
+ * UI Interaction feature toggle via `react.userInteraction` (enable/disable user interaction capturing at runtime)
16
17
  * Manual instrumentation
17
18
  * Typescript bindings to add manual instrumentation
18
19
  * New React-Native architecture
@@ -26,15 +27,15 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
26
27
  * Android Gradle plugin version 7.0+
27
28
  * Java 11
28
29
  * Kotlin 2.0.21 - see [Kotlin Compatibility Note](#kotlin-compatibility-note)
29
- * Jetpack Compose 1.4 - 1.9 - see [Compose Compatibility Note](#compose-compatibility-note)
30
+ * Jetpack Compose 1.4 - 1.10 - see [Compose Compatibility Note](#compose-compatibility-note)
30
31
  * For iOS users: Minimum iOS 12
31
32
  * NodeJS 16.0.0+ since our dependencies require NodeJS 16.0.0
32
33
 
33
34
  ## Agent Versions
34
35
  This agent versions are configured in this plugin:
35
36
 
36
- * Android Agent: 8.331.1.1004
37
- * iOS Agent: 8.331.1.1008
37
+ * Android Agent: 8.333.1.1006
38
+ * iOS Agent: 8.333.1.1005
38
39
 
39
40
  ## Quick Setup
40
41
 
@@ -64,12 +65,14 @@ This agent versions are configured in this plugin:
64
65
  * [Set beacon headers](#setting-beacon-headers)
65
66
  * [Exclude Individual JSX Elements](#exclude-individual-jsx-elements)
66
67
  * [New RUM experience](#new-rum-experience)
68
+ * [User Interaction](#user-interaction)
67
69
  * [Send Event](#send-event)
68
70
  * [Send Session Property Event](#send-session-property-event)
69
71
  * [Event Modifier](#event-modifier)
70
72
  * [Send Exception Event](#send-exception-event)
71
73
  * [Send HTTP Request Event](#send-http-request-event)
72
74
  * [View Monitoring](#view-monitoring)
75
+ * [User Interaction](#user-interaction-1)
73
76
  * [React Native Symbolication](#react-native-symbolication)
74
77
  * [NPX Commands](#npx-commands)
75
78
  * [npx instrumentDynatrace](#npx-instrumentdynatrace)
@@ -89,6 +92,7 @@ This agent versions are configured in this plugin:
89
92
  * [Bundle Name and Version](#bundle-name-and-version)
90
93
  * [Navigation](#navigation)
91
94
  * [Source Map](#source-map)
95
+ * [User Interaction](#user-interaction-1)
92
96
  * [Android block](#android-block)
93
97
  * [iOS block](#ios-block)
94
98
  * [Lifecycle modes](#lifecycle)
@@ -427,7 +431,7 @@ import { Dynatrace, DynatraceWebRequestTiming } from '@dynatrace/react-native-pl
427
431
  const action = Dynatrace.enterManualAction('API Data Fetch');
428
432
  const url = 'https://api.example.com/data';
429
433
  const tag = await action.getRequestTag(url);
430
- const timing = new DynatraceWebRequestTiming(url, tag);
434
+ const timing = new DynatraceWebRequestTiming(tag, url);
431
435
 
432
436
  try {
433
437
  timing.startWebRequestTiming();
@@ -457,7 +461,7 @@ import { Dynatrace, DynatraceWebRequestTiming } from '@dynatrace/react-native-pl
457
461
  const action = Dynatrace.enterManualAction('API Data Upload');
458
462
  const url = 'https://api.example.com/upload';
459
463
  const tag = await action.getRequestTag(url);
460
- const timing = new DynatraceWebRequestTiming(url, tag);
464
+ const timing = new DynatraceWebRequestTiming(tag, url);
461
465
  const requestData = JSON.stringify({ key: 'value' });
462
466
 
463
467
  try {
@@ -1012,6 +1016,42 @@ Dynatrace.sendEvent(new EventData()
1012
1016
  Dynatrace.startView("UserProfileDetailed");
1013
1017
  ```
1014
1018
 
1019
+ ### User Interaction
1020
+
1021
+ User Interaction is an automatic instrumentation feature that captures touch and press events in your React Native application without requiring any manual API calls. When enabled, the plugin instruments your UI components at build time and sends structured interaction events to Dynatrace at runtime.
1022
+
1023
+ To enable this feature, see the [User Interaction configuration](#user-interaction-1) section.
1024
+
1025
+ #### Produced data
1026
+
1027
+ Each captured interaction produces an event describing what the user touched and where. The event includes:
1028
+
1029
+ - **Element name** — the resolved label of the touched element, derived from its visible text, accessibility label, component name, or test ID.
1030
+ - **Component type** — the type of the UI component that was touched (e.g. `Pressable`).
1031
+ - **Element path** — a stable path through the component tree that uniquely identifies the element (e.g. `App/View[1]/Pressable[1]`).
1032
+ - **Interaction type** — how the user interacted (e.g. `touch`).
1033
+ - **Position** — the screen coordinates where the touch occurred.
1034
+
1035
+ In some cases, a **responder** is also included. The responder is the component that ultimately handled the user's touch — for example, a `Pressable` that received the press event. It carries the same name, component type, and path information as the touched element, and can differ when a touch is visually on a child element but handled by a parent.
1036
+
1037
+ #### Example event
1038
+
1039
+ ```json
1040
+ {
1041
+ "characteristics.has_user_interaction": true,
1042
+ "ui_element.detected_name": "LoginButton",
1043
+ "ui_element.components": ["Pressable"],
1044
+ "ui_element.id": "App/View[1]/Pressable[1]",
1045
+ "ui_element.name_origin": "component",
1046
+ "interaction.type": "touch",
1047
+ "positions": [{ "x": 120, "y": 460 }],
1048
+ "ui_element.responder.detected_name": "Pressable",
1049
+ "ui_element.responder.components": ["Pressable"],
1050
+ "ui_element.responder.id": "App/View[1]/Pressable[1]",
1051
+ "ui_element.responder.name_origin": "component"
1052
+ }
1053
+ ```
1054
+
1015
1055
  ### React Native Symbolication
1016
1056
 
1017
1057
  Dynatrace can automatically symbolicate JavaScript stack traces captured by the plugin using sourcemaps. This allows you to view human-readable file names, line numbers, and column information in your crash reports.
@@ -1229,6 +1269,7 @@ The `react` configuration block contains all settings regarding the react instru
1229
1269
 
1230
1270
  ```js
1231
1271
  react : {
1272
+
1232
1273
  input : {
1233
1274
  instrument(filename) => {
1234
1275
  return true;
@@ -1269,6 +1310,47 @@ react: {
1269
1310
 
1270
1311
  This activates the debug mode. You will get more console output during instrumentation and at runtime.
1271
1312
 
1313
+
1314
+ ### User Interaction
1315
+
1316
+ ```js
1317
+ react: {
1318
+ userInteraction: true // set it to true here if you want to enable UI interaction, default value is false
1319
+ }
1320
+ ```
1321
+
1322
+ Enables or disables the UI interaction (user interaction) feature.
1323
+ Set to false to disable capturing of user interactions (e.g., touch/click actions) produced by the React Native UI interaction instrumentation.
1324
+
1325
+ #### What customers will observe after enabling UI Interaction
1326
+
1327
+ After setting `react.userInteraction: true` and rebuilding with instrumentation, the expected flow is:
1328
+
1329
+ 1. Build-time instrumentation wraps supported UI elements and app root entrypoints.
1330
+ 2. At runtime, touch/press interactions are captured and converted into UI interaction events.
1331
+ 3. Events are processed by the plugin event pipeline and sent to Dynatrace.
1332
+ 4. In Dynatrace, customers can analyze captured user interactions (for example, touch-driven behavior and related UI element context).
1333
+
1334
+ Notes:
1335
+
1336
+ - No extra UI needs to be added in customer screens for standard automatic capture.
1337
+ - If `react.debug` is enabled, additional debug output can appear during instrumentation/runtime.
1338
+
1339
+ #### Runtime switching (config + remote configuration observer)
1340
+
1341
+ UI Interaction can be controlled by two layers:
1342
+
1343
+ 1. **Build/config layer (`dynatrace.config.js`)**
1344
+ - `react.userInteraction: true|false` controls whether the UI Interaction instrumentation feature is applied.
1345
+
1346
+ 2. **Runtime remote layer (`RuntimeConfigurationObserver`)**
1347
+ - Runtime emission checks the remote flag `touch_interaction_enabled`.
1348
+ - If remote flag is present, it is used as the source of truth.
1349
+ - If remote flag is temporarily unavailable, the plugin falls back to the last known good remote value.
1350
+ - If no remote value was received yet, runtime defaults to enabled behavior.
1351
+
1352
+ In short: local config enables the feature path, while remote configuration can dynamically allow/deny event emission at runtime.
1353
+
1272
1354
  #### Error Handler
1273
1355
 
1274
1356
  ```js
@@ -1825,7 +1907,7 @@ In summary, ensure your build fulfills our Kotlin 2.0.21 requirement while simul
1825
1907
 
1826
1908
  ## Compose Compatibility Note
1827
1909
 
1828
- Our Android Agent currently supports **Jetpack Compose 1.4 - 1.9**. If you are using an incompatible version of Jetpack Compose, you may encounter the following error message during build:
1910
+ Our Android Agent currently supports **Jetpack Compose 1.4 - 1.10**. If you are using an incompatible version of Jetpack Compose, you may encounter the following error message during build:
1829
1911
 
1830
1912
  ```
1831
1913
  Could not resolve all dependencies for configuration ':app:debugCompileClasspath'.
@@ -1972,6 +2054,14 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
1972
2054
  <br/><br/>
1973
2055
  ## Changelog
1974
2056
 
2057
+ Latest
2058
+
2059
+ 2.333.1
2060
+ * Jetpack Compose support range extended to 1.4 - 1.10 see [Compose Compatibility Note](#compose-compatibility-note)
2061
+ * Updated Android (8.333.1.1006) & iOS Agent (8.333.1.1005)
2062
+ * Added Configuration flag to enable/disable the [User Interaction feature](#user-interaction-1).
2063
+ * Added [User Interaction feature](#user-interaction) to collect UI interaction data such as touches, providing insights into user behavior
2064
+
1975
2065
  2.331.1
1976
2066
  * Updated Android (8.331.1.1004) & iOS Agent (8.331.1.1008)
1977
2067
 
@@ -72,7 +72,7 @@ repositories {
72
72
  }
73
73
 
74
74
  dependencies {
75
- implementation 'com.dynatrace.agent:agent-android:8.331.1.1004'
75
+ implementation 'com.dynatrace.agent:agent-android:8.333.1.1006'
76
76
  implementation "com.facebook.react:react-native:${safeExtGet('reactNative', '+')}"
77
77
  }
78
78
 
@@ -75,6 +75,7 @@ class DynatraceRNBridgeImpl(
75
75
  }
76
76
 
77
77
  Dynatrace.startup(reactApplicationContext, builder.buildConfiguration())
78
+
78
79
  promise.resolve(true)
79
80
  }
80
81
  }
@@ -383,6 +384,9 @@ class DynatraceRNBridgeImpl(
383
384
  )!!
384
385
  )
385
386
  )
387
+ if (userPrivacyOptions.hasKey("_screenRecordOptedIn")) {
388
+ optionsBuilder.withScreenRecordOptedIn(userPrivacyOptions.getBoolean("_screenRecordOptedIn"))
389
+ }
386
390
  Dynatrace.applyUserPrivacyOptions(
387
391
  optionsBuilder
388
392
  .build()
@@ -396,6 +400,7 @@ class DynatraceRNBridgeImpl(
396
400
  val privacyMap = Arguments.createMap()
397
401
  privacyMap.putString("dataCollectionLevel", options.dataCollectionLevel.name)
398
402
  privacyMap.putBoolean("crashReportingOptedIn", options.isCrashReportingOptedIn)
403
+ privacyMap.putBoolean("screenRecordOptedIn", options.isScreenRecordOptedIn)
399
404
  promise.resolve(privacyMap)
400
405
  }
401
406
  }
@@ -446,4 +451,5 @@ class DynatraceRNBridgeImpl(
446
451
  private fun shouldWorkOnAndroid(platform: String?): Boolean {
447
452
  return platform == null || platform == PLATFORM_ANDROID || platform == ""
448
453
  }
449
- }
454
+
455
+ }
@@ -8,6 +8,7 @@ import com.facebook.react.bridge.ReadableType
8
8
  /**
9
9
  * @author matthias.hochrieser
10
10
  */
11
+
11
12
  internal object DynatraceUtils {
12
13
 
13
14
  private const val TAG = "DynatraceUtils"
@@ -238,4 +238,5 @@ class DynatraceRNBridge(
238
238
  override fun stopViewInternal() {
239
239
  impl.stopViewInternal()
240
240
  }
241
+
241
242
  }
@@ -271,4 +271,5 @@ class DynatraceRNBridge(
271
271
  fun stopViewInternal() {
272
272
  impl.stopViewInternal()
273
273
  }
274
- }
274
+
275
+ }
@@ -1,4 +1,4 @@
1
1
  // TEMPLATE: plugin-gradle.template
2
2
  dependencies {
3
- classpath 'com.dynatrace.tools.android:gradle-plugin:8.331.1.1004'
3
+ classpath 'com.dynatrace.tools.android:gradle-plugin:8.333.1.1006'
4
4
  }
@@ -1 +1 @@
1
- var a,n=require("@babel/runtime/helpers/interopRequireDefault"),e=n(require("@babel/runtime/helpers/toConsumableArray")),c=(Object.defineProperty(exports,"t",{value:!0}),exports.instrument=void 0,require("path")),u=require("jscodeshift"),i=require("jscodeshift/src/Collection"),r=require("../scripts/FileOperationHelper"),l=require("../scripts/PathsConstants"),f=require("../lib/core/util/GetValuesFromPackage"),t=require("../scripts/util/InstrumentUtil"),o=require("./libs/react-native/Touchables.InstrInfo"),s=require("./libs/react-native/RefreshControl.InstrInfo"),v=require("./libs/react-native/Switch.InstrInfo"),d=require("./libs/community/gesture-handler/Touchables.InstrInfo"),p=require("./libs/community/Picker.InstrInfo"),m=require("./model/Types"),g=require("./parser/ParserUtil"),y=((n=>{n[n.i=-1]="Filtered",n[n.u=0]="Normal",n[n.o=1]="ReactNative",n[n.l=2]="React",n[n.v=3]="ReactNativeCssInterop"})(a=a||{}),[]),q=(y.push.apply(y,(0,e.default)(o.instrumentationInfo)),y.push.apply(y,(0,e.default)(s.instrumentationInfo)),y.push.apply(y,(0,e.default)(v.instrumentationInfo)),y.push.apply(y,(0,e.default)(d.instrumentationInfo)),y.push.apply(y,(0,e.default)(p.instrumentationInfo)),["AppRegistry","AppRegistryImpl","renderApplication","ExceptionsManager"]),b="@dynatrace/react-native-plugin/instrumentation/libs",instrument=function(n,e,r){e=O(e);var t=z(e);if(t!==a.i){var i=!1,u=N(e,n);if(t===a.l)U(u),i=!0;else if(t===a.o)e.endsWith("AppRegistryImpl.js")?null!=r&&r.autoStart&&V(u)&&(i=!0):e.endsWith("AppRegistry.js")?null!=r&&r.autoStart&&w(u)&&(i=!0):e.endsWith("renderApplication.js")?(A(u),i=!0):e.endsWith("ExceptionsManager.js")&&(o=void 0!==r&&r.autoStart&&r.errorHandler.enabled,J(u,r.errorHandler.reportFatalErrorAsCrash,o),i=!0);else if(t===a.v)i=G(u)||i;else{var o=k(e,r);if(r.navigation.enabled&&L(e,u))i=!0;else{if(!o.input&&!o.lifecycle)return null!=r&&r.debug&&console.log("Dynatrace - Filtered All: ".concat(e)),I(e),n;o.lifecycle&&A(u)&&(i=!0),o.input&&y.forEach(function(n){n=X(u,n);u=n.root,i=i||n.p})}}i?(n=u.toSource({quote:"single"}),h(n,e)):I(e),null!=r&&r.debug&&i&&console.log("Dynatrace - Modified Filename: "+e)}else e.includes(c.join("@dynatrace","react-native-plugin"))&&e.endsWith(c.join("lib","core","configuration","ConfigurationPreset.js"))&&void 0!==r&&(t=(0,f.getHostAppBundleInfo)(l.default.getPackageJsonFile()),o=N(e,n),void 0!==r.lifecycle&&x(o,"getLifecycleUpdate",r.lifecycle.includeUpdate),void 0!==r.debug&&x(o,"getLogLevel",r.debug?0:1),void 0!==r.bundleName?x(o,"getBundleName",r.bundleName):null!==t&&x(o,"getBundleName",null==t?void 0:t.name),void 0!==r.bundleVersion?x(o,"getBundleVersion",r.bundleVersion):null!==t&&x(o,"getBundleVersion",null==t?void 0:t.version),void 0!==r.input&&void 0!==r.input.actionNamePrivacy&&x(o,"getActionNamePrivacy",r.input.actionNamePrivacy),void 0!==r.errorHandler&&(x(o,"isErrorHandlerEnabled",r.errorHandler.enabled),x(o,"isReportFatalErrorAsCrash",r.errorHandler.reportFatalErrorAsCrash)),r.autoStart&&x(o,"isAutoStartupEnabled",r.autoStart),n=o.toSource({quote:"single"}),h(n,e));return n},L=(exports.instrument=instrument,function(n,e){return!!T(n,e)&&(n="import { monitorNavigation } from '".concat(b,"/react-navigation/ReactNavigation';"),e.find(u.ImportDeclaration).at(0).insertBefore(n),!0)}),T=function(n,e){var r=!1;return n.includes("@react-navigation")&&n.includes("core")&&(n.includes("BaseNavigationContainer.js")||n.includes("BaseNavigationContainer.tsx"))&&e.find(u.VariableDeclarator,{id:{name:"getRootState"}}).forEach(function(n){r=!0,n.parent.insertAfter("monitorNavigation(getRootState);")}),r},A=function(n){var e=n.findJSXElements(),t=!1;return 0<e.length&&(n.find(u.FunctionDeclaration).forEach(function(n){var e,r=(0,i.fromPaths)([n]);0<r.findJSXElements().length&&null!=n&&null!=n.value&&null!=n.value.id&&n.value.id.name.toString()&&(e=r.find(u.ClassDeclaration),r=r.find(u.ClassExpression),0===e.length)&&0===r.length&&(j(n,m.Types.FunctionalComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ClassDeclaration).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n&&null!=n.value&&n.value.id&&n.value.id.name.toString()&&(j(n,m.Types.ClassComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ArrowFunctionExpression).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.id&&null!=n.parent.value.id.name&&(j(n,m.Types.FunctionalComponent,n.parent.value.id.name),t=!0)}),n.find(u.FunctionExpression).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.id&&null!=n.parent.value.id.name&&(j(n,m.Types.FunctionalComponent,n.parent.value.id.name),t=!0)})),t},j=function(n,e,r){for(e=u.expressionStatement(u.assignmentExpression("=",u.memberExpression(u.identifier(r),u.identifier("_dtInfo")),M(e,r)));"body"!==(null==n?void 0:n.parentPath.name);)n=n.parentPath;void 0!==n.parentPath&&n.insertAfter(e)},M=function(n,e){return u.objectExpression([u.objectProperty(u.identifier("type"),u.numericLiteral(n)),u.objectProperty(u.identifier("name"),u.stringLiteral(e))])},x=function(n,e,r){var n=n.find(u.Identifier).filter(function(n){return n.node.name===e});1===n.length&&"ReturnStatement"===(n=n.paths()[0].parent.value.body.body[0]).type&&("boolean"==typeof r&&(n.argument=u.booleanLiteral(r)),"string"==typeof r&&(n.argument=u.stringLiteral(r)),"number"==typeof r)&&(n.argument=u.numericLiteral(r))},N=function(n,e){return u.withParser((0,g.chooseParser)(n,e))(e)},O=function(n){return c.isAbsolute(n)?n.replace(l.default.getApplicationPath()+c.sep,""):n},I=function(n){try{var e=c.join(l.default.getBuildPath(),n+t.INSTRUMENTED_FILE_EXTENSION);r.default.checkIfFileExistsSync(e),r.default.deleteFileSync(e)}catch(n){}},h=function(n,e){e=c.join(l.default.getBuildPath(),e);try{r.default.checkIfFileExistsSync(c.dirname(e))}catch(n){r.default.createDirectorySync(c.dirname(e))}r.default.writeTextToFileSync(e+t.INSTRUMENTED_FILE_EXTENSION,n)},k=function(n,e){var r={input:!1,lifecycle:!1};return void 0!==e&&(void 0!==e.lifecycle&&void 0!==e.lifecycle.instrument&&e.lifecycle.instrument(n)&&(r.lifecycle=!0),void 0!==e.input)&&void 0!==e.input.instrument&&e.input.instrument(n)&&(r.input=!0),r},U=function(n){var e,n=n.find(u.Program);1===n.length&&(e=u.expressionStatement(u.callExpression(u.memberExpression(u.callExpression(u.identifier("require"),[u.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")]),u.identifier("instrumentCreateElement")),[u.memberExpression(u.identifier("module"),u.identifier("exports"))])),n.paths()[0].node.body.push(e))},V=function(n){var e=n.find(u.FunctionDeclaration,{id:{name:"runApplication"}});return 1===e.length&&(D(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,_("_DynatraceApplicationHandler","startup",[])),!0)},w=function(n){var e=n.find(u.ObjectMethod,{key:{name:"runApplication"}});return 1===e.length&&(D(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,_("_DynatraceApplicationHandler","startup",[])),!0)},J=function(n,r,t){var i=u;n.find(i.FunctionDeclaration,{id:{name:"handleException"}}).forEach(function(n){var e=i.callExpression(i.memberExpression(i.callExpression(i.identifier("require"),[i.literal("@dynatrace/react-native-plugin/lib/core/ErrorHandler")]),i.identifier("reportErrorToDynatrace")),[i.identifier("e"),i.identifier("isFatal"),i.literal(r),i.literal(t)]),e=i.expressionStatement(i.callExpression(i.identifier("setTimeout"),[i.arrowFunctionExpression([],i.blockStatement(n.node.body.body)),e]));n.node.body.body=[e]})},G=function(n){var e=!1,n=n.find(u.CallExpression,{callee:{name:"require"}});return n.find(u.Literal,{value:"react/jsx-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-runtime",e=!0,n}),n.find(u.Literal,{value:"react/jsx-dev-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-dev-runtime",e=!0,n}),e},R=function(n,e){for(var r=arguments.length,t=new Array(2<r?r-2:0),i=2;i<r;i++)t[i-2]=arguments[i];return n.splice.apply(n,[e,0].concat(t))},z=function(n){if(n.includes("@dynatrace"))return a.i;var e=c.extname(n);if(".js"!==e&&".ts"!==e&&".tsx"!==e&&".jsx"!==e)return a.i;for(var r=c.parse(n),t=r.dir.split(c.sep),i=0;i<t.length;i++)if("node_modules"===t[i]){if("react-native"===t[i+1]||"create-react-class"===t[i+1]||"react-clone-referenced-element"===t[i+1])return q.includes(r.name)?a.o:a.i;if("react"===t[i+1]&&"index"===r.name)return a.l;if("react-native-css-interop"===t[i+1]&&("jsx-runtime"===r.name||"jsx-dev-runtime"===r.name))return a.v}return a.u},K=function(n,e,r){var t=Q(n,e,r);return W(n,e,r)||t},Q=function(n,e,r){var t=Y(n,e);return 0<t.length&&(void 0!==(t=H(t,e.reference,!1))&&(r.m=t.localName),tn(n,r),!0)},W=function(n,e,r){var t=C(n,e.module);if(1===t.length){t=H(t,e.reference,!0);if(void 0!==t)return un(n,r.defaultImport,t.localName,"ImportNamespaceSpecifier"===t.type),!0}return!1},X=function(n,e){var r=JSON.parse(JSON.stringify(e.new));return{root:n,p:K(n,e.old,r)||Z(n,e.old,e.new.defaultImport)}},Y=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module&&null!=n.node.specifiers&&n.node.specifiers.some(function(n){return E(n)&&n.imported.name===e.reference||n.local&&n.local.name===e.reference})})},E=function(n){return void 0!==n.imported},Z=function(n,e,r){var t=!1;return n.find(u.CallExpression).filter(function(n){return $(n.node.callee)&&nn(n.node.arguments[0])&&n.node.arguments[0].value===e.module&&void 0!==n.parent}).forEach(function(n){(void 0===n.parent.value.property||void 0!==n.parent.value.property&&void 0!==n.parent.value.property.name&&n.parent.value.property.name===e.reference)&&(n.node.arguments[0].value=r,t=t||!0)}),t},$=function(n){return"require"===n.name},nn=function(n){return"StringLiteral"===n.type||"Literal"===n.type},C=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e})},H=function(n,r,t){var i;return n.forEach(function(n){void 0!==n.node.specifiers&&(n.node.specifiers=n.node.specifiers.filter(function(n){var e;return E(n)&&!t?((e=n.imported.name!==r)||null==n.local||n.imported.name===n.local.name||(i={localName:n.local.name.toString(),type:n.type}),e):!(!E(n)&&t&&(null!=n.local&&(i={localName:n.local.name.toString(),type:n.type}),1))}),0===n.node.specifiers.length)&&n.prune()}),i},en=function(n,e){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(P(e))})},rn=function(n,e,r){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(r)})},S=function(n,e,r){var t=n.find(u.ImportDeclaration);0<t.length?u(t.paths()[0]).insertAfter(B(e,r)):1===(t=n.find(u.Program)).length&&t.paths()[0].node.body.unshift(B(e,r))},tn=function(n,e){0<C(n,e.module).length?en(n,e):S(n,e.module,[P(e)])},un=function(n,e,r,t){var i=C(n,e),t=(t?vn:sn)(r);0<i.length?rn(n,e,t):S(n,e,[t])},D=function(n,e){n=n.find(u.VariableDeclaration);0<n.length&&u(n.paths()[0]).insertAfter(an(e))},_=function(n,e,r){return u.expressionStatement(on(n,e,r))},on=function(n,e,r){return u.callExpression(fn(n,e),r)},an=function(n){return u.variableDeclaration("var",[cn(n)])},cn=function(n){return u.variableDeclarator(void 0!==n.m?u.identifier(n.m):u.identifier(n.reference),(0<n.reference.length?ln:F)(n))},ln=function(n){return u.memberExpression(F(n),u.identifier(n.reference))},fn=function(n,e){return u.memberExpression(u.identifier(n),u.identifier(e))},F=function(n){return u.callExpression(u.identifier("require"),[u.literal(n.module)])},B=function(n,e){return u.importDeclaration(e,u.literal(n))},P=function(n){return void 0!==n.m?u.importSpecifier(u.identifier(n.reference),u.identifier(n.m)):u.importSpecifier(u.identifier(n.reference))},sn=function(n){return u.importDefaultSpecifier(u.identifier(n))},vn=function(n){return u.importNamespaceSpecifier(u.identifier(n))};
1
+ var n=require("@babel/runtime/helpers/interopRequireDefault"),e=n(require("@babel/runtime/helpers/toConsumableArray"));function v(n,e){var r,t,i,u,o="undefined"!=typeof Symbol&&n[Symbol.iterator]||n["@@iterator"];if(o)return i=!(t=!0),{s:function(){o=o.call(n)},n:function(){var n=o.next();return t=n.done,n},e:function(n){i=!0,r=n},f:function(){try{t||null==o.return||o.return()}finally{if(i)throw r}}};if(Array.isArray(n)||(o=a(n))||e&&n&&"number"==typeof n.length)return o&&(n=o),u=0,{s:e=function(){},n:function(){return u>=n.length?{done:!0}:{done:!1,value:n[u++]}},e:function(n){throw n},f:e};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function a(n,e){var r;if(n)return"string"==typeof n?t(n,e):"Map"===(r="Object"===(r={}.toString.call(n).slice(8,-1))&&n.constructor?n.constructor.name:r)||"Set"===r?Array.from(n):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?t(n,e):void 0}function t(n,e){(null==e||e>n.length)&&(e=n.length);for(var r=0,t=Array(e);r<e;r++)t[r]=n[r];return t}Object.defineProperty(exports,"t",{value:!0}),exports.instrument=void 0;var d,p=require("path"),u=require("jscodeshift"),i=require("jscodeshift/src/Collection"),r=require("../scripts/FileOperationHelper"),m=require("../scripts/PathsConstants"),y=require("../lib/core/util/GetValuesFromPackage"),o=require("../scripts/util/InstrumentUtil"),g=require("../lib/features/ui-interaction/Run"),c=require("./libs/react-native/Touchables.InstrInfo"),l=require("./libs/react-native/RefreshControl.InstrInfo"),f=require("./libs/react-native/Switch.InstrInfo"),s=require("./libs/community/gesture-handler/Touchables.InstrInfo"),P=require("./libs/community/Picker.InstrInfo"),b=require("./model/Types"),T=require("./parser/ParserUtil"),q=((n=>{n[n.i=-1]="Filtered",n[n.u=0]="Normal",n[n.o=1]="ReactNative",n[n.l=2]="React",n[n.v=3]="ReactNativeCssInterop"})(d=d||{}),[]),L=(q.push.apply(q,(0,e.default)(c.instrumentationInfo)),q.push.apply(q,(0,e.default)(l.instrumentationInfo)),q.push.apply(q,(0,e.default)(f.instrumentationInfo)),q.push.apply(q,(0,e.default)(s.instrumentationInfo)),q.push.apply(q,(0,e.default)(P.instrumentationInfo)),new Set(["AppRegistry","AppRegistryImpl","renderApplication","ExceptionsManager"])),M="@dynatrace/react-native-plugin/instrumentation/libs",instrument=function(n,e,r){e=V(e);var t=W(e);if(t!==d.i){var i=!1,u=I(e,n);if(t===d.l)G(u),i=!0;else if(t===d.o)e.endsWith("AppRegistryImpl.js")?null!=r&&r.autoStart&&$(u)&&(i=!0):e.endsWith("AppRegistry.js")?null!=r&&r.autoStart&&z(u)&&(i=!0):e.endsWith("renderApplication.js")?(A(u),i=!0):e.endsWith("ExceptionsManager.js")&&(o=void 0!==r&&r.autoStart&&r.errorHandler.enabled,K(u,r.errorHandler.reportFatalErrorAsCrash,o),i=!0);else if(t===d.v)i=Q(u)||i;else{var o=J(e,r),t=[{isEnabled:function(n,e){return!0===(null==e?void 0:e.userInteraction)},p:function(n,e,r){return(0,g.runDTUserInteraction)(n,e,r)}}].filter(function(n){return n.isEnabled(e,r)});if(r.navigation.enabled&&O(e,u))i=!0;else{if(!o.input&&!o.lifecycle&&0===t.length)return null!=r&&r.debug&&console.log("Dynatrace - Filtered All: ".concat(e)),x(e),n;o.lifecycle&&A(u)&&(i=!0),o.input&&q.forEach(function(n){n=nn(u,n);u=n.root,i=i||n.m})}var a,c=v(t);try{for(c.s();!(a=c.n()).done;){var l=a.value;try{var f=l.p(u,e,r),u=f.root;f.m&&(i=!0)}catch(n){var s=n instanceof Error?n.stack||n.message:String(n);null!=r&&r.debug&&console.log("[DynatraceInstrumentationRaw]: Feature instrumentation failed for ".concat(e,": ").concat(s))}}}catch(n){c.e(n)}finally{c.f()}}var o=i?u.toSource({quote:"single"}):n;i?N(n=o,e):x(e),null!=r&&r.debug&&i&&console.log("Dynatrace - Modified Filename: "+e)}else e.includes(p.join("@dynatrace","react-native-plugin"))&&e.endsWith(p.join("lib","core","configuration","ConfigurationPreset.js"))&&void 0!==r&&(t=(0,y.getHostAppBundleInfo)(m.default.getPackageJsonFile()),o=I(e,n),void 0!==r.lifecycle&&j(o,"getLifecycleUpdate",r.lifecycle.includeUpdate),void 0!==r.debug&&j(o,"getLogLevel",r.debug?0:1),void 0!==r.bundleName?j(o,"getBundleName",r.bundleName):null!==t&&j(o,"getBundleName",null==t?void 0:t.name),void 0!==r.bundleVersion?j(o,"getBundleVersion",r.bundleVersion):null!==t&&j(o,"getBundleVersion",null==t?void 0:t.version),void 0!==r.input&&void 0!==r.input.actionNamePrivacy&&j(o,"getActionNamePrivacy",r.input.actionNamePrivacy),void 0!==r.errorHandler&&(j(o,"isErrorHandlerEnabled",r.errorHandler.enabled),j(o,"isReportFatalErrorAsCrash",r.errorHandler.reportFatalErrorAsCrash)),r.autoStart&&j(o,"isAutoStartupEnabled",r.autoStart),n=o.toSource({quote:"single"}),N(n,e));return n},O=(exports.instrument=instrument,function(n,e){return!!U(n,e)&&(n="import { monitorNavigation } from '".concat(M,"/react-navigation/ReactNavigation';"),e.find(u.ImportDeclaration).at(0).insertBefore(n),!0)}),U=function(n,e){var r=!1;return n.includes("@react-navigation")&&n.includes("core")&&(n.includes("BaseNavigationContainer.js")||n.includes("BaseNavigationContainer.tsx"))&&e.find(u.VariableDeclarator,{id:{name:"getRootState"}}).forEach(function(n){r=!0,n.parent.insertAfter("monitorNavigation(getRootState);")}),r},A=function(n){var e=n.findJSXElements(),t=!1;return 0<e.length&&(n.find(u.FunctionDeclaration).forEach(function(n){var e,r=(0,i.fromPaths)([n]);0<r.findJSXElements().length&&null!=n&&null!=n.value&&null!=n.value.id&&n.value.id.name.toString()&&(e=r.find(u.ClassDeclaration),r=r.find(u.ClassExpression),0===e.length)&&0===r.length&&(h(n,b.Types.FunctionalComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ClassDeclaration).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n&&null!=n.value&&n.value.id&&n.value.id.name.toString()&&(h(n,b.Types.ClassComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ArrowFunctionExpression).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.id&&null!=n.parent.value.id.name&&(h(n,b.Types.FunctionalComponent,n.parent.value.id.name),t=!0)}),n.find(u.FunctionExpression).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.id&&null!=n.parent.value.id.name&&(h(n,b.Types.FunctionalComponent,n.parent.value.id.name),t=!0)})),t},h=function(n,e,r){for(e=u.expressionStatement(u.assignmentExpression("=",u.memberExpression(u.identifier(r),u.identifier("_dtInfo")),k(e,r)));"body"!==(null==n?void 0:n.parentPath.name);)n=n.parentPath;void 0!==n.parentPath&&n.insertAfter(e)},k=function(n,e){return u.objectExpression([u.objectProperty(u.identifier("type"),u.numericLiteral(n)),u.objectProperty(u.identifier("name"),u.stringLiteral(e))])},j=function(n,e,r){var n=n.find(u.Identifier).filter(function(n){return n.node.name===e});1===n.length&&"ReturnStatement"===(n=n.paths()[0].parent.value.body.body[0]).type&&("boolean"==typeof r&&(n.argument=u.booleanLiteral(r)),"string"==typeof r&&(n.argument=u.stringLiteral(r)),"number"==typeof r)&&(n.argument=u.numericLiteral(r))},I=function(n,e){return u.withParser((0,T.chooseParser)(n,e))(e)},V=function(n){return p.isAbsolute(n)?n.replace(m.default.getApplicationPath()+p.sep,""):n},x=function(n){try{var e=p.join(m.default.getBuildPath(),n+o.INSTRUMENTED_FILE_EXTENSION);r.default.checkIfFileExistsSync(e),r.default.deleteFileSync(e)}catch(n){}},N=function(n,e){e=p.join(m.default.getBuildPath(),e);try{r.default.checkIfFileExistsSync(p.dirname(e))}catch(n){r.default.createDirectorySync(p.dirname(e))}r.default.writeTextToFileSync(e+o.INSTRUMENTED_FILE_EXTENSION,n)},J=function(n,e){var r={input:!1,lifecycle:!1};return void 0!==e&&(void 0!==e.lifecycle&&void 0!==e.lifecycle.instrument&&e.lifecycle.instrument(n)&&(r.lifecycle=!0),void 0!==e.input)&&void 0!==e.input.instrument&&e.input.instrument(n)&&(r.input=!0),r},G=function(n){var e,n=n.find(u.Program);1===n.length&&(e=u.expressionStatement(u.callExpression(u.memberExpression(u.callExpression(u.identifier("require"),[u.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")]),u.identifier("instrumentCreateElement")),[u.memberExpression(u.identifier("module"),u.identifier("exports"))])),n.paths()[0].node.body.push(e))},$=function(n){var e=n.find(u.FunctionDeclaration,{id:{name:"runApplication"}});return 1===e.length&&(D(n,{g:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,w("_DynatraceApplicationHandler","startup",[])),!0)},z=function(n){var e=n.find(u.ObjectMethod,{key:{name:"runApplication"}});return 1===e.length&&(D(n,{g:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,w("_DynatraceApplicationHandler","startup",[])),!0)},K=function(n,r,t){var i=u;n.find(i.FunctionDeclaration,{id:{name:"handleException"}}).forEach(function(n){var e=i.callExpression(i.memberExpression(i.callExpression(i.identifier("require"),[i.literal("@dynatrace/react-native-plugin/lib/core/ErrorHandler")]),i.identifier("reportErrorToDynatrace")),[i.identifier("e"),i.identifier("isFatal"),i.literal(r),i.literal(t)]),e=i.expressionStatement(i.callExpression(i.identifier("setTimeout"),[i.arrowFunctionExpression([],i.blockStatement(n.node.body.body)),e]));n.node.body.body=[e]})},Q=function(n){var e=!1,n=n.find(u.CallExpression,{callee:{name:"require"}});return n.find(u.Literal,{value:"react/jsx-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-runtime",e=!0,n}),n.find(u.Literal,{value:"react/jsx-dev-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-dev-runtime",e=!0,n}),e},R=function(n,e){for(var r=arguments.length,t=new Array(2<r?r-2:0),i=2;i<r;i++)t[i-2]=arguments[i];return n.splice.apply(n,[e,0].concat(t))},W=function(n){if(n.includes("@dynatrace"))return d.i;var e=p.extname(n);if(".js"!==e&&".ts"!==e&&".tsx"!==e&&".jsx"!==e)return d.i;for(var r=p.parse(n),t=r.dir.split(p.sep),i=0;i<t.length;i++)if("node_modules"===t[i]){if("react-native"===t[i+1]||"create-react-class"===t[i+1]||"react-clone-referenced-element"===t[i+1])return L.has(r.name)?d.o:d.i;if("react"===t[i+1]&&"index"===r.name)return d.l;if("react-native-css-interop"===t[i+1]&&("jsx-runtime"===r.name||"jsx-dev-runtime"===r.name))return d.v}return d.u},X=function(n,e,r){var t=Y(n,e,r);return Z(n,e,r)||t},Y=function(n,e,r){var t=en(n,e);return 0<t.length&&(void 0!==(t=C(t,e.reference,!1))&&(r.g=t.localName),cn(n,r),!0)},Z=function(n,e,r){var t=E(n,e.module);if(1===t.length){t=C(t,e.reference,!0);if(void 0!==t)return ln(n,r.defaultImport,t.localName,"ImportNamespaceSpecifier"===t.type),!0}return!1},nn=function(n,e){var r=JSON.parse(JSON.stringify(e.new));return{root:n,m:X(n,e.old,r)||rn(n,e.old,e.new.defaultImport)}},en=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module&&null!=n.node.specifiers&&n.node.specifiers.some(function(n){return S(n)&&n.imported.name===e.reference||n.local&&n.local.name===e.reference})})},S=function(n){return void 0!==n.imported},rn=function(n,e,r){var t=!1;return n.find(u.CallExpression).filter(function(n){return tn(n.node.callee)&&un(n.node.arguments[0])&&n.node.arguments[0].value===e.module&&void 0!==n.parent}).forEach(function(n){(void 0===n.parent.value.property||void 0!==n.parent.value.property&&void 0!==n.parent.value.property.name&&n.parent.value.property.name===e.reference)&&(n.node.arguments[0].value=r,t=t||!0)}),t},tn=function(n){return"require"===n.name},un=function(n){return"StringLiteral"===n.type||"Literal"===n.type},E=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e})},C=function(n,r,t){var i;return n.forEach(function(n){void 0!==n.node.specifiers&&(n.node.specifiers=n.node.specifiers.filter(function(n){var e;return S(n)&&!t?((e=n.imported.name!==r)||null==n.local||n.imported.name===n.local.name||(i={localName:n.local.name.toString(),type:n.type}),e):!(!S(n)&&t&&(null!=n.local&&(i={localName:n.local.name.toString(),type:n.type}),1))}),0===n.node.specifiers.length)&&n.prune()}),i},on=function(n,e){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(B(e))})},an=function(n,e,r){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(r)})},H=function(n,e,r){var t=n.find(u.ImportDeclaration);0<t.length?u(t.paths()[0]).insertAfter(_(e,r)):1===(t=n.find(u.Program)).length&&t.paths()[0].node.body.unshift(_(e,r))},cn=function(n,e){0<E(n,e.module).length?on(n,e):H(n,e.module,[B(e)])},ln=function(n,e,r,t){var i=E(n,e),t=(t?yn:mn)(r);0<i.length?an(n,e,t):H(n,e,[t])},D=function(n,e){n=n.find(u.VariableDeclaration);0<n.length&&u(n.paths()[0]).insertAfter(sn(e))},w=function(n,e,r){return u.expressionStatement(fn(n,e,r))},fn=function(n,e,r){return u.callExpression(pn(n,e),r)},sn=function(n){return u.variableDeclaration("var",[vn(n)])},vn=function(n){return u.variableDeclarator(void 0!==n.g?u.identifier(n.g):u.identifier(n.reference),(0<n.reference.length?dn:F)(n))},dn=function(n){return u.memberExpression(F(n),u.identifier(n.reference))},pn=function(n,e){return u.memberExpression(u.identifier(n),u.identifier(e))},F=function(n){return u.callExpression(u.identifier("require"),[u.literal(n.module)])},_=function(n,e){return u.importDeclaration(e,u.literal(n))},B=function(n){return void 0!==n.g?u.importSpecifier(u.identifier(n.reference),u.identifier(n.g)):u.importSpecifier(u.identifier(n.reference))},mn=function(n){return u.importDefaultSpecifier(u.identifier(n))},yn=function(n){return u.importNamespaceSpecifier(u.identifier(n))};
@@ -1,29 +1,129 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createElement = void 0;
4
+ const react_1 = require("react");
4
5
  const Types_1 = require("../model/Types");
5
6
  const ElementHelper_1 = require("./ElementHelper");
6
7
  const ClassComponent_1 = require("./components/ClassComponent");
7
8
  const FunctionalComponent_1 = require("./components/FunctionalComponent");
8
- const react_1 = require("react");
9
+ const PRESS_PROP_KEYS = [
10
+ 'onPress',
11
+ 'onLongPress',
12
+ 'onPressIn',
13
+ 'onPressOut',
14
+ 'onTap',
15
+ 'onClick',
16
+ ];
17
+ const getGlobalPressHook = () => {
18
+ const g = (typeof globalThis !== 'undefined' && globalThis) ||
19
+ (typeof global !== 'undefined' && global) ||
20
+ (typeof window !== 'undefined' && window) ||
21
+ undefined;
22
+ return g === null || g === void 0 ? void 0 : g.__DT_UI_PLUGIN_PRESS_HOOK__;
23
+ };
24
+ const getDisplayName = (type) => {
25
+ if (!type) {
26
+ return 'Unknown';
27
+ }
28
+ if (typeof type === 'string') {
29
+ return type;
30
+ }
31
+ return (type.displayName ||
32
+ type.name ||
33
+ (type.constructor && type.constructor.name) ||
34
+ 'Anonymous');
35
+ };
36
+ const guessTouchableName = (type, props) => {
37
+ if (!props) {
38
+ return getDisplayName(type);
39
+ }
40
+ if (typeof props.dtActionName === 'string' && props.dtActionName.length) {
41
+ return props.dtActionName;
42
+ }
43
+ if (typeof props.title === 'string' && props.title.length) {
44
+ return props.title;
45
+ }
46
+ if (typeof props.accessibilityLabel === 'string' &&
47
+ props.accessibilityLabel.length) {
48
+ return props.accessibilityLabel;
49
+ }
50
+ if (typeof props.testID === 'string' && props.testID.length) {
51
+ return props.testID;
52
+ }
53
+ return getDisplayName(type);
54
+ };
55
+ const mapHandlerToPhase = (handler) => {
56
+ if (handler === 'onPressIn') {
57
+ return 'press-in';
58
+ }
59
+ if (handler === 'onPressOut') {
60
+ return 'press-out';
61
+ }
62
+ return 'press';
63
+ };
64
+ const attachPressHookToProps = (type, props) => {
65
+ if (!props) {
66
+ return props;
67
+ }
68
+ const hook = getGlobalPressHook();
69
+ if (!hook) {
70
+ return props;
71
+ }
72
+ let cloned = null;
73
+ const wrapOne = (key) => {
74
+ const orig = props[key];
75
+ if (typeof orig !== 'function') {
76
+ return;
77
+ }
78
+ if (!cloned) {
79
+ cloned = Object.assign({}, props);
80
+ }
81
+ cloned[key] = (...args) => {
82
+ var _a;
83
+ try {
84
+ const evt = args[0];
85
+ const nativeEvent = (_a = evt === null || evt === void 0 ? void 0 : evt.nativeEvent) !== null && _a !== void 0 ? _a : evt;
86
+ const touchableName = guessTouchableName(type, props);
87
+ hook({
88
+ phase: mapHandlerToPhase(key),
89
+ handler: key,
90
+ touchableName,
91
+ nativeEvent,
92
+ });
93
+ }
94
+ catch (e) {
95
+ const errorMsg = e instanceof Error ? e.stack || e.message : String(e);
96
+ console.log(`[CreateElement]: DT press hook failed: ${errorMsg}`);
97
+ }
98
+ return orig(...args);
99
+ };
100
+ };
101
+ for (const key of PRESS_PROP_KEYS) {
102
+ wrapOne(key);
103
+ }
104
+ return cloned || props;
105
+ };
9
106
  const createElement = (type, props, ...children) => {
10
- if (type != null && type._dtInfo != null && !(0, ElementHelper_1.isDtActionIgnore)(props)) {
107
+ const patchedProps = attachPressHookToProps(type, props);
108
+ if (type != null &&
109
+ type._dtInfo != null &&
110
+ !(0, ElementHelper_1.isDtActionIgnore)(patchedProps)) {
11
111
  if (type._dtInfo.type === Types_1.Types.FunctionalComponent) {
12
112
  return (0, react_1.createElement)(FunctionalComponent_1.DynatraceFunctionalComponent, {
13
- children: (0, react_1.createElement)(type, props, ...children),
113
+ children: (0, react_1.createElement)(type, patchedProps, ...children),
14
114
  });
15
115
  }
16
116
  else if (type._dtInfo.type === Types_1.Types.ClassComponent &&
17
117
  type.prototype !== undefined &&
18
118
  type.prototype.isReactComponent !== undefined) {
19
119
  return (0, react_1.createElement)(ClassComponent_1.DynatraceClassComponent, {
20
- children: (0, react_1.createElement)(type, props, ...children),
120
+ children: (0, react_1.createElement)(type, patchedProps, ...children),
21
121
  });
22
122
  }
23
123
  else {
24
- (0, ElementHelper_1.modifyElement)(type, props);
124
+ (0, ElementHelper_1.modifyElement)(type, patchedProps);
25
125
  }
26
126
  }
27
- return (0, react_1.createElement)(type, props, ...children);
127
+ return (0, react_1.createElement)(type, patchedProps, ...children);
28
128
  };
29
129
  exports.createElement = createElement;
@@ -11,9 +11,7 @@ try {
11
11
  args[0]._dtInfo !== undefined &&
12
12
  !(0, ElementHelper_1.isDtActionIgnore)(args[1])) {
13
13
  if (args[0]._dtInfo.type === Types_1.Types.FunctionalComponent) {
14
- const wrapperProps = {
15
- children: ReactDevRuntime.jsxDEV(...args),
16
- };
14
+ const wrapperProps = Object.assign(Object.assign({}, args[1]), { children: ReactDevRuntime.jsxDEV(...args) });
17
15
  wrapperProps.dtActionName =
18
16
  args[1] !== undefined && args[1].dtActionName !== undefined
19
17
  ? args[1].dtActionName
@@ -28,9 +26,7 @@ try {
28
26
  else if (args[0]._dtInfo.type === Types_1.Types.ClassComponent &&
29
27
  args[0].prototype !== undefined &&
30
28
  args[0].prototype.isReactComponent !== undefined) {
31
- const wrapperProps = {
32
- children: ReactDevRuntime.jsxDEV(...args),
33
- };
29
+ const wrapperProps = Object.assign(Object.assign({}, args[1]), { children: ReactDevRuntime.jsxDEV(...args) });
34
30
  if (args[2] !== undefined) {
35
31
  return ReactDevRuntime.jsxDEV(ClassComponent_1.DynatraceClassComponent, wrapperProps, args[2] + '_dt');
36
32
  }
@@ -10,9 +10,7 @@ const instrumentJsxCall = (jsxFunction) => (...args) => {
10
10
  args[0]._dtInfo !== undefined &&
11
11
  !(0, ElementHelper_1.isDtActionIgnore)(args[1])) {
12
12
  if (args[0]._dtInfo.type === Types_1.Types.FunctionalComponent) {
13
- const wrapperProps = {
14
- children: jsxFunction(...args),
15
- };
13
+ const wrapperProps = Object.assign(Object.assign({}, args[1]), { children: jsxFunction(...args) });
16
14
  wrapperProps.dtActionName =
17
15
  args[1] !== undefined && args[1].dtActionName !== undefined
18
16
  ? args[1].dtActionName
@@ -27,9 +25,7 @@ const instrumentJsxCall = (jsxFunction) => (...args) => {
27
25
  else if (args[0]._dtInfo.type === Types_1.Types.ClassComponent &&
28
26
  args[0].prototype !== undefined &&
29
27
  args[0].prototype.isReactComponent !== undefined) {
30
- const wrapperProps = {
31
- children: jsxFunction(...args),
32
- };
28
+ const wrapperProps = Object.assign(Object.assign({}, args[1]), { children: jsxFunction(...args) });
33
29
  if (args[2] !== undefined) {
34
30
  return jsxFunction(ClassComponent_1.DynatraceClassComponent, wrapperProps, args[2] + '_dt');
35
31
  }
@@ -13,20 +13,66 @@ function withOnPressMonitoring(Component, fallbackName) {
13
13
  const { onPress, onLongPress } = props;
14
14
  const touchableName = (0, exports.chooseTouchableName)(props, fallbackName);
15
15
  const dynatraceIgnored = (0, ComponentUtil_1.isDynatraceIgnored)(props);
16
+ const isRNButton = 'title' in props && typeof props.title === 'string';
17
+ const isRectButton = fallbackName === 'Button';
18
+ const isButtonLike = isRNButton || isRectButton;
19
+ const buttonLabel = isRNButton ? String(props.title) : null;
16
20
  const propsWithoutRef = Object.assign(Object.assign(Object.assign({}, props), (!dynatraceIgnored &&
17
21
  onPress && {
18
- onPress: (0, exports.wrapOnPress)(onPress, touchableName),
22
+ onPress: (0, exports.wrapOnPress)(onPress, touchableName, isButtonLike, buttonLabel),
19
23
  })), (!dynatraceIgnored &&
20
24
  onLongPress && {
21
- onLongPress: (0, exports.wrapOnPress)(onLongPress, touchableName),
25
+ onLongPress: (0, exports.wrapOnPress)(onLongPress, touchableName, isButtonLike, buttonLabel),
22
26
  }));
23
27
  const propsWithRef = Object.assign(Object.assign({}, propsWithoutRef), { ref });
24
28
  return React.createElement(Component, Object.assign({}, propsWithRef));
25
29
  });
26
30
  }
27
31
  exports.withOnPressMonitoring = withOnPressMonitoring;
28
- const wrapOnPress = (onPress, touchableName) => {
32
+ const dtGetUiBridge = () => {
33
+ const g = globalThis;
34
+ return g && g.__DT_UII_BRIDGE ? g.__DT_UII_BRIDGE : null;
35
+ };
36
+ const dtBuildPressPath = (startPath, touchableName) => {
37
+ const base = (startPath && String(startPath)) || '';
38
+ if (!base)
39
+ return `Touchable(${touchableName})`;
40
+ const cut1 = base.lastIndexOf('/Text');
41
+ const cut2 = base.lastIndexOf('/Text(');
42
+ const cut = Math.max(cut1, cut2);
43
+ const parent = cut > 0 ? base.slice(0, cut) : base;
44
+ return parent + `/Touchable(${touchableName})`;
45
+ };
46
+ const wrapOnPress = (onPress, touchableName, isButtonLike, buttonLabel) => {
29
47
  return (...args) => {
48
+ const bridge = dtGetUiBridge();
49
+ if (bridge && typeof bridge.registerPress === 'function') {
50
+ try {
51
+ const e = args && args[0];
52
+ const ne = e && e.nativeEvent;
53
+ const x = Number(ne && ne.pageX);
54
+ const y = Number(ne && ne.pageY);
55
+ const pos = Number.isFinite(x) && Number.isFinite(y)
56
+ ? { x, y }
57
+ : undefined;
58
+ const startPath = bridge.getStartPath &&
59
+ typeof bridge.getStartPath === 'function'
60
+ ? bridge.getStartPath()
61
+ : null;
62
+ const nameForBridge = isButtonLike
63
+ ? buttonLabel || touchableName
64
+ : touchableName;
65
+ bridge.registerPress({
66
+ path: dtBuildPressPath(startPath, nameForBridge),
67
+ elementName: nameForBridge,
68
+ pos,
69
+ });
70
+ }
71
+ catch (e) {
72
+ const errorMsg = e instanceof Error ? e.stack || e.message : String(e);
73
+ Logger.debug(`registerPress bridge hook failed: ${errorMsg}`);
74
+ }
75
+ }
30
76
  if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
31
77
  Logger.info('React Native plugin has not been started yet! Touch will not be reported!');
32
78
  onPress(...args);
@@ -279,6 +279,7 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
279
279
  /**
280
280
  * Triggered when starting to emit events
281
281
  */
282
+
282
283
  - (void)startObserving
283
284
  {
284
285
  hasListeners = YES;
@@ -720,7 +721,7 @@ RCT_EXPORT_METHOD(getUserPrivacyOptions:(NSString *) platform findEventsWithReso
720
721
  level = DataCollectionOff;
721
722
  }
722
723
 
723
- NSDictionary *privacyDict = @{@"dataCollectionLevel": level, @"crashReportingOptedIn": [NSNumber numberWithBool: privacyConfig.crashReportingOptedIn]};
724
+ NSDictionary *privacyDict = @{@"dataCollectionLevel": level, @"crashReportingOptedIn": [NSNumber numberWithBool: privacyConfig.crashReportingOptedIn], @"screenRecordOptedIn": [NSNumber numberWithBool: privacyConfig.screenRecordOptedIn]};
724
725
 
725
726
  resolve(privacyDict);
726
727
  }
@@ -750,6 +751,12 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
750
751
  // do nothing and keep current value
751
752
  }
752
753
 
754
+ if ([[userPrivacyOptions valueForKey:@"_screenRecordOptedIn"] isEqual: @(YES)]) {
755
+ privacyConfig.screenRecordOptedIn = @(YES);
756
+ } else if ([[userPrivacyOptions valueForKey:@"_screenRecordOptedIn"] isEqual: @(NO)]) {
757
+ privacyConfig.screenRecordOptedIn = @(NO);
758
+ }
759
+
753
760
  [Dynatrace applyUserPrivacyOptions:privacyConfig completion:^(BOOL successful) {
754
761
  // do nothing with callback
755
762
  }];
@@ -2,10 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ApplicationHandler = void 0;
4
4
  const AppStartObserver_1 = require("../next/appstart/AppStartObserver");
5
+ const RuntimeConfigurationObserver_1 = require("../next/configuration/RuntimeConfigurationObserver");
5
6
  const ConfigurationBuilder_1 = require("./configuration/ConfigurationBuilder");
6
7
  const ConfigurationHandler_1 = require("./configuration/ConfigurationHandler");
7
8
  const ConsoleLogger_1 = require("./logging/ConsoleLogger");
8
9
  AppStartObserver_1.AppStartObserver.call();
10
+ RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.call();
9
11
  const logger = new ConsoleLogger_1.ConsoleLogger('ApplicationHandler');
10
12
  exports.ApplicationHandler = {
11
13
  startup: (configuration) => {
@@ -287,10 +287,11 @@ exports.Dynatrace = {
287
287
  }
288
288
  },
289
289
  getUserPrivacyOptions: (platform) => __awaiter(void 0, void 0, void 0, function* () {
290
+ var _a;
290
291
  if (ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
291
292
  logger.debug('getUserPrivacyOptions()');
292
293
  const options = yield DynatraceBridge_1.DynatraceNative.getUserPrivacyOptions(platform === null || platform === void 0 ? void 0 : platform.toString());
293
- const currentOptions = new UserPrivacyOptions_1.UserPrivacyOptions((0, DataCollectionLevel_1.StringToDataCollectionLevel)(options.dataCollectionLevel), options.crashReportingOptedIn);
294
+ const currentOptions = new UserPrivacyOptions_1.UserPrivacyOptions((0, DataCollectionLevel_1.StringToDataCollectionLevel)(options.dataCollectionLevel), options.crashReportingOptedIn, (_a = options.screenRecordOptedIn) !== null && _a !== void 0 ? _a : false);
294
295
  return currentOptions;
295
296
  }
296
297
  else {