@dynatrace/react-native-plugin 2.341.1 → 2.343.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +37 -9
  2. package/android/build.gradle +11 -2
  3. package/android/src/main/java/com/dynatrace/android/agent/DynatraceAppStartModule.kt +9 -31
  4. package/android/src/main/java/com/dynatrace/android/agent/DynatraceConfigurationModule.kt +1 -0
  5. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +41 -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.gradle +1 -1
  12. package/instrumentation/libs/UserInteraction.js +1 -1
  13. package/ios/DTXScreenshotSelfMonitor.h +29 -0
  14. package/ios/DTXScreenshotSelfMonitor.mm +213 -0
  15. package/ios/DTXScreenshotSelfMonitorSwizzler.h +15 -0
  16. package/ios/DTXScreenshotSelfMonitorSwizzler.mm +68 -0
  17. package/ios/DynatraceRNBridge.h +6 -0
  18. package/ios/DynatraceRNBridge.mm +53 -0
  19. package/lib/core/Dynatrace.js +2 -0
  20. package/lib/core/logging/LogMessages.js +42 -0
  21. package/lib/features/ui-interaction/IUserInteractionEvent.js +1 -1
  22. package/lib/features/ui-interaction/Runtime.js +1 -1
  23. package/lib/next/Dynatrace.js +26 -1
  24. package/lib/next/events/EventPipeline.js +48 -31
  25. package/lib/next/events/HttpRequestEventData.js +1 -1
  26. package/lib/next/events/spec/EventSpecContstants.js +1 -1
  27. package/lib/next/userAction/NullUserAction.js +15 -0
  28. package/lib/next/userAction/UserAction.js +2 -0
  29. package/lib/next/userAction/UserActionConfiguration.js +10 -0
  30. package/lib/next/userAction/UserActionImpl.js +70 -0
  31. package/lib/next/util/TraceContextUtils.js +8 -14
  32. package/lib/next/util/Utils.js +13 -0
  33. package/package.json +7 -3
  34. package/public.js +3 -1
  35. package/react-native-dynatrace.podspec +10 -3
  36. package/scripts/Config.js +17 -3
  37. package/scripts/core/InstrumentCall.js +12 -4
  38. package/src/lib/core/interface/NativeDynatraceBridge.ts +34 -1
  39. package/types.d.ts +29 -2
@@ -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,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NullUserAction = void 0;
4
+ class NullUserAction {
5
+ getCustomName() {
6
+ return '';
7
+ }
8
+ isCompleteAutomatically() {
9
+ return false;
10
+ }
11
+ setCompleteAutomatically(enabled) { }
12
+ complete() { }
13
+ addEventProperty(key, value) { }
14
+ }
15
+ exports.NullUserAction = NullUserAction;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserActionConfiguration = void 0;
4
+ class UserActionConfiguration {
5
+ constructor(customName, completeAutomatically = false) {
6
+ this.customName = customName;
7
+ this.completeAutomatically = completeAutomatically;
8
+ }
9
+ }
10
+ exports.UserActionConfiguration = UserActionConfiguration;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserActionImpl = void 0;
4
+ const DynatraceBridge_1 = require("../../core/DynatraceBridge");
5
+ const ConsoleLogger_1 = require("../../core/logging/ConsoleLogger");
6
+ const LogMessages_1 = require("../../core/logging/LogMessages");
7
+ const Utils_1 = require("../util/Utils");
8
+ const randomActionId = () => (0, Utils_1.randomHex)(16);
9
+ class UserActionImpl {
10
+ constructor(configuration) {
11
+ this.completed = false;
12
+ this.logger = new ConsoleLogger_1.ConsoleLogger('UserAction');
13
+ this.customName = configuration.customName;
14
+ this.completeAutomatically = configuration.completeAutomatically;
15
+ this.actionId = randomActionId();
16
+ DynatraceBridge_1.DynatraceNative.createUserAction(this.actionId, this.customName, this.completeAutomatically, null);
17
+ this.logger.debug(LogMessages_1.LogMessage.USER_ACTION_CREATED, {
18
+ customName: this.customName,
19
+ completeAutomatically: this.completeAutomatically,
20
+ actionId: this.actionId,
21
+ });
22
+ }
23
+ getCustomName() {
24
+ return this.customName;
25
+ }
26
+ isCompleteAutomatically() {
27
+ return this.completeAutomatically;
28
+ }
29
+ setCompleteAutomatically(enabled) {
30
+ if (this.completed) {
31
+ return;
32
+ }
33
+ this.logger.debug(LogMessages_1.LogMessage.USER_ACTION_SET_COMPLETE_AUTOMATICALLY, {
34
+ enabled,
35
+ customName: this.customName,
36
+ });
37
+ this.completeAutomatically = enabled;
38
+ DynatraceBridge_1.DynatraceNative.setCompleteUserActionAutomatically(this.actionId, enabled);
39
+ }
40
+ complete() {
41
+ if (this.completed) {
42
+ return;
43
+ }
44
+ this.completed = true;
45
+ this.logger.debug(LogMessages_1.LogMessage.USER_ACTION_COMPLETE, {
46
+ customName: this.customName,
47
+ });
48
+ DynatraceBridge_1.DynatraceNative.completeUserAction(this.actionId);
49
+ }
50
+ addEventProperty(key, value) {
51
+ if (this.completed) {
52
+ return;
53
+ }
54
+ this.logger.debug(LogMessages_1.LogMessage.USER_ACTION_ADD_EVENT_PROPERTY, {
55
+ key,
56
+ value: String(value),
57
+ customName: this.customName,
58
+ });
59
+ if (typeof value === 'string') {
60
+ DynatraceBridge_1.DynatraceNative.addEventStringPropertyToUserAction(this.actionId, key, value);
61
+ }
62
+ else if (typeof value === 'number') {
63
+ DynatraceBridge_1.DynatraceNative.addEventDoublePropertyToUserAction(this.actionId, key, value);
64
+ }
65
+ else {
66
+ DynatraceBridge_1.DynatraceNative.addEventBooleanPropertyToUserAction(this.actionId, key, value);
67
+ }
68
+ }
69
+ }
70
+ exports.UserActionImpl = UserActionImpl;
@@ -4,6 +4,7 @@ exports.trimTraceState = exports.generateTracestate = exports.generateTraceparen
4
4
  const ConsoleLogger_1 = require("../../core/logging/ConsoleLogger");
5
5
  const LogMessages_1 = require("../../core/logging/LogMessages");
6
6
  const ConfigurationHandler_1 = require("../../core/configuration/ConfigurationHandler");
7
+ const Utils_1 = require("./Utils");
7
8
  const logger = new ConsoleLogger_1.ConsoleLogger('TraceContextUtils');
8
9
  const parseTraceparent = (traceparent) => {
9
10
  const traceparentRegex = /^[0-9a-f]{2}-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/i;
@@ -26,27 +27,18 @@ const parseTraceparent = (traceparent) => {
26
27
  exports.parseTraceparent = parseTraceparent;
27
28
  const allZeros = (str) => /^0*$/.test(str);
28
29
  const generateTraceparentHeader = () => {
29
- let traceId = randomHex(32);
30
+ let traceId = (0, Utils_1.randomHex)(32);
30
31
  if (/^0+$/.test(traceId)) {
31
32
  traceId = '1' + traceId.slice(1);
32
33
  }
33
- let spanId = randomHex(16);
34
+ let spanId = (0, Utils_1.randomHex)(16);
34
35
  if (/^0+$/.test(spanId)) {
35
36
  spanId = '1' + spanId.slice(1);
36
37
  }
37
38
  return `00-${traceId}-${spanId}-01`;
38
39
  };
39
40
  exports.generateTraceparentHeader = generateTraceparentHeader;
40
- const randomHex = (length) => {
41
- let hex = '';
42
- while (hex.length < length) {
43
- hex += Math.floor(Math.random() * 0xffffffff)
44
- .toString(16)
45
- .padStart(8, '0');
46
- }
47
- return hex.slice(0, length);
48
- };
49
- const generateTracestate = (parentId, existingTracestate) => {
41
+ const generateTracestate = (parentId, traceparentFromDynatrace, existingTracestate) => {
50
42
  const instanceId = ConfigurationHandler_1.ConfigurationHandler.getInstanceId();
51
43
  const sessionId = ConfigurationHandler_1.ConfigurationHandler.getSessionId();
52
44
  const applicationId = ConfigurationHandler_1.ConfigurationHandler.getApplicationId();
@@ -55,10 +47,12 @@ const generateTracestate = (parentId, existingTracestate) => {
55
47
  !(instanceId && sessionId && applicationId && tracestateKeyPrefix)) {
56
48
  return undefined;
57
49
  }
58
- const version = 1;
59
50
  const originMarker = 'dtr';
51
+ const version = 2;
60
52
  const capture = 0;
61
- let tracestate = `${tracestateKeyPrefix}@${originMarker}=${version};${parentId};${capture};${formatApplicationId(applicationId)};${instanceId};${sessionId}`;
53
+ const formattedApplicationId = formatApplicationId(applicationId);
54
+ const tpSource = traceparentFromDynatrace ? 1 : 2;
55
+ let tracestate = `${tracestateKeyPrefix}@${originMarker}=${version};${parentId};${capture};${formattedApplicationId};${instanceId};${sessionId};${tpSource}`;
62
56
  if (typeof existingTracestate === 'string' && existingTracestate.trim()) {
63
57
  tracestate += `,${existingTracestate}`;
64
58
  }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.randomHex = void 0;
4
+ const randomHex = (length) => {
5
+ let hex = '';
6
+ while (hex.length < length) {
7
+ hex += Math.floor(Math.random() * 0xffffffff)
8
+ .toString(16)
9
+ .padStart(8, '0');
10
+ }
11
+ return hex.slice(0, length);
12
+ };
13
+ exports.randomHex = randomHex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynatrace/react-native-plugin",
3
- "version": "2.341.1",
3
+ "version": "2.343.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",
@@ -50,7 +50,7 @@
50
50
  "license": "SEE LICENSE IN LICENSE.md",
51
51
  "dependencies": {
52
52
  "@babel/runtime": "^8.0.0",
53
- "jscodeshift": "^17.3.0",
53
+ "jscodeshift": "^17.4.0",
54
54
  "plist": "^3.1.0",
55
55
  "proxy-polyfill": "^0.3.2",
56
56
  "semver": "^7.8.5"
@@ -69,7 +69,10 @@
69
69
  "ast-types": "npm:ast-types-x",
70
70
  "flow-parser": "0.160",
71
71
  "tmp": ">=0.2.6",
72
- "ws": "^7.5.11"
72
+ "ws": "^7.5.11",
73
+ "@istanbuljs/load-nyc-config": {
74
+ "js-yaml": "^3.15.0"
75
+ }
73
76
  },
74
77
  "devDependencies": {
75
78
  "@babel/plugin-transform-class-properties": "^7.27.1",
@@ -175,6 +178,7 @@
175
178
  "lib/next/events/spec/*.js",
176
179
  "lib/next/util/*.js",
177
180
  "lib/next/provider/*.js",
181
+ "lib/next/userAction/*.js",
178
182
  "lib/features/ui-interaction/*.js",
179
183
  "src/lib/core/interface/NativeDynatraceBridge.ts",
180
184
  "types.d.ts"
package/public.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExceptionEventData = exports.SessionPropertyEventData = exports.EventData = exports.HttpRequestEventData = exports.DynatraceWebRequestTiming = exports.UserPrivacyOptions = exports.LogLevel = exports.Platform = exports.ConfigurationBuilder = exports.ManualStartupConfiguration = exports.DataCollectionLevel = exports.Dynatrace = void 0;
3
+ exports.UserActionConfiguration = exports.ExceptionEventData = exports.SessionPropertyEventData = exports.EventData = exports.HttpRequestEventData = exports.DynatraceWebRequestTiming = exports.UserPrivacyOptions = exports.LogLevel = exports.Platform = exports.ConfigurationBuilder = exports.ManualStartupConfiguration = exports.DataCollectionLevel = exports.Dynatrace = void 0;
4
4
  var Dynatrace_1 = require("./lib/core/Dynatrace");
5
5
  Object.defineProperty(exports, "Dynatrace", { enumerable: true, get: function () { return Dynatrace_1.Dynatrace; } });
6
6
  var DataCollectionLevel_1 = require("./lib/core/model/DataCollectionLevel");
@@ -25,4 +25,6 @@ var SessionPropertyEventData_1 = require("./lib/next/events/SessionPropertyEvent
25
25
  Object.defineProperty(exports, "SessionPropertyEventData", { enumerable: true, get: function () { return SessionPropertyEventData_1.default; } });
26
26
  var ExceptionEventData_1 = require("./lib/next/events/ExceptionEventData");
27
27
  Object.defineProperty(exports, "ExceptionEventData", { enumerable: true, get: function () { return ExceptionEventData_1.default; } });
28
+ var UserActionConfiguration_1 = require("./lib/next/userAction/UserActionConfiguration");
29
+ Object.defineProperty(exports, "UserActionConfiguration", { enumerable: true, get: function () { return UserActionConfiguration_1.UserActionConfiguration; } });
28
30
  require("./react-augmentation");
@@ -12,10 +12,17 @@ Pod::Spec.new do |s|
12
12
  s.version = package['version']
13
13
  s.summary = package['description']
14
14
  s.homepage = package['homepage']
15
- s.ios.deployment_target = "12.0"
16
- s.tvos.deployment_target = "12.0"
15
+ s.ios.deployment_target = "15.0"
16
+ s.tvos.deployment_target = "15.0"
17
17
  s.source_files = ["ios/*.{h,mm}"]
18
18
 
19
+ # Build-time off-switch for screenshot self-monitoring (replay metrics), passed at `pod install`:
20
+ # DYNATRACE_REPLAY_METRICS_ENABLED=0 pod install
21
+ # Defaults to enabled; when set to 0 the monitor is compiled out (DynatraceRNBridge.mm #if guard).
22
+ if ENV['DYNATRACE_REPLAY_METRICS_ENABLED'] == '0'
23
+ s.prefix_header_contents = '#define DTX_REPLAY_METRICS_ENABLED 0'
24
+ end
25
+
19
26
  s.license = { :type => 'Commercial', :text => 'https://github.com/Dynatrace/dem-license/blob/main/LICENSE.md'}
20
27
 
21
28
  # --- License ----------------------------------------------------------- #
@@ -111,7 +118,7 @@ Pod::Spec.new do |s|
111
118
  #
112
119
 
113
120
  s.dependency "React"
114
- s.dependency 'Dynatrace', '~> 8.341.1.1010'
121
+ s.dependency 'Dynatrace', '~> 8.343.1.1007'
115
122
 
116
123
  # Allows for better compatibility for older and newer versions
117
124
  if defined?(install_modules_dependencies)
package/scripts/Config.js CHANGED
@@ -12,6 +12,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.checkConfiguration = exports.addDefaultConfigs = exports.readConfig = exports.readConfigDefault = exports.defaultConfig = exports.ERROR_CONFIG_NOT_AVAILABLE = void 0;
14
14
  const path = require("node:path");
15
+ const node_fs_1 = require("node:fs");
15
16
  const FileOperationHelper_1 = require("./FileOperationHelper");
16
17
  const Logger_1 = require("./Logger");
17
18
  const PathsConstants_1 = require("./PathsConstants");
@@ -45,9 +46,19 @@ exports.defaultConfig = {
45
46
  };
46
47
  const readConfigDefault = () => {
47
48
  const customArguments = (0, CustomArgumentUtil_1.readCustomArguments)();
48
- const configPath = customArguments.isCustomConfigurationPathSet()
49
- ? path.resolve(PathsConstants_1.default.getApplicationPath(), customArguments.getCustomConfigurationPath())
50
- : PathsConstants_1.default.getConfigFilePath();
49
+ let configPath;
50
+ if (customArguments.isCustomConfigurationPathSet()) {
51
+ configPath = path.resolve(PathsConstants_1.default.getApplicationPath(), customArguments.getCustomConfigurationPath());
52
+ }
53
+ else {
54
+ const envConfig = process.env.DYNATRACE_CONFIG;
55
+ if (envConfig === undefined || envConfig.trim() === '') {
56
+ configPath = PathsConstants_1.default.getConfigFilePath();
57
+ }
58
+ else {
59
+ configPath = path.resolve(PathsConstants_1.default.getApplicationPath(), envConfig.trim());
60
+ }
61
+ }
51
62
  return (0, exports.readConfig)(configPath);
52
63
  };
53
64
  exports.readConfigDefault = readConfigDefault;
@@ -87,6 +98,9 @@ const logConfigCreatedMessage = () => {
87
98
  Logger_1.default.logMessageSync(message, Logger_1.default.INFO);
88
99
  };
89
100
  const patchMalformedConfiguration = (pathToDynatraceConfig) => {
101
+ if (!(0, node_fs_1.existsSync)(pathToDynatraceConfig)) {
102
+ return;
103
+ }
90
104
  const configContent = FileOperationHelper_1.default.readTextFromFileSync(pathToDynatraceConfig);
91
105
  if (configContent.indexOf('\u200B') !== -1) {
92
106
  FileOperationHelper_1.default.writeTextToFileSync(pathToDynatraceConfig, configContent.split('\u200B').join(''));
@@ -20,6 +20,10 @@ const logHelpMessage = () => {
20
20
 
21
21
  Options:
22
22
  --help Show this help message and exit.
23
+ --reset Clear any previously-persisted custom config path and
24
+ revert the Metro/Babel transformer to the default
25
+ dynatrace.config.js lookup. Use this if you previously
26
+ ran with config="..." and want to go back to the default.
23
27
  config="/custom/path/to/dynatrace.config.js"
24
28
  Specify a custom path to the Dynatrace configuration file.
25
29
  Default: ${PathsConstants_1.default.getConfigFilePath()}
@@ -38,14 +42,13 @@ const logHelpMessage = () => {
38
42
  npx instrumentDynatrace config="/custom/path/to/dynatrace.config.js"
39
43
  npx instrumentDynatrace gradle="/custom/path/to/build.gradle"
40
44
  npx instrumentDynatrace plist="/custom/path/to/Info.plist"
45
+ npx instrumentDynatrace --reset
41
46
  `, Logger_1.default.INFO);
42
47
  };
43
48
  const persistCustomArguments = (argv) => {
44
- if (argv.isEmpty()) {
45
- (0, CustomArgumentUtil_1.clearCustomArguments)();
46
- return;
49
+ if (!argv.isEmpty()) {
50
+ (0, CustomArgumentUtil_1.writeCustomArguments)(argv);
47
51
  }
48
- (0, CustomArgumentUtil_1.writeCustomArguments)(argv);
49
52
  };
50
53
  const resolveInstrumentationPaths = (argv) => {
51
54
  let pathToConfig = PathsConstants_1.default.getConfigFilePath();
@@ -140,6 +143,11 @@ const instrumentCommand = () => {
140
143
  logHelpMessage();
141
144
  return;
142
145
  }
146
+ if (commandArgs.includes('--reset')) {
147
+ (0, CustomArgumentUtil_1.clearCustomArguments)();
148
+ Logger_1.default.logMessageSync('✅ Custom config path cleared. Metro/Babel transformer will use dynatrace.config.js.', Logger_1.default.INFO);
149
+ return;
150
+ }
143
151
  Logger_1.default.logMessageSync('⏳ Starting instrumentation of React Native application ..', Logger_1.default.INFO);
144
152
  Logger_1.default.withPrefix({ info: ' ℹ️ ', warning: ' ⚠️ ' }, () => (0, InstrumentUtil_1.showVersionOfPlugin)());
145
153
  const argv = (0, CustomArgumentUtil_1.parseCommandLine)(commandArgs.slice(2));
@@ -54,7 +54,6 @@ export interface Spec extends TurboModule {
54
54
  platform?: string,
55
55
  ): void;
56
56
 
57
- // eslint-disable-next-line max-len
58
57
  reportCrash(
59
58
  errorName: string,
60
59
  reason: string,
@@ -123,6 +122,40 @@ export interface Spec extends TurboModule {
123
122
  appStartKeys: string[],
124
123
  ): void;
125
124
 
125
+ setAutomaticUserActionDetection(enabled: boolean): void;
126
+
127
+ createUserAction(
128
+ actionId: string,
129
+ name: string,
130
+ completeAutomatically: boolean,
131
+ properties?: UnsafeObject | null,
132
+ ): void;
133
+
134
+ addEventStringPropertyToUserAction(
135
+ actionId: string,
136
+ key: string,
137
+ value: string,
138
+ ): void;
139
+
140
+ addEventDoublePropertyToUserAction(
141
+ actionId: string,
142
+ key: string,
143
+ value: number,
144
+ ): void;
145
+
146
+ addEventBooleanPropertyToUserAction(
147
+ actionId: string,
148
+ key: string,
149
+ value: boolean,
150
+ ): void;
151
+
152
+ completeUserAction(actionId: string): void;
153
+
154
+ setCompleteUserActionAutomatically(
155
+ actionId: string,
156
+ enabled: boolean,
157
+ ): void;
158
+
126
159
  setGPSLocation(
127
160
  latitude: number,
128
161
  longitude: number,
package/types.d.ts CHANGED
@@ -1113,6 +1113,20 @@ declare class ExceptionEventData implements IExceptionEventData {
1113
1113
  toJSON(): JSONObject | null;
1114
1114
  }
1115
1115
 
1116
+ interface UserAction {
1117
+ getCustomName(): string;
1118
+ isCompleteAutomatically(): boolean;
1119
+ setCompleteAutomatically(enabled: boolean): void;
1120
+ complete(): void;
1121
+ addEventProperty(key: string, value: string | number | boolean): void;
1122
+ }
1123
+
1124
+ declare class UserActionConfiguration {
1125
+ readonly customName: string;
1126
+ readonly completeAutomatically: boolean;
1127
+ constructor(customName: string, completeAutomatically?: boolean);
1128
+ }
1129
+
1116
1130
  interface IDynatrace$1 {
1117
1131
  /**
1118
1132
  * Adds an event modifier that is executed just before the event is transferred.
@@ -1348,6 +1362,19 @@ interface IDynatrace$1 {
1348
1362
  * ```
1349
1363
  */
1350
1364
  generateTraceContext(traceparent?: TraceparentHeader, tracestate?: string): TraceContext | undefined;
1365
+ /**
1366
+ * Creates a new manual user action.
1367
+ *
1368
+ * @param configuration The user action configuration
1369
+ * @returns A new {@link UserAction} instance
1370
+ */
1371
+ createUserAction(configuration: UserActionConfiguration): UserAction;
1372
+ /**
1373
+ * Enables or disables automatic user action detection.
1374
+ *
1375
+ * @param enabled True to enable, false to disable
1376
+ */
1377
+ setAutomaticUserActionDetection(enabled: boolean): void;
1351
1378
  }
1352
1379
 
1353
1380
  /**
@@ -2504,5 +2531,5 @@ declare module 'react' {
2504
2531
  }
2505
2532
  }
2506
2533
 
2507
- export { ConfigurationBuilder, DataCollectionLevel, Dynatrace, DynatraceWebRequestTiming, EventData, ExceptionEventData, HttpRequestEventData, LogLevel, ManualStartupConfiguration, Platform, SessionPropertyEventData, UserPrivacyOptions };
2508
- export type { DynatraceUserConfiguration, IConfiguration, IDynatraceAction, IDynatraceRootAction, IDynatraceWebRequestTiming, IEventModifier, JSONObject };
2534
+ export { ConfigurationBuilder, DataCollectionLevel, Dynatrace, DynatraceWebRequestTiming, EventData, ExceptionEventData, HttpRequestEventData, LogLevel, ManualStartupConfiguration, Platform, SessionPropertyEventData, UserActionConfiguration, UserPrivacyOptions };
2535
+ export type { DynatraceUserConfiguration,IConfiguration, IDynatraceAction, IDynatraceRootAction, IDynatraceWebRequestTiming, IEventModifier, JSONObject, UserAction };