@dynatrace/react-native-plugin 2.329.1 → 2.333.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +102 -8
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +7 -1
  4. package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.kt +1 -0
  5. package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +1 -0
  6. package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +2 -1
  7. package/files/plugin.gradle +1 -1
  8. package/instrumentation/DynatraceInstrumentation.js +1 -1
  9. package/instrumentation/jsx/CreateElement.js +106 -6
  10. package/instrumentation/jsx/JsxDevRuntime.js +2 -6
  11. package/instrumentation/jsx/JsxRuntime.js +2 -6
  12. package/instrumentation/libs/withOnPressMonitoring.js +49 -3
  13. package/ios/DynatraceRNBridge.mm +8 -1
  14. package/lib/core/Application.js +2 -0
  15. package/lib/core/Dynatrace.js +2 -1
  16. package/lib/core/UserPrivacyOptions.js +8 -1
  17. package/lib/core/configuration/ConfigurationHandler.js +21 -0
  18. package/lib/features/ui-interaction/Config.js +36 -0
  19. package/lib/features/ui-interaction/IUserInteractionEvent.js +16 -0
  20. package/lib/features/ui-interaction/Plugin.js +945 -0
  21. package/lib/features/ui-interaction/RootDetection.js +51 -0
  22. package/lib/features/ui-interaction/RootWrapper.js +236 -0
  23. package/lib/features/ui-interaction/Run.js +34 -0
  24. package/lib/features/ui-interaction/Runtime.js +1494 -0
  25. package/lib/features/ui-interaction/Types.js +75 -0
  26. package/lib/next/Dynatrace.js +35 -0
  27. package/lib/next/DynatraceArgValidators.js +10 -0
  28. package/lib/next/configuration/INativeRuntimeConfiguration.js +1 -0
  29. package/lib/next/configuration/RuntimeConfigurationObserver.js +47 -12
  30. package/lib/next/events/EventPipeline.js +9 -0
  31. package/lib/next/events/HttpRequestEventData.js +22 -20
  32. package/lib/next/events/modifier/ModifyEventValidation.js +2 -4
  33. package/lib/next/events/spec/EventSpecContstants.js +2 -2
  34. package/package.json +21 -11
  35. package/react-native-dynatrace.podspec +1 -1
  36. package/scripts/Config.js +1 -0
  37. package/src/lib/core/interface/NativeDynatraceBridge.ts +1 -0
  38. package/types.d.ts +46 -32
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Literals = exports.IdName = exports.AttrName = exports.PressKey = exports.DangerousWrapDeny = exports.StopMemberProp = exports.TabBase = exports.StopMemberBase = exports.StopId = void 0;
4
+ var StopId;
5
+ (function (StopId) {
6
+ StopId["React"] = "React";
7
+ StopId["Fragment"] = "Fragment";
8
+ StopId["Segment"] = "Segment";
9
+ StopId["AnalyticsRoot"] = "AnalyticsRoot";
10
+ StopId["PathPrefix"] = "PathPrefix";
11
+ StopId["NavigationTraceInner"] = "NavigationTraceInner";
12
+ StopId["TabButton"] = "TabButton";
13
+ StopId["NavigationContainer"] = "NavigationContainer";
14
+ })(StopId = exports.StopId || (exports.StopId = {}));
15
+ var StopMemberBase;
16
+ (function (StopMemberBase) {
17
+ StopMemberBase["Stack"] = "Stack";
18
+ StopMemberBase["NativeStack"] = "NativeStack";
19
+ StopMemberBase["MaterialBottomTab"] = "MaterialBottomTab";
20
+ StopMemberBase["MaterialTopTab"] = "MaterialTopTab";
21
+ StopMemberBase["Drawer"] = "Drawer";
22
+ })(StopMemberBase = exports.StopMemberBase || (exports.StopMemberBase = {}));
23
+ var TabBase;
24
+ (function (TabBase) {
25
+ TabBase["Tabs"] = "Tabs";
26
+ TabBase["Tab"] = "Tab";
27
+ TabBase["BottomTab"] = "BottomTab";
28
+ TabBase["MaterialBottomTab"] = "MaterialBottomTab";
29
+ TabBase["MaterialTopTab"] = "MaterialTopTab";
30
+ })(TabBase = exports.TabBase || (exports.TabBase = {}));
31
+ var StopMemberProp;
32
+ (function (StopMemberProp) {
33
+ StopMemberProp["Screen"] = "Screen";
34
+ StopMemberProp["Group"] = "Group";
35
+ })(StopMemberProp = exports.StopMemberProp || (exports.StopMemberProp = {}));
36
+ var DangerousWrapDeny;
37
+ (function (DangerousWrapDeny) {
38
+ DangerousWrapDeny["KeyboardAwareScrollView"] = "KeyboardAwareScrollView";
39
+ DangerousWrapDeny["SectionListWithKeyboardAwareScrollView"] = "SectionListWithKeyboardAwareScrollView";
40
+ })(DangerousWrapDeny = exports.DangerousWrapDeny || (exports.DangerousWrapDeny = {}));
41
+ var PressKey;
42
+ (function (PressKey) {
43
+ PressKey["onPress"] = "onPress";
44
+ PressKey["onLongPress"] = "onLongPress";
45
+ PressKey["onPressIn"] = "onPressIn";
46
+ PressKey["onPressOut"] = "onPressOut";
47
+ PressKey["onTap"] = "onTap";
48
+ PressKey["onClick"] = "onClick";
49
+ })(PressKey = exports.PressKey || (exports.PressKey = {}));
50
+ var AttrName;
51
+ (function (AttrName) {
52
+ AttrName["Options"] = "options";
53
+ AttrName["TabBarButton"] = "tabBarButton";
54
+ AttrName["DtUIMask"] = "dtMask";
55
+ AttrName["Key"] = "key";
56
+ AttrName["Name"] = "name";
57
+ })(AttrName = exports.AttrName || (exports.AttrName = {}));
58
+ var IdName;
59
+ (function (IdName) {
60
+ IdName["DtPrefix"] = "__DT_PREFIX";
61
+ IdName["DtEmit"] = "__DT_emit";
62
+ })(IdName = exports.IdName || (exports.IdName = {}));
63
+ exports.Literals = {
64
+ ReactFragmentFQN: 'React.Fragment',
65
+ NavigatorProp: 'Navigator',
66
+ PluginName: 'dt-user-interaction',
67
+ LogTag: '[dt] instrumented:',
68
+ RawHandlerTag: '[DT raw] handler',
69
+ KeySuffixPrefix: '~dt@',
70
+ DefaultRuntimeImport: '@dynatrace/react-native-plugin/lib/features/ui-interaction/Runtime',
71
+ DefaultArtifactsDir: 'node_modules/@dynatrace/react-native-plugin/build/ui_instrumented',
72
+ DefaultSegmentName: 'Segment',
73
+ DefaultTabButtonName: 'TabButton',
74
+ DefaultRootName: 'AnalyticsRoot',
75
+ };
@@ -8,20 +8,39 @@ const EventPipeline_1 = require("./events/EventPipeline");
8
8
  const EventTimestamp_1 = require("./events/EventTimestamp");
9
9
  const EventModifierUtil_1 = require("./events/modifier/EventModifierUtil");
10
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");
11
16
  class DynatraceImpl {
12
17
  constructor(timestampProvider) {
13
18
  this.timestampProvider = timestampProvider;
14
19
  this.logger = new ConsoleLogger_1.ConsoleLogger('Dynatrace');
15
20
  }
16
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
+ }
17
28
  this.logger.debug('addEventModifier()');
18
29
  return EventPipeline_1.EventPipeline.addEventModifier(eventModifier);
19
30
  }
20
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
+ }
21
36
  this.logger.debug('removeEventModifier()');
22
37
  return EventPipeline_1.EventPipeline.removeEventModifier(eventModifier);
23
38
  }
24
39
  startView(name) {
40
+ if (typeof name !== 'string') {
41
+ this.logger.info('startView(name): Name must be a string!');
42
+ return;
43
+ }
25
44
  this.logger.debug(`startView(${name})`);
26
45
  if (name != null && name.length > 0) {
27
46
  DynatraceBridge_1.DynatraceNative.startView(name);
@@ -61,6 +80,10 @@ class DynatraceImpl {
61
80
  EventPipeline_1.EventPipeline.insertEvent(event);
62
81
  }
63
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
+ }
64
87
  this.logger.debug('sendExceptionEvent(exceptionEventData)');
65
88
  const eventValidated = exceptionEventData.toJSON();
66
89
  if (eventValidated !== null) {
@@ -68,6 +91,10 @@ class DynatraceImpl {
68
91
  }
69
92
  }
70
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
+ }
71
98
  this.logger.debug('sendEvent(eventData)');
72
99
  const eventValidated = eventData.toJSON();
73
100
  if (eventValidated !== null) {
@@ -75,6 +102,10 @@ class DynatraceImpl {
75
102
  }
76
103
  }
77
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
+ }
78
109
  this.logger.debug('sendSessionPropertyEvent(SessionPropertyEventData)');
79
110
  const eventValidated = sessionPropertyEventData.toJSON();
80
111
  if (eventValidated !== null) {
@@ -82,6 +113,10 @@ class DynatraceImpl {
82
113
  }
83
114
  }
84
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
+ }
85
120
  this.logger.debug('sendHttpRequestEvent(HttpRequestEventData)');
86
121
  const sanitizedEvent = httpRequestEvent.toJSON();
87
122
  if (sanitizedEvent !== null) {
@@ -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;
@@ -3,5 +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,
6
7
  });
7
8
  exports.generateDefaultConfiguration = generateDefaultConfiguration;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RuntimeConfigurationObserver = void 0;
4
+ const react_native_1 = require("react-native");
4
5
  const DynatraceBridge_1 = require("../../core/DynatraceBridge");
5
- const DynatraceEventBus_1 = require("../DynatraceEventBus");
6
6
  const INativeRuntimeConfiguration_1 = require("./INativeRuntimeConfiguration");
7
7
  class RuntimeConfigurationObserverImpl {
8
8
  constructor() {
@@ -12,25 +12,60 @@ class RuntimeConfigurationObserverImpl {
12
12
  this.subscription = null;
13
13
  this.setupNativeEventEmitter();
14
14
  }
15
+ call() {
16
+ }
15
17
  getCurrentRuntimeConfiguration() {
16
18
  return this.runtimeConfiguration;
17
19
  }
18
20
  isInitiated() {
19
21
  return this.observerIsInitiated;
20
22
  }
23
+ updateRuntimeConfiguration(data) {
24
+ if (!data || typeof data !== 'object') {
25
+ return;
26
+ }
27
+ const payload = data;
28
+ const thirdGenEnabled = typeof payload['3rd_gen_enabled'] === 'boolean'
29
+ ? payload['3rd_gen_enabled']
30
+ : undefined;
31
+ const touchInteractionEnabled = typeof payload.touch_interaction_enabled === 'boolean'
32
+ ? payload.touch_interaction_enabled
33
+ : undefined;
34
+ const normalized = Object.assign(Object.assign({}, (typeof thirdGenEnabled === 'boolean'
35
+ ? { '3rd_gen_enabled': thirdGenEnabled }
36
+ : {})), (typeof touchInteractionEnabled === 'boolean'
37
+ ? { touch_interaction_enabled: touchInteractionEnabled }
38
+ : {}));
39
+ this.runtimeConfiguration = Object.assign(Object.assign({}, (0, INativeRuntimeConfiguration_1.generateDefaultConfiguration)()), normalized);
40
+ this.observerIsInitiated = true;
41
+ }
42
+ resolveBridgeModule() {
43
+ const dynatraceModule = DynatraceBridge_1.DynatraceNative;
44
+ const hasDynatraceBridgeAPI = !!dynatraceModule &&
45
+ (typeof dynatraceModule.addListener === 'function' ||
46
+ typeof dynatraceModule.getCurrentConfiguration === 'function');
47
+ if (hasDynatraceBridgeAPI) {
48
+ return dynatraceModule;
49
+ }
50
+ return react_native_1.NativeModules.DynatraceBridge;
51
+ }
21
52
  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())
53
+ const bridgeModule = this.resolveBridgeModule();
54
+ if (!bridgeModule) {
55
+ return;
56
+ }
57
+ const iosModule = react_native_1.NativeModules.DynatraceBridge;
58
+ const nativeEmitterModule = react_native_1.Platform.OS === 'ios' ? iosModule || bridgeModule : bridgeModule;
59
+ const emitter = new react_native_1.NativeEventEmitter(nativeEmitterModule);
60
+ if (this.subscription == null) {
61
+ this.subscription = emitter.addListener(this.EMIT_CONFIGURATION, (data) => {
62
+ this.updateRuntimeConfiguration(data);
63
+ });
64
+ }
65
+ if (typeof bridgeModule.getCurrentConfiguration === 'function') {
66
+ Promise.resolve(bridgeModule.getCurrentConfiguration())
29
67
  .then((data) => {
30
- if (data) {
31
- this.runtimeConfiguration = data;
32
- this.observerIsInitiated = true;
33
- }
68
+ this.updateRuntimeConfiguration(data);
34
69
  })
35
70
  .catch(() => {
36
71
  });
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventPipeline = void 0;
4
4
  const DynatraceBridge_1 = require("../../core/DynatraceBridge");
5
5
  const ConsoleLogger_1 = require("../../core/logging/ConsoleLogger");
6
+ const ConfigurationHandler_1 = require("../../core/configuration/ConfigurationHandler");
6
7
  const BaseDataEventModifier_1 = require("./modifier/BaseDataEventModifier");
7
8
  const ValueRestrictionModifier_1 = require("./modifier/ValueRestrictionModifier");
8
9
  const ModifyEventValidation_1 = require("./modifier/ModifyEventValidation");
@@ -24,6 +25,14 @@ class EventPipelineImpl {
24
25
  ];
25
26
  }
26
27
  insertEvent(event) {
28
+ if (!ConfigurationHandler_1.ConfigurationHandler.isRuntimeConfigurationInitiated()) {
29
+ this.logger.debug('isRuntimeConfigurationInitiated is not enabled! App start event will be discarded!');
30
+ return;
31
+ }
32
+ if (!ConfigurationHandler_1.ConfigurationHandler.isGrailEnabled()) {
33
+ this.logger.debug('RUM on Grail is not enabled! App start event will be discarded!');
34
+ return;
35
+ }
27
36
  this.logger.debug(`insertEvent(${JSON.stringify(event)})`);
28
37
  let isDiscarded = false;
29
38
  for (const modifier of this.getEventModifierChain()) {
@@ -12,7 +12,6 @@ class HttpRequestEventData {
12
12
  this.requestMethod = requestMethod;
13
13
  this.duration = 0;
14
14
  this.rawEventProperties = {};
15
- this.traceContextHint = "api_unused";
16
15
  this.hasDroppedProperties = false;
17
16
  this.triedToOverwriteDuration = false;
18
17
  this.requestMethod =
@@ -45,7 +44,6 @@ class HttpRequestEventData {
45
44
  }
46
45
  withTraceparentHeader(traceparentHeader) {
47
46
  this.traceparentHeader = traceparentHeader;
48
- this.traceContextHint = "api_set";
49
47
  return this;
50
48
  }
51
49
  addEventProperty(key, value) {
@@ -57,23 +55,26 @@ class HttpRequestEventData {
57
55
  logger.debug('toJSON(): Dropped invalid event');
58
56
  return null;
59
57
  }
60
- this.sanitizeDuration();
61
- this.sanitizeStatusCode();
62
- this.sanitizeBytesReceived();
63
- this.sanitizeBytesSent();
58
+ const sanitizedDuration = this.sanitizeDuration();
59
+ const sanitizedStatusCode = this.sanitizeStatusCode();
60
+ const sanitizedBytesReceived = this.sanitizeBytesReceived();
61
+ const sanitizedBytesSent = this.sanitizeBytesSent();
64
62
  const parsedTraceparentHeader = this.traceparentHeader &&
65
63
  this.parseTraceparent(this.traceparentHeader);
66
- if (!!this.traceparentHeader && !parsedTraceparentHeader) {
67
- this.traceContextHint = "invalid";
68
- }
64
+ const traceContextHint = !this.traceparentHeader
65
+ ? "api_unused"
66
+ : parsedTraceparentHeader
67
+ ? "api_set"
68
+ : "invalid";
69
69
  const hasFailedRequest = this.isStatusCodeError() || !!this.error;
70
70
  const sanitizedEventProperties = SendEventValidation_1.SendEventValidation.modifyEvent(this.rawEventProperties);
71
71
  (0, EventModifierUtil_1.flagEventProperties)(sanitizedEventProperties);
72
- return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, sanitizedEventProperties), { ["url.full"]: this.url, ["network.protocol.name"]: 'http', ["http.request.method"]: this.requestMethod, ["request.trace_context_hint"]: this.traceContextHint, ["duration"]: this.duration, ["start_time"]: TimestampProvider_1.defaultTimestampProvider.getCurrentTimestamp() - this.duration }), (this.triedToOverwriteDuration && {
72
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, sanitizedEventProperties), { ["url.full"]: this.url, ["network.protocol.name"]: 'http', ["http.request.method"]: this.requestMethod, ["request.trace_context_hint"]: traceContextHint, ["duration"]: sanitizedDuration, ["start_time"]: TimestampProvider_1.defaultTimestampProvider.getCurrentTimestamp() -
73
+ sanitizedDuration }), (this.triedToOverwriteDuration && {
73
74
  ["dt.support.api.overridden_fields"]: [
74
75
  'duration',
75
76
  ],
76
- })), (0, EventBuilderUtil_1.includeIfDefined)("http.response.status_code", this.statusCode)), (0, EventBuilderUtil_1.includeIfDefined)("http.response.reason_phrase", this.reasonPhrase)), (0, EventBuilderUtil_1.includeIfDefined)("request.bytes_sent", this.bytesSent)), (0, EventBuilderUtil_1.includeIfDefined)("request.bytes_received", this.bytesReceived)), { ["characteristics.has_request"]: true, ["characteristics.is_api_reported"]: true }), (0, EventBuilderUtil_1.includeIfTrue)("characteristics.has_failed_request", hasFailedRequest)), (0, EventBuilderUtil_1.includeIfTrue)("characteristics.has_error", hasFailedRequest)), (this.error !== undefined && Object.assign({ ["characteristics.has_exception"]: true, ["exception.type"]: this.error.name, ["exception.message"]: this.error.message }, (0, EventBuilderUtil_1.includeIfDefined)("exception.stack_trace", this.error.stack)))), (parsedTraceparentHeader && {
77
+ })), (0, EventBuilderUtil_1.includeIfDefined)("http.response.status_code", sanitizedStatusCode)), (0, EventBuilderUtil_1.includeIfDefined)("http.response.reason_phrase", this.reasonPhrase)), (0, EventBuilderUtil_1.includeIfDefined)("request.bytes_sent", sanitizedBytesSent)), (0, EventBuilderUtil_1.includeIfDefined)("request.bytes_received", sanitizedBytesReceived)), { ["characteristics.has_request"]: true, ["characteristics.is_api_reported"]: true }), (0, EventBuilderUtil_1.includeIfTrue)("characteristics.has_failed_request", hasFailedRequest)), (0, EventBuilderUtil_1.includeIfTrue)("characteristics.has_error", hasFailedRequest)), (this.error !== undefined && Object.assign({ ["characteristics.has_exception"]: true, ["exception.type"]: this.error.name, ["exception.message"]: this.error.message }, (0, EventBuilderUtil_1.includeIfDefined)("exception.stack_trace", this.error.stack)))), (parsedTraceparentHeader && {
77
78
  ["trace.id"]: parsedTraceparentHeader.traceId,
78
79
  ["span.id"]: parsedTraceparentHeader.spanId,
79
80
  })), (0, EventBuilderUtil_1.includeIfTrue)("dt.support.api.has_dropped_properties", this.hasDroppedProperties));
@@ -103,35 +104,36 @@ class HttpRequestEventData {
103
104
  }
104
105
  }
105
106
  sanitizeStatusCode() {
106
- if (this.statusCode === undefined && this.error === undefined) {
107
- this.statusCode = 0;
108
- }
109
- if (this.statusCode && this.statusCode < 0) {
110
- logger.debug('HttpRequestEventData: overriding invalid Status Code with 0');
111
- this.statusCode = 0;
107
+ if (this.statusCode !== undefined && this.statusCode < 0) {
108
+ logger.debug('HttpRequestEventData: dropping invalid Status Code');
112
109
  this.hasDroppedProperties = true;
110
+ return undefined;
113
111
  }
112
+ return this.statusCode;
114
113
  }
115
114
  sanitizeDuration() {
116
115
  if (!Number.isFinite(this.duration) || this.duration < 0) {
117
116
  logger.debug('HttpRequestEventData: overriding invalid Duration with 0');
118
- this.duration = 0;
119
117
  this.hasDroppedProperties = true;
118
+ return 0;
120
119
  }
120
+ return this.duration;
121
121
  }
122
122
  sanitizeBytesSent() {
123
123
  if (this.bytesSent && this.bytesSent < 0) {
124
124
  logger.debug(`HttpRequestEventData: dropping invalid value for Bytes Sent: ${this.bytesSent}`);
125
- this.bytesSent = undefined;
126
125
  this.hasDroppedProperties = true;
126
+ return undefined;
127
127
  }
128
+ return this.bytesSent;
128
129
  }
129
130
  sanitizeBytesReceived() {
130
131
  if (this.bytesReceived && this.bytesReceived < 0) {
131
132
  logger.debug(`HttpRequestEventData: dropping invalid value for Bytes Received: ${this.bytesReceived}`);
132
- this.bytesReceived = undefined;
133
133
  this.hasDroppedProperties = true;
134
+ return undefined;
134
135
  }
136
+ return this.bytesReceived;
135
137
  }
136
138
  isStatusCodeError() {
137
139
  return (this.statusCode && 400 <= this.statusCode && this.statusCode <= 599);
@@ -29,7 +29,7 @@ class ModifyEventValidation {
29
29
  for (const modifier of this.customEventModifierChain) {
30
30
  try {
31
31
  const eventRv = modifier.modifyEvent(event);
32
- if (eventRv === null) {
32
+ if (!eventRv) {
33
33
  isDiscarded = true;
34
34
  break;
35
35
  }
@@ -154,9 +154,7 @@ class ModifyEventValidation {
154
154
  if (!isNewlyAdded) {
155
155
  validEntries.push([prop, originalValue]);
156
156
  }
157
- else {
158
- droppedProperties = true;
159
- }
157
+ droppedProperties = true;
160
158
  continue;
161
159
  }
162
160
  if (!isNewlyAdded && !overriddenKeys.includes(prop)) {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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_EVENT_WHITELIST_FIELDS = exports.SEND_SESSION_PROPERTY_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 = void 0;
4
- const SPECIFICATION_VERSION = '0.23';
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_EVENT_WHITELIST_FIELDS = exports.SEND_SESSION_PROPERTY_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';
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynatrace/react-native-plugin",
3
- "version": "2.329.1",
3
+ "version": "2.333.1",
4
4
  "description": "This plugin gives you the ability to use the Dynatrace Mobile agent in your react native application.",
5
5
  "main": "index.js",
6
6
  "types": "types.d.ts",
@@ -52,7 +52,7 @@
52
52
  "jscodeshift": "^17.3.0",
53
53
  "plist": "^3.1.0",
54
54
  "proxy-polyfill": "^0.3.2",
55
- "semver": "^7.7.3"
55
+ "semver": "^7.7.4"
56
56
  },
57
57
  "homepage": "https://www.dynatrace.com/",
58
58
  "peerDependencies": {
@@ -67,7 +67,12 @@
67
67
  "ast-types": "npm:ast-types-x"
68
68
  },
69
69
  "ast-types": "npm:ast-types-x",
70
- "flow-parser": "0.160"
70
+ "flow-parser": "0.160",
71
+ "fast-xml-parser@>=4.3.6 <=5.3.5": "5.3.6",
72
+ "@isaacs/brace-expansion": ">=5.0.1",
73
+ "minimatch@>=9.0.0 <9.0.6": ">=9.0.6",
74
+ "minimatch@>=10.0.0 <10.2.2": ">=10.2.2",
75
+ "minimatch@>=3.0.0 <3.1.3": ">=3.1.3"
71
76
  },
72
77
  "devDependencies": {
73
78
  "@babel/plugin-transform-class-properties": "^7.27.1",
@@ -79,33 +84,37 @@
79
84
  "@react-native/babel-preset": "^0.80.1",
80
85
  "@react-navigation/core": "^7.13.0",
81
86
  "@react-navigation/drawer": "^7.7.2",
82
- "@testing-library/react-native": "^13.2.0",
87
+ "@testing-library/react-native": "^13.3.3",
83
88
  "@types/jest": "^30.0.0",
84
89
  "@types/jscodeshift": "^17.3.0",
90
+ "@types/micromatch": "^4.0.10",
85
91
  "@types/node": "^18.19.123",
86
92
  "@types/plist": "^3.0.5",
87
93
  "@types/react": "^19.1.8",
88
94
  "@types/semver": "^7.7.0",
89
95
  "@types/shelljs": "^0.8.17",
90
96
  "@types/uglify-js": "^3.17.5",
91
- "@typescript-eslint/eslint-plugin": "^8.22.0",
92
- "@typescript-eslint/parser": "^8.22.0",
97
+ "@typescript-eslint/eslint-plugin": "^8.56.0",
98
+ "@typescript-eslint/parser": "^8.56.0",
93
99
  "compressing": "^1.10.3",
94
100
  "diff": "^8.0.2",
95
101
  "eslint": "^9.29.0",
96
102
  "eslint-config-prettier": "^8.5.0",
97
- "eslint-plugin-import": "^2.31.0",
103
+ "eslint-plugin-import": "^2.32.0",
98
104
  "eslint-plugin-jsdoc": "^50.6.3",
99
105
  "eslint-plugin-prefer-arrow": "^1.2.3",
100
- "eslint-plugin-unicorn": "^42.0.0",
106
+ "eslint-plugin-unicorn": "^63.0.0",
101
107
  "husky": "^9.1.6",
102
- "jest": "^30.0.4",
103
- "jest-each": "^30.0.2",
108
+ "jest": "^30.2.0",
109
+ "jest-each": "^30.2.0",
104
110
  "jest-junit": "^16.0.0",
105
- "jest-mock": "^30.0.2",
111
+ "jest-mock": "^30.2.0",
106
112
  "npm-check-updates": "^18.0.1",
107
113
  "prettier": "^2.6.1",
114
+ "react": "19.2.3",
115
+ "react-native": "^0.84.0",
108
116
  "react-native-gesture-handler": "^2.28.0",
117
+ "react-test-renderer": "19.2.3",
109
118
  "rollup": "^4.52.4",
110
119
  "rollup-plugin-dts": "^6.2.3",
111
120
  "shelljs": "^0.10.0",
@@ -166,6 +175,7 @@
166
175
  "lib/next/events/modifier/*.js",
167
176
  "lib/next/events/spec/*.js",
168
177
  "lib/next/provider/*.js",
178
+ "lib/features/ui-interaction/*.js",
169
179
  "src/lib/core/interface/NativeDynatraceBridge.ts",
170
180
  "types.d.ts"
171
181
  ],
@@ -111,7 +111,7 @@ Pod::Spec.new do |s|
111
111
  #
112
112
 
113
113
  s.dependency "React"
114
- s.dependency 'Dynatrace', '~> 8.329.1.1017'
114
+ s.dependency 'Dynatrace', '~> 8.333.1.1005'
115
115
 
116
116
  # Allows for better compatibility for older and newer versions
117
117
  if defined?(install_modules_dependencies)
package/scripts/Config.js CHANGED
@@ -34,6 +34,7 @@ exports.defaultConfig = {
34
34
  navigation: {
35
35
  enabled: true,
36
36
  },
37
+ userInteraction: false,
37
38
  sourcemap: {
38
39
  enabled: true,
39
40
  androidSourcemapLocation: 'app/build/generated/sourcemaps/react/release/index.android.bundle.map',
@@ -177,6 +177,7 @@ export interface Spec extends TurboModule {
177
177
  export type NativeUserPrivacyOptions = {
178
178
  dataCollectionLevel: string;
179
179
  crashReportingOptedIn: boolean;
180
+ screenRecordOptedIn?: boolean;
180
181
  };
181
182
 
182
183
  export default TurboModuleRegistry.getEnforcing<Spec>('DynatraceBridge');