@dynatrace/react-native-plugin 2.327.2 → 2.329.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 (52) hide show
  1. package/README.md +414 -163
  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 +14 -32
  21. package/lib/next/DynatraceEventBus.js +35 -0
  22. package/lib/next/appstart/AppStartObserver.js +2 -3
  23. package/lib/next/configuration/INativeRuntimeConfiguration.js +7 -0
  24. package/lib/next/configuration/RuntimeConfigurationObserver.js +40 -0
  25. package/lib/next/events/EventBuilderUtil.js +7 -0
  26. package/lib/next/events/EventData.js +28 -0
  27. package/lib/next/events/EventPipeline.js +5 -11
  28. package/lib/next/events/ExceptionEventData.js +26 -0
  29. package/lib/next/events/{HttpRequestEventBuilder.js → HttpRequestEventData.js} +28 -52
  30. package/lib/next/events/SessionPropertyEventData.js +22 -0
  31. package/lib/next/events/interface/IBaseEvent.js +2 -0
  32. package/lib/next/events/interface/IEventData.js +2 -0
  33. package/lib/next/events/interface/IExceptionEventData.js +2 -0
  34. package/lib/next/events/interface/IHttpRequestEventData.js +2 -0
  35. package/lib/next/events/interface/ISessionPropertyEventData.js +2 -0
  36. package/lib/next/events/modifier/BaseDataEventModifier.js +1 -3
  37. package/lib/next/events/modifier/EventModifierUtil.js +34 -41
  38. package/lib/next/events/modifier/ModifyEventValidation.js +118 -26
  39. package/lib/next/events/modifier/SendEventValidation.js +53 -22
  40. package/lib/next/events/modifier/StringLengthEventModifier.js +53 -0
  41. package/lib/next/events/spec/EventSpecContstants.js +9 -2
  42. package/package.json +8 -3
  43. package/public.js +9 -3
  44. package/react-native-dynatrace.podspec +1 -1
  45. package/scripts/Config.js +6 -2
  46. package/scripts/LineOffsetAnalyze.js +1 -4
  47. package/scripts/core/LineOffsetAnalyzeCall.js +39 -46
  48. package/src/lib/core/interface/NativeDynatraceBridge.ts +6 -2
  49. package/types.d.ts +388 -158
  50. package/lib/next/events/ViewInfoCreator.js +0 -27
  51. package/lib/next/events/modifier/EventLimitation.js +0 -69
  52. /package/lib/next/events/{IHttpRequestEventBuilder.js → interface/EventProperty.js} +0 -0
package/types.d.ts CHANGED
@@ -235,7 +235,7 @@ interface IDynatraceAction {
235
235
  *
236
236
  * @example
237
237
  * ```ts
238
- * import { Dynatrace } from '@dynatrace/react-native-plugin';
238
+ * import { Dynatrace, Platform } from '@dynatrace/react-native-plugin';
239
239
  *
240
240
  * const action = Dynatrace.enterAutoAction('User Login');
241
241
  * action.reportError('Page Not Found', 404);
@@ -383,7 +383,7 @@ interface IDynatraceAction {
383
383
  * action.reportEvent('Processing Started');
384
384
  *
385
385
  * // Cancel if running in development or test mode
386
- * if (__DEV__ || isTestEnvironment) {
386
+ * if (__DEV__) {
387
387
  * action.cancel(); // Don't send test data to production monitoring
388
388
  * } else {
389
389
  * action.leaveAction(); // Send the action data
@@ -609,10 +609,20 @@ interface IEventModifier {
609
609
  /**
610
610
  * Event as JSONObject is received and can be modified.
611
611
  *
612
- * Returning null discards this event and prevents future mutator functions to be executed.
612
+ * Returning null discards the event and prevents future modifier functions from being executed.
613
+ *
614
+ * Certain reserved fields and namespaces cannot be modified in any way (added, removed, or overridden),
615
+ * while others are open for modification.
616
+ *
617
+ * Open for modification:
618
+ * - url.full
619
+ * - exception.stack_trace
620
+ *
621
+ * Open for modification or can be added:
622
+ * - event_properties.*
623
+ * - session_properties.*
613
624
  *
614
- * Certain reserved fields and namespaces can't be modified in any way (added, removed or overridden),
615
- * while others are open for modification. See the public documentation for a detailed list of reserved/open fields.
625
+ * See the public documentation for a detailed list of reserved/open fields.
616
626
  * @param event Event as JSONObject
617
627
  * @returns Either the modified event or null if you want to cancel the event
618
628
  *
@@ -631,18 +641,37 @@ interface IEventModifier {
631
641
  modifyEvent(event: JSONObject): JSONObject | null;
632
642
  }
633
643
 
634
- interface IHttpRequestEventBuilder {
644
+ /**
645
+ * Represents the allowed types for event property values.
646
+ */
647
+ type EventProperty = string | number | boolean;
648
+
649
+ /**
650
+ * Base interface for all events.
651
+ */
652
+ interface IBaseEvent {
653
+ /**
654
+ * Converts the event into a JSON event object.
655
+ *
656
+ * @returns The built event as a JSONObject.
657
+ *
658
+ * @internal
659
+ */
660
+ toJSON(): JSONObject | null;
661
+ }
662
+
663
+ interface IHttpRequestEventData extends IBaseEvent {
635
664
  /**
636
665
  * Sets the duration of the HTTP request in milliseconds.
637
666
  *
638
667
  * @param duration The request duration in milliseconds. Only positive numbers are valid.
639
- * @returns The builder instance for method chaining
668
+ * @returns The event instance for method chaining
640
669
  *
641
670
  * @example
642
671
  * ```ts
643
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
672
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
644
673
  *
645
- * const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET')
674
+ * const requestEvent = new HttpRequestEventData('https://api.example.com/data', 'GET')
646
675
  * .withDuration(250);
647
676
  * Dynatrace.sendHttpRequestEvent(requestEvent);
648
677
  * ```
@@ -654,13 +683,13 @@ interface IHttpRequestEventBuilder {
654
683
  * Sets the HTTP response status code.
655
684
  *
656
685
  * @param statusCode The HTTP status code (e.g., 200, 404, 500). Only positive numbers are valid.
657
- * @returns The builder instance for method chaining
686
+ * @returns The event instance for method chaining
658
687
  *
659
688
  * @example
660
689
  * ```ts
661
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
690
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
662
691
  *
663
- * const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET')
692
+ * const requestEvent = new HttpRequestEventData('https://api.example.com/data', 'GET')
664
693
  * .withStatusCode(200);
665
694
  * Dynatrace.sendHttpRequestEvent(requestEvent);
666
695
  * ```
@@ -672,13 +701,13 @@ interface IHttpRequestEventBuilder {
672
701
  * Sets the HTTP response reason phrase.
673
702
  *
674
703
  * @param reasonPhrase The reason phrase (e.g., "OK", "Not Found"). Maximum 5000 characters; longer values will be trimmed.
675
- * @returns The builder instance for method chaining
704
+ * @returns The event instance for method chaining
676
705
  *
677
706
  * @example
678
707
  * ```ts
679
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
708
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
680
709
  *
681
- * const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET')
710
+ * const requestEvent = new HttpRequestEventData('https://api.example.com/data', 'GET')
682
711
  * .withReasonPhrase('OK');
683
712
  * Dynatrace.sendHttpRequestEvent(requestEvent);
684
713
  * ```
@@ -690,17 +719,21 @@ interface IHttpRequestEventBuilder {
690
719
  * Associates an error with the HTTP request event.
691
720
  *
692
721
  * @param error A standard JavaScript Error object representing the request failure
693
- * @returns The builder instance for method chaining
722
+ * @returns The event instance for method chaining
694
723
  *
695
724
  * @example
696
725
  * ```ts
697
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
726
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
698
727
  *
699
728
  * try {
700
729
  * // Request code
701
730
  * } catch (error) {
702
- * const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET')
703
- * .withError(error);
731
+ * let requestEvent = new HttpRequestEventData('https://api.example.com/data', 'GET');
732
+ *
733
+ * if (error instanceof Error) {
734
+ * requestEvent.withError(error);
735
+ * }
736
+ *
704
737
  * Dynatrace.sendHttpRequestEvent(requestEvent);
705
738
  * }
706
739
  * ```
@@ -712,13 +745,13 @@ interface IHttpRequestEventBuilder {
712
745
  * Sets the number of bytes sent in the request.
713
746
  *
714
747
  * @param bytesSent The number of bytes sent in the request payload. Only positive numbers are valid.
715
- * @returns The builder instance for method chaining
748
+ * @returns The event instance for method chaining
716
749
  *
717
750
  * @example
718
751
  * ```ts
719
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
752
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
720
753
  *
721
- * const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'POST')
754
+ * const requestEvent = new HttpRequestEventData('https://api.example.com/data', 'POST')
722
755
  * .withBytesSent(1024);
723
756
  * Dynatrace.sendHttpRequestEvent(requestEvent);
724
757
  * ```
@@ -730,13 +763,13 @@ interface IHttpRequestEventBuilder {
730
763
  * Sets the number of bytes received in the response.
731
764
  *
732
765
  * @param bytesReceived The number of bytes received in the response payload. Only positive numbers are valid.
733
- * @returns The builder instance for method chaining
766
+ * @returns The event instance for method chaining
734
767
  *
735
768
  * @example
736
769
  * ```ts
737
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
770
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
738
771
  *
739
- * const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET')
772
+ * const requestEvent = new HttpRequestEventData('https://api.example.com/data', 'GET')
740
773
  * .withBytesReceived(2048);
741
774
  * Dynatrace.sendHttpRequestEvent(requestEvent);
742
775
  * ```
@@ -749,13 +782,13 @@ interface IHttpRequestEventBuilder {
749
782
  *
750
783
  * @param traceparentHeader A valid traceparent header according to the W3C Trace Context specification.
751
784
  * Format: `00-<trace-id>-<parent-id>-<trace-flags>` where trace-id is 32 hex digits, parent-id is 16 hex digits.
752
- * @returns The builder instance for method chaining
785
+ * @returns The event instance for method chaining
753
786
  *
754
787
  * @example
755
788
  * ```ts
756
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
789
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
757
790
  *
758
- * const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET')
791
+ * const requestEvent = new HttpRequestEventData('https://api.example.com/data', 'GET')
759
792
  * .withTraceparentHeader('00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01');
760
793
  * Dynatrace.sendHttpRequestEvent(requestEvent);
761
794
  * ```
@@ -771,18 +804,19 @@ interface IHttpRequestEventBuilder {
771
804
  * **Property Requirements:**
772
805
  * - Only properties prefixed with `event_properties.*` are allowed
773
806
  * - Maximum of 50 custom properties per event
807
+ * - If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
774
808
  * - String properties are limited to 5000 characters (exceeding characters are truncated)
775
809
  * - Field names must contain only alphabetic characters, numbers, underscores, and dots
776
810
  * - Each dot must be followed by an alphabetic character
777
811
  * - Each underscore must be followed by an alphabetic character or number
778
812
  *
779
- * @returns The builder instance for method chaining
813
+ * @returns The event instance for method chaining
780
814
  *
781
815
  * @example
782
816
  * ```ts
783
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
817
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
784
818
  *
785
- * const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET')
819
+ * const requestEvent = new HttpRequestEventData('https://api.example.com/data', 'GET')
786
820
  * .addEventProperty('event_properties.user_id', '12345')
787
821
  * .addEventProperty('event_properties.api_version', 'v2');
788
822
  * Dynatrace.sendHttpRequestEvent(requestEvent);
@@ -793,14 +827,12 @@ interface IHttpRequestEventBuilder {
793
827
  addEventProperty(key: `event_properties.${string}`, value: EventProperty): this;
794
828
  }
795
829
 
796
- type EventProperty = string | number | boolean;
797
830
  type TraceparentHeader = `00-${string}-${string}-0${'0' | '1'}`;
798
831
  type AllowedRequestMethods = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH' | 'get' | 'head' | 'post' | 'put' | 'delete' | 'connect' | 'options' | 'trace' | 'patch';
799
- declare class HttpRequestEventBuilder implements IHttpRequestEventBuilder {
832
+ declare class HttpRequestEventData implements IHttpRequestEventData {
800
833
  private url;
801
834
  private requestMethod;
802
835
  private static readonly allowedRequestMethods;
803
- private static readonly maxReasonPhraseLength;
804
836
  private duration;
805
837
  private statusCode?;
806
838
  private reasonPhrase?;
@@ -809,22 +841,22 @@ declare class HttpRequestEventBuilder implements IHttpRequestEventBuilder {
809
841
  private error?;
810
842
  private traceparentHeader?;
811
843
  private rawEventProperties;
812
- private hasDroppedTraceparent;
813
- private hasDroppedCustomProperties;
814
- private hasNfnValues;
844
+ private traceContextHint;
845
+ private hasDroppedProperties;
815
846
  private triedToOverwriteDuration;
816
847
  /**
817
- * Creates a new HTTP request event builder.
848
+ * Creates a new HTTP request event.
818
849
  *
819
- * @param url The request URL. Must be a valid URL according to the WHATWG URL Standard, starting with `http://` or `https://`.
850
+ * @param url The request URL. Must be a valid URL according to the WHATWG URL Standard, starting with
851
+ * `http://` or `https://`. Maximum 5000 characters; longer values will be trimmed.
820
852
  * @param requestMethod The HTTP request method. Allowed values: GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS,
821
853
  * TRACE, PATCH (case-insensitive).
822
854
  *
823
855
  * @example
824
856
  * ```ts
825
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
857
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
826
858
  *
827
- * const requestEvent = new HttpRequestEventBuilder('https://api.example.com/data', 'GET');
859
+ * const requestEvent = new HttpRequestEventData('https://api.example.com/data', 'GET');
828
860
  * Dynatrace.sendHttpRequestEvent(requestEvent);
829
861
  * ```
830
862
  *
@@ -839,22 +871,200 @@ declare class HttpRequestEventBuilder implements IHttpRequestEventBuilder {
839
871
  withBytesReceived(bytesReceived: number): this;
840
872
  withTraceparentHeader(traceparentHeader: TraceparentHeader): this;
841
873
  addEventProperty(key: `event_properties.${string}`, value: EventProperty): this;
842
- build(): JSONObject | null;
843
- private hasValidMandatoryAttriutes;
874
+ toJSON(): JSONObject | null;
875
+ private hasValidMandatoryAttributes;
844
876
  private isInvalidUrl;
845
877
  private sanitizeStatusCode;
846
- private sanitizeReasonPhrase;
847
878
  private sanitizeDuration;
848
879
  private sanitizeBytesSent;
849
880
  private sanitizeBytesReceived;
850
881
  private isStatusCodeError;
851
- private isEventPropertyKey;
852
- private includeIfDefined;
853
- private includeIfTrue;
854
882
  private parseTraceparent;
855
883
  private allZeros;
856
884
  }
857
885
 
886
+ /**
887
+ * Interface for building events with event properties and duration.
888
+ *
889
+ * Events can include custom properties and duration information.
890
+ * Use implementations of this interface with `Dynatrace.sendEvent()`.
891
+ *
892
+ * @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
893
+ */
894
+ interface IEventData extends IBaseEvent {
895
+ /**
896
+ * Sets the duration of the event in milliseconds.
897
+ *
898
+ * @param duration The event duration in milliseconds. Only positive numbers are valid.
899
+ * @returns The event instance for method chaining
900
+ *
901
+ * @example
902
+ * ```typescript
903
+ * import { Dynatrace, EventData } from '@dynatrace/react-native-plugin';
904
+ *
905
+ * const customEvent = new EventData()
906
+ * .addEventProperty('event_properties.operation', 'data_sync')
907
+ * .withDuration(250);
908
+ * Dynatrace.sendEvent(customEvent);
909
+ * ```
910
+ */
911
+ withDuration(duration: number): this;
912
+ /**
913
+ * Adds a custom event property to the event.
914
+ *
915
+ * Event properties allow you to attach custom key-value pairs to events for better
916
+ * analysis and filtering in Dynatrace.
917
+ *
918
+ * @param key - The property key. Must be prefixed with `event_properties.*`
919
+ * @param value - The property value (string, number, or boolean). Invalid values will be replaced with null.
920
+ * @returns The event instance for method chaining
921
+ *
922
+ * @remarks
923
+ * **Property Requirements:**
924
+ * - Only properties prefixed with `event_properties.*` are allowed
925
+ * - Maximum of 50 custom properties per event
926
+ * - If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
927
+ * - String properties are limited to 5000 characters (exceeding characters are truncated)
928
+ * - Field names must contain only alphabetic characters, numbers, underscores, and dots
929
+ * - Each dot must be followed by an alphabetic character
930
+ * - Each underscore must be followed by an alphabetic character or number
931
+ *
932
+ * @example
933
+ * ```typescript
934
+ * import { Dynatrace, EventData } from '@dynatrace/react-native-plugin';
935
+ *
936
+ * const customEvent = new EventData()
937
+ * .addEventProperty('event_properties.user_id', '12345')
938
+ * .addEventProperty('event_properties.action_type', 'purchase')
939
+ * .addEventProperty('event_properties.amount', 99.99)
940
+ * .addEventProperty('event_properties.is_premium_user', true);
941
+ * Dynatrace.sendEvent(customEvent);
942
+ * ```
943
+ */
944
+ addEventProperty(key: `event_properties.${string}`, value: EventProperty): this;
945
+ }
946
+
947
+ declare class EventData implements IEventData {
948
+ private rawEventProperties;
949
+ private duration?;
950
+ addEventProperty(key: `event_properties.${string}`, value: EventProperty): this;
951
+ withDuration(duration: number): this;
952
+ toJSON(): JSONObject | null;
953
+ }
954
+
955
+ /**
956
+ * Interface for building session property events.
957
+ *
958
+ * Session properties are key-value pairs that persist throughout the entire
959
+ * user session and are attached to all subsequent events in that session.
960
+ * Use implementations of this interface with `Dynatrace.sendSessionPropertyEvent()`.
961
+ *
962
+ * @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
963
+ */
964
+ interface ISessionPropertyEventData extends IBaseEvent {
965
+ /**
966
+ * Adds a custom session property to the event.
967
+ *
968
+ * Session properties allow you to attach custom key-value pairs that persist throughout
969
+ * the entire user session. These properties will be automatically attached to all
970
+ * subsequent events in the current session.
971
+ *
972
+ * @param key - The property key. Must be prefixed with `session_properties.*`
973
+ * @param value - The property value (string, number, or boolean). Invalid values will be replaced with null.
974
+ * @returns The event instance for method chaining
975
+ *
976
+ * @remarks
977
+ * **Property Requirements:**
978
+ * - Only properties prefixed with `session_properties.*` are allowed
979
+ * - Maximum of 50 custom properties per event
980
+ * - If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
981
+ * - String properties are limited to 5000 characters (exceeding characters are truncated)
982
+ * - Field names must contain only alphabetic characters, numbers, underscores, and dots
983
+ * - Each dot must be followed by an alphabetic character
984
+ * - Each underscore must be followed by an alphabetic character or number
985
+ *
986
+ * @example
987
+ * ```typescript
988
+ * import { Dynatrace, SessionPropertyEventData } from '@dynatrace/react-native-plugin';
989
+ *
990
+ * const sessionPropertyEvent = new SessionPropertyEventData()
991
+ * .addSessionProperty('session_properties.user_id', 'user_12345')
992
+ * .addSessionProperty('session_properties.user_type', 'premium')
993
+ * .addSessionProperty('session_properties.feature_flags_enabled', true)
994
+ * .addSessionProperty('session_properties.session_score', 95.5);
995
+ * Dynatrace.sendSessionPropertyEvent(sessionPropertyEvent);
996
+ * ```
997
+ */
998
+ addSessionProperty(key: `session_properties.${string}`, value: EventProperty): this;
999
+ }
1000
+
1001
+ declare class SessionPropertyEventData implements ISessionPropertyEventData {
1002
+ private rawSessionProperties;
1003
+ addSessionProperty(key: `session_properties.${string}`, value: EventProperty): this;
1004
+ toJSON(): JSONObject | null;
1005
+ }
1006
+
1007
+ /**
1008
+ * Interface for building exception events with event properties.
1009
+ *
1010
+ * This interface defines the contract for creating exception events that can be sent
1011
+ * to Dynatrace. Exception events can include custom properties.
1012
+ * Use implementations of this interface with `Dynatrace.sendExceptionEvent()`.
1013
+ *
1014
+ * @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
1015
+ */
1016
+ interface IExceptionEventData extends IBaseEvent {
1017
+ /**
1018
+ * Adds a custom event property to the exception event.
1019
+ *
1020
+ * Event properties allow you to attach additional contextual information to the exception.
1021
+ * Properties must follow the naming convention `event_properties.*` and support string,
1022
+ * number, and boolean values.
1023
+ *
1024
+ * @param key The property key. Must start with "event_properties."
1025
+ * @param value The property value (string, number, or boolean)
1026
+ * @returns The event instance for method chaining
1027
+ *
1028
+ * @remarks
1029
+ * **Property Requirements:**
1030
+ * - Only properties prefixed with `event_properties.*` are allowed
1031
+ * - Maximum of 50 custom properties per event
1032
+ * - If the limit is exceeded, properties are sorted alphabetically by key and excess properties are dropped deterministically
1033
+ * - String properties are limited to 5000 characters (exceeding characters are truncated)
1034
+ * - Field names must contain only alphabetic characters, numbers, underscores, and dots
1035
+ * - Each dot must be followed by an alphabetic character
1036
+ * - Each underscore must be followed by an alphabetic character or number
1037
+ *
1038
+ * @example
1039
+ * ```typescript
1040
+ * import { Dynatrace, ExceptionEventData } from '@dynatrace/react-native-plugin';
1041
+ *
1042
+ * try {
1043
+ * // Some operation that might throw an error
1044
+ * throw new Error('Something went wrong');
1045
+ * } catch (error) {
1046
+ * if (error instanceof Error) {
1047
+ * const exceptionEvent = new ExceptionEventData(error)
1048
+ * .addEventProperty('event_properties.exception_type', 'RuntimeError')
1049
+ * .addEventProperty('event_properties.stack_depth', 15)
1050
+ * .addEventProperty('event_properties.handled', true);
1051
+ *
1052
+ * Dynatrace.sendExceptionEvent(exceptionEvent);
1053
+ * }
1054
+ * }
1055
+ * ```
1056
+ */
1057
+ addEventProperty(key: string, value: EventProperty): this;
1058
+ }
1059
+
1060
+ declare class ExceptionEventData implements IExceptionEventData {
1061
+ private rawEventProperties;
1062
+ private readonly error;
1063
+ constructor(error: Error);
1064
+ addEventProperty(key: `event_properties.${string}`, value: EventProperty): this;
1065
+ toJSON(): JSONObject | null;
1066
+ }
1067
+
858
1068
  interface IDynatrace$1 {
859
1069
  /**
860
1070
  * Adds an event modifier that is executed just before the event is transferred.
@@ -865,6 +1075,14 @@ interface IDynatrace$1 {
865
1075
  * Certain reserved fields and namespaces cannot be modified in any way (added, removed, or overridden),
866
1076
  * while others are open for modification.
867
1077
  *
1078
+ * Open for modification:
1079
+ * - url.full
1080
+ * - exception.stack_trace
1081
+ *
1082
+ * Open for modification or can be added:
1083
+ * - event_properties.*
1084
+ * - session_properties.*
1085
+ *
868
1086
  * See the public documentation for a detailed list of reserved/open fields.
869
1087
  *
870
1088
  * @param eventModifier The modifier function to modify a given JSONObject
@@ -905,65 +1123,53 @@ interface IDynatrace$1 {
905
1123
  /**
906
1124
  * Sends an exception event for error tracking and monitoring.
907
1125
  *
908
- * @param {Error} error The error object containing exception information
909
- * @param {JSONObject} properties Optional custom properties for the exception event. Must be a valid JSON object
910
- * and cannot contain functions, undefined, Infinity, or NaN as values (they will be replaced with null).
911
- *
912
- * **Property Requirements:**
913
- * - Only properties prefixed with `event_properties.*` are allowed
914
- * - Additionally, the `duration` property is allowed
915
- * - Maximum of 50 custom properties per event
916
- * - String properties are limited to 5000 characters (exceeding characters are truncated)
917
- * - Field names must contain only alphabetic characters, numbers, underscores, and dots
918
- * - Each dot must be followed by an alphabetic character
919
- * - Each underscore must be followed by an alphabetic character or number
1126
+ * @param exceptionEventData The exception event data built using ExceptionEventData
920
1127
  *
921
1128
  * @example
922
1129
  * ```ts
923
- * import { Dynatrace } from '@dynatrace/react-native-plugin';
1130
+ * import { Dynatrace, ExceptionEventData } from '@dynatrace/react-native-plugin';
924
1131
  *
925
1132
  * try {
926
1133
  * // Code that may throw an error
927
1134
  * throw new Error('Something went wrong');
928
1135
  * } catch (error) {
929
- * Dynatrace.sendExceptionEvent(error, {
930
- * 'event_properties.custom_key': 'custom_value',
931
- * 'event_properties.error_context': 'user_action'
932
- * });
1136
+ * if (error instanceof Error) {
1137
+ * const exceptionEvent = new ExceptionEventData(error)
1138
+ * .addEventProperty('event_properties.custom_key', 'custom_value')
1139
+ * .addEventProperty('event_properties.error_context', 'user_action');
1140
+ *
1141
+ * Dynatrace.sendExceptionEvent(exceptionEvent);
1142
+ * }
933
1143
  * }
934
1144
  * ```
935
1145
  *
936
1146
  * @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
937
1147
  */
938
- sendExceptionEvent(error: Error, fields?: JSONObject): void;
1148
+ sendExceptionEvent(exceptionEventData: ExceptionEventData): void;
939
1149
  /**
940
- * Sends a custom event with properties in JSON format.
1150
+ * Sends a custom event with event properties and optional duration.
941
1151
  *
942
- * @param {JSONObject} properties Event properties as a valid JSON object. Cannot contain functions, undefined,
943
- * Infinity, or NaN as values (they will be replaced with null). Empty objects are valid.
944
- *
945
- * **Property Requirements:**
946
- * - Only properties prefixed with `event_properties.*` are allowed
947
- * - Additionally, the `duration` property is allowed
948
- * - Maximum of 50 custom properties per event
949
- * - String properties are limited to 5000 characters (exceeding characters are truncated)
950
- * - Field names must contain only alphabetic characters, numbers, underscores, and dots
951
- * - Each dot must be followed by an alphabetic character
952
- * - Each underscore must be followed by an alphabetic character or number
1152
+ * @param eventData The event data built using EventData
953
1153
  *
954
1154
  * @example
955
1155
  * ```ts
956
- * import { Dynatrace } from '@dynatrace/react-native-plugin';
1156
+ * import { Dynatrace, EventData } from '@dynatrace/react-native-plugin';
1157
+ *
1158
+ * const customEvent = new EventData()
1159
+ * .addEventProperty('event_properties.user_action', 'button_click')
1160
+ * .addEventProperty('event_properties.screen_name', 'checkout')
1161
+ * .addEventProperty('event_properties.item_count', 3)
1162
+ * .withDuration(150);
957
1163
  *
958
- * Dynatrace.sendEvent({'event_properties.custom_key':'custom_value'});
1164
+ * Dynatrace.sendEvent(customEvent);
959
1165
  * ```
960
1166
  *
961
1167
  * @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
962
1168
  */
963
- sendEvent(properties: JSONObject): void;
1169
+ sendEvent(eventData: EventData): void;
964
1170
  /**
965
1171
  * Starts a new view context. All events reported after this call will be associated
966
- * with this view until `stopView()` is called or a new view is started.
1172
+ * with this view until a new view is started.
967
1173
  *
968
1174
  * **Note:** Only one view context can be active at a time. Starting a new view will
969
1175
  * automatically stop any currently active view context.
@@ -981,78 +1187,53 @@ interface IDynatrace$1 {
981
1187
  * @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
982
1188
  */
983
1189
  startView(name: string): void;
984
- /**
985
- * Stops the current view context. Events reported after this call will not be
986
- * associated with any view until a new view is started.
987
- *
988
- * @example
989
- * ```ts
990
- * import { Dynatrace } from '@dynatrace/react-native-plugin';
991
- *
992
- * Dynatrace.startView('HomeScreen');
993
- * // ... user interactions ...
994
- * Dynatrace.stopView();
995
- * ```
996
- *
997
- * @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
998
- */
999
- stopView(): void;
1000
1190
  /**
1001
1191
  * Sends a session properties event. Session properties apply to all events in the current session.
1002
1192
  *
1003
1193
  * **Note:** While you can send multiple session properties at once, if you report the same
1004
1194
  * property multiple times, session aggregation will only use one of the values (first or last).
1005
1195
  *
1006
- * @param {JSONObject} properties Session properties as a valid JSON object. Cannot contain functions,
1007
- * undefined, Infinity, or NaN as values (they will be replaced with null). Empty objects are valid.
1008
- *
1009
- * **Property Requirements:**
1010
- * - Only properties prefixed with `session_properties.*` are allowed
1011
- * - Additionally, the `duration` property is allowed
1012
- * - Maximum of 50 custom properties per event
1013
- * - String properties are limited to 5000 characters (exceeding characters are truncated)
1014
- * - Field names must contain only alphabetic characters, numbers, underscores, and dots
1015
- * - Each dot must be followed by an alphabetic character
1016
- * - Each underscore must be followed by an alphabetic character or number
1196
+ * @param sessionPropertyEventData The session property event data built using SessionPropertyEventData builder
1017
1197
  *
1018
1198
  * @example
1019
1199
  * ```ts
1020
- * import { Dynatrace } from '@dynatrace/react-native-plugin';
1200
+ * import { Dynatrace, SessionPropertyEventData } from '@dynatrace/react-native-plugin';
1021
1201
  *
1022
1202
  * // Set session-level properties
1023
- * Dynatrace.sendSessionPropertyEvent({
1024
- * 'session_properties.user_tier': 'premium',
1025
- * 'session_properties.app_version': '2.1.0',
1026
- * 'session_properties.device_type': 'mobile'
1027
- * });
1203
+ * const sessionEvent = new SessionPropertyEventData()
1204
+ * .addSessionProperty('session_properties.user_tier', 'premium')
1205
+ * .addSessionProperty('session_properties.app_version', '2.1.0')
1206
+ * .addSessionProperty('session_properties.device_type', 'mobile');
1207
+ *
1208
+ * Dynatrace.sendSessionPropertyEvent(sessionEvent);
1028
1209
  * ```
1029
1210
  *
1030
1211
  * @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
1031
1212
  */
1032
- sendSessionPropertyEvent(properties: JSONObject): void;
1213
+ sendSessionPropertyEvent(sessionPropertyEventData: SessionPropertyEventData): void;
1033
1214
  /**
1034
1215
  * Sends an HTTP request event for network activity monitoring.
1035
1216
  *
1036
- * @param {HttpRequestEventBuilder} httpRequestEventBuilder Builder object containing the HTTP request details
1217
+ * @param {HttpRequestEventData} httpRequestEvent Event object containing the HTTP request details
1037
1218
  *
1038
1219
  * @example
1039
1220
  * ```ts
1040
- * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
1221
+ * import { Dynatrace, HttpRequestEventData } from '@dynatrace/react-native-plugin';
1041
1222
  *
1042
1223
  * // Basic HTTP request event
1043
- * const requestBuilder = new HttpRequestEventBuilder('https://api.example.com/users', 'GET');
1044
- * Dynatrace.sendHttpRequestEvent(requestBuilder);
1224
+ * const requestEvent = new HttpRequestEventData('https://api.example.com/users', 'GET');
1225
+ * Dynatrace.sendHttpRequestEvent(requestEvent);
1045
1226
  *
1046
1227
  * // HTTP request with additional details
1047
- * const detailedBuilder = new HttpRequestEventBuilder('https://api.example.com/data', 'POST')
1048
- * .setResponseCode(200)
1049
- * .setRequestHeaders({ 'Content-Type': 'application/json' });
1050
- * Dynatrace.sendHttpRequestEvent(detailedBuilder);
1228
+ * const detailedRequest = new HttpRequestEventData('https://api.example.com/data', 'POST')
1229
+ * .withStatusCode(200)
1230
+ * .addEventProperty('event_properties.headers.content_type', 'application/json');
1231
+ * Dynatrace.sendHttpRequestEvent(detailedRequest);
1051
1232
  * ```
1052
1233
  *
1053
1234
  * @see https://docs.dynatrace.com/docs/observe/digital-experience/new-rum-experience/api
1054
1235
  */
1055
- sendHttpRequestEvent(httpRequestEventBuilder: HttpRequestEventBuilder): void;
1236
+ sendHttpRequestEvent(httpRequestEvent: HttpRequestEventData): void;
1056
1237
  }
1057
1238
 
1058
1239
  /**
@@ -1130,9 +1311,10 @@ interface IDynatrace extends IDynatrace$1 {
1130
1311
  * @example
1131
1312
  * ```ts
1132
1313
  * import { Dynatrace } from '@dynatrace/react-native-plugin';
1314
+ * import { FunctionComponent } from 'react';
1133
1315
  *
1134
- * export function MyFunctionalComponent(){
1135
- * // Content of component
1316
+ * export const MyFunctionalComponent: FunctionComponent<{}> = () => {
1317
+ * return null;
1136
1318
  * }
1137
1319
  *
1138
1320
  * Dynatrace.withMonitoring(MyFunctionalComponent, "MyFunctionalComponent");
@@ -1224,54 +1406,87 @@ interface IDynatrace extends IDynatrace$1 {
1224
1406
  */
1225
1407
  reportErrorWithStacktrace(errorName: string, reason: string, stacktrace: string, platform?: Platform): void;
1226
1408
  /**
1227
- * Reports a stacktrace
1409
+ * Reports an error with its complete stacktrace to Dynatrace for monitoring and analysis.
1410
+ * Use this method to capture and report errors with their full stack traces, typically within
1411
+ * try-catch blocks to handle exceptions gracefully while maintaining observability.
1228
1412
  *
1229
- * @param {string} errorName Name of the error (limited to 250 characters)
1230
- * @param {string} errorValue Value of the error
1231
- * @param {string} reason Reason for the error
1232
- * @param {string} stacktrace Whole stacktrace
1233
- * @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
1413
+ * @param errorName Name or type of the error (e.g., 'DatabaseError', 'NetworkError'). Limited to 250 characters.
1414
+ * @param errorValue The error message or value describing what went wrong
1415
+ * @param reason Additional context explaining why the error occurred
1416
+ * @param stacktrace The complete stack trace from the error. Use error.stack or provide a custom trace.
1417
+ * @param platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
1234
1418
  *
1235
1419
  * @example
1236
1420
  * ```ts
1237
1421
  * import { Dynatrace } from '@dynatrace/react-native-plugin';
1238
1422
  *
1239
- * Dynatrace.reportErrorStacktrace("Error Name", "Error Value", "Reason", "Stacktrace");
1423
+ * try {
1424
+ * throw new Error('Database connection failed');
1425
+ * } catch (error) {
1426
+ * if (error instanceof Error) {
1427
+ * Dynatrace.reportErrorStacktrace(
1428
+ * 'DatabaseError',
1429
+ * error.message,
1430
+ * 'Failed to connect to remote database',
1431
+ * error.stack || 'No stack trace available'
1432
+ * );
1433
+ * }
1434
+ * }
1240
1435
  * ```
1241
1436
  *
1242
1437
  * @see https://www.npmjs.com/package/@dynatrace/react-native-plugin#report-an-error-stacktrace
1243
1438
  */
1244
1439
  reportErrorStacktrace(errorName: string, errorValue: string, reason: string, stacktrace: string, platform?: Platform): void;
1245
1440
  /**
1246
- * Reports a custom crash
1441
+ * Reports a custom crash event to Dynatrace for critical failures that cause app termination.
1442
+ * Use this to manually report crashes with detailed stack traces when automatic crash detection
1443
+ * is insufficient or when you need to report non-fatal errors as crashes for monitoring purposes.
1247
1444
  *
1248
- * @param {string} crashName Name of the crash (limited to 250 characters)
1249
- * @param {string} reason Reason for the crash
1250
- * @param {string} stacktrace Whole stacktrace
1251
- * @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
1445
+ * @param crashName Descriptive name for the crash (e.g., 'OutOfMemoryError', 'UnhandledException'). Limited to 250 characters.
1446
+ * @param reason Brief explanation of why the crash occurred
1447
+ * @param stacktrace Complete stack trace showing the call sequence leading to the crash
1448
+ * @param platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
1252
1449
  *
1253
1450
  * @example
1254
1451
  * ```ts
1255
1452
  * import { Dynatrace } from '@dynatrace/react-native-plugin';
1256
1453
  *
1257
- * Dynatrace.reportCrash("Crash Name", "Reason", "Stacktrace");
1454
+ * try {
1455
+ * throw new Error('Fatal memory allocation failure');
1456
+ * } catch (error) {
1457
+ * if (error instanceof Error) {
1458
+ * Dynatrace.reportCrash(
1459
+ * 'MemoryError',
1460
+ * error.message,
1461
+ * error.stack || 'No stack trace available'
1462
+ * );
1463
+ * }
1464
+ * }
1258
1465
  * ```
1259
1466
  *
1260
1467
  * @see https://www.npmjs.com/package/@dynatrace/react-native-plugin#manually-report-a-crash
1261
1468
  */
1262
1469
  reportCrash(crashName: string, reason: string, stacktrace: string, platform?: Platform): void;
1263
1470
  /**
1264
- * Reports a crash with an error object (which needs to contain a stacktrace)
1471
+ * Reports a crash using a native JavaScript Error object to Dynatrace.
1472
+ * This is a convenience method that automatically extracts the error message and stack trace
1473
+ * from an Error object, making it easier to report crashes from caught exceptions.
1265
1474
  *
1266
- * @param {string} crashName Name of the crash (limited to 250 characters)
1267
- * @param {Error} crash error object
1268
- * @param {Platform} platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
1475
+ * @param crashName Descriptive name for the crash (e.g., 'UnhandledPromiseRejection'). Limited to 250 characters.
1476
+ * @param crash The Error object containing the stack trace and error details
1477
+ * @param platform Is optional, which means by default this call will be applied on both platforms (Android & iOS).
1269
1478
  *
1270
1479
  * @example
1271
1480
  * ```ts
1272
1481
  * import { Dynatrace } from '@dynatrace/react-native-plugin';
1273
1482
  *
1274
- * Dynatrace.reportCrashWithException("Crash Name", error);
1483
+ * try {
1484
+ * throw new Error('Critical API endpoint unavailable');
1485
+ * } catch (error) {
1486
+ * if (error instanceof Error) {
1487
+ * Dynatrace.reportCrashWithException('APIFailureCrash', error);
1488
+ * }
1489
+ * }
1275
1490
  * ```
1276
1491
  *
1277
1492
  * @see https://www.npmjs.com/package/@dynatrace/react-native-plugin#manually-report-a-crash
@@ -1720,7 +1935,7 @@ declare class ConfigurationBuilder {
1720
1935
  *
1721
1936
  * @example
1722
1937
  * ```ts
1723
- * import { ConfigurationBuilder, Dynatrace } from '@dynatrace/react-native-plugin';
1938
+ * import { ConfigurationBuilder, Dynatrace, LogLevel } from '@dynatrace/react-native-plugin';
1724
1939
  *
1725
1940
  * const config = new ConfigurationBuilder('beaconUrl', 'applicationId')
1726
1941
  * .withLogLevel(LogLevel.Debug)
@@ -1753,14 +1968,19 @@ interface IDynatraceWebRequestTiming {
1753
1968
  *
1754
1969
  * try {
1755
1970
  * timing.startWebRequestTiming();
1756
- * const axiosResponse = await axios.get(url, {
1971
+ * const response = await fetch(url, {
1757
1972
  * headers: {
1758
1973
  * [timing.getRequestTagHeader()]: tag
1759
1974
  * }
1760
1975
  * });
1761
- * timing.stopWebRequestTiming(axiosResponse.status, axiosResponse.data);
1976
+ * const data = await response.text();
1977
+ * timing.stopWebRequestTiming(response.status, data);
1762
1978
  * } catch (error) {
1763
- * timing.stopWebRequestTiming(-1, error.message);
1979
+ * if (error instanceof Error) {
1980
+ * timing.stopWebRequestTiming(-1, error.message);
1981
+ * } else {
1982
+ * timing.stopWebRequestTiming(-1, (error as any).toString());
1983
+ * }
1764
1984
  * } finally {
1765
1985
  * action.leaveAction();
1766
1986
  * }
@@ -1788,14 +2008,18 @@ interface IDynatraceWebRequestTiming {
1788
2008
  *
1789
2009
  * try {
1790
2010
  * timing.startWebRequestTiming();
1791
- * const axiosResponse = await axios.get(url, {
2011
+ * const response = await fetch(url, {
1792
2012
  * headers: {
1793
2013
  * [timing.getRequestTagHeader()]: tag
1794
2014
  * }
1795
2015
  * });
1796
- * timing.stopWebRequestTiming(axiosResponse.status, axiosResponse.statusText);
2016
+ * timing.stopWebRequestTiming(response.status, response.statusText);
1797
2017
  * } catch (error) {
1798
- * timing.stopWebRequestTiming(-1, error.message);
2018
+ * if (error instanceof Error) {
2019
+ * timing.stopWebRequestTiming(-1, error.message);
2020
+ * } else {
2021
+ * timing.stopWebRequestTiming(-1, (error as any).toString());
2022
+ * }
1799
2023
  * } finally {
1800
2024
  * action.leaveAction();
1801
2025
  * }
@@ -1826,21 +2050,27 @@ interface IDynatraceWebRequestTiming {
1826
2050
  *
1827
2051
  * try {
1828
2052
  * timing.startWebRequestTiming();
1829
- * const axiosResponse = await axios.post(url, requestData, {
2053
+ * const response = await fetch(url, {
2054
+ * method: 'POST',
1830
2055
  * headers: {
1831
2056
  * [timing.getRequestTagHeader()]: tag,
1832
2057
  * 'Content-Type': 'application/json'
1833
- * }
2058
+ * },
2059
+ * body: requestData
1834
2060
  * });
1835
- * const responseData = JSON.stringify(axiosResponse.data);
2061
+ * const responseData = await response.text();
1836
2062
  * timing.stopWebRequestTimingWithSize(
1837
- * axiosResponse.status,
1838
- * axiosResponse.statusText,
2063
+ * response.status,
2064
+ * response.statusText,
1839
2065
  * requestData.length,
1840
2066
  * responseData.length
1841
2067
  * );
1842
2068
  * } catch (error) {
1843
- * timing.stopWebRequestTiming(-1, error.message);
2069
+ * if (error instanceof Error) {
2070
+ * timing.stopWebRequestTiming(-1, error.message);
2071
+ * } else {
2072
+ * timing.stopWebRequestTiming(-1, (error as any).toString());
2073
+ * }
1844
2074
  * } finally {
1845
2075
  * action.leaveAction();
1846
2076
  * }
@@ -1970,5 +2200,5 @@ declare module 'react' {
1970
2200
  }
1971
2201
  }
1972
2202
 
1973
- export { ConfigurationBuilder, DataCollectionLevel, Dynatrace, DynatraceWebRequestTiming, HttpRequestEventBuilder, LogLevel, ManualStartupConfiguration, Platform, UserPrivacyOptions };
2203
+ export { ConfigurationBuilder, DataCollectionLevel, Dynatrace, DynatraceWebRequestTiming, EventData, ExceptionEventData, HttpRequestEventData, LogLevel, ManualStartupConfiguration, Platform, SessionPropertyEventData, UserPrivacyOptions };
1974
2204
  export type { IConfiguration, IDynatraceAction, IDynatraceRootAction, IDynatraceWebRequestTiming, IEventModifier, JSONObject };