@dynatrace/react-native-plugin 2.341.1 → 2.345.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 (78) hide show
  1. package/README.md +674 -668
  2. package/android/build.gradle +16 -3
  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 -0
  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-runtime.gradle +17 -33
  12. package/files/plugin.gradle +1 -1
  13. package/instrumentation/BabelPluginDynatrace.js +1 -1
  14. package/instrumentation/libs/UserInteraction.js +21 -7
  15. package/instrumentation/libs/react-navigation/ReactNavigation.js +14 -58
  16. package/instrumentation/libs/withOnPressMonitoring.js +3 -54
  17. package/internal.d.ts +1 -0
  18. package/internal.js +3 -1
  19. package/ios/DTXScreenshotSelfMonitor.h +29 -0
  20. package/ios/DTXScreenshotSelfMonitor.mm +213 -0
  21. package/ios/DTXScreenshotSelfMonitorSwizzler.h +15 -0
  22. package/ios/DTXScreenshotSelfMonitorSwizzler.mm +68 -0
  23. package/ios/DynatraceRNBridge.h +6 -0
  24. package/ios/DynatraceRNBridge.mm +62 -0
  25. package/lib/core/Dynatrace.js +2 -0
  26. package/lib/core/configuration/ConfigurationHandler.js +0 -21
  27. package/lib/core/logging/LogMessages.js +42 -0
  28. package/lib/dynatrace-reporter.js +1 -30
  29. package/lib/dynatrace-transformer.js +6 -34
  30. package/lib/next/Dynatrace.js +26 -1
  31. package/lib/next/configuration/INativeRuntimeConfiguration.js +0 -1
  32. package/lib/next/configuration/RuntimeConfigurationObserver.js +1 -6
  33. package/lib/next/events/EventPipeline.js +48 -31
  34. package/lib/next/events/HttpRequestEventData.js +1 -1
  35. package/lib/next/events/spec/EventSpecContstants.js +1 -1
  36. package/lib/next/navigation/NavigationTracker.js +93 -0
  37. package/lib/next/navigation/useNavigationTracking.js +54 -0
  38. package/lib/next/userAction/NullUserAction.js +15 -0
  39. package/lib/next/userAction/UserActionConfiguration.js +10 -0
  40. package/lib/next/userAction/UserActionImpl.js +70 -0
  41. package/lib/next/util/TraceContextUtils.js +8 -14
  42. package/lib/next/util/Utils.js +13 -0
  43. package/package.json +10 -18
  44. package/public.js +5 -1
  45. package/react-native-dynatrace.podspec +10 -3
  46. package/scripts/Android.js +1 -20
  47. package/scripts/Config.js +17 -7
  48. package/scripts/Deprecations.js +18 -0
  49. package/scripts/Install.js +13 -0
  50. package/scripts/PathsConstants.js +0 -4
  51. package/scripts/Uninstall.js +0 -15
  52. package/scripts/core/InstrumentCall.js +14 -7
  53. package/scripts/util/DeprecationReport.js +24 -0
  54. package/src/lib/core/interface/NativeDynatraceBridge.ts +34 -1
  55. package/types.d.ts +236 -7
  56. package/instrumentation/DynatraceInstrumentation.js +0 -1
  57. package/instrumentation/libs/community/Picker.InstrInfo.js +0 -20
  58. package/instrumentation/libs/community/gesture-handler/Touchables.InstrInfo.js +0 -25
  59. package/instrumentation/libs/react-native/RefreshControl.InstrInfo.js +0 -12
  60. package/instrumentation/libs/react-native/Switch.InstrInfo.js +0 -12
  61. package/instrumentation/libs/react-native/Touchables.InstrInfo.js +0 -25
  62. package/instrumentation/parser/Babel.js +0 -60
  63. package/instrumentation/parser/ParserUtil.js +0 -11
  64. package/lib/features/ui-interaction/Config.js +0 -42
  65. package/lib/features/ui-interaction/IUserInteractionEvent.js +0 -16
  66. package/lib/features/ui-interaction/Plugin.Fragment.Test.js +0 -170
  67. package/lib/features/ui-interaction/Plugin.js +0 -289
  68. package/lib/features/ui-interaction/RootDetection.js +0 -51
  69. package/lib/features/ui-interaction/RootWrapper.js +0 -236
  70. package/lib/features/ui-interaction/Run.js +0 -38
  71. package/lib/features/ui-interaction/Runtime.js +0 -843
  72. package/lib/features/ui-interaction/TouchMetaResolver.js +0 -493
  73. package/lib/features/ui-interaction/Types.js +0 -14
  74. package/lib/metro/getSourceMapInfo.js +0 -26
  75. package/scripts/LineOffsetAnalyze.js +0 -25
  76. package/scripts/core/LineOffsetAnalyzeCall.js +0 -165
  77. package/scripts/util/SourceMapUtil.js +0 -68
  78. /package/{instrumentation/model/Reference.js → lib/next/userAction/UserAction.js} +0 -0
@@ -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
@@ -219,11 +225,13 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
219
225
  /**
220
226
  * When bridge is starting we will add an observer for content did appear so we can emit our app start measurements
221
227
  */
228
+ #if !RCT_NEW_ARCH_ENABLED
222
229
  - (void)setBridge:(RCTBridge *)bridge
223
230
  {
224
231
  [super setBridge:bridge];
225
232
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentAppeared) name:RCTContentDidAppearNotification object:nil];
226
233
  }
234
+ #endif
227
235
 
228
236
  - (BOOL)isReady
229
237
  {
@@ -283,6 +291,13 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
283
291
  - (void)startObserving
284
292
  {
285
293
  hasListeners = YES;
294
+ #if RCT_NEW_ARCH_ENABLED
295
+ // On new arch setBridge: is not called, so RCTContentDidAppearNotification is never observed.
296
+ // JS adding a listener is the earliest signal we have that content is visible.
297
+ if (contentAppeared == -1) {
298
+ contentAppeared = GetTimestampUnix();
299
+ }
300
+ #endif
286
301
  [self emitMeasurements];
287
302
 
288
303
  [self setupRuntimeConfigurationListenerIfNeeded];
@@ -307,6 +322,18 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
307
322
  }
308
323
  remoteConfigSubscribed = YES;
309
324
  [HybridBridge addConfigurationSubscriber:(id)configurationSubscriber];
325
+
326
+ // Start the screenshot self-monitor here — same proven-safe timing as the config subscriber
327
+ // above (post-startup). Started once; -start touches UIApplication and the layer swizzle, so it
328
+ // must run on the main thread.
329
+ #if DTX_REPLAY_METRICS_ENABLED
330
+ if (!screenshotMonitorSubscribed) {
331
+ screenshotMonitorSubscribed = YES;
332
+ NSLog(@"[dtxScreenshotSelfMonitor] bridge: registering screenshot self-monitor as config subscriber");
333
+ screenshotMonitor = [[DTXScreenshotSelfMonitor alloc] init];
334
+ [HybridBridge addConfigurationSubscriber:(id)screenshotMonitor];
335
+ }
336
+ #endif
310
337
  }
311
338
 
312
339
  - (void)emitToJS:(NSString*)event body:(id)body
@@ -627,6 +654,41 @@ RCT_EXPORT_METHOD(forwardAppStartEvent:(NSDictionary<NSString*, id>*) attributes
627
654
  [HybridBridge forwardAppStartEvent:attributes keys:appStartKeys];
628
655
  }
629
656
 
657
+ RCT_EXPORT_METHOD(setAutomaticUserActionDetection:(BOOL)enabled)
658
+ {
659
+ [HybridBridge setAutomaticUserActionDetection:enabled];
660
+ }
661
+
662
+ RCT_EXPORT_METHOD(createUserAction:(NSString *)actionId name:(NSString *)name completeAutomatically:(BOOL)completeAutomatically properties:(NSDictionary<NSString*, id>* _Nullable)properties)
663
+ {
664
+ [HybridBridge createUserAction:actionId name:name completeAutomatically:completeAutomatically properties:properties];
665
+ }
666
+
667
+ RCT_EXPORT_METHOD(addEventStringPropertyToUserAction:(NSString *)actionId key:(NSString *)key value:(NSString *)value)
668
+ {
669
+ [HybridBridge addEventPropertyToUserAction:actionId key:key value:value];
670
+ }
671
+
672
+ RCT_EXPORT_METHOD(addEventDoublePropertyToUserAction:(NSString *)actionId key:(NSString *)key value:(double)value)
673
+ {
674
+ [HybridBridge addEventPropertyToUserAction:actionId key:key value:@(value)];
675
+ }
676
+
677
+ RCT_EXPORT_METHOD(addEventBooleanPropertyToUserAction:(NSString *)actionId key:(NSString *)key value:(BOOL)value)
678
+ {
679
+ [HybridBridge addEventPropertyToUserAction:actionId key:key value:@(value)];
680
+ }
681
+
682
+ RCT_EXPORT_METHOD(completeUserAction:(NSString *)actionId)
683
+ {
684
+ [HybridBridge completeUserAction:actionId];
685
+ }
686
+
687
+ RCT_EXPORT_METHOD(setCompleteUserActionAutomatically:(NSString *)actionId enabled:(BOOL)enabled)
688
+ {
689
+ [HybridBridge setCompleteUserActionAutomatically:actionId enabled:enabled];
690
+ }
691
+
630
692
  RCT_EXPORT_METHOD(setGPSLocation:(double)latitude andLongitude: (double)longitude platform: (NSString *) platform)
631
693
  {
632
694
  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
  };
@@ -4,7 +4,6 @@ exports.ConfigurationHandler = void 0;
4
4
  const RuntimeConfigurationObserver_1 = require("../../next/configuration/RuntimeConfigurationObserver");
5
5
  const LogLevel_1 = require("../logging/LogLevel");
6
6
  let _configuration;
7
- let _uiiEnabledLastKnownGood = undefined;
8
7
  const getRuntimeConfiguration = () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration();
9
8
  const getBaseThirdGenDecision = () => {
10
9
  if (!RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated()) {
@@ -46,9 +45,6 @@ exports.ConfigurationHandler = {
46
45
  setConfiguration(configuration) {
47
46
  _configuration = configuration;
48
47
  },
49
- setUserInteractionEnabledLastKnownGood(value) {
50
- _uiiEnabledLastKnownGood = value;
51
- },
52
48
  isConfigurationAvailable: () => _configuration !== undefined,
53
49
  isErrorHandlerEnabled: () => _configuration.errorHandler,
54
50
  isReportFatalErrorAsCrash: () => _configuration.reportFatalErrorAsCrash,
@@ -84,23 +80,6 @@ exports.ConfigurationHandler = {
84
80
  getApplicationId: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()['application_id'],
85
81
  getTracestateKeyPrefix: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()['tracestate_key_prefix'],
86
82
  getTraceContextEnabled: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()['trace_context_enabled'],
87
- isUserInteractionEnabled: () => {
88
- const isRuntimeConfigInitiated = RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated();
89
- if (isRuntimeConfigInitiated) {
90
- const realTimeconfiguration = RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration();
91
- const remoteUIConfiguration = realTimeconfiguration
92
- ? realTimeconfiguration.touch_interaction_enabled
93
- : undefined;
94
- if (typeof remoteUIConfiguration === 'boolean') {
95
- _uiiEnabledLastKnownGood = remoteUIConfiguration;
96
- return remoteUIConfiguration;
97
- }
98
- }
99
- if (typeof _uiiEnabledLastKnownGood === 'boolean') {
100
- return _uiiEnabledLastKnownGood;
101
- }
102
- return false;
103
- },
104
83
  isRuntimeConfigurationInitiated: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated(),
105
84
  getBundleName: () => _configuration.bundleName,
106
85
  getBundleVersion: () => _configuration.bundleVersion,
@@ -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,
@@ -1,14 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
2
  const TerminalReporter = (() => {
13
3
  try {
14
4
  return require('metro/src/lib/TerminalReporter');
@@ -18,23 +8,4 @@ const TerminalReporter = (() => {
18
8
  }
19
9
  })();
20
10
  const { Terminal } = require('metro-core');
21
- const files = require('../scripts/FileOperationHelper');
22
- const paths = require('../scripts/PathsConstants');
23
- const reporter = new TerminalReporter(new Terminal(process.stdout));
24
- const updateOrig = TerminalReporter.prototype.update;
25
- TerminalReporter.prototype.update = function update(event) {
26
- return updateOrig === null || updateOrig === void 0 ? void 0 : updateOrig.apply(this, arguments);
27
- };
28
- const update = (event) => __awaiter(void 0, void 0, void 0, function* () {
29
- if (event != null) {
30
- if (event.type === 'transform_cache_reset') {
31
- try {
32
- yield files.default.deleteDirectory(paths.default.getBuildPath());
33
- }
34
- catch (e) {
35
- }
36
- }
37
- }
38
- reporter.update(event);
39
- });
40
- module.exports.update = update;
11
+ module.exports = new TerminalReporter(new Terminal(process.stdout));
@@ -1,40 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getUpstreamTransformer = exports.transform = void 0;
4
- const config = require("../scripts/Config");
5
- const Logger_1 = require("../scripts/Logger");
6
4
  const BabelPluginDynatrace_1 = require("../instrumentation/BabelPluginDynatrace");
7
- const instrumentor = require("../instrumentation/DynatraceInstrumentation");
8
5
  const Config_1 = require("../scripts/Config");
9
6
  const transform = (args) => {
10
7
  var _a;
11
- let src = args.src;
12
- const { filename, options } = args;
13
- let reactOptions;
14
- try {
15
- reactOptions = (0, Config_1.readConfigDefault)();
16
- if (!reactOptions.react.useLegacyJscodeshift) {
17
- args.plugins = [BabelPluginDynatrace_1.default, ...((_a = args.plugins) !== null && _a !== void 0 ? _a : [])];
18
- return (0, exports.getUpstreamTransformer)(reactOptions === null || reactOptions === void 0 ? void 0 : reactOptions.react).transform(args);
19
- }
20
- src = instrumentor.instrument(src, filename, reactOptions.react);
21
- }
22
- catch (e) {
23
- if (e instanceof Error) {
24
- if (e.message === config.ERROR_CONFIG_NOT_AVAILABLE) {
25
- console.log('dynatrace.config.js not found!');
26
- }
27
- else {
28
- console.log("Couldn't instrument file: " + filename);
29
- Logger_1.default.logErrorSync(e.message);
30
- }
31
- }
32
- }
33
- return (0, exports.getUpstreamTransformer)(reactOptions === null || reactOptions === void 0 ? void 0 : reactOptions.react).transform({
34
- src,
35
- filename,
36
- options,
37
- });
8
+ args.plugins = [BabelPluginDynatrace_1.default, ...((_a = args.plugins) !== null && _a !== void 0 ? _a : [])];
9
+ return (0, exports.getUpstreamTransformer)((0, Config_1.readConfigDefault)().react).transform(args);
38
10
  };
39
11
  exports.transform = transform;
40
12
  const safeRequire = (modulePath) => {
@@ -45,10 +17,10 @@ const safeRequire = (modulePath) => {
45
17
  return null;
46
18
  }
47
19
  };
48
- const getUpstreamTransformer = (reactOptions) => {
49
- if (reactOptions !== undefined &&
50
- reactOptions.upstreamTransformer !== undefined) {
51
- return require(reactOptions.upstreamTransformer);
20
+ const getUpstreamTransformer = (transformerReactConfig) => {
21
+ const upstreamTransformer = transformerReactConfig === null || transformerReactConfig === void 0 ? void 0 : transformerReactConfig.upstreamTransformer;
22
+ if (upstreamTransformer !== undefined) {
23
+ return require(upstreamTransformer);
52
24
  }
53
25
  else {
54
26
  const transformer = safeRequire('@expo/metro-config/babel-transformer') ||
@@ -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);
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateDefaultConfiguration = void 0;
4
4
  const generateDefaultConfiguration = () => ({
5
5
  '3rd_gen_enabled': true,
6
- touch_interaction_enabled: false,
7
6
  instance_id: '',
8
7
  session_id: '',
9
8
  application_id: '',
@@ -28,9 +28,6 @@ class RuntimeConfigurationObserverImpl {
28
28
  const thirdGenEnabled = typeof payload['3rd_gen_enabled'] === 'boolean'
29
29
  ? payload['3rd_gen_enabled']
30
30
  : undefined;
31
- const touchInteractionEnabled = typeof payload.touch_interaction_enabled === 'boolean'
32
- ? payload.touch_interaction_enabled
33
- : undefined;
34
31
  const traceContextEnabled = typeof payload.trace_context_enabled === 'boolean'
35
32
  ? payload.trace_context_enabled
36
33
  : undefined;
@@ -60,10 +57,8 @@ class RuntimeConfigurationObserverImpl {
60
57
  const tracestateKeyPrefix = typeof payload.tracestate_key_prefix === 'string'
61
58
  ? payload.tracestate_key_prefix
62
59
  : undefined;
63
- const normalized = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (typeof thirdGenEnabled === 'boolean'
60
+ const normalized = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (typeof thirdGenEnabled === 'boolean'
64
61
  ? { '3rd_gen_enabled': thirdGenEnabled }
65
- : {})), (typeof touchInteractionEnabled === 'boolean'
66
- ? { touch_interaction_enabled: touchInteractionEnabled }
67
62
  : {})), (typeof traceContextEnabled === 'boolean'
68
63
  ? { trace_context_enabled: traceContextEnabled }
69
64
  : {})), (typeof dataCollectionLevel === 'number'
@@ -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();
@@ -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() {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ALL_APP_START_KEYS = exports.EVENT_WHITELIST_SIZE = exports.MODIFY_EVENT_WHITELIST_NAMESPACE = exports.MODIFY_EVENT_WHITELIST_STRING_FIELDS = exports.MODIFY_EVENT_WHITELIST_FIELDS = exports.SEND_SESSION_PROPERTY_EVENT_WHITELIST_FIELDS = exports.SEND_EXCEPTION_EVENT_WHITELIST_FIELDS = exports.SEND_EVENT_WHITELIST_FIELDS = exports.SEND_SESSION_PROPERTY_EVENT_WHITELIST_NAMESPACES = exports.SEND_EXCEPTION_EVENT_WHITELIST_NAMESPACES = exports.SEND_EVENT_WHITELIST_NAMESPACES = exports.AllCharacteristicsKeys = exports.KEY_NAME_REGEX = exports.MAX_CUSTOM_EVENT_VALUE_LENGTH = exports.MAX_CUSTOM_EVENT_KEY_LENGTH = exports.MAX_CUSTOM_EVENT_FIELDS = exports.SPECIFICATION_VERSION = void 0;
4
- exports.SPECIFICATION_VERSION = '0.23.0';
4
+ exports.SPECIFICATION_VERSION = '0.24.0';
5
5
  exports.MAX_CUSTOM_EVENT_FIELDS = 50;
6
6
  exports.MAX_CUSTOM_EVENT_KEY_LENGTH = 100;
7
7
  exports.MAX_CUSTOM_EVENT_VALUE_LENGTH = 5000;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._resetForTest = exports.getActivePath = exports.reportScreenResume = exports.reportScreenBackground = exports.reportScreenChange = exports.buildPathFromState = exports.registerEventTrigger = void 0;
4
+ const ConsoleLogger_1 = require("../../core/logging/ConsoleLogger");
5
+ const LogMessages_1 = require("../../core/logging/LogMessages");
6
+ const ConfigurationHandler_1 = require("../../core/configuration/ConfigurationHandler");
7
+ const DynatraceBridge_1 = require("../../core/DynatraceBridge");
8
+ const BaseDataEventModifier_1 = require("../events/modifier/BaseDataEventModifier");
9
+ const logger = new ConsoleLogger_1.ConsoleLogger('NavigationTracker');
10
+ let eventTrigger = null;
11
+ const registerEventTrigger = (fn) => {
12
+ eventTrigger = fn;
13
+ };
14
+ exports.registerEventTrigger = registerEventTrigger;
15
+ let activePath = '';
16
+ let isBackgrounded = false;
17
+ const buildPathFromState = (state) => {
18
+ var _a, _b;
19
+ let currentState = state;
20
+ const parts = [];
21
+ while (currentState === null || currentState === void 0 ? void 0 : currentState.routes[(_a = currentState.index) !== null && _a !== void 0 ? _a : 0]) {
22
+ const currentRoute = currentState.routes[(_b = currentState.index) !== null && _b !== void 0 ? _b : 0];
23
+ parts.push(currentRoute.name);
24
+ currentState = currentRoute.state;
25
+ }
26
+ return parts.join('/');
27
+ };
28
+ exports.buildPathFromState = buildPathFromState;
29
+ const startView = (newPath) => {
30
+ if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
31
+ logger.info(LogMessages_1.LogMessage.NAVIGATION_NOT_STARTED);
32
+ return;
33
+ }
34
+ const startViewInternalEvent = new BaseDataEventModifier_1.BaseDataEventModifier().modifyEvent(Object.assign({ 'view.detected_name': newPath }, (activePath && {
35
+ 'view.source.detected_name': activePath,
36
+ })));
37
+ const fn = DynatraceBridge_1.DynatraceNative === null || DynatraceBridge_1.DynatraceNative === void 0 ? void 0 : DynatraceBridge_1.DynatraceNative.startViewInternal;
38
+ if (typeof fn === 'function') {
39
+ fn(startViewInternalEvent);
40
+ }
41
+ logger.debug(LogMessages_1.LogMessage.START_VIEW_INTERNAL, {
42
+ event: JSON.stringify(startViewInternalEvent),
43
+ });
44
+ };
45
+ const stopView = () => {
46
+ if (!ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable()) {
47
+ logger.info(LogMessages_1.LogMessage.NAVIGATION_NOT_STARTED);
48
+ return;
49
+ }
50
+ const fn = DynatraceBridge_1.DynatraceNative === null || DynatraceBridge_1.DynatraceNative === void 0 ? void 0 : DynatraceBridge_1.DynatraceNative.stopViewInternal;
51
+ if (typeof fn === 'function') {
52
+ fn();
53
+ }
54
+ logger.debug(LogMessages_1.LogMessage.STOP_VIEW_INTERNAL);
55
+ };
56
+ const reportScreenChange = (newPath) => {
57
+ if (newPath === activePath) {
58
+ return;
59
+ }
60
+ if (activePath !== '') {
61
+ stopView();
62
+ }
63
+ startView(newPath);
64
+ activePath = newPath;
65
+ if (newPath) {
66
+ eventTrigger === null || eventTrigger === void 0 ? void 0 : eventTrigger(newPath, Date.now());
67
+ }
68
+ };
69
+ exports.reportScreenChange = reportScreenChange;
70
+ const reportScreenBackground = () => {
71
+ isBackgrounded = true;
72
+ stopView();
73
+ };
74
+ exports.reportScreenBackground = reportScreenBackground;
75
+ const reportScreenResume = () => {
76
+ if (!isBackgrounded) {
77
+ return;
78
+ }
79
+ isBackgrounded = false;
80
+ startView(activePath);
81
+ if (activePath) {
82
+ eventTrigger === null || eventTrigger === void 0 ? void 0 : eventTrigger(activePath, Date.now());
83
+ }
84
+ };
85
+ exports.reportScreenResume = reportScreenResume;
86
+ const getActivePath = () => activePath;
87
+ exports.getActivePath = getActivePath;
88
+ const _resetForTest = () => {
89
+ activePath = '';
90
+ isBackgrounded = false;
91
+ eventTrigger = null;
92
+ };
93
+ exports._resetForTest = _resetForTest;