@dynatrace/react-native-plugin 2.327.2 → 2.331.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 (54) hide show
  1. package/README.md +419 -164
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/dynatrace/android/agent/DynatraceConfigurationModule.kt +48 -0
  4. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +41 -8
  5. package/android/src/main/java/com/dynatrace/android/agent/DynatraceReactPackage.kt +3 -0
  6. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRuntimeConfigurationStore.kt +14 -0
  7. package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.kt +103 -47
  8. package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +12 -4
  9. package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +15 -5
  10. package/files/default.config.js +7 -0
  11. package/files/plugin-runtime.gradle +7 -17
  12. package/files/plugin.gradle +1 -1
  13. package/instrumentation/DynatraceInstrumentation.js +1 -1
  14. package/instrumentation/libs/react-navigation/ReactNavigation.js +53 -18
  15. package/ios/ConfigurationSubscriber.h +15 -0
  16. package/ios/DynatraceRNBridge.h +4 -0
  17. package/ios/DynatraceRNBridge.mm +125 -29
  18. package/lib/core/Dynatrace.js +8 -11
  19. package/lib/core/configuration/ConfigurationHandler.js +3 -0
  20. package/lib/next/Dynatrace.js +50 -33
  21. package/lib/next/DynatraceArgValidators.js +10 -0
  22. package/lib/next/DynatraceEventBus.js +35 -0
  23. package/lib/next/appstart/AppStartObserver.js +2 -3
  24. package/lib/next/configuration/INativeRuntimeConfiguration.js +7 -0
  25. package/lib/next/configuration/RuntimeConfigurationObserver.js +40 -0
  26. package/lib/next/events/EventBuilderUtil.js +7 -0
  27. package/lib/next/events/EventData.js +28 -0
  28. package/lib/next/events/EventPipeline.js +5 -11
  29. package/lib/next/events/ExceptionEventData.js +26 -0
  30. package/lib/next/events/HttpRequestEventData.js +174 -0
  31. package/lib/next/events/SessionPropertyEventData.js +22 -0
  32. package/lib/next/events/interface/IBaseEvent.js +2 -0
  33. package/lib/next/events/interface/IEventData.js +2 -0
  34. package/lib/next/events/interface/IExceptionEventData.js +2 -0
  35. package/lib/next/events/interface/IHttpRequestEventData.js +2 -0
  36. package/lib/next/events/interface/ISessionPropertyEventData.js +2 -0
  37. package/lib/next/events/modifier/BaseDataEventModifier.js +1 -3
  38. package/lib/next/events/modifier/EventModifierUtil.js +34 -41
  39. package/lib/next/events/modifier/ModifyEventValidation.js +117 -27
  40. package/lib/next/events/modifier/SendEventValidation.js +53 -22
  41. package/lib/next/events/modifier/StringLengthEventModifier.js +53 -0
  42. package/lib/next/events/spec/EventSpecContstants.js +9 -2
  43. package/package.json +11 -5
  44. package/public.js +9 -3
  45. package/react-native-dynatrace.podspec +1 -1
  46. package/scripts/Config.js +6 -2
  47. package/scripts/LineOffsetAnalyze.js +1 -4
  48. package/scripts/core/LineOffsetAnalyzeCall.js +39 -46
  49. package/src/lib/core/interface/NativeDynatraceBridge.ts +6 -2
  50. package/types.d.ts +408 -177
  51. package/lib/next/events/HttpRequestEventBuilder.js +0 -196
  52. package/lib/next/events/ViewInfoCreator.js +0 -27
  53. package/lib/next/events/modifier/EventLimitation.js +0 -69
  54. /package/lib/next/events/{IHttpRequestEventBuilder.js → interface/EventProperty.js} +0 -0
@@ -8,6 +8,7 @@
8
8
  #import <Dynatrace/Dynatrace.h>
9
9
  #import <React/RCTBridgeModule.h>
10
10
  #import <React/RCTEventEmitter.h>
11
+ #import "ConfigurationSubscriber.h"
11
12
 
12
13
  @interface DynatraceRNBridge : RCTEventEmitter <RCTBridgeModule>
13
14
  - (void) newAction:(NSString *)name key:(NSString *)key parentAction:(DTXAction *)parentAction;
@@ -18,6 +19,9 @@
18
19
  @interface HybridBridge : NSObject
19
20
  + (void)forwardEvent:(NSDictionary<NSString*,id>* _Nullable)fields NS_SWIFT_NAME(forwardEvent(fields:));
20
21
  + (void)forwardAppStartEvent:(NSDictionary<NSString*,id>* _Nullable)fields keys:(NSArray<NSString*>* _Nullable)keys NS_SWIFT_NAME(forwardEvent(fields:keys:));
22
+ + (void)startView:(NSDictionary<NSString*,id>* _Nullable)fields NS_SWIFT_NAME(startView(fields:));
23
+ + (void)stopView;
24
+ + (void)addConfigurationSubscriber:(id<ConfigurationSubscriber>)subscriber;
21
25
  @end
22
26
 
23
27
  typedef enum : NSUInteger {
@@ -13,12 +13,46 @@
13
13
  #import <CoreLocation/CoreLocation.h>
14
14
  #import <React/RCTPerformanceLogger.h>
15
15
  #import <React/RCTRootView.h>
16
+ #import <React/RCTBridge+Private.h>
16
17
  #import <cxxreact/ReactMarker.h>
17
18
  #import <cxxreact/ReactNativeVersion.h>
18
19
 
19
20
  #include <chrono>
20
21
  #include <type_traits>
21
22
 
23
+ @interface DynatraceRNBridge ()
24
+ - (void)handleRuntimeConfiguration:(NSDictionary<NSString*, id>*)configuration;
25
+ - (void)setupRuntimeConfigurationListenerIfNeeded;
26
+ - (void)emitToJS:(NSString*)event body:(id)body;
27
+ @end
28
+
29
+ @interface RNConfigurationSubscriber : NSObject <ConfigurationSubscriber>
30
+ @property (nonatomic, weak) DynatraceRNBridge* bridge;
31
+ - (instancetype)initWithBridge:(DynatraceRNBridge*)bridge;
32
+ @end
33
+
34
+ @implementation RNConfigurationSubscriber
35
+
36
+ - (instancetype)initWithBridge:(DynatraceRNBridge*)bridge
37
+ {
38
+ self = [super init];
39
+ if (self) {
40
+ _bridge = bridge;
41
+ }
42
+ return self;
43
+ }
44
+
45
+ - (void)notifyWithConfiguration:(NSDictionary<NSString*, id>*)configuration
46
+ {
47
+ DynatraceRNBridge* bridge = self.bridge;
48
+ if (bridge == nil) {
49
+ return;
50
+ }
51
+ [bridge handleRuntimeConfiguration:configuration];
52
+ }
53
+
54
+ @end
55
+
22
56
  @implementation DynatraceRNBridge
23
57
 
24
58
  NSMutableDictionary *actionDict;
@@ -37,6 +71,7 @@ NSString *const DataCollectionUserBehavior = @"USER_BEHAVIOR";
37
71
  * Emitting app start event with this identifier
38
72
  */
39
73
  NSString *const EmitAppMeasurementsIdentifier = @"dynatraceAppStartMeasurements";
74
+ NSString *const EmitDynatraceConfiguration = @"dynatraceConfiguration";
40
75
 
41
76
  // All types which are interesting for us
42
77
  NSString *const DownloadStart = @"downloadStart";
@@ -71,6 +106,11 @@ int64_t runJSBundleStartTime;
71
106
  */
72
107
  int64_t runJSBundleEndTime;
73
108
 
109
+ // Runtime configuration (remote config)
110
+ static bool remoteConfigSubscribed;
111
+ static NSDictionary<NSString*, id>* lastRuntimeConfiguration;
112
+ static RNConfigurationSubscriber* configurationSubscriber;
113
+
74
114
  RCT_EXPORT_MODULE(DynatraceBridge);
75
115
 
76
116
  - (instancetype) init
@@ -83,6 +123,11 @@ RCT_EXPORT_MODULE(DynatraceBridge);
83
123
  contentAppeared = -1;
84
124
  runJSBundleStartTime = -1;
85
125
  runJSBundleEndTime = -1;
126
+
127
+ remoteConfigSubscribed = NO;
128
+ lastRuntimeConfiguration = nil;
129
+ configurationSubscriber = [[RNConfigurationSubscriber alloc] initWithBridge:self];
130
+
86
131
  registerLogTaggedMarkerCallbacks();
87
132
  }
88
133
  return self;
@@ -127,7 +172,7 @@ int64_t getRunJSBundleEndTime() {
127
172
  }
128
173
 
129
174
  - (NSArray<NSString *> *)supportedEvents {
130
- return @[EmitAppMeasurementsIdentifier];
175
+ return @[EmitAppMeasurementsIdentifier, EmitDynatraceConfiguration];
131
176
  }
132
177
 
133
178
  int64_t GetTimestampUnix()
@@ -148,13 +193,13 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
148
193
  using namespace facebook::react::ReactMarker;
149
194
  auto logTaggedMarkerCommon = [](const ReactMarkerId markerId, const char* tag, auto previousLogTaggedMarker) {
150
195
  if (previousLogTaggedMarker) {
151
- previousLogTaggedMarker(markerId, tag);
196
+ previousLogTaggedMarker(markerId, tag);
152
197
  }
153
198
 
154
199
  if (markerId == RUN_JS_BUNDLE_START) {
155
- runJSBundleStartTime = GetTimestampUnix();
200
+ runJSBundleStartTime = GetTimestampUnix();
156
201
  } else if (markerId == RUN_JS_BUNDLE_STOP) {
157
- runJSBundleEndTime = GetTimestampUnix();
202
+ runJSBundleEndTime = GetTimestampUnix();
158
203
  }
159
204
  };
160
205
 
@@ -182,7 +227,7 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
182
227
 
183
228
  - (BOOL)isReady
184
229
  {
185
- return contentAppeared != -1 && getRunJSBundleEndTime() != -1;
230
+ return contentAppeared != -1 && getRunJSBundleEndTime() != -1;
186
231
  }
187
232
 
188
233
  - (void) contentAppeared
@@ -198,13 +243,13 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
198
243
  {
199
244
  if (!didEmit && hasListeners && [self isReady]) {
200
245
  didEmit = YES;
201
-
246
+
202
247
  NSMutableDictionary<NSString*, NSNumber*> *appStartMeasurements = [[NSMutableDictionary alloc] init];
203
-
248
+
204
249
  [appStartMeasurements setObject:[self correctionOfTimestamp:getRunJSBundleStartTime()] forKey:RunJSBundleStart];
205
250
  [appStartMeasurements setObject:[self correctionOfTimestamp:getRunJSBundleEndTime()] forKey:RunJSBundleEnd];
206
251
  [appStartMeasurements setObject:[NSNumber numberWithLongLong:contentAppeared] forKey:ContentAppeared];
207
-
252
+
208
253
  if (hasListeners) {
209
254
  [self sendEventWithName:EmitAppMeasurementsIdentifier body:appStartMeasurements];
210
255
  }
@@ -238,6 +283,12 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
238
283
  {
239
284
  hasListeners = YES;
240
285
  [self emitMeasurements];
286
+
287
+ [self setupRuntimeConfigurationListenerIfNeeded];
288
+
289
+ if (lastRuntimeConfiguration != nil) {
290
+ [self emitToJS:EmitDynatraceConfiguration body:lastRuntimeConfiguration];
291
+ }
241
292
  }
242
293
 
243
294
  /**
@@ -248,6 +299,39 @@ template<typename T = void> std::enable_if_t<(facebook::react::ReactNativeVersio
248
299
  hasListeners = NO;
249
300
  }
250
301
 
302
+ - (void)setupRuntimeConfigurationListenerIfNeeded
303
+ {
304
+ if (remoteConfigSubscribed) {
305
+ return;
306
+ }
307
+ remoteConfigSubscribed = YES;
308
+ [HybridBridge addConfigurationSubscriber:(id)configurationSubscriber];
309
+ }
310
+
311
+ - (void)emitToJS:(NSString*)event body:(id)body
312
+ {
313
+ if (self.bridge == nil) {
314
+ return;
315
+ }
316
+
317
+ id payload = body == nil ? [NSNull null] : body;
318
+
319
+ dispatch_async(dispatch_get_main_queue(), ^{
320
+ [self.bridge.eventDispatcher sendDeviceEventWithName:event body:payload];
321
+ });
322
+ }
323
+
324
+ - (void)handleRuntimeConfiguration:(NSDictionary<NSString*, id>*)configuration
325
+ {
326
+ lastRuntimeConfiguration = configuration;
327
+
328
+ if (!hasListeners) {
329
+ return;
330
+ }
331
+
332
+ [self emitToJS:EmitDynatraceConfiguration body:configuration];
333
+ }
334
+
251
335
  /**
252
336
  * Constants which are exported to the JS part
253
337
  */
@@ -265,9 +349,9 @@ RCT_EXPORT_METHOD(start:(NSDictionary *) options)
265
349
  if (options == nil) {
266
350
  return;
267
351
  }
268
-
352
+
269
353
  NSMutableDictionary<NSString*, id> *properties = [[NSMutableDictionary alloc] init];
270
-
354
+
271
355
  if (options[@"applicationId"] != NULL) {
272
356
  properties[@"DTXApplicationID"] = options[@"applicationId"];
273
357
  }
@@ -279,11 +363,11 @@ RCT_EXPORT_METHOD(start:(NSDictionary *) options)
279
363
  if (options[@"userOptIn"] != NULL && [[options valueForKey:@"userOptIn"] isEqual: @(YES)]) {
280
364
  properties[@"DTXUserOptIn"] = @YES;
281
365
  }
282
-
366
+
283
367
  if (options[@"reportCrash"] != NULL && [[options valueForKey:@"reportCrash"] isEqual: @(NO)]) {
284
368
  properties[@"DTXCrashReportingEnabled"] = @NO;
285
369
  }
286
-
370
+
287
371
  if (options[@"logLevel"] != NULL && [((NSNumber *) options[@"logLevel"]) intValue] == 0){
288
372
  properties[@"DTXLogLevel"] = @"ALL";
289
373
  }
@@ -309,7 +393,7 @@ RCT_EXPORT_METHOD(enterManualAction:(NSString *)name key:(nonnull NSString *)key
309
393
  if ([self shouldWorkOnIosWithPlatform: platform])
310
394
  {
311
395
  DTXAction *action = [DTXAction enterActionWithName:name];
312
-
396
+
313
397
  if (action)
314
398
  {
315
399
  [actionDict setObject:action forKey:key];
@@ -326,7 +410,7 @@ RCT_EXPORT_METHOD(enterManualActionWithParent:(NSString *)name key:(nonnull NSSt
326
410
  if (parentAction != nil)
327
411
  {
328
412
  DTXAction *childAction = [DTXAction enterActionWithName:name parentAction:parentAction];
329
-
413
+
330
414
  if (childAction)
331
415
  {
332
416
  [actionDict setObject:childAction forKey:key];
@@ -378,11 +462,6 @@ RCT_EXPORT_METHOD(startView: (NSString *) name)
378
462
  [Dynatrace startViewWithName:name];
379
463
  }
380
464
 
381
- RCT_EXPORT_METHOD(stopView)
382
- {
383
- [Dynatrace stopView];
384
- }
385
-
386
465
  RCT_EXPORT_METHOD(reportErrorWithoutStacktrace:(NSString *)errorName errorCode:(nonnull NSNumber *)errorCode platform: (NSString *) platform)
387
466
  {
388
467
  if ([self shouldWorkOnIosWithPlatform: platform])
@@ -406,11 +485,11 @@ RCT_EXPORT_METHOD(reportCrash:(NSString *)errorName errorReason:(NSString *)erro
406
485
  if ([self shouldWorkOnIosWithPlatform: platform])
407
486
  {
408
487
  if(isRealError){
409
- [DTXAction reportExternalCrashForPlatformType:DTXActionPlatformJavaScript crashName:errorName reason:errorReason stacktrace:stacktrace];
488
+ [DTXAction reportExternalCrashForPlatformType:DTXActionPlatformJavaScript crashName:errorName reason:errorReason stacktrace:stacktrace];
410
489
  }else{
411
490
  [DTXAction reportExternalCrashForPlatformType:DTXActionPlatformCustom crashName:errorName reason:errorReason stacktrace:stacktrace];
412
491
  }
413
-
492
+
414
493
  // Always end the session as the iOS agent has no troubles with this behavior
415
494
  [Dynatrace endVisit];
416
495
  }
@@ -488,7 +567,6 @@ RCT_EXPORT_METHOD(startWebRequestTiming:(NSString*) requestTag url:(NSString*) u
488
567
  [timing startWebRequestTiming];
489
568
  }
490
569
  }
491
-
492
570
  }
493
571
 
494
572
  - (void)stopWebRequestTimingHelper:(NSString*) requestTag url:(NSString*)url responseCode:(nonnull NSNumber*) responseCode responseMessage:(NSString*)responseMessage bytesSent:(nonnull NSNumber*)bytesSent bytesReceived:(nonnull NSNumber*)bytesReceived
@@ -590,7 +668,7 @@ RCT_EXPORT_METHOD(getDataCollectionLevel:(NSString *) platform findEventsWithRes
590
668
  if ([self shouldWorkOnIosWithPlatform: platform])
591
669
  {
592
670
  int i = [Dynatrace dataCollectionLevel];
593
-
671
+
594
672
  if(i == DTX_DataCollectionUserBehavior){
595
673
  resolve(DataCollectionUserBehavior);
596
674
  }else if(i == DTX_DataCollectionPerformance){
@@ -633,7 +711,7 @@ RCT_EXPORT_METHOD(getUserPrivacyOptions:(NSString *) platform findEventsWithReso
633
711
  {
634
712
  id<DTXUserPrivacyOptions> privacyConfig = [Dynatrace userPrivacyOptions];
635
713
  NSString * level;
636
-
714
+
637
715
  if(privacyConfig.dataCollectionLevel == DTX_DataCollectionUserBehavior){
638
716
  level = DataCollectionUserBehavior;
639
717
  }else if(privacyConfig.dataCollectionLevel == DTX_DataCollectionPerformance){
@@ -653,7 +731,7 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
653
731
  if ([self shouldWorkOnIosWithPlatform: platform])
654
732
  {
655
733
  id<DTXUserPrivacyOptions> privacyConfig = [Dynatrace userPrivacyOptions];
656
-
734
+
657
735
  if([[userPrivacyOptions valueForKey:@"_dataCollectionLevel"] isEqualToString: DataCollectionPerformance]){
658
736
  privacyConfig.dataCollectionLevel = DTX_DataCollectionPerformance;
659
737
  }else if([[userPrivacyOptions valueForKey:@"_dataCollectionLevel"] isEqualToString: DataCollectionUserBehavior]){
@@ -663,7 +741,7 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
663
741
  } else {
664
742
  // do nothing and keep current value
665
743
  }
666
-
744
+
667
745
  if ([[userPrivacyOptions valueForKey:@"_crashReportingOptedIn"] isEqual: @(YES)]) {
668
746
  privacyConfig.crashReportingOptedIn = YES;
669
747
  } else if ([[userPrivacyOptions valueForKey:@"_crashReportingOptedIn"] isEqual: @(NO)]) {
@@ -678,10 +756,29 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
678
756
  }
679
757
  }
680
758
 
759
+ RCT_EXPORT_METHOD(getCurrentConfiguration:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
760
+ {
761
+ if (lastRuntimeConfiguration != nil) {
762
+ resolve(lastRuntimeConfiguration);
763
+ } else {
764
+ resolve([NSNull null]);
765
+ }
766
+ }
767
+
768
+ RCT_EXPORT_METHOD(startViewInternal:(NSDictionary<NSString*, id>*) fields)
769
+ {
770
+ [HybridBridge startView:fields];
771
+ }
772
+
773
+ RCT_EXPORT_METHOD(stopViewInternal)
774
+ {
775
+ [HybridBridge stopView];
776
+ }
777
+
681
778
  - (void)newAction:(NSString *)name key:(nonnull NSString *)key parentAction:(DTXAction *)parentAction
682
779
  {
683
780
  DTXAction *action = [DTXAction integrateActionWithName:name];
684
-
781
+
685
782
  if (action)
686
783
  {
687
784
  [actionDict setObject:action forKey:key];
@@ -693,7 +790,6 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
693
790
  return [actionDict objectForKey:key];
694
791
  }
695
792
 
696
-
697
793
  + (BOOL)requiresMainQueueSetup
698
794
  {
699
795
  return YES;
@@ -713,4 +809,4 @@ RCT_EXPORT_METHOD(applyUserPrivacyOptions:(NSDictionary *) userPrivacyOptions pl
713
809
  }
714
810
  #endif
715
811
 
716
- @end
812
+ @end
@@ -338,22 +338,19 @@ exports.Dynatrace = {
338
338
  },
339
339
  addEventModifier: (eventModifier) => Dynatrace_1.Dynatrace.addEventModifier(eventModifier),
340
340
  removeEventModifier: (eventModifier) => Dynatrace_1.Dynatrace.removeEventModifier(eventModifier),
341
- sendEvent: (properties) => {
342
- Dynatrace_1.Dynatrace.sendEvent(properties);
343
- },
344
341
  startView: (name) => {
345
342
  Dynatrace_1.Dynatrace.startView(name);
346
343
  },
347
- stopView: () => {
348
- Dynatrace_1.Dynatrace.stopView();
344
+ sendEvent: (customEvent) => {
345
+ Dynatrace_1.Dynatrace.sendEvent(customEvent);
349
346
  },
350
- sendSessionPropertyEvent: (properties) => {
351
- Dynatrace_1.Dynatrace.sendSessionPropertyEvent(properties);
347
+ sendSessionPropertyEvent: (sessionPropertyEventData) => {
348
+ Dynatrace_1.Dynatrace.sendSessionPropertyEvent(sessionPropertyEventData);
352
349
  },
353
- sendExceptionEvent: (error, fields) => {
354
- Dynatrace_1.Dynatrace.sendExceptionEvent(error, fields);
350
+ sendExceptionEvent: (exceptionEvent) => {
351
+ Dynatrace_1.Dynatrace.sendExceptionEvent(exceptionEvent);
355
352
  },
356
- sendHttpRequestEvent(httpRequestEventBuilder) {
357
- Dynatrace_1.Dynatrace.sendHttpRequestEvent(httpRequestEventBuilder);
353
+ sendHttpRequestEvent: (httpRequestEvent) => {
354
+ Dynatrace_1.Dynatrace.sendHttpRequestEvent(httpRequestEvent);
358
355
  },
359
356
  };
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConfigurationHandler = void 0;
4
+ const RuntimeConfigurationObserver_1 = require("../../next/configuration/RuntimeConfigurationObserver");
4
5
  const LogLevel_1 = require("../logging/LogLevel");
5
6
  let _configuration;
6
7
  exports.ConfigurationHandler = {
@@ -14,6 +15,8 @@ exports.ConfigurationHandler = {
14
15
  _configuration.logLevel === LogLevel_1.LogLevel.Debug,
15
16
  isLifecycleUpdateEnabled: () => _configuration.lifecycleUpdate,
16
17
  isActionNamePrivacyEnabled: () => _configuration.actionNamePrivacy,
18
+ isGrailEnabled: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()['3rd_gen_enabled'],
19
+ isRuntimeConfigurationInitiated: () => RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated(),
17
20
  getBundleName: () => _configuration.bundleName,
18
21
  getBundleVersion: () => _configuration.bundleVersion,
19
22
  };
@@ -7,24 +7,41 @@ const EventCreator_1 = require("./events/EventCreator");
7
7
  const EventPipeline_1 = require("./events/EventPipeline");
8
8
  const EventTimestamp_1 = require("./events/EventTimestamp");
9
9
  const EventModifierUtil_1 = require("./events/modifier/EventModifierUtil");
10
- const SendEventValidation_1 = require("./events/modifier/SendEventValidation");
11
10
  const TimestampProvider_1 = require("./provider/TimestampProvider");
11
+ const EventData_1 = require("./events/EventData");
12
+ const SessionPropertyEventData_1 = require("./events/SessionPropertyEventData");
13
+ const ExceptionEventData_1 = require("./events/ExceptionEventData");
14
+ const HttpRequestEventData_1 = require("./events/HttpRequestEventData");
15
+ const DynatraceArgValidators_1 = require("./DynatraceArgValidators");
12
16
  class DynatraceImpl {
13
17
  constructor(timestampProvider) {
14
18
  this.timestampProvider = timestampProvider;
15
19
  this.logger = new ConsoleLogger_1.ConsoleLogger('Dynatrace');
16
20
  }
17
21
  addEventModifier(eventModifier) {
22
+ if (!(0, DynatraceArgValidators_1.isEventModifier)(eventModifier)) {
23
+ this.logger.info('addEventModifier(eventModifier): eventModifier is not of type IEventModifier');
24
+ return {
25
+ modifyEvent: (event) => event,
26
+ };
27
+ }
18
28
  this.logger.debug('addEventModifier()');
19
29
  return EventPipeline_1.EventPipeline.addEventModifier(eventModifier);
20
30
  }
21
31
  removeEventModifier(eventModifier) {
32
+ if (!(0, DynatraceArgValidators_1.isEventModifier)(eventModifier)) {
33
+ this.logger.info('removeEventModifier(eventModifier): eventModifier is not of type IEventModifier');
34
+ return false;
35
+ }
22
36
  this.logger.debug('removeEventModifier()');
23
37
  return EventPipeline_1.EventPipeline.removeEventModifier(eventModifier);
24
38
  }
25
39
  startView(name) {
40
+ if (typeof name !== 'string') {
41
+ this.logger.info(`startView(name): Name must be a string!`);
42
+ return;
43
+ }
26
44
  this.logger.debug(`startView(${name})`);
27
- EventPipeline_1.EventPipeline.generateViewData(name);
28
45
  if (name != null && name.length > 0) {
29
46
  DynatraceBridge_1.DynatraceNative.startView(name);
30
47
  }
@@ -32,11 +49,6 @@ class DynatraceImpl {
32
49
  this.logger.debug(`startView(${name}): Name can't be used. Either empty or null!`);
33
50
  }
34
51
  }
35
- stopView() {
36
- this.logger.debug('stopView()');
37
- EventPipeline_1.EventPipeline.releaseViewData();
38
- DynatraceBridge_1.DynatraceNative.stopView();
39
- }
40
52
  reportCrash(crash, isApiReported, isFatal = true) {
41
53
  this.logger.debug(`reportCrash(${JSON.stringify(crash)}, ${isFatal})`);
42
54
  const eventTimestamp = new EventTimestamp_1.EventTimestamp(this.timestampProvider);
@@ -67,42 +79,47 @@ class DynatraceImpl {
67
79
  }
68
80
  EventPipeline_1.EventPipeline.insertEvent(event);
69
81
  }
70
- sendExceptionEvent(error, fields) {
71
- this.logger.debug(`sendExceptionEvent(${JSON.stringify(error)}, ${JSON.stringify(fields)})`);
72
- const event = Object.assign({}, (0, EventCreator_1.createErrorEvent)(error.name, error.message, error.stack));
73
- let eventValidated = null;
74
- if (fields) {
75
- eventValidated = Object.assign({}, SendEventValidation_1.SendEventValidation.modifyEvent(fields));
76
- }
77
- eventValidated = Object.assign(Object.assign({}, event), eventValidated);
78
- (0, EventModifierUtil_1.addIsApiReported)(eventValidated);
79
- EventPipeline_1.EventPipeline.insertEvent(eventValidated);
82
+ sendExceptionEvent(exceptionEventData) {
83
+ if (!(exceptionEventData instanceof ExceptionEventData_1.default)) {
84
+ this.logger.info('sendExceptionEvent(exceptionEventData): exceptionEventData is not of type ExceptionEventData');
85
+ return;
86
+ }
87
+ this.logger.debug('sendExceptionEvent(exceptionEventData)');
88
+ const eventValidated = exceptionEventData.toJSON();
89
+ if (eventValidated !== null) {
90
+ EventPipeline_1.EventPipeline.insertEvent(eventValidated);
91
+ }
80
92
  }
81
- sendEvent(properties) {
82
- this.logger.debug(`sendEvent(${JSON.stringify(properties)})`);
83
- const eventValidated = SendEventValidation_1.SendEventValidation.modifyEvent(properties);
93
+ sendEvent(eventData) {
94
+ if (!(eventData instanceof EventData_1.default)) {
95
+ this.logger.info('sendEvent(eventData): eventData is not of type EventData');
96
+ return;
97
+ }
98
+ this.logger.debug('sendEvent(eventData)');
99
+ const eventValidated = eventData.toJSON();
84
100
  if (eventValidated !== null) {
85
- (0, EventModifierUtil_1.flagEventProperties)(eventValidated);
86
- (0, EventModifierUtil_1.addIsApiReported)(eventValidated);
87
101
  EventPipeline_1.EventPipeline.insertEvent(eventValidated);
88
102
  }
89
103
  }
90
- sendSessionPropertyEvent(properties) {
91
- this.logger.debug(`sendSessionPropertyEvent(${JSON.stringify(properties)})`);
92
- const eventValidated = SendEventValidation_1.SendSessionPropertyEventValidation.modifyEvent(properties);
104
+ sendSessionPropertyEvent(sessionPropertyEventData) {
105
+ if (!(sessionPropertyEventData instanceof SessionPropertyEventData_1.default)) {
106
+ this.logger.info('sendSessionPropertyEvent(SessionPropertyEventData): sessionPropertyEventData is not of type SessionPropertyEventData');
107
+ return;
108
+ }
109
+ this.logger.debug('sendSessionPropertyEvent(SessionPropertyEventData)');
110
+ const eventValidated = sessionPropertyEventData.toJSON();
93
111
  if (eventValidated !== null) {
94
- if ((0, EventModifierUtil_1.containSessionProperties)(eventValidated)) {
95
- eventValidated["characteristics.has_session_properties"] = true;
96
- }
97
- (0, EventModifierUtil_1.addIsApiReported)(eventValidated);
98
112
  EventPipeline_1.EventPipeline.insertEvent(eventValidated);
99
113
  }
100
114
  }
101
- sendHttpRequestEvent(httpRequestEventBuilder) {
102
- const sanitizedEvent = httpRequestEventBuilder.build();
103
- this.logger.debug(`sendHttpRequestEvent(${JSON.stringify(sanitizedEvent)})`);
115
+ sendHttpRequestEvent(httpRequestEvent) {
116
+ if (!(httpRequestEvent instanceof HttpRequestEventData_1.default)) {
117
+ this.logger.info('sendHttpRequestEvent(HttpRequestEventData): httpRequestEvent is not of type HttpRequestEventData');
118
+ return;
119
+ }
120
+ this.logger.debug('sendHttpRequestEvent(HttpRequestEventData)');
121
+ const sanitizedEvent = httpRequestEvent.toJSON();
104
122
  if (sanitizedEvent !== null) {
105
- (0, EventModifierUtil_1.flagEventProperties)(sanitizedEvent);
106
123
  EventPipeline_1.EventPipeline.insertEvent(sanitizedEvent);
107
124
  }
108
125
  }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isEventModifier = void 0;
4
+ function isEventModifier(eventModifier) {
5
+ return (typeof eventModifier === 'object' &&
6
+ eventModifier !== null &&
7
+ 'modifyEvent' in eventModifier &&
8
+ typeof eventModifier.modifyEvent === 'function');
9
+ }
10
+ exports.isEventModifier = isEventModifier;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addListenerOnce = exports.createEmitterNativeOnly = exports.createEmitterRuntimeConfig = void 0;
4
+ const react_native_1 = require("react-native");
5
+ const DynatraceBridge_1 = require("../core/DynatraceBridge");
6
+ const isEmptyObject = (value) => {
7
+ if (value == null) {
8
+ return true;
9
+ }
10
+ if (typeof value !== 'object') {
11
+ return false;
12
+ }
13
+ return Object.keys(value).length === 0;
14
+ };
15
+ const createEmitterRuntimeConfig = () => {
16
+ if (react_native_1.Platform.OS === 'ios' && isEmptyObject(DynatraceBridge_1.DynatraceNative || {})) {
17
+ return null;
18
+ }
19
+ const iosModule = react_native_1.NativeModules.DynatraceBridge;
20
+ const nativeEmitterModule = react_native_1.Platform.OS === 'android' ? DynatraceBridge_1.DynatraceNative : iosModule;
21
+ return new react_native_1.NativeEventEmitter(nativeEmitterModule);
22
+ };
23
+ exports.createEmitterRuntimeConfig = createEmitterRuntimeConfig;
24
+ const createEmitterNativeOnly = () => new react_native_1.NativeEventEmitter(DynatraceBridge_1.DynatraceNative);
25
+ exports.createEmitterNativeOnly = createEmitterNativeOnly;
26
+ const addListenerOnce = (emitter, current, eventName, handler) => {
27
+ if (current != null) {
28
+ return current;
29
+ }
30
+ if (emitter == null) {
31
+ return null;
32
+ }
33
+ return emitter.addListener(eventName, handler);
34
+ };
35
+ exports.addListenerOnce = addListenerOnce;
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AppStartObserver = void 0;
4
- const react_native_1 = require("react-native");
5
4
  const EventCreator_1 = require("../events/EventCreator");
6
5
  const ConsoleLogger_1 = require("../../core/logging/ConsoleLogger");
7
- const DynatraceBridge_1 = require("../../core/DynatraceBridge");
8
6
  const EventPipeline_1 = require("../events/EventPipeline");
7
+ const DynatraceEventBus_1 = require("../DynatraceEventBus");
9
8
  class AppStartObserverImpl {
10
9
  constructor() {
11
10
  this.EMIT_APP_START = 'dynatraceAppStartMeasurements';
@@ -15,7 +14,7 @@ class AppStartObserverImpl {
15
14
  call() {
16
15
  }
17
16
  setupNativeEventEmitter() {
18
- const emitter = new react_native_1.NativeEventEmitter(DynatraceBridge_1.DynatraceNative);
17
+ const emitter = (0, DynatraceEventBus_1.createEmitterNativeOnly)();
19
18
  emitter.addListener(this.EMIT_APP_START, (data) => {
20
19
  this.logger.debug(`emitter(${JSON.stringify(data)}})`);
21
20
  const appStartEvent = (0, EventCreator_1.createAppStartEvent)(data);
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateDefaultConfiguration = void 0;
4
+ const generateDefaultConfiguration = () => ({
5
+ '3rd_gen_enabled': true,
6
+ });
7
+ exports.generateDefaultConfiguration = generateDefaultConfiguration;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RuntimeConfigurationObserver = void 0;
4
+ const DynatraceBridge_1 = require("../../core/DynatraceBridge");
5
+ const DynatraceEventBus_1 = require("../DynatraceEventBus");
6
+ const INativeRuntimeConfiguration_1 = require("./INativeRuntimeConfiguration");
7
+ class RuntimeConfigurationObserverImpl {
8
+ constructor() {
9
+ this.EMIT_CONFIGURATION = 'dynatraceConfiguration';
10
+ this.runtimeConfiguration = (0, INativeRuntimeConfiguration_1.generateDefaultConfiguration)();
11
+ this.observerIsInitiated = false;
12
+ this.subscription = null;
13
+ this.setupNativeEventEmitter();
14
+ }
15
+ getCurrentRuntimeConfiguration() {
16
+ return this.runtimeConfiguration;
17
+ }
18
+ isInitiated() {
19
+ return this.observerIsInitiated;
20
+ }
21
+ setupNativeEventEmitter() {
22
+ const emitter = (0, DynatraceEventBus_1.createEmitterRuntimeConfig)();
23
+ this.subscription = (0, DynatraceEventBus_1.addListenerOnce)(emitter, this.subscription, this.EMIT_CONFIGURATION, (data) => {
24
+ this.runtimeConfiguration = data;
25
+ this.observerIsInitiated = true;
26
+ });
27
+ if (typeof DynatraceBridge_1.DynatraceNative.getCurrentConfiguration === 'function') {
28
+ Promise.resolve(DynatraceBridge_1.DynatraceNative.getCurrentConfiguration())
29
+ .then((data) => {
30
+ if (data) {
31
+ this.runtimeConfiguration = data;
32
+ this.observerIsInitiated = true;
33
+ }
34
+ })
35
+ .catch(() => {
36
+ });
37
+ }
38
+ }
39
+ }
40
+ exports.RuntimeConfigurationObserver = new RuntimeConfigurationObserverImpl();
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.includeIfTrue = exports.includeIfDefined = void 0;
4
+ const includeIfDefined = (key, value) => (value !== undefined ? { [key]: value } : {});
5
+ exports.includeIfDefined = includeIfDefined;
6
+ const includeIfTrue = (key, value) => value === true ? { [key]: value } : {};
7
+ exports.includeIfTrue = includeIfTrue;