@dynatrace/react-native-plugin 2.337.3 → 2.341.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 (57) hide show
  1. package/README.md +122 -21
  2. package/android/build.gradle +1 -1
  3. package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +0 -1
  4. package/files/default.config.js +2 -0
  5. package/files/plugin.gradle +1 -1
  6. package/instrumentation/BabelPluginDynatrace.js +1 -1
  7. package/instrumentation/DynatraceInstrumentation.js +1 -1
  8. package/instrumentation/jsx/CreateElement.js +5 -9
  9. package/instrumentation/jsx/ElementHelper.js +5 -6
  10. package/instrumentation/jsx/JsxDevRuntime.js +33 -31
  11. package/instrumentation/jsx/JsxRuntime.js +30 -30
  12. package/instrumentation/jsx/JsxRuntimeHelpers.js +14 -0
  13. package/instrumentation/jsx/components/ClassComponent.js +6 -9
  14. package/instrumentation/jsx/components/ComponentUtil.js +24 -25
  15. package/instrumentation/libs/UserInteraction.js +27 -24
  16. package/instrumentation/libs/react-native/RefreshControl.js +5 -9
  17. package/instrumentation/libs/react-navigation/ReactNavigation.js +7 -4
  18. package/instrumentation/libs/withOnPressMonitoring.js +67 -55
  19. package/lib/core/Application.js +5 -2
  20. package/lib/core/Dynatrace.js +113 -44
  21. package/lib/core/DynatraceAction.js +78 -23
  22. package/lib/core/DynatraceInternal.js +39 -26
  23. package/lib/core/DynatraceRootAction.js +6 -3
  24. package/lib/core/DynatraceWebRequestTiming.js +25 -4
  25. package/lib/core/ErrorHandler.js +46 -19
  26. package/lib/core/NullAction.js +1 -3
  27. package/lib/core/logging/ConsoleLogger.js +17 -6
  28. package/lib/core/logging/LogMessages.js +764 -0
  29. package/lib/core/logging/LogType.js +9 -0
  30. package/lib/core/util/JsonUtils.js +6 -0
  31. package/lib/features/ui-interaction/IUserInteractionEvent.js +1 -1
  32. package/lib/features/ui-interaction/Runtime.js +7 -3
  33. package/lib/features/ui-interaction/TouchMetaResolver.js +4 -3
  34. package/lib/next/Dynatrace.js +42 -22
  35. package/lib/next/appstart/AppStartObserver.js +7 -2
  36. package/lib/next/events/EventPipeline.js +12 -5
  37. package/lib/next/events/EventTimestamp.js +5 -1
  38. package/lib/next/events/ExceptionEventData.js +1 -1
  39. package/lib/next/events/HttpRequestEventData.js +18 -9
  40. package/lib/next/events/interface/HttpRequestEventDataTypes.js +2 -0
  41. package/lib/next/events/modifier/BaseDataEventModifier.js +4 -1
  42. package/lib/next/events/modifier/EventModifierUtil.js +12 -5
  43. package/lib/next/events/modifier/ModifyEventValidation.js +99 -58
  44. package/lib/next/events/modifier/SendEventValidation.js +10 -4
  45. package/lib/next/events/modifier/StringLengthEventModifier.js +4 -1
  46. package/lib/next/events/modifier/ValueRestrictionModifier.js +5 -1
  47. package/lib/next/events/spec/EventSpecContstants.js +6 -2
  48. package/lib/next/util/TraceContextUtils.js +4 -3
  49. package/package.json +7 -5
  50. package/react-native-dynatrace.podspec +1 -1
  51. package/scripts/Config.js +7 -3
  52. package/scripts/DebugFlag.js +20 -0
  53. package/scripts/FileOperationHelper.js +15 -39
  54. package/scripts/Logger.js +2 -3
  55. package/scripts/core/InstrumentCall.js +101 -80
  56. package/scripts/util/CustomArgumentUtil.js +8 -6
  57. package/types.d.ts +159 -8
@@ -1,20 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.instrumentCommand = void 0;
4
- const path_1 = require("path");
4
+ const node_path_1 = require("node:path");
5
5
  const Logger_1 = require("../Logger");
6
6
  const Config_1 = require("../Config");
7
7
  const android = require("../Android");
8
8
  const PathsConstants_1 = require("../PathsConstants");
9
- const nodePath = require("path");
10
9
  const Ios_1 = require("../Ios");
11
10
  const InstrumentUtil_1 = require("../util/InstrumentUtil");
12
11
  const CustomArgumentUtil_1 = require("../util/CustomArgumentUtil");
13
12
  const Platform_1 = require("../api/model/Platform");
14
13
  const SourceMapUtil_1 = require("../util/SourceMapUtil");
15
- const instrumentCommand = () => {
16
- if (process.argv.includes('--help')) {
17
- Logger_1.default.logMessageSync(`
14
+ const platformLogPrefix = { info: ' ℹ️ ', warning: ' ⚠️ ', error: ' ❌ ' };
15
+ const logHelpMessage = () => {
16
+ const iOSDefaultPath = (0, node_path_1.join)(PathsConstants_1.default.getIOSFolder(), '<appName>', 'Info.plist');
17
+ const iOSSupportingDefaultPath = (0, node_path_1.join)(PathsConstants_1.default.getIOSFolder(), '<appName>', 'Supporting', 'Info.plist');
18
+ Logger_1.default.logMessageSync(`
18
19
  Usage: npx instrumentDynatrace [options]
19
20
 
20
21
  Options:
@@ -28,8 +29,8 @@ const instrumentCommand = () => {
28
29
  plist="/custom/path/to/Info.plist"
29
30
  Specify a custom path to the Info.plist file of your ios project.
30
31
  Default: Extracts <appName> from app.json and then tries
31
- ${nodePath.join(PathsConstants_1.default.getIOSFolder(), "<appName>", 'Info.plist')}
32
- and ${nodePath.join(PathsConstants_1.default.getIOSFolder(), "<appName>", "Supporting", "Info.plist")}
32
+ ${iOSDefaultPath}
33
+ and ${iOSSupportingDefaultPath}
33
34
  in that order
34
35
 
35
36
  Examples:
@@ -38,94 +39,114 @@ const instrumentCommand = () => {
38
39
  npx instrumentDynatrace gradle="/custom/path/to/build.gradle"
39
40
  npx instrumentDynatrace plist="/custom/path/to/Info.plist"
40
41
  `, Logger_1.default.INFO);
42
+ };
43
+ const persistCustomArguments = (argv) => {
44
+ if (argv.isEmpty()) {
45
+ (0, CustomArgumentUtil_1.clearCustomArguments)();
41
46
  return;
42
47
  }
43
- Logger_1.default.logMessageSync('⏳ Starting instrumentation of React Native application ..', Logger_1.default.INFO);
44
- Logger_1.default.withPrefix({ info: ' ℹ️ ', warning: ' ⚠️ ' }, () => (0, InstrumentUtil_1.showVersionOfPlugin)());
48
+ (0, CustomArgumentUtil_1.writeCustomArguments)(argv);
49
+ };
50
+ const resolveInstrumentationPaths = (argv) => {
45
51
  let pathToConfig = PathsConstants_1.default.getConfigFilePath();
46
52
  let pathToGradle = PathsConstants_1.default.getAndroidGradleFile(PathsConstants_1.default.getAndroidFolder());
47
53
  let pathToAppGradle = PathsConstants_1.default.getAndroidAppGradleFile(PathsConstants_1.default.getAndroidFolder());
48
- let androidAvailable = true;
49
54
  let pathToPList;
50
- let iosAvailable = true;
51
- const argv = (0, CustomArgumentUtil_1.parseCommandLine)(process.argv.slice(2));
52
- if (argv.isEmpty()) {
53
- (0, CustomArgumentUtil_1.clearCustomArguments)();
54
- }
55
- else {
56
- (0, CustomArgumentUtil_1.writeCustomArguments)(argv);
57
- }
58
55
  if (argv.isCustomConfigurationPathSet()) {
59
56
  pathToConfig = argv.getCustomConfigurationPath();
60
57
  }
61
- Logger_1.default.withPrefix({ info: ' ℹ️ ', warning: ' ⚠️ ', error: ' ❌ ' }, () => {
62
- if (argv.isCustomGradlePathSet()) {
63
- pathToGradle = argv.getCustomGradlePath();
64
- if (!/build\.gradle(\.kts)?$/.test(pathToGradle)) {
65
- throw new Error(`--gradle must point to build.gradle or build.gradle.kts file, got ${pathToGradle}`);
66
- }
67
- const androidFolder = nodePath.dirname(pathToGradle);
68
- pathToAppGradle = PathsConstants_1.default.getAndroidAppGradleFile(androidFolder);
69
- androidAvailable = (0, InstrumentUtil_1.isPlatformAvailable)(pathToGradle, Platform_1.Platform.Android);
70
- }
71
- else {
72
- androidAvailable = (0, InstrumentUtil_1.isPlatformAvailable)(PathsConstants_1.default.getAndroidFolder(), Platform_1.Platform.Android);
73
- }
74
- if (argv.isCustomPlistPathSet()) {
75
- pathToPList = (0, path_1.resolve)(argv.getCustomPlistPath());
76
- iosAvailable = (0, InstrumentUtil_1.isPlatformAvailable)(pathToPList, Platform_1.Platform.IOS);
58
+ if (argv.isCustomGradlePathSet()) {
59
+ pathToGradle = argv.getCustomGradlePath();
60
+ if (!/build\.gradle(\.kts)?$/.test(pathToGradle)) {
61
+ throw new Error(`--gradle must point to build.gradle or build.gradle.kts file, got ${pathToGradle}`);
77
62
  }
78
- else {
79
- iosAvailable = (0, InstrumentUtil_1.isPlatformAvailable)(PathsConstants_1.default.getIOSFolder(), Platform_1.Platform.IOS);
80
- }
81
- });
82
- pathToConfig = (0, path_1.resolve)(pathToConfig);
83
- pathToGradle = (0, path_1.resolve)(pathToGradle);
84
- pathToAppGradle = (0, path_1.resolve)(pathToAppGradle);
85
- if (iosAvailable || androidAvailable) {
86
- try {
87
- Logger_1.default.logMessageSync('⏳ Trying to read configuration file: ' + pathToConfig, Logger_1.default.INFO);
88
- const configAgent = (0, Config_1.readConfig)(pathToConfig);
89
- if (androidAvailable) {
90
- try {
91
- Logger_1.default.logMessageSync('⏳ Starting Android Instrumentation with Dynatrace!', Logger_1.default.INFO);
92
- Logger_1.default.withPrefix({ info: ' ℹ️ ', warning: ' ⚠️ ', error: ' ❌ ' }, () => {
93
- android.instrumentAndroidPlatform(pathToGradle, false);
94
- android.writeGradleConfig(configAgent.android, pathToGradle);
95
- android.ensureRuntimeScriptApplied(pathToAppGradle);
96
- });
97
- Logger_1.default.logMessageSync(' ✅ Finished Android Instrumentation with Dynatrace!', Logger_1.default.INFO);
98
- }
99
- catch (e) {
100
- if (e instanceof Error) {
101
- Logger_1.default.logMessageSync(' ❌ Android Instrumentation failed: ' + e.message, Logger_1.default.ERROR);
102
- }
103
- }
104
- }
105
- if (iosAvailable) {
106
- try {
107
- Logger_1.default.logMessageSync('⏳ Starting iOS Instrumentation with Dynatrace!', Logger_1.default.INFO);
108
- Logger_1.default.withPrefix({ info: ' ℹ️ ', warning: ' ⚠️ ', error: ' ❌ ' }, () => Ios_1.default.modifyPListFile(pathToPList, configAgent.ios, false));
109
- Logger_1.default.logMessageSync(' ✅ Finished iOS Instrumentation with Dynatrace!', Logger_1.default.INFO);
110
- }
111
- catch (e) {
112
- if (e instanceof Error) {
113
- Logger_1.default.logMessageSync(' ❌ iOS Instrumentation failed: ' + e.message, Logger_1.default.ERROR);
114
- }
115
- }
116
- }
117
- (0, SourceMapUtil_1.patchMetroSourceMap)();
118
- Logger_1.default.logMessageSync('🎉 Finished instrumentation of React Native application ..', Logger_1.default.INFO);
63
+ pathToAppGradle = PathsConstants_1.default.getAndroidAppGradleFile((0, node_path_1.dirname)(pathToGradle));
64
+ }
65
+ if (argv.isCustomPlistPathSet()) {
66
+ pathToPList = argv.getCustomPlistPath();
67
+ }
68
+ return {
69
+ pathToConfig: (0, node_path_1.resolve)(pathToConfig),
70
+ pathToGradle: (0, node_path_1.resolve)(pathToGradle),
71
+ pathToAppGradle: (0, node_path_1.resolve)(pathToAppGradle),
72
+ pathToPList: pathToPList ? (0, node_path_1.resolve)(pathToPList) : undefined,
73
+ };
74
+ };
75
+ const detectPlatformAvailability = (argv, paths) => {
76
+ const androidAvailable = argv.isCustomGradlePathSet()
77
+ ? (0, InstrumentUtil_1.isPlatformAvailable)(paths.pathToGradle, Platform_1.Platform.Android)
78
+ : (0, InstrumentUtil_1.isPlatformAvailable)(PathsConstants_1.default.getAndroidFolder(), Platform_1.Platform.Android);
79
+ const iosAvailable = argv.isCustomPlistPathSet()
80
+ ? (0, InstrumentUtil_1.isPlatformAvailable)(paths.pathToPList, Platform_1.Platform.IOS)
81
+ : (0, InstrumentUtil_1.isPlatformAvailable)(PathsConstants_1.default.getIOSFolder(), Platform_1.Platform.IOS);
82
+ return { androidAvailable, iosAvailable };
83
+ };
84
+ const instrumentAndroidIfAvailable = (androidAvailable, pathToGradle, pathToAppGradle, androidConfig) => {
85
+ if (!androidAvailable) {
86
+ return;
87
+ }
88
+ try {
89
+ Logger_1.default.logMessageSync('⏳ Starting Android Instrumentation with Dynatrace!', Logger_1.default.INFO);
90
+ Logger_1.default.withPrefix(platformLogPrefix, () => {
91
+ android.instrumentAndroidPlatform(pathToGradle, false);
92
+ android.writeGradleConfig(androidConfig, pathToGradle);
93
+ android.ensureRuntimeScriptApplied(pathToAppGradle);
94
+ });
95
+ Logger_1.default.logMessageSync(' ✅ Finished Android Instrumentation with Dynatrace!', Logger_1.default.INFO);
96
+ }
97
+ catch (e) {
98
+ if (e instanceof Error) {
99
+ Logger_1.default.logMessageSync(' ❌ Android Instrumentation failed: ' + e.message, Logger_1.default.ERROR);
119
100
  }
120
- catch (e) {
121
- if (e instanceof Error) {
122
- Logger_1.default.logMessageSync('❌ Instrumentation failed: ' + e.message, Logger_1.default.ERROR);
123
- }
101
+ }
102
+ };
103
+ const instrumentIosIfAvailable = (iosAvailable, pathToPList, iosConfig) => {
104
+ if (!iosAvailable) {
105
+ return;
106
+ }
107
+ try {
108
+ Logger_1.default.logMessageSync('⏳ Starting iOS Instrumentation with Dynatrace!', Logger_1.default.INFO);
109
+ Logger_1.default.withPrefix(platformLogPrefix, () => Ios_1.default.modifyPListFile(pathToPList, iosConfig, false));
110
+ Logger_1.default.logMessageSync(' ✅ Finished iOS Instrumentation with Dynatrace!', Logger_1.default.INFO);
111
+ }
112
+ catch (e) {
113
+ if (e instanceof Error) {
114
+ Logger_1.default.logMessageSync(' ❌ iOS Instrumentation failed: ' + e.message, Logger_1.default.ERROR);
124
115
  }
125
116
  }
126
- else {
117
+ };
118
+ const runPlatformInstrumentation = (paths, availability) => {
119
+ if (!availability.iosAvailable && !availability.androidAvailable) {
127
120
  Logger_1.default.logMessageSync('⚠️ Both Android and iOS Folder are not available - Skip instrumentation.', Logger_1.default.WARNING);
121
+ return;
128
122
  }
123
+ try {
124
+ Logger_1.default.logMessageSync('⏳ Trying to read configuration file: ' + paths.pathToConfig, Logger_1.default.INFO);
125
+ const configAgent = (0, Config_1.readConfig)(paths.pathToConfig);
126
+ instrumentAndroidIfAvailable(availability.androidAvailable, paths.pathToGradle, paths.pathToAppGradle, configAgent.android);
127
+ instrumentIosIfAvailable(availability.iosAvailable, paths.pathToPList, configAgent.ios);
128
+ (0, SourceMapUtil_1.patchMetroSourceMap)();
129
+ Logger_1.default.logMessageSync('🎉 Finished instrumentation of React Native application ..', Logger_1.default.INFO);
130
+ }
131
+ catch (e) {
132
+ if (e instanceof Error) {
133
+ Logger_1.default.logMessageSync('❌ Instrumentation failed: ' + e.message, Logger_1.default.ERROR);
134
+ }
135
+ }
136
+ };
137
+ const instrumentCommand = () => {
138
+ const commandArgs = process.argv;
139
+ if (commandArgs.includes('--help')) {
140
+ logHelpMessage();
141
+ return;
142
+ }
143
+ Logger_1.default.logMessageSync('⏳ Starting instrumentation of React Native application ..', Logger_1.default.INFO);
144
+ Logger_1.default.withPrefix({ info: ' ℹ️ ', warning: ' ⚠️ ' }, () => (0, InstrumentUtil_1.showVersionOfPlugin)());
145
+ const argv = (0, CustomArgumentUtil_1.parseCommandLine)(commandArgs.slice(2));
146
+ persistCustomArguments(argv);
147
+ const instrumentationPaths = resolveInstrumentationPaths(argv);
148
+ const availability = Logger_1.default.withPrefix(platformLogPrefix, () => detectPlatformAvailability(argv, instrumentationPaths));
149
+ runPlatformInstrumentation(instrumentationPaths, availability);
129
150
  Logger_1.default.closeLogFile();
130
151
  };
131
152
  exports.instrumentCommand = instrumentCommand;
@@ -10,17 +10,19 @@ exports.PROCESS_CUSTOM_ARGUMENT_NAME = 'dtCustomArguments';
10
10
  const parseCommandLine = (inputArgs) => {
11
11
  const parsedArgs = new CustomArgumentsBuilderImpl_1.CustomArgumentsBuilderImpl();
12
12
  inputArgs.forEach((entry) => {
13
- const parts = entry.split('=');
14
- if (parts.length === 2) {
15
- switch (parts[0]) {
13
+ const eqIndex = entry.indexOf('=');
14
+ if (eqIndex !== -1) {
15
+ const key = entry.slice(0, eqIndex);
16
+ const value = entry.slice(eqIndex + 1);
17
+ switch (key) {
16
18
  case "gradle":
17
- parsedArgs.withGradleArgument(parts[1]);
19
+ parsedArgs.withGradleArgument(value);
18
20
  break;
19
21
  case "config":
20
- parsedArgs.withConfigurationArgument(parts[1]);
22
+ parsedArgs.withConfigurationArgument(value);
21
23
  break;
22
24
  case "plist":
23
- parsedArgs.withPlistArgument(parts[1]);
25
+ parsedArgs.withPlistArgument(value);
24
26
  break;
25
27
  }
26
28
  }
package/types.d.ts CHANGED
@@ -684,17 +684,17 @@ interface IEventModifier {
684
684
  modifyEvent(event: JSONObject): JSONObject | null;
685
685
  }
686
686
 
687
- /**
688
- * Represents the allowed types for event property values.
689
- */
690
- type EventProperty = string | number | boolean;
691
-
692
687
  type TraceparentHeader = `${string}-${string}-${string}-${string}`;
693
688
  interface TraceContext {
694
689
  traceparent: TraceparentHeader;
695
690
  tracestate: string;
696
691
  }
697
692
 
693
+ /**
694
+ * Represents the allowed types for event property values.
695
+ */
696
+ type EventProperty = string | number | boolean;
697
+
698
698
  /**
699
699
  * Base interface for all events.
700
700
  */
@@ -1845,8 +1845,8 @@ declare class ManualStartupConfiguration implements IConfiguration {
1845
1845
  * Builder for manual startup configuration used with `Dynatrace.start()`.
1846
1846
  */
1847
1847
  declare class ConfigurationBuilder {
1848
- private beaconUrl;
1849
- private applicationId;
1848
+ private readonly beaconUrl;
1849
+ private readonly applicationId;
1850
1850
  private reportCrash;
1851
1851
  private errorHandler;
1852
1852
  private reportFatalErrorAsCrash;
@@ -2346,6 +2346,157 @@ declare class DynatraceWebRequestTiming implements IDynatraceWebRequestTiming {
2346
2346
  getRequestTagHeader(): string;
2347
2347
  }
2348
2348
 
2349
+ /**
2350
+ * Configuration for React Native transformer
2351
+ */
2352
+ interface TransformerReactConfiguration {
2353
+ /**
2354
+ * Path to an upstream transformer to use before Dynatrace transformation
2355
+ */
2356
+ upstreamTransformer?: string;
2357
+ }
2358
+ /**
2359
+ * Configuration for React Native instrumentation
2360
+ */
2361
+ interface InstrumentationReactConfiguration {
2362
+ /**
2363
+ * Whether to automatically start the Dynatrace agent (and insert instrumentation for startup)
2364
+ */
2365
+ autoStart: boolean;
2366
+ /**
2367
+ * Enable debug mode for additional console output during instrumentation and runtime
2368
+ */
2369
+ debug: boolean;
2370
+ /**
2371
+ * Unique name for the bundle. Required for multiple bundle setups and sourcemap deobfuscation.
2372
+ */
2373
+ bundleName?: string;
2374
+ /**
2375
+ * Version of the bundle
2376
+ */
2377
+ bundleVersion?: string;
2378
+ /**
2379
+ * Error handler configuration
2380
+ */
2381
+ errorHandler: {
2382
+ /**
2383
+ * Enable the Dynatrace error/crash handler
2384
+ */
2385
+ enabled: boolean;
2386
+ /**
2387
+ * Report fatal/unhandled errors as crashes instead of errors
2388
+ *
2389
+ * @remarks
2390
+ * When false, fatal errors are reported as errors and the current session remains open
2391
+ */
2392
+ reportFatalErrorAsCrash: boolean;
2393
+ };
2394
+ /**
2395
+ * Lifecycle event monitoring configuration
2396
+ */
2397
+ lifecycle: {
2398
+ /**
2399
+ * Include React component update lifecycle events
2400
+ */
2401
+ includeUpdate: boolean;
2402
+ /**
2403
+ * Determine which files should have lifecycle instrumentation
2404
+ *
2405
+ * @param filename - Path to the file being instrumented
2406
+ * @returns true to instrument the file, false to skip
2407
+ *
2408
+ * @defaultValue Returns false for all files
2409
+ */
2410
+ instrument: (filename: string) => boolean;
2411
+ };
2412
+ /**
2413
+ * User input monitoring configuration
2414
+ */
2415
+ input: {
2416
+ /**
2417
+ * Determine which files should have input instrumentation
2418
+ *
2419
+ * @param filename - Path to the file being instrumented
2420
+ * @returns true to instrument the file, false to skip
2421
+ *
2422
+ * @defaultValue Returns true for all files
2423
+ */
2424
+ instrument: (filename: string) => boolean;
2425
+ /**
2426
+ * Enable action name privacy to exclude automatic text/label detection
2427
+ *
2428
+ * @defaultValue false
2429
+ *
2430
+ * @remarks
2431
+ * When true, action names will not include accessibility labels, button titles,
2432
+ * or inner text. Use dtActionName property to set custom names.
2433
+ */
2434
+ actionNamePrivacy?: boolean;
2435
+ actionNamePreference?: ActionNamePreference;
2436
+ actionNameAlgorithm?: ActionNameAlgorithm;
2437
+ };
2438
+ /**
2439
+ * Navigation monitoring configuration
2440
+ */
2441
+ navigation: {
2442
+ /**
2443
+ * Enable automatic navigation tracking
2444
+ */
2445
+ enabled: boolean;
2446
+ };
2447
+ userInteraction: boolean;
2448
+ sourcemap: {
2449
+ enabled: boolean;
2450
+ androidSourcemapLocation: string;
2451
+ };
2452
+ debugBabelPlugin?: boolean;
2453
+ useLegacyJscodeshift?: boolean;
2454
+ }
2455
+ /**
2456
+ * Combined React configuration including transformer and instrumentation settings
2457
+ */
2458
+ type ReactConfiguration = TransformerReactConfiguration & InstrumentationReactConfiguration;
2459
+ /**
2460
+ * Main Dynatrace configuration structure
2461
+ */
2462
+ interface DynatraceConfiguration {
2463
+ /**
2464
+ * React Native specific configuration
2465
+ */
2466
+ react: ReactConfiguration;
2467
+ /**
2468
+ * Android native agent configuration
2469
+ */
2470
+ android?: NativeConfiguration;
2471
+ /**
2472
+ * iOS native agent configuration
2473
+ */
2474
+ ios?: NativeConfiguration;
2475
+ }
2476
+ /**
2477
+ * The type of dynatrace.config.js
2478
+ * All properties are optional since the user can only specify a subset
2479
+ * Will be merged with defaultConfig to ensure all required values are present
2480
+ * When T is a primitive or a function, then DeepPartial<T> resolves to T for better readability
2481
+ */
2482
+ type DeepPartial<T> = T extends Function ? T : T extends object ? {
2483
+ [K in keyof T]?: DeepPartial<T[K]>;
2484
+ } : T;
2485
+ type DynatraceUserConfiguration = DeepPartial<DynatraceConfiguration>;
2486
+ /**
2487
+ * Native platform (Android/iOS) configuration
2488
+ */
2489
+ interface NativeConfiguration {
2490
+ /**
2491
+ * Platform-specific configuration string
2492
+ *
2493
+ * @remarks
2494
+ * For Android: Contains Gradle DSL configuration block
2495
+ * For iOS: Contains plist key-value pairs
2496
+ */
2497
+ config?: string;
2498
+ }
2499
+
2349
2500
  declare module 'react' {
2350
2501
  namespace JSX {
2351
2502
  interface IntrinsicAttributes extends IDynatraceProperties {
@@ -2354,4 +2505,4 @@ declare module 'react' {
2354
2505
  }
2355
2506
 
2356
2507
  export { ConfigurationBuilder, DataCollectionLevel, Dynatrace, DynatraceWebRequestTiming, EventData, ExceptionEventData, HttpRequestEventData, LogLevel, ManualStartupConfiguration, Platform, SessionPropertyEventData, UserPrivacyOptions };
2357
- export type { IConfiguration, IDynatraceAction, IDynatraceRootAction, IDynatraceWebRequestTiming, IEventModifier, JSONObject };
2508
+ export type { DynatraceUserConfiguration, IConfiguration, IDynatraceAction, IDynatraceRootAction, IDynatraceWebRequestTiming, IEventModifier, JSONObject };