@dynatrace/react-native-plugin 2.339.1 → 2.343.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 (62) hide show
  1. package/README.md +149 -23
  2. package/android/build.gradle +11 -2
  3. package/android/src/main/java/com/dynatrace/android/agent/DynatraceAppStartModule.kt +9 -31
  4. package/android/src/main/java/com/dynatrace/android/agent/DynatraceConfigurationModule.kt +1 -0
  5. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +41 -1
  6. package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.kt +1 -0
  7. package/android/src/main/java/com/dynatrace/android/agent/ScreenshotSelfMonitor.kt +175 -0
  8. package/android/src/main/java/com/dynatrace/android/agent/UIChangeScreenshotListener.kt +124 -0
  9. package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +33 -0
  10. package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +40 -0
  11. package/files/plugin.gradle +1 -1
  12. package/instrumentation/BabelPluginDynatrace.js +1 -1
  13. package/instrumentation/DynatraceInstrumentation.js +1 -1
  14. package/instrumentation/jsx/CreateElement.js +5 -9
  15. package/instrumentation/jsx/ElementHelper.js +5 -6
  16. package/instrumentation/jsx/JsxDevRuntime.js +33 -31
  17. package/instrumentation/jsx/JsxRuntime.js +30 -30
  18. package/instrumentation/jsx/JsxRuntimeHelpers.js +14 -0
  19. package/instrumentation/jsx/components/ClassComponent.js +4 -8
  20. package/instrumentation/jsx/components/ComponentUtil.js +24 -25
  21. package/instrumentation/libs/UserInteraction.js +27 -24
  22. package/instrumentation/libs/react-native/RefreshControl.js +5 -9
  23. package/instrumentation/libs/withOnPressMonitoring.js +66 -57
  24. package/ios/DTXScreenshotSelfMonitor.h +29 -0
  25. package/ios/DTXScreenshotSelfMonitor.mm +213 -0
  26. package/ios/DTXScreenshotSelfMonitorSwizzler.h +15 -0
  27. package/ios/DTXScreenshotSelfMonitorSwizzler.mm +68 -0
  28. package/ios/DynatraceRNBridge.h +6 -0
  29. package/ios/DynatraceRNBridge.mm +53 -0
  30. package/lib/core/Dynatrace.js +2 -0
  31. package/lib/core/DynatraceAction.js +1 -3
  32. package/lib/core/DynatraceInternal.js +38 -40
  33. package/lib/core/ErrorHandler.js +41 -21
  34. package/lib/core/NullAction.js +1 -3
  35. package/lib/core/logging/LogMessages.js +42 -0
  36. package/lib/core/util/JsonUtils.js +6 -0
  37. package/lib/features/ui-interaction/IUserInteractionEvent.js +1 -1
  38. package/lib/features/ui-interaction/Runtime.js +1 -1
  39. package/lib/features/ui-interaction/TouchMetaResolver.js +4 -3
  40. package/lib/next/Dynatrace.js +26 -1
  41. package/lib/next/events/EventPipeline.js +48 -31
  42. package/lib/next/events/HttpRequestEventData.js +3 -3
  43. package/lib/next/events/interface/HttpRequestEventDataTypes.js +2 -0
  44. package/lib/next/events/modifier/ModifyEventValidation.js +79 -51
  45. package/lib/next/events/spec/EventSpecContstants.js +1 -1
  46. package/lib/next/userAction/NullUserAction.js +15 -0
  47. package/lib/next/userAction/UserAction.js +2 -0
  48. package/lib/next/userAction/UserActionConfiguration.js +10 -0
  49. package/lib/next/userAction/UserActionImpl.js +70 -0
  50. package/lib/next/util/TraceContextUtils.js +8 -14
  51. package/lib/next/util/Utils.js +13 -0
  52. package/package.json +11 -6
  53. package/public.js +3 -1
  54. package/react-native-dynatrace.podspec +10 -3
  55. package/scripts/Config.js +22 -4
  56. package/scripts/DebugFlag.js +20 -0
  57. package/scripts/FileOperationHelper.js +15 -39
  58. package/scripts/Logger.js +2 -3
  59. package/scripts/core/InstrumentCall.js +110 -81
  60. package/scripts/util/CustomArgumentUtil.js +8 -6
  61. package/src/lib/core/interface/NativeDynatraceBridge.ts +34 -1
  62. package/types.d.ts +187 -9
@@ -22,6 +22,12 @@
22
22
  + (void)startView:(NSDictionary<NSString*,id>* _Nullable)fields NS_SWIFT_NAME(startView(fields:));
23
23
  + (void)stopView;
24
24
  + (void)addConfigurationSubscriber:(id<ConfigurationSubscriber>)subscriber;
25
+ + (void)trackCrossPlatformScreenshot;
26
+ + (void)setAutomaticUserActionDetection:(BOOL)enabled NS_SWIFT_NAME(setAutomaticUserActionDetection(enabled:));
27
+ + (void)createUserAction:(NSString *)actionId name:(NSString *)name completeAutomatically:(BOOL)completeAutomatically properties:(NSDictionary<NSString*,id>* _Nullable)properties NS_SWIFT_NAME(createUserAction(actionId:name:completeAutomatically:properties:));
28
+ + (void)addEventPropertyToUserAction:(NSString *)actionId key:(NSString *)key value:(id _Nullable)value NS_SWIFT_NAME(addEventPropertyToUserAction(actionId:key:value:));
29
+ + (void)completeUserAction:(NSString *)actionId NS_SWIFT_NAME(completeUserAction(actionId:));
30
+ + (void)setCompleteUserActionAutomatically:(NSString *)actionId enabled:(BOOL)enabled NS_SWIFT_NAME(setCompleteUserActionAutomatically(actionId:enabled:));
25
31
  @end
26
32
 
27
33
  typedef enum : NSUInteger {
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  #import "DynatraceRNBridge.h"
6
+ #import "DTXScreenshotSelfMonitor.h"
6
7
 
7
8
  // For Turbo Module
8
9
  #ifdef RCT_NEW_ARCH_ENABLED
@@ -111,6 +112,11 @@ static bool remoteConfigSubscribed;
111
112
  static NSDictionary<NSString*, id>* lastRuntimeConfiguration;
112
113
  static RNConfigurationSubscriber* configurationSubscriber;
113
114
 
115
+ // Screenshot self-monitoring. Registered once per process; the configuration publisher retains it
116
+ // as a subscriber and the remote `replay_metrics_enabled` flag toggles monitoring on/off.
117
+ static bool screenshotMonitorSubscribed;
118
+ static DTXScreenshotSelfMonitor* screenshotMonitor;
119
+
114
120
  RCT_EXPORT_MODULE(DynatraceBridge);
115
121
 
116
122
  - (instancetype) init
@@ -307,6 +313,18 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
307
313
  }
308
314
  remoteConfigSubscribed = YES;
309
315
  [HybridBridge addConfigurationSubscriber:(id)configurationSubscriber];
316
+
317
+ // Start the screenshot self-monitor here — same proven-safe timing as the config subscriber
318
+ // above (post-startup). Started once; -start touches UIApplication and the layer swizzle, so it
319
+ // must run on the main thread.
320
+ #if DTX_REPLAY_METRICS_ENABLED
321
+ if (!screenshotMonitorSubscribed) {
322
+ screenshotMonitorSubscribed = YES;
323
+ NSLog(@"[dtxScreenshotSelfMonitor] bridge: registering screenshot self-monitor as config subscriber");
324
+ screenshotMonitor = [[DTXScreenshotSelfMonitor alloc] init];
325
+ [HybridBridge addConfigurationSubscriber:(id)screenshotMonitor];
326
+ }
327
+ #endif
310
328
  }
311
329
 
312
330
  - (void)emitToJS:(NSString*)event body:(id)body
@@ -627,6 +645,41 @@ RCT_EXPORT_METHOD(forwardAppStartEvent:(NSDictionary<NSString*, id>*) attributes
627
645
  [HybridBridge forwardAppStartEvent:attributes keys:appStartKeys];
628
646
  }
629
647
 
648
+ RCT_EXPORT_METHOD(setAutomaticUserActionDetection:(BOOL)enabled)
649
+ {
650
+ [HybridBridge setAutomaticUserActionDetection:enabled];
651
+ }
652
+
653
+ RCT_EXPORT_METHOD(createUserAction:(NSString *)actionId name:(NSString *)name completeAutomatically:(BOOL)completeAutomatically properties:(NSDictionary<NSString*, id>* _Nullable)properties)
654
+ {
655
+ [HybridBridge createUserAction:actionId name:name completeAutomatically:completeAutomatically properties:properties];
656
+ }
657
+
658
+ RCT_EXPORT_METHOD(addEventStringPropertyToUserAction:(NSString *)actionId key:(NSString *)key value:(NSString *)value)
659
+ {
660
+ [HybridBridge addEventPropertyToUserAction:actionId key:key value:value];
661
+ }
662
+
663
+ RCT_EXPORT_METHOD(addEventDoublePropertyToUserAction:(NSString *)actionId key:(NSString *)key value:(double)value)
664
+ {
665
+ [HybridBridge addEventPropertyToUserAction:actionId key:key value:@(value)];
666
+ }
667
+
668
+ RCT_EXPORT_METHOD(addEventBooleanPropertyToUserAction:(NSString *)actionId key:(NSString *)key value:(BOOL)value)
669
+ {
670
+ [HybridBridge addEventPropertyToUserAction:actionId key:key value:@(value)];
671
+ }
672
+
673
+ RCT_EXPORT_METHOD(completeUserAction:(NSString *)actionId)
674
+ {
675
+ [HybridBridge completeUserAction:actionId];
676
+ }
677
+
678
+ RCT_EXPORT_METHOD(setCompleteUserActionAutomatically:(NSString *)actionId enabled:(BOOL)enabled)
679
+ {
680
+ [HybridBridge setCompleteUserActionAutomatically:actionId enabled:enabled];
681
+ }
682
+
630
683
  RCT_EXPORT_METHOD(setGPSLocation:(double)latitude andLongitude: (double)longitude platform: (NSString *) platform)
631
684
  {
632
685
  if ([self shouldWorkOnIosWithPlatform: platform])
@@ -426,4 +426,6 @@ exports.Dynatrace = {
426
426
  generateTraceContext(traceparent, tracestate) {
427
427
  return Dynatrace_1.Dynatrace.generateTraceContext(traceparent, tracestate);
428
428
  },
429
+ createUserAction: (configuration) => Dynatrace_1.Dynatrace.createUserAction(configuration),
430
+ setAutomaticUserActionDetection: (enabled) => Dynatrace_1.Dynatrace.setAutomaticUserActionDetection(enabled),
429
431
  };
@@ -153,9 +153,7 @@ class DynatraceAction {
153
153
  this.logger.debug(LogMessages_1.LogMessage.ACTION_GET_REQUEST_TAG_CLOSED, {
154
154
  url,
155
155
  });
156
- return new Promise((resolve) => {
157
- resolve('');
158
- });
156
+ return Promise.resolve('');
159
157
  }
160
158
  this.logger.debug(LogMessages_1.LogMessage.ACTION_GET_REQUEST_TAG, {
161
159
  url,
@@ -10,52 +10,50 @@ const LogMessages_1 = require("./logging/LogMessages");
10
10
  let counter = 0;
11
11
  const logger = new ConsoleLogger_1.ConsoleLogger('DyntraceInt');
12
12
  exports.DynatraceInternal = {
13
- reportErrorFromHandler: (isFatal, errorName, reason, stacktrace, isReportFatalErrorAsCrash, platform) => {
14
- if (isFatal && isReportFatalErrorAsCrash) {
15
- if (react_native_1.Platform.OS === 'ios') {
16
- logger.debug(LogMessages_1.LogMessage.STORE_CRASH, {
17
- errorName,
18
- reason,
19
- stacktrace,
20
- });
21
- DynatraceBridge_1.DynatraceNative.storeCrash(errorName, reason, stacktrace);
22
- }
23
- else {
24
- logger.debug(LogMessages_1.LogMessage.REPORT_CRASH, {
25
- crashName: errorName,
26
- reason,
27
- stacktrace,
28
- });
29
- DynatraceBridge_1.DynatraceNative.reportCrash(errorName, reason, stacktrace, true, platform === null || platform === void 0 ? void 0 : platform.toString());
30
- }
31
- Dynatrace_1.Dynatrace.reportCrash({
13
+ reportErrorFromHandler: (_isFatal, errorName, reason, stacktrace, isLegacyApiReported = false, platform) => {
14
+ if (StringUtils_1.StringUtils.isStringNullEmptyOrUndefined(stacktrace)) {
15
+ logger.debug(LogMessages_1.LogMessage.INTERNAL_REPORT_ERROR_SIMPLE, {
16
+ errorName,
17
+ });
18
+ DynatraceBridge_1.DynatraceNative.reportErrorWithoutStacktrace(errorName, -1);
19
+ Dynatrace_1.Dynatrace.reportErrorCode(errorName, -1, isLegacyApiReported);
20
+ }
21
+ else {
22
+ logger.debug(LogMessages_1.LogMessage.INTERNAL_REPORT_ERROR, {
23
+ errorName,
24
+ reason,
25
+ stacktrace,
26
+ });
27
+ DynatraceBridge_1.DynatraceNative.reportError(errorName, '-', reason, stacktrace, platform === null || platform === void 0 ? void 0 : platform.toString());
28
+ Dynatrace_1.Dynatrace.reportError({
32
29
  name: errorName,
33
30
  message: reason,
34
31
  stack: stacktrace,
35
- }, false, isFatal);
32
+ }, isLegacyApiReported);
33
+ }
34
+ },
35
+ reportFatalErrorAsCrashFromHandler: (isFatal, errorName, reason, stacktrace, platform) => {
36
+ if (react_native_1.Platform.OS === 'ios') {
37
+ logger.debug(LogMessages_1.LogMessage.STORE_CRASH, {
38
+ errorName,
39
+ reason,
40
+ stacktrace,
41
+ });
42
+ DynatraceBridge_1.DynatraceNative.storeCrash(errorName, reason, stacktrace);
36
43
  }
37
44
  else {
38
- if (!StringUtils_1.StringUtils.isStringNullEmptyOrUndefined(stacktrace)) {
39
- logger.debug(LogMessages_1.LogMessage.INTERNAL_REPORT_ERROR, {
40
- errorName,
41
- reason,
42
- stacktrace,
43
- });
44
- DynatraceBridge_1.DynatraceNative.reportError(errorName, '-', reason, stacktrace, platform === null || platform === void 0 ? void 0 : platform.toString());
45
- Dynatrace_1.Dynatrace.reportError({
46
- name: errorName,
47
- message: reason,
48
- stack: stacktrace,
49
- }, false);
50
- }
51
- else {
52
- logger.debug(LogMessages_1.LogMessage.INTERNAL_REPORT_ERROR_SIMPLE, {
53
- errorName,
54
- });
55
- DynatraceBridge_1.DynatraceNative.reportErrorWithoutStacktrace(errorName, -1);
56
- Dynatrace_1.Dynatrace.reportErrorCode(errorName, -1, false);
57
- }
45
+ logger.debug(LogMessages_1.LogMessage.REPORT_CRASH, {
46
+ crashName: errorName,
47
+ reason,
48
+ stacktrace,
49
+ });
50
+ DynatraceBridge_1.DynatraceNative.reportCrash(errorName, reason, stacktrace, true, platform === null || platform === void 0 ? void 0 : platform.toString());
58
51
  }
52
+ Dynatrace_1.Dynatrace.reportCrash({
53
+ name: errorName,
54
+ message: reason,
55
+ stack: stacktrace,
56
+ }, false, isFatal);
59
57
  },
60
58
  getCounter: () => counter++,
61
59
  };
@@ -1,49 +1,69 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.reportErrorToDynatrace = exports.startErrorHandler = void 0;
4
+ const react_native_1 = require("react-native");
4
5
  const DynatraceInternal_1 = require("./DynatraceInternal");
5
- const Dynatrace_1 = require("./Dynatrace");
6
6
  const StringUtils_1 = require("./util/StringUtils");
7
7
  const ConsoleLogger_1 = require("./logging/ConsoleLogger");
8
8
  const LogMessages_1 = require("./logging/LogMessages");
9
- const react_native_1 = require("react-native");
10
9
  const logger = new ConsoleLogger_1.ConsoleLogger('ErrorHandler');
11
10
  let manualStart = { enabled: false };
12
11
  const startErrorHandler = (reportFatalErrorAsCrash) => {
13
12
  manualStart = {
14
13
  enabled: true,
15
- reportFatalErrorAsCrash: reportFatalErrorAsCrash,
14
+ reportFatalErrorAsCrash,
16
15
  };
17
16
  };
18
17
  exports.startErrorHandler = startErrorHandler;
19
18
  const reportErrorToDynatrace = (exception, isFatal, reportFatalErrorAsCrashFromConfig, autoStart) => {
20
- if (!autoStart && !manualStart)
19
+ if (!isErrorHandlingEnabled(autoStart)) {
21
20
  return 0;
22
- const reportFatalErrorAsCrash = manualStart.enabled
23
- ? manualStart.reportFatalErrorAsCrash
24
- : reportFatalErrorAsCrashFromConfig;
25
- if (exception != null && isExceptionAnError(exception)) {
26
- if (!StringUtils_1.StringUtils.isStringNullEmptyOrUndefined(exception.name)) {
27
- if (isFatal === undefined) {
28
- isFatal = false;
29
- }
30
- DynatraceInternal_1.DynatraceInternal.reportErrorFromHandler(isFatal, String(exception.name), adjustedReason(exception.message), exception.stack != null ? exception.stack : '', reportFatalErrorAsCrash);
31
- logger.debug(LogMessages_1.LogMessage.REPORT_ERROR_TO_DYNATRACE, {
32
- exception: String(exception),
33
- isFatal: String(isFatal),
34
- });
35
- }
36
21
  }
37
- else {
38
- Dynatrace_1.Dynatrace.reportError(String(exception), -1);
22
+ if (!isExceptionAnErrorWithName(exception)) {
23
+ DynatraceInternal_1.DynatraceInternal.reportErrorFromHandler(false, String(exception), '', '', true);
39
24
  logger.debug(LogMessages_1.LogMessage.REPORT_ERROR_TO_DYNATRACE, {
40
25
  exception: String(exception),
41
26
  isFatal: '-1',
42
27
  });
28
+ return getCrashDelay();
43
29
  }
44
- return react_native_1.Platform.OS === 'ios' ? 200 : 0;
30
+ const resolvedIsFatal = isFatal !== null && isFatal !== void 0 ? isFatal : false;
31
+ const reportFatalErrorAsCrash = resolveReportFatalErrorAsCrash(reportFatalErrorAsCrashFromConfig);
32
+ const { errorName, errorReason, errorStack } = buildErrorDetails(exception);
33
+ reportErrorFromException(resolvedIsFatal, reportFatalErrorAsCrash, errorName, errorReason, errorStack);
34
+ logger.debug(LogMessages_1.LogMessage.REPORT_ERROR_TO_DYNATRACE, {
35
+ exception: String(exception),
36
+ isFatal: String(resolvedIsFatal),
37
+ });
38
+ return getCrashDelay();
45
39
  };
46
40
  exports.reportErrorToDynatrace = reportErrorToDynatrace;
41
+ const isErrorHandlingEnabled = (autoStart) => autoStart || manualStart.enabled;
42
+ const resolveReportFatalErrorAsCrash = (reportFatalErrorAsCrashFromConfig) => manualStart.enabled
43
+ ? manualStart.reportFatalErrorAsCrash
44
+ : reportFatalErrorAsCrashFromConfig;
45
+ const isExceptionAnErrorWithName = (exception) => {
46
+ if (exception == null || !isExceptionAnError(exception)) {
47
+ return false;
48
+ }
49
+ return !StringUtils_1.StringUtils.isStringNullEmptyOrUndefined(exception.name);
50
+ };
51
+ const buildErrorDetails = (exception) => {
52
+ var _a;
53
+ return ({
54
+ errorName: String(exception.name),
55
+ errorReason: adjustedReason(exception.message),
56
+ errorStack: (_a = exception.stack) !== null && _a !== void 0 ? _a : '',
57
+ });
58
+ };
59
+ const reportErrorFromException = (isFatal, reportFatalErrorAsCrash, errorName, errorReason, errorStack) => {
60
+ if (isFatal && reportFatalErrorAsCrash) {
61
+ DynatraceInternal_1.DynatraceInternal.reportFatalErrorAsCrashFromHandler(isFatal, errorName, errorReason, errorStack);
62
+ return;
63
+ }
64
+ DynatraceInternal_1.DynatraceInternal.reportErrorFromHandler(isFatal, errorName, errorReason, errorStack);
65
+ };
66
+ const getCrashDelay = () => (react_native_1.Platform.OS === 'ios' ? 200 : 0);
47
67
  const adjustedReason = (reason) => {
48
68
  if (!StringUtils_1.StringUtils.isStringNullEmptyOrUndefined(reason)) {
49
69
  const reasonNewLineIndex = reason.indexOf('\n');
@@ -24,9 +24,7 @@ class NullAction {
24
24
  return;
25
25
  }
26
26
  getRequestTag(url) {
27
- return new Promise((resolve) => {
28
- resolve('');
29
- });
27
+ return Promise.resolve('');
30
28
  }
31
29
  getRequestTagHeader() {
32
30
  return '';
@@ -36,6 +36,8 @@ var LogMessage;
36
36
  LogMessage["COMPONENT_NOT_STARTED"] = "COMPONENT_NOT_STARTED";
37
37
  LogMessage["CONFIGURATION_DUPLICATE_STARTUP"] = "CONFIGURATION_DUPLICATE_STARTUP";
38
38
  LogMessage["CONFIGURATION_SET"] = "CONFIGURATION_SET";
39
+ LogMessage["CREATE_USER_ACTION"] = "CREATE_USER_ACTION";
40
+ LogMessage["CREATE_USER_ACTION_NOT_STARTED"] = "CREATE_USER_ACTION_NOT_STARTED";
39
41
  LogMessage["END_SESSION"] = "END_SESSION";
40
42
  LogMessage["END_SESSION_NOT_STARTED"] = "END_SESSION_NOT_STARTED";
41
43
  LogMessage["ENTER_AUTO_ACTION"] = "ENTER_AUTO_ACTION";
@@ -115,6 +117,8 @@ var LogMessage;
115
117
  LogMessage["SEND_SESSION_PROPERTY_EVENT"] = "SEND_SESSION_PROPERTY_EVENT";
116
118
  LogMessage["SEND_SESSION_PROPERTY_EVENT_INVALID_TYPE"] = "SEND_SESSION_PROPERTY_EVENT_INVALID_TYPE";
117
119
  LogMessage["SESSION_PROPERTIES_FILTERED"] = "SESSION_PROPERTIES_FILTERED";
120
+ LogMessage["SET_AUTOMATIC_USER_ACTION_DETECTION"] = "SET_AUTOMATIC_USER_ACTION_DETECTION";
121
+ LogMessage["SET_AUTOMATIC_USER_ACTION_DETECTION_NOT_STARTED"] = "SET_AUTOMATIC_USER_ACTION_DETECTION_NOT_STARTED";
118
122
  LogMessage["SET_BEACON_HEADERS"] = "SET_BEACON_HEADERS";
119
123
  LogMessage["SET_BEACON_HEADERS_NOT_STARTED"] = "SET_BEACON_HEADERS_NOT_STARTED";
120
124
  LogMessage["SET_CRASH_REPORTING_OPTED_IN"] = "SET_CRASH_REPORTING_OPTED_IN";
@@ -137,6 +141,10 @@ var LogMessage;
137
141
  LogMessage["TRACE_CONTEXT_NOT_STARTED"] = "TRACE_CONTEXT_NOT_STARTED";
138
142
  LogMessage["TRIM_STRING_VALUE_LIMITED"] = "TRIM_STRING_VALUE_LIMITED";
139
143
  LogMessage["UI_INTERACTION_DEBUG"] = "UI_INTERACTION_DEBUG";
144
+ LogMessage["USER_ACTION_ADD_EVENT_PROPERTY"] = "USER_ACTION_ADD_EVENT_PROPERTY";
145
+ LogMessage["USER_ACTION_COMPLETE"] = "USER_ACTION_COMPLETE";
146
+ LogMessage["USER_ACTION_CREATED"] = "USER_ACTION_CREATED";
147
+ LogMessage["USER_ACTION_SET_COMPLETE_AUTOMATICALLY"] = "USER_ACTION_SET_COMPLETE_AUTOMATICALLY";
140
148
  LogMessage["VALUE_SIZE_LIMITED"] = "VALUE_SIZE_LIMITED";
141
149
  LogMessage["WEB_REQUEST_TIMING_START"] = "WEB_REQUEST_TIMING_START";
142
150
  LogMessage["WEB_REQUEST_TIMING_START_FAILED"] = "WEB_REQUEST_TIMING_START_FAILED";
@@ -281,6 +289,15 @@ exports.LOG_MESSAGES = {
281
289
  template: ({ config }) => `Configuration set: ${config}`,
282
290
  logType: LogType_1.LogType.Info,
283
291
  },
292
+ [LogMessage.CREATE_USER_ACTION]: {
293
+ template: ({ customName, completeAutomatically, }) => `createUserAction(${customName}, ${completeAutomatically})`,
294
+ logType: LogType_1.LogType.Info,
295
+ },
296
+ [LogMessage.CREATE_USER_ACTION_NOT_STARTED]: {
297
+ template: 'createUserAction(): React Native plugin has not been started yet! User action will not be created!',
298
+ logType: LogType_1.LogType.Warning,
299
+ documentationUri: 'https://dt-url.net/r2g3975',
300
+ },
284
301
  [LogMessage.END_SESSION]: {
285
302
  template: 'Dynatrace endSession()',
286
303
  logType: LogType_1.LogType.Info,
@@ -640,6 +657,15 @@ exports.LOG_MESSAGES = {
640
657
  logType: LogType_1.LogType.Warning,
641
658
  documentationUri: 'https://dt-url.net/lsk39cn',
642
659
  },
660
+ [LogMessage.SET_AUTOMATIC_USER_ACTION_DETECTION]: {
661
+ template: ({ enabled }) => `setAutomaticUserActionDetection(${enabled})`,
662
+ logType: LogType_1.LogType.Info,
663
+ },
664
+ [LogMessage.SET_AUTOMATIC_USER_ACTION_DETECTION_NOT_STARTED]: {
665
+ template: 'setAutomaticUserActionDetection(): React Native plugin has not been started yet! Setting will not be applied!',
666
+ logType: LogType_1.LogType.Warning,
667
+ documentationUri: 'https://dt-url.net/r2g3975',
668
+ },
643
669
  [LogMessage.SET_BEACON_HEADERS]: {
644
670
  template: 'setBeaconHeaders(headers)',
645
671
  logType: LogType_1.LogType.Info,
@@ -738,6 +764,22 @@ exports.LOG_MESSAGES = {
738
764
  template: ({ event }) => `[DT UI]${event}`,
739
765
  logType: LogType_1.LogType.Info,
740
766
  },
767
+ [LogMessage.USER_ACTION_ADD_EVENT_PROPERTY]: {
768
+ template: ({ key, value, customName, }) => `addEventProperty(${key}, ${value}): in UserAction - ${customName}`,
769
+ logType: LogType_1.LogType.Info,
770
+ },
771
+ [LogMessage.USER_ACTION_COMPLETE]: {
772
+ template: ({ customName }) => `complete(): ${customName}`,
773
+ logType: LogType_1.LogType.Info,
774
+ },
775
+ [LogMessage.USER_ACTION_CREATED]: {
776
+ template: ({ customName, completeAutomatically, actionId, }) => `UserAction created: ${customName} (actionId: ${actionId}, completeAutomatically: ${completeAutomatically})`,
777
+ logType: LogType_1.LogType.Info,
778
+ },
779
+ [LogMessage.USER_ACTION_SET_COMPLETE_AUTOMATICALLY]: {
780
+ template: ({ enabled, customName, }) => `setCompleteAutomatically(${enabled}): ${customName}`,
781
+ logType: LogType_1.LogType.Info,
782
+ },
741
783
  [LogMessage.VALUE_SIZE_LIMITED]: {
742
784
  template: ({ key, maxLength }) => `restrictingValueSize(): Limiting value of ${key} as maximum value length (${maxLength}) is reached!`,
743
785
  logType: LogType_1.LogType.Warning,
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JsonUtils = void 0;
4
+ exports.JsonUtils = {
5
+ stringify: (value) => typeof value === 'string' ? value : JSON.stringify(value),
6
+ };
@@ -8,7 +8,7 @@ var UserInteractionEventKey;
8
8
  UserInteractionEventKey["UiElementComponents"] = "ui_element.components";
9
9
  UserInteractionEventKey["UiElementId"] = "ui_element.id";
10
10
  UserInteractionEventKey["UiElementNameOrigin"] = "ui_element.name_origin";
11
- UserInteractionEventKey["InteractionName"] = "interaction.name";
11
+ UserInteractionEventKey["InteractionType"] = "interaction.type";
12
12
  UserInteractionEventKey["UiElementResponderDetectedName"] = "ui_element.responder.detected_name";
13
13
  UserInteractionEventKey["UiElementResponderComponents"] = "ui_element.responder.components";
14
14
  UserInteractionEventKey["UiElementResponderOriginName"] = "ui_element.responder.name_origin";
@@ -330,7 +330,7 @@ function _an_flat(e) {
330
330
  [IUserInteractionEvent_1.UserInteractionEventKey.UiElementDetectedName]: (_c = (_b = e === null || e === void 0 ? void 0 : e.ui_element) === null || _b === void 0 ? void 0 : _b.detected_name) !== null && _c !== void 0 ? _c : null,
331
331
  [IUserInteractionEvent_1.UserInteractionEventKey.UiElementComponents]: normalizedUiComponents,
332
332
  [IUserInteractionEvent_1.UserInteractionEventKey.UiElementId]: (_e = (_d = e === null || e === void 0 ? void 0 : e.ui_element) === null || _d === void 0 ? void 0 : _d.id) !== null && _e !== void 0 ? _e : null,
333
- [IUserInteractionEvent_1.UserInteractionEventKey.InteractionName]: _an_interaction_type(e),
333
+ [IUserInteractionEvent_1.UserInteractionEventKey.InteractionType]: _an_interaction_type(e),
334
334
  positions: Array.isArray(e === null || e === void 0 ? void 0 : e.positions)
335
335
  ? e.positions.map((pos) => ({
336
336
  x: Math.trunc(pos.x),
@@ -148,9 +148,10 @@ class TouchMetaResolver {
148
148
  return null;
149
149
  }
150
150
  const props = (_a = node.memoizedProps) !== null && _a !== void 0 ? _a : {};
151
- const dtName = props.dtName;
152
- if (typeof dtName === 'string' && dtName.trim().length > 0) {
153
- return dtName.trim();
151
+ const dtActionName = props.dtActionName;
152
+ if (typeof dtActionName === 'string' &&
153
+ dtActionName.trim().length > 0) {
154
+ return dtActionName.trim();
154
155
  }
155
156
  const testId = props.testID;
156
157
  if (typeof testId === 'string' && testId.trim().length > 0) {
@@ -14,6 +14,8 @@ const EventData_1 = require("./events/EventData");
14
14
  const SessionPropertyEventData_1 = require("./events/SessionPropertyEventData");
15
15
  const ExceptionEventData_1 = require("./events/ExceptionEventData");
16
16
  const HttpRequestEventData_1 = require("./events/HttpRequestEventData");
17
+ const NullUserAction_1 = require("./userAction/NullUserAction");
18
+ const UserActionImpl_1 = require("./userAction/UserActionImpl");
17
19
  const DynatraceArgValidators_1 = require("./DynatraceArgValidators");
18
20
  const TraceContextUtils_1 = require("./util/TraceContextUtils");
19
21
  const DECISION_REASON_TEXT = {
@@ -169,12 +171,14 @@ class DynatraceImpl {
169
171
  let parsedTraceparent = traceparent === undefined
170
172
  ? undefined
171
173
  : (0, TraceContextUtils_1.parseTraceparent)(traceparent);
174
+ let traceparentFromDynatrace = false;
172
175
  if (parsedTraceparent === undefined) {
173
176
  traceparent = (0, TraceContextUtils_1.generateTraceparentHeader)();
174
177
  parsedTraceparent = (0, TraceContextUtils_1.parseTraceparent)(traceparent);
175
178
  tracestate = undefined;
179
+ traceparentFromDynatrace = true;
176
180
  }
177
- tracestate = (0, TraceContextUtils_1.generateTracestate)(parsedTraceparent.parentId, tracestate);
181
+ tracestate = (0, TraceContextUtils_1.generateTracestate)(parsedTraceparent.parentId, traceparentFromDynatrace, tracestate);
178
182
  if (tracestate === undefined) {
179
183
  this.logger.info(LogMessages_1.LogMessage.TRACE_CONTEXT_DISABLED_OR_INVALID, {
180
184
  existingTraceparent: existingTraceparent !== null && existingTraceparent !== void 0 ? existingTraceparent : 'undefined',
@@ -187,5 +191,26 @@ class DynatraceImpl {
187
191
  tracestate,
188
192
  };
189
193
  }
194
+ createUserAction(configuration) {
195
+ if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
196
+ this.logger.info(LogMessages_1.LogMessage.CREATE_USER_ACTION_NOT_STARTED);
197
+ return new NullUserAction_1.NullUserAction();
198
+ }
199
+ this.logger.debug(LogMessages_1.LogMessage.CREATE_USER_ACTION, {
200
+ customName: configuration.customName,
201
+ completeAutomatically: configuration.completeAutomatically,
202
+ });
203
+ return new UserActionImpl_1.UserActionImpl(configuration);
204
+ }
205
+ setAutomaticUserActionDetection(enabled) {
206
+ if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
207
+ this.logger.info(LogMessages_1.LogMessage.SET_AUTOMATIC_USER_ACTION_DETECTION_NOT_STARTED);
208
+ return;
209
+ }
210
+ this.logger.debug(LogMessages_1.LogMessage.SET_AUTOMATIC_USER_ACTION_DETECTION, {
211
+ enabled,
212
+ });
213
+ DynatraceBridge_1.DynatraceNative.setAutomaticUserActionDetection(enabled);
214
+ }
190
215
  }
191
216
  exports.Dynatrace = new DynatraceImpl(TimestampProvider_1.defaultTimestampProvider);
@@ -34,30 +34,53 @@ class EventPipelineImpl {
34
34
  ];
35
35
  }
36
36
  insertEvent(event) {
37
+ if (this.isSuppressed(event)) {
38
+ return;
39
+ }
40
+ this.logger.debug(LogMessages_1.LogMessage.EVENT_PIPELINE_INSERT_EVENT, {
41
+ event: JSON.stringify(event),
42
+ });
43
+ const processed = this.applyModifiers(event);
44
+ if (processed != null) {
45
+ this.dispatchEvent(processed);
46
+ }
47
+ }
48
+ addEventModifier(eventModifier) {
49
+ this.logger.debug(LogMessages_1.LogMessage.ADD_EVENT_MODIFIER);
50
+ return this.customEventModifierChain.addEventModifier(eventModifier);
51
+ }
52
+ removeEventModifier(eventModifier) {
53
+ this.logger.debug(LogMessages_1.LogMessage.REMOVE_EVENT_MODIFIER);
54
+ return this.customEventModifierChain.removeEventModifier(eventModifier);
55
+ }
56
+ isSuppressed(event) {
37
57
  const decision = ConfigurationHandler_1.ConfigurationHandler.getThirdGenDataReportingDecision();
38
- if (!decision.allowed) {
58
+ if (decision.allowed) {
59
+ return false;
60
+ }
61
+ const isAppStart = event["characteristics.has_app_start"] ===
62
+ true;
63
+ const suppressed = !isAppStart ||
64
+ decision.reason === 'data_collection_off' ||
65
+ decision.reason === 'agent_inactive';
66
+ if (suppressed) {
39
67
  const reasonText = decision.reason
40
68
  ? DECISION_REASON_TEXT[decision.reason]
41
69
  : 'Unknown reason';
42
70
  this.logger.debug(LogMessages_1.LogMessage.THIRD_GEN_EVENT_SUPPRESSED, {
43
71
  reason: reasonText,
44
72
  });
45
- return;
46
73
  }
47
- this.logger.debug(LogMessages_1.LogMessage.EVENT_PIPELINE_INSERT_EVENT, {
48
- event: JSON.stringify(event),
49
- });
50
- let isDiscarded = false;
74
+ return suppressed;
75
+ }
76
+ applyModifiers(event) {
51
77
  for (const modifier of this.getEventModifierChain()) {
52
78
  try {
53
- const eventRv = modifier.modifyEvent(event);
54
- if (eventRv == null) {
55
- isDiscarded = true;
56
- break;
57
- }
58
- else {
59
- event = eventRv;
79
+ const result = modifier.modifyEvent(event);
80
+ if (result == null) {
81
+ return null;
60
82
  }
83
+ event = result;
61
84
  }
62
85
  catch (_a) {
63
86
  if (event != null) {
@@ -65,25 +88,19 @@ class EventPipelineImpl {
65
88
  }
66
89
  }
67
90
  }
68
- if (event != null && !isDiscarded) {
69
- this.logger.debug(LogMessages_1.LogMessage.EVENT_PIPELINE_FORWARD_EVENT, {
70
- event: JSON.stringify(event),
71
- });
72
- if (event["characteristics.has_app_start"] === true) {
73
- DynatraceBridge_1.DynatraceNative.forwardAppStartEvent(event, EventSpecContstants_1.ALL_APP_START_KEYS);
74
- }
75
- else {
76
- DynatraceBridge_1.DynatraceNative.forwardEvent(event);
77
- }
78
- }
79
- }
80
- addEventModifier(eventModifier) {
81
- this.logger.debug(LogMessages_1.LogMessage.ADD_EVENT_MODIFIER);
82
- return this.customEventModifierChain.addEventModifier(eventModifier);
91
+ return event;
83
92
  }
84
- removeEventModifier(eventModifier) {
85
- this.logger.debug(LogMessages_1.LogMessage.REMOVE_EVENT_MODIFIER);
86
- return this.customEventModifierChain.removeEventModifier(eventModifier);
93
+ dispatchEvent(event) {
94
+ this.logger.debug(LogMessages_1.LogMessage.EVENT_PIPELINE_FORWARD_EVENT, {
95
+ event: JSON.stringify(event),
96
+ });
97
+ if (event["characteristics.has_app_start"] ===
98
+ true) {
99
+ DynatraceBridge_1.DynatraceNative.forwardAppStartEvent(event, EventSpecContstants_1.ALL_APP_START_KEYS);
100
+ }
101
+ else {
102
+ DynatraceBridge_1.DynatraceNative.forwardEvent(event);
103
+ }
87
104
  }
88
105
  }
89
106
  exports.EventPipeline = new EventPipelineImpl();
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ConsoleLogger_1 = require("../../core/logging/ConsoleLogger");
4
4
  const LogMessages_1 = require("../../core/logging/LogMessages");
5
5
  const TimestampProvider_1 = require("../provider/TimestampProvider");
6
+ const TraceContextUtils_1 = require("../util/TraceContextUtils");
7
+ const ConfigurationHandler_1 = require("../../core/configuration/ConfigurationHandler");
6
8
  const SendEventValidation_1 = require("./modifier/SendEventValidation");
7
9
  const EventModifierUtil_1 = require("./modifier/EventModifierUtil");
8
10
  const EventBuilderUtil_1 = require("./EventBuilderUtil");
9
- const TraceContextUtils_1 = require("../util/TraceContextUtils");
10
- const ConfigurationHandler_1 = require("../../core/configuration/ConfigurationHandler");
11
11
  const logger = new ConsoleLogger_1.ConsoleLogger('HttpRequestEventData');
12
12
  class HttpRequestEventData {
13
13
  constructor(url, requestMethod) {
@@ -94,7 +94,7 @@ class HttpRequestEventData {
94
94
  return "api_set";
95
95
  }
96
96
  else {
97
- return "invalid";
97
+ return "invalid_set";
98
98
  }
99
99
  }
100
100
  hasValidMandatoryAttributes() {
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });