@dynatrace/react-native-plugin 2.323.1 → 2.323.2

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.
package/README.md CHANGED
@@ -21,13 +21,14 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
21
21
  ## Requirements
22
22
  * React v16.8 or newer
23
23
  * React Native v0.60 or newer
24
- * For Android users:
24
+ * For Android users:
25
25
  * SDK version 21+
26
26
  * Gradle version 7.0+ ([How to update?](#updating-to-gradle-7))
27
27
  * Android Gradle plugin version 7.0+
28
28
  * Java 11
29
+ * Kotlin 2.0.21 — see [Kotlin Compatibility Note](#⚠️-kotlin-compatibility-note)
29
30
  * For iOS users: Minimum iOS 12
30
- * NodeJS 18.18+
31
+ * NodeJS 16.0.0+ since our dependencies require NodeJS 16.0.0
31
32
 
32
33
  ## Agent Versions
33
34
  This agent versions are configured in this plugin:
@@ -80,6 +81,7 @@ This agent versions are configured in this plugin:
80
81
  * [React Automatic Runtime](#react-automatic-runtime)
81
82
  * [Using a second transformer besides the dynatrace transformer](#using-a-second-transformer-besides-the-dynatrace-transformer)
82
83
  * [Upgrading project to Gradle 7](#updating-to-gradle-7)
84
+ * [Kotlin Compatibility Note](#⚠️-kotlin-compatibility-note)
83
85
  * [Maven Central in top-level gradle file](#maven-central-in-top-level-gradle-file)
84
86
  * [Configuration of standalone React Native project](#configuration-of-standalone-react-native-project)
85
87
  * [Instrumentation Overhead](#instrumentation-overhead)
@@ -1378,6 +1380,18 @@ dependencies {
1378
1380
 
1379
1381
  ```
1380
1382
 
1383
+ ## ⚠️ Kotlin Compatibility Note
1384
+
1385
+ Our Android Agent currently (2025-09-15) requires **Kotlin 2.0.21**. However, it should be noted that using this version may cause compatibility issues with older versions of React Native and the corresponding `react-native-gradle-plugin` due to, for instance, differences in Kotlin metadata:
1386
+
1387
+ Kotlin embeds language-specific features that Java doesn't natively support (like nullability and extension functions) into bytecode using `@Metadata` annotations. These annotations include a `metadataVersion`.
1388
+
1389
+ - **React Native 0.66**, for instance, works with Kotlin 2.0.21 because its `react-native-gradle-plugin` does **not use Kotlin**, avoiding metadata conflicts.
1390
+ - **React Native 0.71**, for instance, uses a `react-native-gradle-plugin` compiled with Kotlin **1.7.22**, which expects `metadataVersion 1.6.0`. Using Kotlin 2.0.21 (which produces `metadataVersion 1.9.0`) can lead to build failures.
1391
+ - **React Native 0.72**, for instance, again is compatible with Kotlin 2.0.21, as its `react-native-gradle-plugin` expects a metadata version that is compatible with `1.9.0`.
1392
+
1393
+ In summary, ensure your build fulfills our Kotlin 2.0.21 requirement while simultaneously fulfilling the requirements of your React Native version and its `react-native-gradle-plugin`.
1394
+
1381
1395
  ## Configuration of standalone React Native project
1382
1396
 
1383
1397
  This section explains the configuration of a standalone React Native project. This means you have a React Native project, but don't use the typicial `iOS` and `android` folders. Instead you have a seperate native `iOS` or `android` project which is embedding your React Native project.
@@ -1477,6 +1491,11 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
1477
1491
  <br/><br/>
1478
1492
  ## Changelog
1479
1493
 
1494
+ 2.323.2
1495
+ * Fixed error "Execution failed for task ':app:mergeReleaseAssets'. A problem occured starting process 'command 'npx''" when building for release on Windows.
1496
+ * Downgraded required NodeJS version to 16.0.0+
1497
+ * Fixing Switch instrumentation for React Native 0.81+
1498
+
1480
1499
  2.323.1
1481
1500
  * Updated Android (8.323.1.1002) & iOS Agent (8.323.1.1009)
1482
1501
  * Fixing Touchable/Text instrumentation for React Native 0.81+
@@ -11,7 +11,7 @@ def isNewArchitectureEnabled() {
11
11
  buildscript {
12
12
  repositories {
13
13
  google()
14
- jcenter()
14
+ mavenCentral()
15
15
  }
16
16
 
17
17
  dependencies {
@@ -68,7 +68,7 @@ android {
68
68
 
69
69
  repositories {
70
70
  google()
71
- jcenter()
71
+ mavenCentral()
72
72
  }
73
73
 
74
74
  dependencies {
@@ -1,3 +1,5 @@
1
+ import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
2
+
1
3
  android.applicationVariants.all { variant ->
2
4
  if (variant.buildType.name == "release") {
3
5
  variant.mergeAssetsProvider.configure { task ->
@@ -10,7 +12,12 @@ android.applicationVariants.all { variant ->
10
12
 
11
13
  exec {
12
14
  workingDir rootDir
13
- commandLine 'npx', 'lineOffsetDynatrace', 'env=prod'
15
+ if (DefaultNativePlatform.currentOperatingSystem.isWindows()) {
16
+ // On windows, npx.cmd may not be a true binary executable and may need to be interpreted by a shell instead of executed direclty
17
+ commandLine 'cmd', '/c', 'npx', 'lineOffsetDynatrace', 'env=prod'
18
+ } else {
19
+ commandLine 'npx', 'lineOffsetDynatrace', 'env=prod'
20
+ }
14
21
  }
15
22
 
16
23
  } else {
package/index.js CHANGED
@@ -8,3 +8,4 @@ export { ApplicationHandler } from './lib/core/Application';
8
8
  export { UserPrivacyOptions } from './lib/core/UserPrivacyOptions';
9
9
  export { DynatraceWebRequestTiming } from './lib/core/DynatraceWebRequestTiming';
10
10
  export { createElement } from './instrumentation/jsx/CreateElement';
11
+ export { default as HttpRequestEventBuilder } from './lib/next/events/HttpRequestEventBuilder'
@@ -1 +1 @@
1
- var o,n=require("@babel/runtime/helpers/interopRequireDefault"),e=n(require("@babel/runtime/helpers/toConsumableArray")),l=(Object.defineProperty(exports,"t",{value:!0}),exports.instrument=void 0,require("path")),i=require("jscodeshift"),u=require("jscodeshift/src/Collection"),r=require("../scripts/FileOperationHelper"),c=require("../scripts/PathsConstants"),f=require("../lib/core/util/GetValuesFromPackage"),t=require("../scripts/util/InstrumentUtil"),a=require("./libs/react-native/Touchables.InstrInfo"),s=require("./libs/react-native/RefreshControl.InstrInfo"),d=require("./libs/react-native/Switch.InstrInfo"),v=require("./libs/community/gesture-handler/Touchables.InstrInfo"),p=require("./libs/community/Picker.InstrInfo"),m=require("./model/Types"),y=require("./parser/ParserUtil"),g=((n=>{n[n.i=-1]="Filtered",n[n.u=0]="Normal",n[n.o=1]="ReactNative",n[n.l=2]="React",n[n.v=3]="ReactNativeCssInterop"})(o=o||{}),[]),b=(g.push.apply(g,(0,e.default)(a.instrumentationInfo)),g.push.apply(g,(0,e.default)(s.instrumentationInfo)),g.push.apply(g,(0,e.default)(d.instrumentationInfo)),g.push.apply(g,(0,e.default)(v.instrumentationInfo)),g.push.apply(g,(0,e.default)(p.instrumentationInfo)),["AppRegistry","AppRegistryImpl","renderApplication","setUpErrorHandling"]),U="@dynatrace/react-native-plugin/instrumentation/libs",instrument=function(n,e,r){e=k(e);var t,i=K(e);if(i!==o.i){var u=!1,a=I(e,n);if(i===o.l)w(a),u=!0;else if(i===o.o)e.endsWith("AppRegistryImpl.js")?null!=r&&r.autoStart&&J(a)&&(u=!0):e.endsWith("AppRegistry.js")?null!=r&&r.autoStart&&M(a)&&(u=!0):e.endsWith("renderApplication.js")?(q(a),u=!0):e.endsWith("setUpErrorHandling.js")&&void 0!==r&&r.autoStart&&r.errorHandler.enabled&&(G(a,r.autoStart,r.errorHandler.reportFatalErrorAsCrash),u=!0);else if(i===o.v)u=z(a)||u;else{var i=T(e,r);if(r.custom.reactnavigation&&B(e,a))u=!0;else{if(!i.input&&!i.lifecycle)return null!=r&&r.debug&&console.log("Dynatrace - Filtered All: ".concat(e)),N(e),n;i.lifecycle&&q(a)&&(u=!0),i.input&&g.forEach(function(n){n=Y(a,n);a=n.root,u=u||n.p})}}u?(n=a.toSource({quote:"single"}),x(n,e)):N(e),null!=r&&r.debug&&u&&console.log("Dynatrace - Modified Filename: "+e)}else e.includes(l.join("@dynatrace","react-native-plugin"))&&e.endsWith(l.join("lib","core","configuration","ConfigurationPreset.js"))&&void 0!==r&&(i=(0,f.getHostAppBundleInfo)(c.default.getPackageJsonFile()),t=I(e,n),void 0!==r.lifecycle&&j(t,"getLifecycleUpdate",r.lifecycle.includeUpdate),void 0!==r.debug&&j(t,"getLogLevel",r.debug?0:1),void 0!==r.bundleName?j(t,"getBundleName",r.bundleName):null!==i&&j(t,"getBundleName",null==i?void 0:i.name),void 0!==r.bundleVersion?j(t,"getBundleVersion",r.bundleVersion):null!==i&&j(t,"getBundleVersion",null==i?void 0:i.version),void 0!==r.input&&void 0!==r.input.actionNamePrivacy&&j(t,"getActionNamePrivacy",r.input.actionNamePrivacy),void 0!==r.errorHandler&&(j(t,"isErrorHandlerEnabled",r.errorHandler.enabled),j(t,"isReportFatalErrorAsCrash",r.errorHandler.reportFatalErrorAsCrash)),r.autoStart&&j(t,"isAutoStartupEnabled",r.autoStart),n=t.toSource({quote:"single"}),x(n,e));return n},B=(exports.instrument=instrument,function(n,e){return!!O(n,e)&&(n="import { registerListener } from '".concat(U,"/react-navigation/ReactNavigation';"),e.find(i.ImportDeclaration).at(0).insertBefore(n),!0)}),O=function(n,e){var r=!1;return n.includes("react-navigation")&&n.includes("NavigationContainer.tsx")&&e.find(i.VariableDeclarator).forEach(function(n){r||null==n.value||null==n.value.id||"refContainer"!==n.value.id.name||null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.type&&"VariableDeclaration"===n.parent.value.type&&(n.parent.insertAfter("registerListener(refContainer);"),r=!0)}),r},q=function(n){var e=n.findJSXElements(),t=!1;return 0<e.length&&(n.find(i.FunctionDeclaration).forEach(function(n){var e,r=(0,u.fromPaths)([n]);0<r.findJSXElements().length&&null!=n&&null!=n.value&&null!=n.value.id&&n.value.id.name.toString()&&(e=r.find(i.ClassDeclaration),r=r.find(i.ClassExpression),0===e.length)&&0===r.length&&(A(n,m.Types.FunctionalComponent,n.value.id.name.toString()),t=!0)}),n.find(i.ClassDeclaration).forEach(function(n){0<(0,u.fromPaths)([n]).findJSXElements().length&&null!=n&&null!=n.value&&n.value.id&&n.value.id.name.toString()&&(A(n,m.Types.ClassComponent,n.value.id.name.toString()),t=!0)}),n.find(i.ArrowFunctionExpression).forEach(function(n){0<(0,u.fromPaths)([n]).findJSXElements().length&&null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.id&&null!=n.parent.value.id.name&&(A(n,m.Types.FunctionalComponent,n.parent.value.id.name),t=!0)})),t},A=function(n,e,r){for(e=i.expressionStatement(i.assignmentExpression("=",i.memberExpression(i.identifier(r),i.identifier("_dtInfo")),V(e,r)));"body"!==(null==n?void 0:n.parentPath.name);)n=n.parentPath;void 0!==n.parentPath&&n.insertAfter(e)},V=function(n,e){return i.objectExpression([i.objectProperty(i.identifier("type"),i.numericLiteral(n)),i.objectProperty(i.identifier("name"),i.stringLiteral(e))])},j=function(n,e,r){var n=n.find(i.Identifier).filter(function(n){return n.node.name===e});1===n.length&&"ReturnStatement"===(n=n.paths()[0].parent.value.body.body[0]).type&&("boolean"==typeof r&&(n.argument=i.booleanLiteral(r)),"string"==typeof r&&(n.argument=i.stringLiteral(r)),"number"==typeof r)&&(n.argument=i.numericLiteral(r))},I=function(n,e){return i.withParser((0,y.chooseParser)(n,e))(e)},k=function(n){return l.isAbsolute(n)?n.replace(c.default.getApplicationPath()+l.sep,""):n},N=function(n){try{var e=l.join(c.default.getBuildPath(),n+t.INSTRUMENTED_FILE_EXTENSION);r.default.checkIfFileExistsSync(e),r.default.deleteFileSync(e)}catch(n){}},x=function(n,e){e=l.join(c.default.getBuildPath(),e);try{r.default.checkIfFileExistsSync(l.dirname(e))}catch(n){r.default.createDirectorySync(l.dirname(e))}r.default.writeTextToFileSync(e+t.INSTRUMENTED_FILE_EXTENSION,n)},T=function(n,e){var r={input:!1,lifecycle:!1};return void 0!==e&&(void 0!==e.lifecycle&&void 0!==e.lifecycle.instrument&&e.lifecycle.instrument(n)&&(r.lifecycle=!0),void 0!==e.input)&&void 0!==e.input.instrument&&e.input.instrument(n)&&(r.input=!0),r},w=function(n){var e,n=n.find(i.Program);1===n.length&&(e=i.expressionStatement(i.callExpression(i.memberExpression(i.callExpression(i.identifier("require"),[i.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")]),i.identifier("instrumentCreateElement")),[i.memberExpression(i.identifier("module"),i.identifier("exports"))])),n.paths()[0].node.body.push(e))},J=function(n){var e=n.find(i.FunctionDeclaration,{id:{name:"runApplication"}});return 1===e.length&&(D(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),H(e.get().value.body.body,0,_("_DynatraceApplicationHandler","startup",[])),!0)},M=function(n){var e=n.find(i.ObjectMethod,{key:{name:"runApplication"}});return 1===e.length&&(D(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),H(e.get().value.body.body,0,_("_DynatraceApplicationHandler","startup",[])),!0)},G=function(n,e,r){n=n.paths()[0].value.program.body;null!=n&&(H(n,n.length,L({m:"_DynatraceErrorHandler",module:"@dynatrace/react-native-plugin/lib/core/ErrorHandler",reference:""})),H(n,n.length,_("_DynatraceErrorHandler","registerErrorHandler",[i.literal(r)])))},z=function(n){var e=!1,n=n.find(i.CallExpression,{callee:{name:"require"}});return n.find(i.Literal,{value:"react/jsx-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-runtime",e=!0,n}),n.find(i.Literal,{value:"react/jsx-dev-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-dev-runtime",e=!0,n}),e},H=function(n,e){for(var r=arguments.length,t=new Array(2<r?r-2:0),i=2;i<r;i++)t[i-2]=arguments[i];return n.splice.apply(n,[e,0].concat(t))},K=function(n){if(n.includes("@dynatrace"))return o.i;var e=l.extname(n);if(".js"!==e&&".ts"!==e&&".tsx"!==e&&".jsx"!==e)return o.i;for(var r=l.parse(n),t=r.dir.split(l.sep),i=0;i<t.length;i++)if("node_modules"===t[i]){if("react-native"===t[i+1]||"create-react-class"===t[i+1]||"react-clone-referenced-element"===t[i+1])return b.includes(r.name)?o.o:o.i;if("react"===t[i+1]&&"index"===r.name)return o.l;if("react-native-css-interop"===t[i+1]&&("jsx-runtime"===r.name||"jsx-dev-runtime"===r.name))return o.v}return o.u},Q=function(n,e,r){var t=W(n,e,r);return X(n,e,r)||t},W=function(n,e,r){var t=Z(n,e);return 0<t.length&&(void 0!==(t=R(t,e.reference,!1))&&(r.m=t.localName),un(n,r),!0)},X=function(n,e,r){var t=E(n,e.module);if(1===t.length){t=R(t,e.reference,!0);if(void 0!==t)return an(n,r.defaultImport,t.localName,"ImportNamespaceSpecifier"===t.type),!0}return!1},Y=function(n,e){var r=JSON.parse(JSON.stringify(e.new));return{root:n,p:Q(n,e.old,r)||$(n,e.old,e.new.defaultImport)}},Z=function(n,e){return n.find(i.ImportDeclaration).filter(function(n){return n.node.source.value===e.module&&null!=n.node.specifiers&&n.node.specifiers.some(function(n){return h(n)&&n.imported.name===e.reference||n.local&&n.local.name===e.reference})})},h=function(n){return void 0!==n.imported},$=function(n,e,r){var t=!1;return n.find(i.CallExpression).filter(function(n){return nn(n.node.callee)&&en(n.node.arguments[0])&&n.node.arguments[0].value===e.module&&void 0!==n.parent}).forEach(function(n){(void 0===n.parent.value.property||void 0!==n.parent.value.property&&void 0!==n.parent.value.property.name&&n.parent.value.property.name===e.reference)&&(n.node.arguments[0].value=r,t=t||!0)}),t},nn=function(n){return"require"===n.name},en=function(n){return"StringLiteral"===n.type||"Literal"===n.type},E=function(n,e){return n.find(i.ImportDeclaration).filter(function(n){return n.node.source.value===e})},R=function(n,r,t){var i;return n.forEach(function(n){void 0!==n.node.specifiers&&(n.node.specifiers=n.node.specifiers.filter(function(n){var e;return h(n)&&!t?((e=n.imported.name!==r)||null==n.local||n.imported.name===n.local.name||(i={localName:n.local.name.toString(),type:n.type}),e):!(!h(n)&&t&&(null!=n.local&&(i={localName:n.local.name.toString(),type:n.type}),1))}),0===n.node.specifiers.length)&&n.prune()}),i},rn=function(n,e){n.find(i.ImportDeclaration).filter(function(n){return n.node.source.value===e.module}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(P(e))})},tn=function(n,e,r){n.find(i.ImportDeclaration).filter(function(n){return n.node.source.value===e}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(r)})},C=function(n,e,r){var t=n.find(i.ImportDeclaration);0<t.length?i(t.paths()[0]).insertAfter(F(e,r)):1===(t=n.find(i.Program)).length&&t.paths()[0].node.body.unshift(F(e,r))},un=function(n,e){0<E(n,e.module).length?rn(n,e):C(n,e.module,[P(e)])},an=function(n,e,r,t){var i=E(n,e),t=(t?dn:sn)(r);0<i.length?tn(n,e,t):C(n,e,[t])},D=function(n,e){n=n.find(i.VariableDeclaration);0<n.length&&i(n.paths()[0]).insertAfter(L(e))},_=function(n,e,r){return i.expressionStatement(on(n,e,r))},on=function(n,e,r){return i.callExpression(fn(n,e),r)},L=function(n){return i.variableDeclaration("var",[ln(n)])},ln=function(n){return i.variableDeclarator(void 0!==n.m?i.identifier(n.m):i.identifier(n.reference),(0<n.reference.length?cn:S)(n))},cn=function(n){return i.memberExpression(S(n),i.identifier(n.reference))},fn=function(n,e){return i.memberExpression(i.identifier(n),i.identifier(e))},S=function(n){return i.callExpression(i.identifier("require"),[i.literal(n.module)])},F=function(n,e){return i.importDeclaration(e,i.literal(n))},P=function(n){return void 0!==n.m?i.importSpecifier(i.identifier(n.reference),i.identifier(n.m)):i.importSpecifier(i.identifier(n.reference))},sn=function(n){return i.importDefaultSpecifier(i.identifier(n))},dn=function(n){return i.importNamespaceSpecifier(i.identifier(n))};
1
+ var o,n=require("@babel/runtime/helpers/interopRequireDefault"),e=n(require("@babel/runtime/helpers/toConsumableArray")),c=(Object.defineProperty(exports,"t",{value:!0}),exports.instrument=void 0,require("path")),u=require("jscodeshift"),i=require("jscodeshift/src/Collection"),r=require("../scripts/FileOperationHelper"),l=require("../scripts/PathsConstants"),f=require("../lib/core/util/GetValuesFromPackage"),t=require("../scripts/util/InstrumentUtil"),a=require("./libs/react-native/Touchables.InstrInfo"),s=require("./libs/react-native/RefreshControl.InstrInfo"),v=require("./libs/react-native/Switch.InstrInfo"),d=require("./libs/community/gesture-handler/Touchables.InstrInfo"),p=require("./libs/community/Picker.InstrInfo"),m=require("./model/Types"),y=require("./parser/ParserUtil"),g=((n=>{n[n.i=-1]="Filtered",n[n.u=0]="Normal",n[n.o=1]="ReactNative",n[n.l=2]="React",n[n.v=3]="ReactNativeCssInterop"})(o=o||{}),[]),q=(g.push.apply(g,(0,e.default)(a.instrumentationInfo)),g.push.apply(g,(0,e.default)(s.instrumentationInfo)),g.push.apply(g,(0,e.default)(v.instrumentationInfo)),g.push.apply(g,(0,e.default)(d.instrumentationInfo)),g.push.apply(g,(0,e.default)(p.instrumentationInfo)),["AppRegistry","AppRegistryImpl","renderApplication","ExceptionsManager"]),b="@dynatrace/react-native-plugin/instrumentation/libs",instrument=function(n,e,r){e=T(e);var t=z(e);if(t!==o.i){var i=!1,u=I(e,n);if(t===o.l)k(u),i=!0;else if(t===o.o)e.endsWith("AppRegistryImpl.js")?null!=r&&r.autoStart&&U(u)&&(i=!0):e.endsWith("AppRegistry.js")?null!=r&&r.autoStart&&w(u)&&(i=!0):e.endsWith("renderApplication.js")?(A(u),i=!0):e.endsWith("ExceptionsManager.js")&&(a=void 0!==r&&r.autoStart&&r.errorHandler.enabled,J(u,r.errorHandler.reportFatalErrorAsCrash,a),i=!0);else if(t===o.v)i=G(u)||i;else{var a=V(e,r);if(r.custom.reactnavigation&&B(e,u))i=!0;else{if(!a.input&&!a.lifecycle)return null!=r&&r.debug&&console.log("Dynatrace - Filtered All: ".concat(e)),h(e),n;a.lifecycle&&A(u)&&(i=!0),a.input&&g.forEach(function(n){n=X(u,n);u=n.root,i=i||n.p})}}i?(n=u.toSource({quote:"single"}),N(n,e)):h(e),null!=r&&r.debug&&i&&console.log("Dynatrace - Modified Filename: "+e)}else e.includes(c.join("@dynatrace","react-native-plugin"))&&e.endsWith(c.join("lib","core","configuration","ConfigurationPreset.js"))&&void 0!==r&&(t=(0,f.getHostAppBundleInfo)(l.default.getPackageJsonFile()),a=I(e,n),void 0!==r.lifecycle&&j(a,"getLifecycleUpdate",r.lifecycle.includeUpdate),void 0!==r.debug&&j(a,"getLogLevel",r.debug?0:1),void 0!==r.bundleName?j(a,"getBundleName",r.bundleName):null!==t&&j(a,"getBundleName",null==t?void 0:t.name),void 0!==r.bundleVersion?j(a,"getBundleVersion",r.bundleVersion):null!==t&&j(a,"getBundleVersion",null==t?void 0:t.version),void 0!==r.input&&void 0!==r.input.actionNamePrivacy&&j(a,"getActionNamePrivacy",r.input.actionNamePrivacy),void 0!==r.errorHandler&&(j(a,"isErrorHandlerEnabled",r.errorHandler.enabled),j(a,"isReportFatalErrorAsCrash",r.errorHandler.reportFatalErrorAsCrash)),r.autoStart&&j(a,"isAutoStartupEnabled",r.autoStart),n=a.toSource({quote:"single"}),N(n,e));return n},B=(exports.instrument=instrument,function(n,e){return!!M(n,e)&&(n="import { registerListener } from '".concat(b,"/react-navigation/ReactNavigation';"),e.find(u.ImportDeclaration).at(0).insertBefore(n),!0)}),M=function(n,e){var r=!1;return n.includes("react-navigation")&&n.includes("NavigationContainer.tsx")&&e.find(u.VariableDeclarator).forEach(function(n){r||null==n.value||null==n.value.id||"refContainer"!==n.value.id.name||null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.type&&"VariableDeclaration"===n.parent.value.type&&(n.parent.insertAfter("registerListener(refContainer);"),r=!0)}),r},A=function(n){var e=n.findJSXElements(),t=!1;return 0<e.length&&(n.find(u.FunctionDeclaration).forEach(function(n){var e,r=(0,i.fromPaths)([n]);0<r.findJSXElements().length&&null!=n&&null!=n.value&&null!=n.value.id&&n.value.id.name.toString()&&(e=r.find(u.ClassDeclaration),r=r.find(u.ClassExpression),0===e.length)&&0===r.length&&(x(n,m.Types.FunctionalComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ClassDeclaration).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n&&null!=n.value&&n.value.id&&n.value.id.name.toString()&&(x(n,m.Types.ClassComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ArrowFunctionExpression).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.id&&null!=n.parent.value.id.name&&(x(n,m.Types.FunctionalComponent,n.parent.value.id.name),t=!0)})),t},x=function(n,e,r){for(e=u.expressionStatement(u.assignmentExpression("=",u.memberExpression(u.identifier(r),u.identifier("_dtInfo")),O(e,r)));"body"!==(null==n?void 0:n.parentPath.name);)n=n.parentPath;void 0!==n.parentPath&&n.insertAfter(e)},O=function(n,e){return u.objectExpression([u.objectProperty(u.identifier("type"),u.numericLiteral(n)),u.objectProperty(u.identifier("name"),u.stringLiteral(e))])},j=function(n,e,r){var n=n.find(u.Identifier).filter(function(n){return n.node.name===e});1===n.length&&"ReturnStatement"===(n=n.paths()[0].parent.value.body.body[0]).type&&("boolean"==typeof r&&(n.argument=u.booleanLiteral(r)),"string"==typeof r&&(n.argument=u.stringLiteral(r)),"number"==typeof r)&&(n.argument=u.numericLiteral(r))},I=function(n,e){return u.withParser((0,y.chooseParser)(n,e))(e)},T=function(n){return c.isAbsolute(n)?n.replace(l.default.getApplicationPath()+c.sep,""):n},h=function(n){try{var e=c.join(l.default.getBuildPath(),n+t.INSTRUMENTED_FILE_EXTENSION);r.default.checkIfFileExistsSync(e),r.default.deleteFileSync(e)}catch(n){}},N=function(n,e){e=c.join(l.default.getBuildPath(),e);try{r.default.checkIfFileExistsSync(c.dirname(e))}catch(n){r.default.createDirectorySync(c.dirname(e))}r.default.writeTextToFileSync(e+t.INSTRUMENTED_FILE_EXTENSION,n)},V=function(n,e){var r={input:!1,lifecycle:!1};return void 0!==e&&(void 0!==e.lifecycle&&void 0!==e.lifecycle.instrument&&e.lifecycle.instrument(n)&&(r.lifecycle=!0),void 0!==e.input)&&void 0!==e.input.instrument&&e.input.instrument(n)&&(r.input=!0),r},k=function(n){var e,n=n.find(u.Program);1===n.length&&(e=u.expressionStatement(u.callExpression(u.memberExpression(u.callExpression(u.identifier("require"),[u.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")]),u.identifier("instrumentCreateElement")),[u.memberExpression(u.identifier("module"),u.identifier("exports"))])),n.paths()[0].node.body.push(e))},U=function(n){var e=n.find(u.FunctionDeclaration,{id:{name:"runApplication"}});return 1===e.length&&(_(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,F("_DynatraceApplicationHandler","startup",[])),!0)},w=function(n){var e=n.find(u.ObjectMethod,{key:{name:"runApplication"}});return 1===e.length&&(_(n,{m:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,F("_DynatraceApplicationHandler","startup",[])),!0)},J=function(n,r,t){var i=u;n.find(i.FunctionDeclaration,{id:{name:"handleException"}}).forEach(function(n){var e=i.expressionStatement(i.callExpression(i.memberExpression(i.callExpression(i.identifier("require"),[i.literal("@dynatrace/react-native-plugin/lib/core/ErrorHandler")]),i.identifier("reportErrorToDynatrace")),[i.identifier("e"),i.identifier("isFatal"),i.literal(r),i.literal(t)]));n.node.body.body.unshift(e)})},G=function(n){var e=!1,n=n.find(u.CallExpression,{callee:{name:"require"}});return n.find(u.Literal,{value:"react/jsx-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-runtime",e=!0,n}),n.find(u.Literal,{value:"react/jsx-dev-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-dev-runtime",e=!0,n}),e},R=function(n,e){for(var r=arguments.length,t=new Array(2<r?r-2:0),i=2;i<r;i++)t[i-2]=arguments[i];return n.splice.apply(n,[e,0].concat(t))},z=function(n){if(n.includes("@dynatrace"))return o.i;var e=c.extname(n);if(".js"!==e&&".ts"!==e&&".tsx"!==e&&".jsx"!==e)return o.i;for(var r=c.parse(n),t=r.dir.split(c.sep),i=0;i<t.length;i++)if("node_modules"===t[i]){if("react-native"===t[i+1]||"create-react-class"===t[i+1]||"react-clone-referenced-element"===t[i+1])return q.includes(r.name)?o.o:o.i;if("react"===t[i+1]&&"index"===r.name)return o.l;if("react-native-css-interop"===t[i+1]&&("jsx-runtime"===r.name||"jsx-dev-runtime"===r.name))return o.v}return o.u},K=function(n,e,r){var t=Q(n,e,r);return W(n,e,r)||t},Q=function(n,e,r){var t=Y(n,e);return 0<t.length&&(void 0!==(t=H(t,e.reference,!1))&&(r.m=t.localName),tn(n,r),!0)},W=function(n,e,r){var t=E(n,e.module);if(1===t.length){t=H(t,e.reference,!0);if(void 0!==t)return un(n,r.defaultImport,t.localName,"ImportNamespaceSpecifier"===t.type),!0}return!1},X=function(n,e){var r=JSON.parse(JSON.stringify(e.new));return{root:n,p:K(n,e.old,r)||Z(n,e.old,e.new.defaultImport)}},Y=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module&&null!=n.node.specifiers&&n.node.specifiers.some(function(n){return C(n)&&n.imported.name===e.reference||n.local&&n.local.name===e.reference})})},C=function(n){return void 0!==n.imported},Z=function(n,e,r){var t=!1;return n.find(u.CallExpression).filter(function(n){return $(n.node.callee)&&nn(n.node.arguments[0])&&n.node.arguments[0].value===e.module&&void 0!==n.parent}).forEach(function(n){(void 0===n.parent.value.property||void 0!==n.parent.value.property&&void 0!==n.parent.value.property.name&&n.parent.value.property.name===e.reference)&&(n.node.arguments[0].value=r,t=t||!0)}),t},$=function(n){return"require"===n.name},nn=function(n){return"StringLiteral"===n.type||"Literal"===n.type},E=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e})},H=function(n,r,t){var i;return n.forEach(function(n){void 0!==n.node.specifiers&&(n.node.specifiers=n.node.specifiers.filter(function(n){var e;return C(n)&&!t?((e=n.imported.name!==r)||null==n.local||n.imported.name===n.local.name||(i={localName:n.local.name.toString(),type:n.type}),e):!(!C(n)&&t&&(null!=n.local&&(i={localName:n.local.name.toString(),type:n.type}),1))}),0===n.node.specifiers.length)&&n.prune()}),i},en=function(n,e){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(P(e))})},rn=function(n,e,r){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(r)})},D=function(n,e,r){var t=n.find(u.ImportDeclaration);0<t.length?u(t.paths()[0]).insertAfter(S(e,r)):1===(t=n.find(u.Program)).length&&t.paths()[0].node.body.unshift(S(e,r))},tn=function(n,e){0<E(n,e.module).length?en(n,e):D(n,e.module,[P(e)])},un=function(n,e,r,t){var i=E(n,e),t=(t?vn:sn)(r);0<i.length?rn(n,e,t):D(n,e,[t])},_=function(n,e){n=n.find(u.VariableDeclaration);0<n.length&&u(n.paths()[0]).insertAfter(on(e))},F=function(n,e,r){return u.expressionStatement(an(n,e,r))},an=function(n,e,r){return u.callExpression(fn(n,e),r)},on=function(n){return u.variableDeclaration("var",[cn(n)])},cn=function(n){return u.variableDeclarator(void 0!==n.m?u.identifier(n.m):u.identifier(n.reference),(0<n.reference.length?ln:L)(n))},ln=function(n){return u.memberExpression(L(n),u.identifier(n.reference))},fn=function(n,e){return u.memberExpression(u.identifier(n),u.identifier(e))},L=function(n){return u.callExpression(u.identifier("require"),[u.literal(n.module)])},S=function(n,e){return u.importDeclaration(e,u.literal(n))},P=function(n){return void 0!==n.m?u.importSpecifier(u.identifier(n.reference),u.identifier(n.m)):u.importSpecifier(u.identifier(n.reference))},sn=function(n){return u.importDefaultSpecifier(u.identifier(n))},vn=function(n){return u.importNamespaceSpecifier(u.identifier(n))};
@@ -5,7 +5,6 @@ const Types_1 = require("../model/Types");
5
5
  const Dynatrace_1 = require("../../lib/core/Dynatrace");
6
6
  const Picker_1 = require("./components/Picker");
7
7
  const RefreshControl_1 = require("./components/RefreshControl");
8
- const Switch_1 = require("./components/Switch");
9
8
  const FunctionalComponent_1 = require("./components/FunctionalComponent");
10
9
  const ClassComponent_1 = require("./components/ClassComponent");
11
10
  const instrumentCreateElement = (reactModule) => {
@@ -38,10 +37,6 @@ const modifyElement = (type, props) => {
38
37
  props.onRefresh != null) {
39
38
  (0, RefreshControl_1.RefreshControlHelper)(Dynatrace_1.Dynatrace).attachOnRefresh(props);
40
39
  }
41
- else if (type._dtInfo.type === Types_1.Types.Switch &&
42
- props.onValueChange != null) {
43
- (0, Switch_1.SwitchHelper)(Dynatrace_1.Dynatrace).attachOnValueChange(props);
44
- }
45
40
  else if (props.onValueChange != null &&
46
41
  type._dtInfo.type === Types_1.Types.Picker) {
47
42
  (0, Picker_1.PickerHelper)(Dynatrace_1.Dynatrace).attachOnValueChange(props);
@@ -1,15 +1,58 @@
1
1
  "use strict";
2
- var _a;
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
3
13
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.Switch = void 0;
14
+ exports.wrapOnValueChange = exports.Switch = void 0;
5
15
  const react_native_1 = require("react-native");
6
- const Types_1 = require("../../model/Types");
7
- if (typeof react_native_1.Switch === 'object') {
8
- exports.Switch = Object.assign({ _dtInfo: { type: Types_1.Types.Switch } }, react_native_1.Switch);
9
- }
10
- else {
11
- exports.Switch = (_a = class Switch extends react_native_1.Switch {
12
- },
13
- _a._dtInfo = { type: Types_1.Types.Switch },
14
- _a);
15
- }
16
+ const React = require("react");
17
+ const ConfigurationHandler_1 = require("../../../lib/core/configuration/ConfigurationHandler");
18
+ const Dynatrace_1 = require("../../../lib/core/Dynatrace");
19
+ const ComponentUtil_1 = require("../../jsx/components/ComponentUtil");
20
+ exports.Switch = React.forwardRef((_a, ref) => {
21
+ var { onValueChange } = _a, rest = __rest(_a, ["onValueChange"]);
22
+ const shouldWrap = (0, ComponentUtil_1.isDynatraceIgnored)(rest) || !onValueChange;
23
+ const wrappedOnValueChange = shouldWrap
24
+ ? onValueChange
25
+ : (0, exports.wrapOnValueChange)(onValueChange, rest);
26
+ return (React.createElement(react_native_1.Switch, Object.assign({ ref: ref, onValueChange: wrappedOnValueChange }, rest)));
27
+ });
28
+ const wrapOnValueChange = (onValueChange, switchProps) => (value) => {
29
+ const switchName = findSwitchName(switchProps);
30
+ const action = Dynatrace_1.Dynatrace.enterAutoAction(`Touch on ${switchName} to ${value}`);
31
+ let isSync = true;
32
+ try {
33
+ const returnValue = onValueChange(value);
34
+ if (returnValue instanceof Promise) {
35
+ isSync = false;
36
+ return Promise.resolve(returnValue).finally(() => {
37
+ action.leaveAction();
38
+ });
39
+ }
40
+ }
41
+ finally {
42
+ if (isSync) {
43
+ action.leaveAction();
44
+ }
45
+ }
46
+ };
47
+ exports.wrapOnValueChange = wrapOnValueChange;
48
+ const findSwitchName = (switchProps) => {
49
+ var _a;
50
+ if (switchProps.dtActionName) {
51
+ return switchProps.dtActionName;
52
+ }
53
+ if (ConfigurationHandler_1.ConfigurationHandler.isConfigurationAvailable() &&
54
+ ConfigurationHandler_1.ConfigurationHandler.isActionNamePrivacyEnabled()) {
55
+ return 'Switch';
56
+ }
57
+ return (_a = switchProps.accessibilityLabel) !== null && _a !== void 0 ? _a : 'Switch';
58
+ };
@@ -71,7 +71,7 @@ const findTouchableName = (props) => {
71
71
  return props.accessibilityLabel;
72
72
  }
73
73
  if (typeof props.children === 'function') {
74
- return findTouchableNameRecursive(props.children({ pressed: false }));
74
+ return null;
75
75
  }
76
76
  return findTouchableNameRecursive(props.children);
77
77
  };
@@ -33,7 +33,7 @@ exports.Dynatrace = {
33
33
  if (configuration !== undefined) {
34
34
  yield DynatraceBridge_1.DynatraceNative.start(configuration);
35
35
  if (configuration.errorHandler) {
36
- (0, ErrorHandler_1.registerErrorHandler)(configuration.reportFatalErrorAsCrash);
36
+ (0, ErrorHandler_1.startErrorHandler)(configuration.reportFatalErrorAsCrash);
37
37
  }
38
38
  else {
39
39
  logger.debug('Dynatrace error handler will not be enabled as errorHandler was set to false!');
@@ -353,4 +353,7 @@ exports.Dynatrace = {
353
353
  sendExceptionEvent: (error, fields) => {
354
354
  Dynatrace_1.Dynatrace.sendExceptionEvent(error, fields);
355
355
  },
356
+ sendHttpRequestEvent(httpRequestEventBuilder) {
357
+ Dynatrace_1.Dynatrace.sendHttpRequestEvent(httpRequestEventBuilder);
358
+ },
356
359
  };
@@ -1,56 +1,40 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports._reportErrorToDynatrace = exports.registerErrorHandler = void 0;
4
- const react_native_1 = require("react-native");
3
+ exports.reportErrorToDynatrace = exports.startErrorHandler = void 0;
5
4
  const DynatraceInternal_1 = require("./DynatraceInternal");
6
5
  const Dynatrace_1 = require("./Dynatrace");
7
6
  const StringUtils_1 = require("./util/StringUtils");
8
7
  const ConsoleLogger_1 = require("./logging/ConsoleLogger");
9
- let _isReportFatalErrorAsCrash = true;
10
- const _isReactNativeGlobal = (globalScope) => globalScope.ErrorUtils !== undefined;
11
8
  const logger = new ConsoleLogger_1.ConsoleLogger('ErrorHandler');
12
- const registerErrorHandler = (reportFatalErrorAsCrash) => {
13
- if (global !== undefined && _isReactNativeGlobal(global)) {
14
- _isReportFatalErrorAsCrash = reportFatalErrorAsCrash;
15
- const oldHandler = global.ErrorUtils.getGlobalHandler();
16
- global.ErrorUtils.setGlobalHandler((error, isFatal) => {
17
- (0, exports._reportErrorToDynatrace)(error, isFatal, oldHandler);
18
- });
19
- const setter = global.ErrorUtils.setGlobalHandler;
20
- global.ErrorUtils.setGlobalHandler = (errorHandler) => {
21
- setter((error, isFatal) => {
22
- (0, exports._reportErrorToDynatrace)(error, isFatal, errorHandler);
23
- });
24
- };
25
- }
9
+ let manualStart = { enabled: false };
10
+ const startErrorHandler = (reportFatalErrorAsCrash) => {
11
+ manualStart = {
12
+ enabled: true,
13
+ reportFatalErrorAsCrash: reportFatalErrorAsCrash,
14
+ };
26
15
  };
27
- exports.registerErrorHandler = registerErrorHandler;
28
- const _reportErrorToDynatrace = (exception, isFatal, oldHandler) => {
16
+ exports.startErrorHandler = startErrorHandler;
17
+ const reportErrorToDynatrace = (exception, isFatal, reportFatalErrorAsCrashFromConfig, autoStart) => {
18
+ if (!autoStart && !manualStart)
19
+ return;
20
+ const reportFatalErrorAsCrash = manualStart.enabled
21
+ ? manualStart.reportFatalErrorAsCrash
22
+ : reportFatalErrorAsCrashFromConfig;
29
23
  if (exception != null && isExceptionAnError(exception)) {
30
24
  if (!StringUtils_1.StringUtils.isStringNullEmptyOrUndefined(exception.name)) {
31
25
  if (isFatal === undefined) {
32
26
  isFatal = false;
33
27
  }
34
- DynatraceInternal_1.DynatraceInternal.reportErrorFromHandler(isFatal, String(exception.name), adjustedReason(exception.message), exception.stack != null ? exception.stack : '', _isReportFatalErrorAsCrash);
35
- logger.debug(`_reportErrorToDynatrace(${exception}, ${isFatal})`);
28
+ DynatraceInternal_1.DynatraceInternal.reportErrorFromHandler(isFatal, String(exception.name), adjustedReason(exception.message), exception.stack != null ? exception.stack : '', reportFatalErrorAsCrash);
29
+ logger.debug(`reportErrorToDynatrace(${exception}, ${isFatal})`);
36
30
  }
37
31
  }
38
32
  else {
39
33
  Dynatrace_1.Dynatrace.reportError(String(exception), -1);
40
- logger.debug(`_reportErrorToDynatrace(${exception}, -1)`);
41
- }
42
- if (oldHandler !== undefined) {
43
- if (react_native_1.Platform.OS === 'ios') {
44
- setTimeout(() => {
45
- oldHandler(exception, isFatal);
46
- }, 200);
47
- }
48
- else {
49
- oldHandler(exception, isFatal);
50
- }
34
+ logger.debug(`reportErrorToDynatrace(${exception}, -1)`);
51
35
  }
52
36
  };
53
- exports._reportErrorToDynatrace = _reportErrorToDynatrace;
37
+ exports.reportErrorToDynatrace = reportErrorToDynatrace;
54
38
  const adjustedReason = (reason) => {
55
39
  if (!StringUtils_1.StringUtils.isStringNullEmptyOrUndefined(reason)) {
56
40
  const reasonNewLineIndex = reason.indexOf('\n');
@@ -42,8 +42,7 @@ class DynatraceImpl {
42
42
  const eventTimestamp = new EventTimestamp_1.EventTimestamp(this.timestampProvider);
43
43
  const event = Object.assign(Object.assign({}, (0, EventCreator_1.createCrashEvent)(crash.name, crash.message, crash.stack, isFatal)), eventTimestamp.getEventTimeInfo());
44
44
  if (isApiReported) {
45
- event["characteristics.is_api_reported"] =
46
- true;
45
+ (0, EventModifierUtil_1.addIsApiReported)(event);
47
46
  event["dt.support.is_legacy_api_reported"] = true;
48
47
  }
49
48
  EventPipeline_1.EventPipeline.insertEvent(event);
@@ -53,8 +52,7 @@ class DynatraceImpl {
53
52
  const eventTimestamp = new EventTimestamp_1.EventTimestamp(this.timestampProvider);
54
53
  const event = Object.assign(Object.assign({}, (0, EventCreator_1.createErrorCodeEvent)(errorName, errorCode)), eventTimestamp.getEventTimeInfo());
55
54
  if (isApiReported) {
56
- event["characteristics.is_api_reported"] =
57
- true;
55
+ (0, EventModifierUtil_1.addIsApiReported)(event);
58
56
  event["dt.support.is_legacy_api_reported"] = true;
59
57
  }
60
58
  EventPipeline_1.EventPipeline.insertEvent(event);
@@ -64,8 +62,7 @@ class DynatraceImpl {
64
62
  const eventTimestamp = new EventTimestamp_1.EventTimestamp(this.timestampProvider);
65
63
  const event = Object.assign(Object.assign({}, (0, EventCreator_1.createErrorEvent)(error.name, error.message, error.stack)), eventTimestamp.getEventTimeInfo());
66
64
  if (isApiReported) {
67
- event["characteristics.is_api_reported"] =
68
- true;
65
+ (0, EventModifierUtil_1.addIsApiReported)(event);
69
66
  event["dt.support.is_legacy_api_reported"] = true;
70
67
  }
71
68
  EventPipeline_1.EventPipeline.insertEvent(event);
@@ -76,15 +73,14 @@ class DynatraceImpl {
76
73
  const event = Object.assign({}, (0, EventCreator_1.createErrorEvent)(error.name, error.message, error.stack));
77
74
  let eventValidated = SendEventValidation_1.SendEventValidation.modifyEvent(fieldsCheck);
78
75
  eventValidated = Object.assign(Object.assign({}, event), eventValidated);
79
- eventValidated["characteristics.is_api_reported"] = true;
76
+ (0, EventModifierUtil_1.addIsApiReported)(eventValidated);
80
77
  EventPipeline_1.EventPipeline.insertEvent(eventValidated);
81
78
  }
82
79
  sendEvent(properties, context) {
83
80
  this.logger.debug(`sendEvent(${JSON.stringify(properties, context)})`);
84
81
  const eventValidated = SendEventValidation_1.SendEventValidation.modifyEvent(properties);
85
- if (eventValidated != null && (0, EventModifierUtil_1.containEventProperties)(eventValidated)) {
86
- eventValidated["characteristics.has_event_properties"] = true;
87
- }
82
+ (0, EventModifierUtil_1.flagEventProperties)(eventValidated);
83
+ (0, EventModifierUtil_1.addIsApiReported)(eventValidated);
88
84
  EventPipeline_1.EventPipeline.insertEvent(eventValidated, context);
89
85
  }
90
86
  sendSessionPropertyEvent(properties) {
@@ -94,7 +90,14 @@ class DynatraceImpl {
94
90
  (0, EventModifierUtil_1.containSessionProperties)(eventValidated)) {
95
91
  eventValidated["characteristics.has_session_properties"] = true;
96
92
  }
93
+ (0, EventModifierUtil_1.addIsApiReported)(eventValidated);
97
94
  EventPipeline_1.EventPipeline.insertEvent(eventValidated);
98
95
  }
96
+ sendHttpRequestEvent(httpRequestEventBuilder) {
97
+ const sanitizedEvent = httpRequestEventBuilder.build();
98
+ this.logger.debug(`sendHttpRequestEvent(${JSON.stringify(sanitizedEvent)})`);
99
+ (0, EventModifierUtil_1.flagEventProperties)(sanitizedEvent);
100
+ EventPipeline_1.EventPipeline.insertEvent(sanitizedEvent);
101
+ }
99
102
  }
100
103
  exports.Dynatrace = new DynatraceImpl(TimestampProvider_1.defaultTimestampProvider);
@@ -26,7 +26,8 @@ const createErrorCodeEvent = (errorName, errorCode) => {
26
26
  'error.is_fatal': false,
27
27
  };
28
28
  if (errorName != null) {
29
- event["name"] = errorName;
29
+ event["error.name"] = errorName;
30
+ event["error.has_custom_name"] = true;
30
31
  }
31
32
  if (errorCode != null) {
32
33
  event["error.code"] = errorCode;
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ConsoleLogger_1 = require("../../core/logging/ConsoleLogger");
4
+ const SendEventValidation_1 = require("./modifier/SendEventValidation");
5
+ const TimestampProvider_1 = require("../provider/TimestampProvider");
6
+ const logger = new ConsoleLogger_1.ConsoleLogger('Dynatrace');
7
+ class HttpRequestEventBuilder {
8
+ constructor(url, requestMethod) {
9
+ this.url = url;
10
+ this.requestMethod = requestMethod;
11
+ this.duration = 0;
12
+ this.rawEventProperties = {};
13
+ this.hasDroppedTraceparent = false;
14
+ this.hasDroppedCustomProperties = false;
15
+ this.hasNfnValues = false;
16
+ this.triedToOverwriteDuration = false;
17
+ this.requestMethod =
18
+ requestMethod.toUpperCase();
19
+ }
20
+ withDuration(duration) {
21
+ this.duration = duration;
22
+ this.triedToOverwriteDuration = true;
23
+ return this;
24
+ }
25
+ withStatusCode(statusCode) {
26
+ this.statusCode = statusCode;
27
+ return this;
28
+ }
29
+ withReasonPhrase(reasonPhrase) {
30
+ this.reasonPhrase = reasonPhrase;
31
+ return this;
32
+ }
33
+ withError(error) {
34
+ this.error = error;
35
+ return this;
36
+ }
37
+ withBytesSent(bytesSent) {
38
+ this.bytesSent = bytesSent;
39
+ return this;
40
+ }
41
+ withBytesReceived(bytesReceived) {
42
+ this.bytesReceived = bytesReceived;
43
+ return this;
44
+ }
45
+ withTraceparentHeader(traceparentHeader) {
46
+ this.traceparentHeader = traceparentHeader;
47
+ return this;
48
+ }
49
+ addEventProperty(key, value) {
50
+ this.rawEventProperties[key] = value;
51
+ return this;
52
+ }
53
+ build() {
54
+ if (!this.hasValidMandatoryAttriutes()) {
55
+ logger.debug('HttpRequestEventBuilder dropped invalid event');
56
+ return null;
57
+ }
58
+ this.sanitizeDuration();
59
+ this.sanitizeStatusCode();
60
+ this.sanitizeReasonPhrase();
61
+ this.sanitizeBytesReceived();
62
+ this.sanitizeBytesSent();
63
+ const parsedTraceparentHeader = this.traceparentHeader &&
64
+ this.parseTraceparent(this.traceparentHeader);
65
+ this.hasDroppedTraceparent =
66
+ !!this.traceparentHeader && !parsedTraceparentHeader;
67
+ const hasFailedRequest = this.isStatusCodeError() || !!this.error;
68
+ const filteredEventProperties = Object.fromEntries(Object.entries(this.rawEventProperties).filter(this.isEventPropertyKey, this));
69
+ const sanitizedEventProperties = SendEventValidation_1.SendEventValidation.modifyEvent(filteredEventProperties);
70
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, sanitizedEventProperties), { ["url.full"]: this.url, ["network.protocol.name"]: 'http', ["http.request.method"]: this.requestMethod, ["duration"]: this.duration, ["start_time"]: TimestampProvider_1.defaultTimestampProvider.getCurrentTimestamp() - this.duration }), (this.triedToOverwriteDuration && {
71
+ ["dt.support.api.overridden_fields"]: [
72
+ 'duration',
73
+ ],
74
+ })), this.includeIfDefined("http.response.status_code", this.statusCode)), this.includeIfDefined("http.response.reason_phrase", this.reasonPhrase)), this.includeIfDefined("request.bytes_sent", this.bytesSent)), this.includeIfDefined("request.bytes_received", this.bytesReceived)), { ["characteristics.has_request"]: true, ["characteristics.is_api_reported"]: true }), this.includeIfTrue("characteristics.has_failed_request", hasFailedRequest)), this.includeIfTrue("characteristics.has_error", hasFailedRequest)), (this.error !== undefined && Object.assign({ ["characteristics.has_exception"]: true, ["exception.type"]: this.error.name, ["exception.message"]: this.error.message }, this.includeIfDefined("exception.stack_trace", this.error.stack)))), (parsedTraceparentHeader && {
75
+ ["trace.id"]: parsedTraceparentHeader.traceId,
76
+ ["span.id"]: parsedTraceparentHeader.spanId,
77
+ })), (this.hasDroppedTraceparent && {
78
+ ["request.trace_context_hint"]: 'invalid_header',
79
+ })), this.includeIfTrue("dt.support.api.has_dropped_custom_properties", this.hasDroppedCustomProperties)), this.includeIfTrue("dt.support.has_nfn_values", this.hasNfnValues));
80
+ }
81
+ hasValidMandatoryAttriutes() {
82
+ let isValid = true;
83
+ if (this.isInvalidUrl(this.url)) {
84
+ logger.debug(`HttpRequestEventBuilder: dropped event since given URL is malformed: ${this.url}`);
85
+ isValid = false;
86
+ }
87
+ if (!HttpRequestEventBuilder.allowedRequestMethods.includes(this.requestMethod)) {
88
+ logger.debug(`HttpRequestEventBuilder: dropped event since given Request Method is invalid: ${this.requestMethod}`);
89
+ isValid = false;
90
+ }
91
+ return isValid;
92
+ }
93
+ isInvalidUrl(url) {
94
+ try {
95
+ if (!url.match(/^(https?):\/\/[^\s/$.?#-][^\s]*$/i)) {
96
+ return true;
97
+ }
98
+ new URL(url);
99
+ return false;
100
+ }
101
+ catch (_a) {
102
+ return true;
103
+ }
104
+ }
105
+ sanitizeStatusCode() {
106
+ if (this.statusCode == undefined && this.error === undefined) {
107
+ this.statusCode = 0;
108
+ }
109
+ if (this.statusCode && this.statusCode < 0) {
110
+ logger.debug('HttpRequestEventBuilder: overriding invalid Status Code with 0');
111
+ this.statusCode = 0;
112
+ this.hasDroppedCustomProperties = true;
113
+ }
114
+ }
115
+ sanitizeReasonPhrase() {
116
+ if (this.reasonPhrase &&
117
+ this.reasonPhrase.length >
118
+ HttpRequestEventBuilder.maxReasonPhraseLength) {
119
+ logger.debug(`HttpRequestEventBuilder: trimming too long Reason Phrase to a length of ${HttpRequestEventBuilder.maxReasonPhraseLength}`);
120
+ this.reasonPhrase = this.reasonPhrase.slice(0, HttpRequestEventBuilder.maxReasonPhraseLength);
121
+ }
122
+ }
123
+ sanitizeDuration() {
124
+ this.hasNfnValues || (this.hasNfnValues = !Number.isFinite(this.duration));
125
+ if (!Number.isFinite(this.duration) || this.duration < 0) {
126
+ logger.debug('HttpRequestEventBuilder: overriding invalid Duration with 0');
127
+ this.duration = 0;
128
+ this.hasDroppedCustomProperties = true;
129
+ }
130
+ }
131
+ sanitizeBytesSent() {
132
+ if (this.bytesSent && this.bytesSent < 0) {
133
+ logger.debug(`HttpRequestEventBuilder: dropping invalid value for Bytes Sent: ${this.bytesSent}`);
134
+ this.bytesSent = undefined;
135
+ this.hasDroppedCustomProperties = true;
136
+ }
137
+ }
138
+ sanitizeBytesReceived() {
139
+ if (this.bytesReceived && this.bytesReceived < 0) {
140
+ logger.debug(`HttpRequestEventBuilder: dropping invalid value for Bytes Received: ${this.bytesReceived}`);
141
+ this.bytesReceived = undefined;
142
+ this.hasDroppedCustomProperties = true;
143
+ }
144
+ }
145
+ isStatusCodeError() {
146
+ return (this.statusCode && 400 <= this.statusCode && this.statusCode <= 599);
147
+ }
148
+ isEventPropertyKey([key, _]) {
149
+ if (key.startsWith("event_properties")) {
150
+ return true;
151
+ }
152
+ logger.debug(`HttpRequestEventBuilder: dropped event property '$key' as it did not start with prefix ${"event_properties"}`);
153
+ this.hasDroppedCustomProperties = true;
154
+ return false;
155
+ }
156
+ includeIfDefined(key, value) {
157
+ return value !== undefined ? { [key]: value } : {};
158
+ }
159
+ includeIfTrue(key, value) {
160
+ return value === true ? { [key]: value } : {};
161
+ }
162
+ parseTraceparent(header) {
163
+ const traceparentRegex = /^00-([0-9a-f]{32})-([0-9a-f]{16})-0[01]$/;
164
+ const match = header.match(traceparentRegex);
165
+ if (!match) {
166
+ logger.debug("The provided traceparent header does not match the format: '00-<trace-id-32-HEXDIG>-<parent-id-16-HEXDIG>-<trace-flags-2-HEXDIG>'");
167
+ return null;
168
+ }
169
+ const [, traceId, spanId] = match;
170
+ if (this.allZeros(traceId)) {
171
+ logger.debug('Trace ID in traceparent header must not be all zeros');
172
+ return null;
173
+ }
174
+ if (this.allZeros(spanId)) {
175
+ logger.debug('Parent ID in traceparent header must not be all zeros');
176
+ return null;
177
+ }
178
+ return { traceId, spanId };
179
+ }
180
+ allZeros(str) {
181
+ return /^0*$/.test(str);
182
+ }
183
+ }
184
+ exports.default = HttpRequestEventBuilder;
185
+ HttpRequestEventBuilder.allowedRequestMethods = [
186
+ 'GET',
187
+ 'HEAD',
188
+ 'POST',
189
+ 'PUT',
190
+ 'DELETE',
191
+ 'CONNECT',
192
+ 'OPTIONS',
193
+ 'TRACE',
194
+ 'PATCH',
195
+ ];
196
+ HttpRequestEventBuilder.maxReasonPhraseLength = 5000;
@@ -8,7 +8,7 @@ const ASCII_CODE_A = 65;
8
8
  const NUMERICAL_CHARACTER_COUNT = 10;
9
9
  const OFFSET_A = ASCII_CODE_A - NUMERICAL_CHARACTER_COUNT;
10
10
  const createViewInfo = (name) => ({
11
- ["view.id"]: createRandomHexString(VIEW_ID_LENGTH),
11
+ ["view.instance_id"]: createRandomHexString(VIEW_ID_LENGTH),
12
12
  ["view.name"]: name,
13
13
  });
14
14
  exports.createViewInfo = createViewInfo;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.containEventPropertiesInArray = exports.containEventProperties = exports.containSessionProperties = exports.trimStringValuesInObject = exports.trimString = exports.isObject = exports.flattenAdditionalData = void 0;
3
+ exports.containEventPropertiesInArray = exports.addIsApiReported = exports.flagEventProperties = exports.containEventProperties = exports.containSessionProperties = exports.trimStringValuesInObject = exports.trimString = exports.isObject = exports.flattenAdditionalData = void 0;
4
4
  const MAX_STRING_LENGTH_FOR_VALUES = 5000;
5
5
  const flattenAdditionalData = (obj, parent, res = {}) => {
6
6
  for (const key in obj) {
@@ -60,6 +60,19 @@ const containEventProperties = (jsonData) => {
60
60
  return false;
61
61
  };
62
62
  exports.containEventProperties = containEventProperties;
63
+ const flagEventProperties = (event) => {
64
+ if (event !== null && (0, exports.containEventProperties)(event)) {
65
+ event["characteristics.has_event_properties"] =
66
+ true;
67
+ }
68
+ };
69
+ exports.flagEventProperties = flagEventProperties;
70
+ const addIsApiReported = (event) => {
71
+ if (event !== null) {
72
+ event["characteristics.is_api_reported"] = true;
73
+ }
74
+ };
75
+ exports.addIsApiReported = addIsApiReported;
63
76
  const containEventPropertiesInArray = (eventEntries) => {
64
77
  for (const [key, value] of eventEntries) {
65
78
  if (key.startsWith(`${"event_properties"}.`)) {
@@ -23,18 +23,17 @@ class SendEventValidationImpl {
23
23
  }
24
24
  const timeNow = this.timestampProvider.getCurrentTimestamp();
25
25
  const eventCopy = Object.entries(event).slice();
26
- const filteredEvent = eventCopy
27
- .filter(this.isKeyNameAllowed, this)
28
- .filter(this.isFieldTypeAllowed, this);
26
+ const filteredEvent = eventCopy.filter(this.isKeyNameAllowed, this);
29
27
  const limitedEntries = new EventLimitation_1.EventLimitation().limitEventEntries(filteredEvent);
30
28
  const sizedEntries = new EventLimitation_1.EventLimitation().limitEventProperties(limitedEntries);
31
- this.applyOverriddenKeys(sizedEntries);
32
29
  if (sizedEntries.length < eventCopy.length) {
33
30
  sizedEntries.push([
34
31
  "dt.support.api.has_dropped_custom_properties",
35
32
  true,
36
33
  ]);
37
34
  }
35
+ this.sanitizeDuration(sizedEntries);
36
+ this.applyOverriddenKeys(sizedEntries);
38
37
  const jsonObject = Object.fromEntries(sizedEntries);
39
38
  if (jsonObject["duration"] !== undefined) {
40
39
  jsonObject["start_time"] =
@@ -60,13 +59,27 @@ class SendEventValidationImpl {
60
59
  ]);
61
60
  }
62
61
  }
63
- isFieldTypeAllowed(entry) {
64
- const [key, value] = entry;
65
- if (key === "duration" ||
66
- key === "start_time") {
67
- return typeof value === 'number' && isFinite(value) && value >= 0;
62
+ sanitizeDuration(event) {
63
+ for (const entry of event) {
64
+ const [key, value] = entry;
65
+ if (key === "duration") {
66
+ if (typeof value !== 'number' ||
67
+ !isFinite(value) ||
68
+ value < 0) {
69
+ entry[1] = 0;
70
+ event.push([
71
+ "dt.support.api.has_dropped_custom_properties",
72
+ true,
73
+ ]);
74
+ }
75
+ if (typeof value === 'number' && !isFinite(value)) {
76
+ event.push([
77
+ "dt.support.has_nfn_values",
78
+ true,
79
+ ]);
80
+ }
81
+ }
68
82
  }
69
- return true;
70
83
  }
71
84
  isKeyNameAllowed(entry) {
72
85
  const [key] = entry;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ALL_APP_START_KEYS = exports.MODIFY_EVENT_WHITELIST_NAMESPACE = exports.MODIFY_EVENT_WHITELIST_FIELDS = exports.SEND_SESSION_PROPERTY_EVENT_WHITELIST_FIELDS = exports.SEND_EVENT_WHITELIST_FIELDS = exports.SEND_SESSION_PROPERTY_EVENT_WHITELIST_NAMESPACES = exports.SEND_EVENT_WHITELIST_NAMESPACES = exports.AllCharacteristicsKeys = exports.KEY_NAME_REGEX = exports.MAX_CUSTOM_EVENT_VALUE_LENGTH = exports.MAX_CUSTOM_EVENT_KEY_LENGTH = exports.MAX_CUSTOM_EVENT_FIELDS = void 0;
4
- const SPECIFICATION_VERSION = '0.21';
4
+ const SPECIFICATION_VERSION = '0.22';
5
5
  exports.MAX_CUSTOM_EVENT_FIELDS = 50;
6
6
  exports.MAX_CUSTOM_EVENT_KEY_LENGTH = 100;
7
7
  exports.MAX_CUSTOM_EVENT_VALUE_LENGTH = 5000;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynatrace/react-native-plugin",
3
- "version": "2.323.1",
3
+ "version": "2.323.2",
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": "typings/react-native-dynatrace.d.ts",
@@ -167,6 +167,6 @@
167
167
  }
168
168
  },
169
169
  "engines": {
170
- "node": ">=18"
170
+ "node": ">=16"
171
171
  }
172
- }
172
+ }
@@ -529,7 +529,7 @@ export declare const Dynatrace: {
529
529
  *
530
530
  * @see https://www.npmjs.com/package/@dynatrace/react-native-plugin#manually-report-a-crash
531
531
  */
532
- reportCrashWithException(crashName: string, crash: Error, platform?: Platform);
532
+ reportCrashWithException(crashName: string, crash: Error, platform?: Platform): void;
533
533
 
534
534
  /**
535
535
  * Puts a set of http headers on every agent http request (eg. the Authorization header). It also triggers the agent to
@@ -640,6 +640,35 @@ export declare const Dynatrace: {
640
640
  * @param properties any attributes that should be reported for every event in the session.
641
641
  */
642
642
  sendSessionPropertyEvent(properties: JSONObject): void;
643
+
644
+ /**
645
+ *
646
+ * Send an HttpRequestEvent by passing in an instance of HttpRequestEventBuilder.
647
+ * The Builder allows you to configure common properties of an HttpRequest like url, requestMethod and duration.
648
+ * Additionally, it allows you to set custom event properties.
649
+ *
650
+ * @param httpRequestEventBuilder Mandatory Builder which allows you to configure common properties of an HttpRequest
651
+ *
652
+ * Usage:
653
+ *
654
+ * ```ts
655
+ * import { Dynatrace, HttpRequestEventBuilder } from '@dynatrace/react-native-plugin';
656
+ *
657
+ * Dynatrace.sendHttpRequestEvent(
658
+ * new HttpRequestEventBuilder("http://www.dynatrace.com", "POST")
659
+ * .withDuration(100)
660
+ * .withStatusCode(404)
661
+ * .withReasonPhrase("HTTP/1.1 404 Not Found")
662
+ * .withError(new Error())
663
+ * .withBytesSent(100)
664
+ * .withBytesReceived(100)
665
+ * .withTraceparentHeader("traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01")
666
+ * .addEventProperty("event_properties.userid", 12345)
667
+ * .addEventProperty("event_properties.response", "example body")
668
+ * );
669
+ * ```
670
+ */
671
+ sendHttpRequestEvent(httpRequestEventBuilder: HttpRequestEventBuilder): void
643
672
  }
644
673
 
645
674
  /**
@@ -1722,6 +1751,97 @@ export declare class ConfigurationBuilder {
1722
1751
  public buildConfiguration(): IConfiguration;
1723
1752
  }
1724
1753
 
1754
+ type EventProperty = string | number | boolean;
1755
+ type TraceparentHeader = `00-${string}-${string}-0${'0' | '1'}`;
1756
+ type AllowedRequestMethods =
1757
+ | 'GET'
1758
+ | 'HEAD'
1759
+ | 'POST'
1760
+ | 'PUT'
1761
+ | 'DELETE'
1762
+ | 'CONNECT'
1763
+ | 'OPTIONS'
1764
+ | 'TRACE'
1765
+ | 'PATCH'
1766
+ | 'get'
1767
+ | 'head'
1768
+ | 'post'
1769
+ | 'put'
1770
+ | 'delete'
1771
+ | 'connect'
1772
+ | 'options'
1773
+ | 'trace'
1774
+ | 'patch';
1775
+
1776
+ export declare class HttpRequestEventBuilder {
1777
+ /**
1778
+ *
1779
+ * @param url Accepts only URLs that are valid according to the WHATWG URL Standard. Mandatory.
1780
+ * @param requestMethod Accepts GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE and PATCH. Mandatory
1781
+ */
1782
+ constructor(
1783
+ url: `http://${string}` | `https://${string}`,
1784
+ requestMethod: AllowedRequestMethods
1785
+ );
1786
+
1787
+ /**
1788
+ *
1789
+ * @param duration Only positive numbers are valid.
1790
+ * @returns the HttpRequestEventBuilder
1791
+ */
1792
+ withDuration(duration: number): this;
1793
+
1794
+ /**
1795
+ *
1796
+ * @param statusCode Only positive numbers are valid.
1797
+ * @returns the HttpRequestEventBuilder
1798
+ */
1799
+ withStatusCode(statusCode: number): this;
1800
+
1801
+ /**
1802
+ *
1803
+ * @param reasonPhrase Max. 5000 characters.
1804
+ * @returns the HttpRequestEventBuilder
1805
+ */
1806
+ withReasonPhrase(reasonPhrase: string): this;
1807
+
1808
+ /**
1809
+ *
1810
+ * @param error A standard Javascript Error Object.
1811
+ * @returns the HttpRequestEventBuilder
1812
+ */
1813
+ withError(error: Error): this;
1814
+
1815
+ /**
1816
+ *
1817
+ * @param bytesSent Only positive numbers are valid.
1818
+ * @returns the HttpRequestEventBuilder
1819
+ */
1820
+ withBytesSent(bytesSent: number): this;
1821
+
1822
+ /**
1823
+ *
1824
+ * @param bytesReceived Only positive numbers are valid.
1825
+ * @returns the HttpRequestEventBuilder
1826
+ */
1827
+ withBytesReceived(bytesReceived: number): this;
1828
+
1829
+ /**
1830
+ *
1831
+ * @param traceparentHeader Accepts Traceparent Headers that are valid according to the W3C Trace Context Specification.
1832
+ * @returns the HttpRequestEventBuilder
1833
+ */
1834
+ withTraceparentHeader(traceparentHeader: TraceparentHeader): this;
1835
+
1836
+ /**
1837
+ *
1838
+ * @param key Accepts any string that starts with 'event_properties.'.
1839
+ * @param value Accepts any string (max. 5000 characters), number or boolean.
1840
+ * @returns the HttpRequestEventBuilder
1841
+ */
1842
+ addEventProperty(key: `event_properties.${string}`, value: EventProperty): this;
1843
+ }
1844
+
1725
1845
  declare module 'react' {
1726
1846
  namespace JSX {
1727
1847
  interface IntrinsicAttributes extends IDynatraceProperties {}
@@ -1,57 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SwitchHelper = void 0;
4
- const ComponentUtil_1 = require("./ComponentUtil");
5
- const ConfigurationHandler_1 = require("../../../lib/core/configuration/ConfigurationHandler");
6
- const SwitchHelper = (Dynatrace) => ({
7
- attachOnValueChange: (switchProps) => {
8
- if ((0, ComponentUtil_1.isDynatraceIgnored)(switchProps)) {
9
- return;
10
- }
11
- const origOnValueChange = switchProps.onValueChange;
12
- const nameOfAction = _findActionName(switchProps);
13
- if (origOnValueChange != null) {
14
- switchProps.onValueChange = (value) => {
15
- const useGenericName = nameOfAction == null ||
16
- (!(0, ComponentUtil_1.isDynatraceNaming)(switchProps) &&
17
- ConfigurationHandler_1.ConfigurationHandler.isActionNamePrivacyEnabled());
18
- const finalNameOfAction = useGenericName
19
- ? `Touch on Switch to ${value}`
20
- : `Touch on ${nameOfAction} to ${value}`;
21
- const action = Dynatrace.enterAutoAction(finalNameOfAction);
22
- let isSyncError = true;
23
- try {
24
- const returnValue = origOnValueChange(value);
25
- if (_isPromise(returnValue)) {
26
- isSyncError = false;
27
- return returnValue.finally(() => {
28
- action.leaveAction();
29
- });
30
- }
31
- else {
32
- action.leaveAction();
33
- }
34
- isSyncError = false;
35
- }
36
- finally {
37
- if (isSyncError) {
38
- action.leaveAction();
39
- }
40
- }
41
- };
42
- }
43
- },
44
- });
45
- exports.SwitchHelper = SwitchHelper;
46
- const _findActionName = (switchProps) => {
47
- if ((0, ComponentUtil_1.isDynatraceNaming)(switchProps)) {
48
- return switchProps.dtActionName;
49
- }
50
- else if (switchProps.accessibilityLabel != null) {
51
- return switchProps.accessibilityLabel;
52
- }
53
- return null;
54
- };
55
- const _isPromise = (object) => object != null &&
56
- typeof object.then === 'function' &&
57
- typeof object.catch === 'function';