@dynatrace/react-native-plugin 2.319.1 β†’ 2.321.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.
package/README.md CHANGED
@@ -32,8 +32,8 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
32
32
  ## Agent Versions
33
33
  This agent versions are configured in this plugin:
34
34
 
35
- * Android Agent: 8.319.2.1011
36
- * iOS Agent: 8.319.1.1005
35
+ * Android Agent: 8.321.1.1009
36
+ * iOS Agent: 8.321.1.1007
37
37
 
38
38
  ## Quick Setup
39
39
 
@@ -1163,6 +1163,8 @@ This impacts our instrumentation as well. To keep the instrumentation in place y
1163
1163
 
1164
1164
  For our instrumentation to work properly, you will need to add the importSource property:
1165
1165
 
1166
+ >**Attention:** In case you are using NativeWind, use 'nativewind' as the importSource for the JSX runtime in babel.config.js, as specified in the NativeWind documentation. Since you cannot stack two JSX runtimes using Babel, we internally make the NativeWind JSX runtime then call our @dynatrace/react-native-plugin JSX runtime.
1167
+
1166
1168
  ```js
1167
1169
  module.exports = {
1168
1170
  plugins: [
@@ -1446,10 +1448,11 @@ To resolve problems with the plugin, first look at creating logs and identify wh
1446
1448
  * react-native-gesture-handler
1447
1449
  * react-native-webview
1448
1450
  * Custom libraries that directly use the default React Native components (i.e. Button)
1449
-
1450
- **Unsupported:**
1451
1451
  * NativeWind
1452
1452
 
1453
+ >**Attention:**
1454
+ In case you are using NativeWind, use 'nativewind' as the importSource for the JSX runtime in babel.config.js, as specified in the NativeWind documentation. Since you cannot stack two JSX runtimes using Babel, we internally make the NativeWind JSX runtime then call our @dynatrace/react-native-plugin JSX runtime.
1455
+
1453
1456
  ## Report a bug or open a support case
1454
1457
 
1455
1458
  >**Attention:** If you think something is not working the way it should, ALWAYS try to reset the cache of metro first before starting a support case. You can do this via the CLI *react-native start --reset-cache*. If it still does not work feel free to open a support case.
@@ -1461,6 +1464,12 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
1461
1464
  <br/><br/>
1462
1465
  ## Changelog
1463
1466
 
1467
+ 2.321.1
1468
+ * Updated Android (8.321.1.1009) & iOS Agent (8.321.1.1007)
1469
+ * Auto startup fixed for React Native v0.80 and higher
1470
+ * Fixed Dynatrace Reporter with newer versions of Metro
1471
+ * Added NativeWind support
1472
+
1464
1473
  2.319.1
1465
1474
  * Updated Android (8.319.2.1011) & iOS Agent (8.319.1.1005)
1466
1475
 
@@ -72,7 +72,7 @@ repositories {
72
72
  }
73
73
 
74
74
  dependencies {
75
- implementation 'com.dynatrace.agent:agent-android:8.319.2.1011'
75
+ implementation 'com.dynatrace.agent:agent-android:8.321.1.1009'
76
76
  implementation "com.facebook.react:react-native:${safeExtGet('reactNative', '+')}"
77
77
  }
78
78
 
@@ -0,0 +1,22 @@
1
+ android.applicationVariants.all { variant ->
2
+ if (variant.buildType.name == "release") {
3
+ variant.mergeAssetsProvider.configure { task ->
4
+ task.doLast {
5
+ def sourceMap = file("$buildDir/generated/sourcemaps/react/release/index.android.bundle.map")
6
+ println("πŸ” Check sourceMap: $sourceMap")
7
+
8
+ if (sourceMap.exists()) {
9
+ println("βœ… Source map found. Starting post-processing...")
10
+
11
+ exec {
12
+ workingDir rootDir
13
+ commandLine 'npx', 'lineOffsetDynatrace', 'env=prod'
14
+ }
15
+
16
+ } else {
17
+ println("❌ Source map not found")
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }
@@ -1,3 +1,4 @@
1
+ // TEMPLATE: plugin-gradle.template
1
2
  dependencies {
2
- classpath 'com.dynatrace.tools.android:gradle-plugin:8.319.2.1011'
3
+ classpath 'com.dynatrace.tools.android:gradle-plugin:8.321.1.1009'
3
4
  }
@@ -1 +1 @@
1
- "use strict";var a,n=require("@babel/runtime/helpers/interopRequireDefault"),r=n(require("@babel/runtime/helpers/toConsumableArray")),l=(Object.defineProperty(exports,"t",{value:!0}),exports.instrument=void 0,require("path")),o=require("jscodeshift"),i=require("jscodeshift/src/Collection"),e=require("../scripts/FileOperationHelper"),c=require("../scripts/PathsConstants"),f=require("../lib/core/util/GetValuesFromPackage"),t=require("../scripts/util/InstrumentUtil"),u=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("./parser/Babel"),g=require("./model/Types"),y=(!function(n){n[n.i=-1]="Filtered",n[n.u=0]="Normal",n[n.o=1]="ReactNative",n[n.l=2]="React"}(a=a||{}),[]),b=(y.push.apply(y,(0,r.default)(u.instrumentationInfo)),y.push.apply(y,(0,r.default)(s.instrumentationInfo)),y.push.apply(y,(0,r.default)(d.instrumentationInfo)),y.push.apply(y,(0,r.default)(v.instrumentationInfo)),y.push.apply(y,(0,r.default)(p.instrumentationInfo)),["AppRegistry","renderApplication","setUpErrorHandling"]),q="@dynatrace/react-native-plugin/instrumentation/libs",instrument=function(n,r,e){r=V(r);var t,i=G(r);if(i!==a.i){var u=!1,o=I(r,n);if(i===a.l)T(o),u=!0;else if(i===a.o)r.endsWith("AppRegistry.js")?void 0!==e&&e.autoStart&&(k(o),u=!0):r.endsWith("renderApplication.js")?(A(o),u=!0):r.endsWith("setUpErrorHandling.js")&&void 0!==e&&e.autoStart&&e.errorHandler.enabled&&(J(o,e.autoStart,e.errorHandler.reportFatalErrorAsCrash),u=!0);else{var i=w(r,e);if(e.custom.reactnavigation&&P(r,o))u=!0;else{if(!i.input&&!i.lifecycle)return null!=e&&e.debug&&console.log("Dynatrace - Filtered All: ".concat(r)),E(r),n;i.lifecycle&&A(o)&&(u=!0),i.input&&y.forEach(function(n){n=W(o,n);o=n.root,u=u||n.v})}}u?(n=o.toSource({quote:"single"}),H(n,r)):E(r),null!=e&&e.debug&&u&&console.log("Dynatrace - Modified Filename: "+r)}else r.includes(l.join("@dynatrace","react-native-plugin"))&&r.endsWith(l.join("lib","core","configuration","ConfigurationPreset.js"))&&void 0!==e&&(i=(0,f.getHostAppBundleInfo)(c.default.getPackageJsonFile()),t=I(r,n),void 0!==e.lifecycle&&N(t,"getLifecycleUpdate",e.lifecycle.includeUpdate),void 0!==e.debug&&N(t,"getLogLevel",e.debug?0:1),void 0!==e.bundleName?N(t,"getBundleName",e.bundleName):null!==i&&N(t,"getBundleName",null==i?void 0:i.name),void 0!==e.bundleVersion?N(t,"getBundleVersion",e.bundleVersion):null!==i&&N(t,"getBundleVersion",null==i?void 0:i.version),void 0!==e.input&&void 0!==e.input.actionNamePrivacy&&N(t,"getActionNamePrivacy",e.input.actionNamePrivacy),void 0!==e.errorHandler&&(N(t,"isErrorHandlerEnabled",e.errorHandler.enabled),N(t,"isReportFatalErrorAsCrash",e.errorHandler.reportFatalErrorAsCrash)),e.autoStart&&N(t,"isAutoStartupEnabled",e.autoStart),n=t.toSource({quote:"single"}),H(n,r));return n},P=(exports.instrument=instrument,function(n,r){return!!O(n,r)&&(n="import { registerListener } from '".concat(q,"/react-navigation/ReactNavigation';"),r.find(o.ImportDeclaration).at(0).insertBefore(n),!0)}),O=function(n,r){var e=!1;return n.includes("react-navigation")&&n.includes("NavigationContainer.tsx")&&r.find(o.VariableDeclarator).forEach(function(n){e||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);"),e=!0)}),e},A=function(n){var r=n.findJSXElements(),t=!1;return 0<r.length&&(n.find(o.FunctionDeclaration).forEach(function(n){var r,e=(0,i.fromPaths)([n]);0<e.findJSXElements().length&&null!=n&&null!=n.value&&null!=n.value.id&&n.value.id.name&&(r=e.find(o.ClassDeclaration),e=e.find(o.ClassExpression),0===r.length)&&0===e.length&&(h(n,g.Types.FunctionalComponent,n.value.id.name),t=!0)}),n.find(o.ClassDeclaration).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n&&null!=n.value&&n.value.id&&n.value.id.name&&(h(n,g.Types.ClassComponent,n.value.id.name),t=!0)}),n.find(o.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&&(h(n,g.Types.FunctionalComponent,n.parent.value.id.name),t=!0)})),t},h=function(n,r,e){for(r=o.expressionStatement(o.assignmentExpression("=",o.memberExpression(o.identifier(e),o.identifier("_dtInfo")),U(r,e)));void 0!==n.parentPath&&"body"!==n.parentPath.name;)n=n.parentPath;void 0!==n.parentPath&&n.insertAfter(r)},U=function(n,r){return o.objectExpression([o.objectProperty(o.identifier("type"),o.numericLiteral(n)),o.objectProperty(o.identifier("name"),o.stringLiteral(r))])},N=function(n,r,e){var n=n.find(o.Identifier).filter(function(n){return n.node.name===r});1===n.length&&"ReturnStatement"===(n=n.paths()[0].parent.value.body.body[0]).type&&("boolean"==typeof e&&(n.argument=o.booleanLiteral(e)),"string"==typeof e&&(n.argument=o.stringLiteral(e)),"number"==typeof e)&&(n.argument=o.numericLiteral(e))},I=function(n,r){return o.withParser((0,m.babelParser)(l.extname(n)))(r)},V=function(n){return l.isAbsolute(n)?n.replace(c.default.getApplicationPath()+l.sep,""):n},E=function(n){try{var r=l.join(c.default.getBuildPath(),n+t.INSTRUMENTED_FILE_EXTENSION);e.default.checkIfFileExistsSync(r),e.default.deleteFileSync(r)}catch(n){}},H=function(n,r){r=l.join(c.default.getBuildPath(),r);try{e.default.checkIfFileExistsSync(l.dirname(r))}catch(n){e.default.createDirectorySync(l.dirname(r))}e.default.writeTextToFileSync(r+t.INSTRUMENTED_FILE_EXTENSION,n)},w=function(n,r){var e={input:!1,lifecycle:!1};return void 0!==r&&(void 0!==r.lifecycle&&void 0!==r.lifecycle.instrument&&r.lifecycle.instrument(n)&&(e.lifecycle=!0),void 0!==r.input)&&void 0!==r.input.instrument&&r.input.instrument(n)&&(e.input=!0),e},T=function(n){var r,n=n.find(o.Program);1===n.length&&(r=o.expressionStatement(o.callExpression(o.memberExpression(o.callExpression(o.identifier("require"),[o.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")]),o.identifier("instrumentCreateElement")),[o.memberExpression(o.identifier("module"),o.identifier("exports"))])),n.paths()[0].node.body.push(r))},k=function(n){var r=M(n,"runApplication",!0);1===r.length&&(un(n,{p:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),j(r.paths()[0].parent.value.body.body,0,_("_DynatraceApplicationHandler","startup",[])))},J=function(n,r,e){n=n.paths()[0].value.program.body;null!=n&&(j(n,n.length,L({p:"_DynatraceErrorHandler",module:"@dynatrace/react-native-plugin/lib/core/ErrorHandler",reference:""})),j(n,n.length,_("_DynatraceErrorHandler","registerErrorHandler",[o.literal(e)])))},j=function(n,r){for(var e=arguments.length,t=new Array(2<e?e-2:0),i=2;i<e;i++)t[i-2]=arguments[i];return n.splice.apply(n,[r,0].concat(t))},M=function(n,r,t){for(var e=arguments.length,i=new Array(3<e?e-3:0),u=3;u<e;u++)i[u-3]=arguments[u];return n.find(o.Identifier).filter(function(n){return n.node.name===r}).filter(function(n){return void 0!==n.parent&&void 0!==n.parent.value&&void 0!==n.parent.value.params}).filter(function(n){var r=void 0!==n.parent&&void 0!==n.parent.value;t||(r=r&&n.parent.value.params.length===i.length);for(var e=0;e<0;e++)r=r&&n.parent.value.params[e].name===i[e];return r})},G=function(n){if(n.includes("@dynatrace"))return a.i;var r=l.extname(n);if(".js"!==r&&".ts"!==r&&".tsx"!==r&&".jsx"!==r)return a.i;for(var e=l.parse(n),t=e.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(e.name)?a.o:a.i;if("react"===t[i+1]&&"index"===e.name)return a.l}return a.u},z=function(n,r,e){var t=K(n,r,e);return Q(n,r,e)||t},K=function(n,r,e){var t=X(n,r);return 0<t.length&&(void 0!==(t=R(t,r.reference,!1))&&(e.p=t.localName),en(n,e),!0)},Q=function(n,r,e){var t=x(n,r.module);if(1===t.length){t=R(t,r.reference,!0);if(void 0!==t)return tn(n,e.defaultImport,t.localName,"ImportNamespaceSpecifier"===t.type),!0}return!1},W=function(n,r){var e=JSON.parse(JSON.stringify(r.new));return{root:n,v:z(n,r.old,e)||Y(n,r.old,r.new.defaultImport)}},X=function(n,r){return n.find(o.ImportDeclaration).filter(function(n){return n.node.source.value===r.module&&null!=n.node.specifiers&&n.node.specifiers.some(function(n){return C(n)&&n.imported.name===r.reference||n.local&&n.local.name===r.reference})})},C=function(n){return void 0!==n.imported},Y=function(n,r,e){var t=!1;return n.find(o.CallExpression).filter(function(n){return Z(n.node.callee)&&$(n.node.arguments[0])&&n.node.arguments[0].value===r.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===r.reference)&&(n.node.arguments[0].value=e,t=t||!0)}),t},Z=function(n){return"require"===n.name},$=function(n){return"StringLiteral"===n.type||"Literal"===n.type},x=function(n,r){return n.find(o.ImportDeclaration).filter(function(n){return n.node.source.value===r})},R=function(n,e,t){var i;return n.forEach(function(n){void 0!==n.node.specifiers&&(n.node.specifiers=n.node.specifiers.filter(function(n){var r;return C(n)&&!t?((r=n.imported.name!==e)||null==n.local||n.imported.name===n.local.name||(i={localName:n.local.name,type:n.type}),r):!(!C(n)&&t&&(null!=n.local&&(i={localName:n.local.name,type:n.type}),1))}),0===n.node.specifiers.length)&&n.prune()}),i},nn=function(n,r){n.find(o.ImportDeclaration).filter(function(n){return n.node.source.value===r.module}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(B(r))})},rn=function(n,r,e){n.find(o.ImportDeclaration).filter(function(n){return n.node.source.value===r}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(e)})},D=function(n,r,e){var t=n.find(o.ImportDeclaration);0<t.length?o(t.paths()[0]).insertAfter(F(r,e)):1===(t=n.find(o.Program)).length&&t.paths()[0].node.body.unshift(F(r,e))},en=function(n,r){0<x(n,r.module).length?nn(n,r):D(n,r.module,[B(r)])},tn=function(n,r,e,t){var i=x(n,r),t=(t?sn:fn)(e);0<i.length?rn(n,r,t):D(n,r,[t])},un=function(n,r){n=n.find(o.VariableDeclaration);0<n.length&&o(n.paths()[0]).insertAfter(L(r))},_=function(n,r,e){return o.expressionStatement(on(n,r,e))},on=function(n,r,e){return o.callExpression(cn(n,r),e)},L=function(n){return o.variableDeclaration("var",[an(n)])},an=function(n){return o.variableDeclarator(void 0!==n.p?o.identifier(n.p):o.identifier(n.reference),(0<n.reference.length?ln:S)(n))},ln=function(n){return o.memberExpression(S(n),o.identifier(n.reference))},cn=function(n,r){return o.memberExpression(o.identifier(n),o.identifier(r))},S=function(n){return o.callExpression(o.identifier("require"),[o.literal(n.module)])},F=function(n,r){return o.importDeclaration(r,o.literal(n))},B=function(n){return void 0!==n.p?o.importSpecifier(o.identifier(n.reference),o.identifier(n.p)):o.importSpecifier(o.identifier(n.reference))},fn=function(n){return o.importDefaultSpecifier(o.identifier(n))},sn=function(n){return o.importNamespaceSpecifier(o.identifier(n))};
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))};
@@ -5,7 +5,7 @@ exports.Pressable = exports.Text = exports.TouchableWithoutFeedback = exports.To
5
5
  const ReactNative = require("react-native");
6
6
  const React = require("react");
7
7
  const Types_1 = require("../../model/Types");
8
- exports.Button = React.forwardRef((props, ref) => (React.createElement(ReactNative.Button, Object.assign({}, props, { ref: ref }))));
8
+ exports.Button = React.forwardRef((props, ref) => (React.createElement(ReactNative.Button, Object.assign({ title: props.title }, props, { ref: ref }))));
9
9
  exports.Button._dtInfo = { type: Types_1.Types.Button };
10
10
  if (typeof ReactNative.TouchableOpacity === 'object') {
11
11
  exports.TouchableOpacity = Object.assign({ _dtInfo: { type: Types_1.Types.TouchableOpacity } }, ReactNative.TouchableOpacity);
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.chooseParser = void 0;
4
+ const path_1 = require("path");
5
+ const Babel_1 = require("./Babel");
6
+ const chooseParser = (filename, source) => {
7
+ if (source !== null && source.indexOf('@flow') !== -1) {
8
+ }
9
+ return (0, Babel_1.babelParser)((0, path_1.extname)(filename));
10
+ };
11
+ exports.chooseParser = chooseParser;
@@ -8,11 +8,37 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- const TerminalReporter = require('metro/src/lib/TerminalReporter');
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const child_process_1 = require("child_process");
13
+ const TerminalReporter = (() => {
14
+ try {
15
+ return require('metro/src/lib/TerminalReporter');
16
+ }
17
+ catch (_a) {
18
+ return require('metro').TerminalReporter;
19
+ }
20
+ })();
12
21
  const { Terminal } = require('metro-core');
13
22
  const files = require('../scripts/FileOperationHelper');
14
23
  const paths = require('../scripts/PathsConstants');
15
24
  const reporter = new TerminalReporter(new Terminal(process.stdout));
25
+ const updateOrig = TerminalReporter.prototype.update;
26
+ TerminalReporter.prototype.update = function update(event) {
27
+ if ((event === null || event === void 0 ? void 0 : event.type) === 'bundle_build_done') {
28
+ (0, child_process_1.exec)('npx lineOffsetDynatrace env prod', (error, stdout, stderr) => {
29
+ if (error) {
30
+ console.error(`Error: ${error.message}`);
31
+ return;
32
+ }
33
+ if (stderr) {
34
+ console.error(`stderr: ${stderr}`);
35
+ return;
36
+ }
37
+ console.log(`${stdout}`);
38
+ });
39
+ }
40
+ return updateOrig === null || updateOrig === void 0 ? void 0 : updateOrig.apply(this, arguments);
41
+ };
16
42
  const update = (event) => __awaiter(void 0, void 0, void 0, function* () {
17
43
  if (event != null) {
18
44
  if (event.type === 'transform_cache_reset') {
@@ -28,7 +28,7 @@ class EventPipelineImpl {
28
28
  }
29
29
  catch (error) {
30
30
  if (event != null) {
31
- event["dt.internal.api.has_enrich_exception"] = true;
31
+ event["dt.support.api.has_enrich_exception"] = true;
32
32
  }
33
33
  }
34
34
  });
@@ -76,7 +76,7 @@ class ModifyEventValidation {
76
76
  this.logger.debug(`sanitizeUserEnrichedEvent(${originalEvent}, ${userEnrichedEvent}): Event has not been changed`);
77
77
  return originalEvent;
78
78
  }
79
- let overriddenKeys = originalEvent["dt.internal.api.overridden_keys"];
79
+ let overriddenKeys = originalEvent["dt.support.api.overridden_fields"];
80
80
  if (overriddenKeys == null) {
81
81
  overriddenKeys = [];
82
82
  }
@@ -97,19 +97,19 @@ class ModifyEventValidation {
97
97
  const sizedEntries = new EventLimitation_1.EventLimitation().limitEventProperties(finalEntries);
98
98
  if (sizedEntries.length < userEnrichedEventEntries.length) {
99
99
  sizedEntries.push([
100
- "dt.internal.api.has_dropped_custom_properties",
100
+ "dt.support.api.has_dropped_custom_properties",
101
101
  true,
102
102
  ]);
103
103
  }
104
104
  if (Array.isArray(overriddenKeys) && overriddenKeys.length > 0) {
105
105
  sizedEntries.push([
106
- "dt.internal.api.overridden_keys",
106
+ "dt.support.api.overridden_fields",
107
107
  overriddenKeys,
108
108
  ]);
109
109
  }
110
110
  if (externalException) {
111
111
  sizedEntries.push([
112
- "dt.internal.api.has_enrich_exception",
112
+ "dt.support.api.has_enrich_exception",
113
113
  true,
114
114
  ]);
115
115
  }
@@ -31,7 +31,7 @@ class SendEventValidationImpl {
31
31
  this.applyOverriddenKeys(sizedEntries);
32
32
  if (sizedEntries.length < eventCopy.length) {
33
33
  sizedEntries.push([
34
- "dt.internal.api.has_dropped_custom_properties",
34
+ "dt.support.api.has_dropped_custom_properties",
35
35
  true,
36
36
  ]);
37
37
  }
@@ -55,7 +55,7 @@ class SendEventValidationImpl {
55
55
  }
56
56
  if (overriddenKeys.length > 0) {
57
57
  eventEntries.push([
58
- "dt.internal.api.overridden_keys",
58
+ "dt.support.api.overridden_fields",
59
59
  overriddenKeys,
60
60
  ]);
61
61
  }
@@ -9,7 +9,7 @@ class ValueRestrictionModifierImpl {
9
9
  }
10
10
  modifyEvent(event) {
11
11
  if (event != null && this.eventHasRestrictedValues(event)) {
12
- event["dt.internal.has_nfn_values"] = true;
12
+ event["dt.support.has_nfn_values"] = true;
13
13
  }
14
14
  return JSON.parse(JSON.stringify(event, (_key, value) => {
15
15
  if (value === undefined) {
@@ -1,11 +1,11 @@
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.19';
4
+ const SPECIFICATION_VERSION = '0.20';
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;
8
- exports.KEY_NAME_REGEX = RegExp('^[a-z0-9]+(?:\\.[a-z][a-z0-9]*|_[a-z0-9]+)*$');
8
+ exports.KEY_NAME_REGEX = RegExp('^[a-zA-Z0-9]+(?:\\.[a-zA-Z][a-zA-Z0-9]*|_[a-zA-Z0-9]+)*$');
9
9
  const characteristicsKeyMap = {
10
10
  ["characteristics.has_anr"]: null,
11
11
  ["characteristics.has_crash"]: null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynatrace/react-native-plugin",
3
- "version": "2.319.1",
3
+ "version": "2.321.1",
4
4
  "description": "This plugin gives you the ability to use the Dynatrace Mobile agent in your react native application.",
5
5
  "main": "index.js",
6
6
  "types": "typings/react-native-dynatrace.d.ts",
@@ -35,43 +35,6 @@
35
35
  "prettier:write": "prettier --write ./src",
36
36
  "prepare": "husky"
37
37
  },
38
- "jest": {
39
- "displayName": "@dynatrace/react-native-plugin",
40
- "preset": "react-native",
41
- "moduleNameMapper": {
42
- "@expo/metro-config/babel-transformer": "<rootDir>/__mocks__/@expo/metro-config/babel-transformer.js",
43
- "metro-react-native-babel-transformer/src/index": "<rootDir>/__mocks__/metro-react-native-babel-transformer.js",
44
- "@react-native/metro-babel-transformer": "<rootDir>/__mocks__/@react-native/metro-babel-transformer.js"
45
- },
46
- "moduleDirectories": [
47
- "node_modules"
48
- ],
49
- "unmockedModulePathPatterns": [
50
- "node_modules"
51
- ],
52
- "modulePathIgnorePatterns": [
53
- "<rootDir>/src",
54
- "<rootDir>/tests/commandTestTmp",
55
- "node_modules/react-native/local-cli"
56
- ],
57
- "transform": {
58
- "^.+\\.(ts|tsx)$": "ts-jest"
59
- },
60
- "testPathIgnorePatterns": [
61
- "<rootDir>/src",
62
- "<rootDir>/tests/commandTestTmp"
63
- ],
64
- "transformIgnorePatterns": [
65
- "node_modules/(?!(@react-native|react-native)/)"
66
- ],
67
- "setupFiles": [
68
- "<rootDir>/tests/setup/setup.js"
69
- ],
70
- "testResultsProcessor": "jest-junit",
71
- "testRegex": [
72
- "(/__tests__/.*|(\\.|/)(Test|spec))\\.[jt]sx?$"
73
- ]
74
- },
75
38
  "jest-junit": {
76
39
  "suiteName": "jest tests",
77
40
  "outputDirectory": "test_report",
@@ -83,7 +46,7 @@
83
46
  "author": "Dynatrace",
84
47
  "license": "SEE LICENSE IN LICENSE.md",
85
48
  "dependencies": {
86
- "@babel/runtime": "^7.28.2",
49
+ "@babel/runtime": "^7.28.3",
87
50
  "jscodeshift": "^17.3.0",
88
51
  "plist": "^3.1.0",
89
52
  "proxy-polyfill": "^0.3.2",
@@ -93,32 +56,37 @@
93
56
  "peerDependencies": {
94
57
  "@babel/parser": ">=7.4.4",
95
58
  "@react-native-picker/picker": ">=1.0.0",
59
+ "diff": "^8.0.2",
96
60
  "react": ">=16.11.0",
97
61
  "react-native": ">=0.62.0"
98
62
  },
63
+ "overrides": {
64
+ "jscodeshift": {
65
+ "ast-types": "npm:ast-types-x"
66
+ },
67
+ "ast-types": "npm:ast-types-x",
68
+ "flow-parser": "0.160"
69
+ },
99
70
  "devDependencies": {
100
- "@babel/cli": "^7.27.2",
101
- "@babel/plugin-proposal-class-properties": "^7.8.3",
102
- "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
103
- "@babel/plugin-proposal-optional-chaining": "^7.8.3",
104
- "@babel/plugin-transform-flow-strip-types": "^7.8.3",
105
- "@babel/plugin-transform-runtime": "^7.12.1",
106
- "@babel/preset-env": "^7.4.4",
107
- "@babel/preset-react": "^7.8.3",
108
- "@testing-library/react-native": "^7.0.2",
109
- "@types/jest": "^29.5.1",
110
- "@types/jscodeshift": "^0.11.6",
111
- "@types/libxmljs": "^0.18.3",
112
- "@types/mock-fs": "^4.13.4",
71
+ "@babel/plugin-transform-class-properties": "^7.27.1",
72
+ "@babel/plugin-transform-flow-strip-types": "^7.27.1",
73
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
74
+ "@babel/plugin-transform-optional-chaining": "^7.27.1",
75
+ "@babel/preset-env": "^7.27.2",
76
+ "@babel/preset-react": "^7.27.1",
77
+ "@react-native/babel-preset": "^0.80.1",
78
+ "@testing-library/react-native": "^13.2.0",
79
+ "@types/jest": "^30.0.0",
80
+ "@types/jscodeshift": "^17.3.0",
113
81
  "@types/node": "^18.19.71",
114
- "@types/plist": "^3.0.2",
115
- "@types/react-native": "^0.63.32",
116
- "@types/semver": "^7.5.0",
117
- "@types/shelljs": "^0.8.8",
118
- "@types/uglify-js": "^3.17.1",
82
+ "@types/plist": "^3.0.5",
83
+ "@types/react": "^19.1.8",
84
+ "@types/semver": "^7.7.0",
85
+ "@types/shelljs": "^0.8.17",
86
+ "@types/uglify-js": "^3.17.5",
119
87
  "@typescript-eslint/eslint-plugin": "^8.22.0",
120
88
  "@typescript-eslint/parser": "^8.22.0",
121
- "compressing": "^1.5.1",
89
+ "compressing": "^1.10.3",
122
90
  "diff": "^8.0.2",
123
91
  "eslint": "^9.29.0",
124
92
  "eslint-config-prettier": "^8.5.0",
@@ -127,18 +95,16 @@
127
95
  "eslint-plugin-prefer-arrow": "^1.2.3",
128
96
  "eslint-plugin-unicorn": "^42.0.0",
129
97
  "husky": "^9.1.6",
130
- "jest": "^28.1.3",
131
- "jest-each": "^28.1.3",
132
- "jest-junit": "^14.0.0",
133
- "jest-mock": "^28.1.3",
134
- "mock-fs": "^5.5.0",
98
+ "jest": "^30.0.4",
99
+ "jest-each": "^30.0.2",
100
+ "jest-junit": "^16.0.0",
101
+ "jest-mock": "^30.0.2",
135
102
  "npm-check-updates": "^18.0.1",
136
103
  "prettier": "^2.6.1",
137
- "shelljs": "^0.8.5",
138
- "ts-jest": "^28.0.7",
139
- "ts-mockito": "^2.6.1",
104
+ "shelljs": "^0.10.0",
105
+ "ts-jest": "^29.4.0",
140
106
  "typescript": "^4.7.4",
141
- "uglify-js": "^3.17.4"
107
+ "uglify-js": "^3.19.3"
142
108
  },
143
109
  "files": [
144
110
  "react-native.config.js",
@@ -111,7 +111,7 @@ Pod::Spec.new do |s|
111
111
  #
112
112
 
113
113
  s.dependency "React"
114
- s.dependency 'Dynatrace', '~> 8.319.1.1005'
114
+ s.dependency 'Dynatrace', '~> 8.321.1.1007'
115
115
 
116
116
  # Allows for better compatibility for older and newer versions
117
117
  if defined?(install_modules_dependencies)
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.copyGradleConfigFile = exports.writeGradleConfig = exports.instrumentAndroidPlatform = exports.GRADLE_APPLY_BUILDSCRIPT = exports.GRADLE_DYNATRACE_FILE = void 0;
4
+ exports.ensureRuntimeScriptApplied = exports.copyGradleConfigFile = exports.writeGradleConfig = exports.instrumentAndroidPlatform = exports.GRADLE_APPLY_RUNTIME_SCRIPT = exports.GRADLE_APPLY_BUILDSCRIPT = exports.GRADLE_DYNATRACE_FILE = void 0;
5
5
  const path_1 = require("path");
6
6
  const Logger_1 = require("./Logger");
7
7
  const FileOperationHelper_1 = require("./FileOperationHelper");
@@ -11,6 +11,7 @@ exports.GRADLE_DYNATRACE_FILE = `apply from: "./${PathsConstants_1.DYNATRACE_CON
11
11
  const GRADLE_BUILDSCRIPT_IDENTIFIER = 'buildscript';
12
12
  exports.GRADLE_APPLY_BUILDSCRIPT = 'apply from: "../node_modules/@dynatrace/react-native-plugin/files/plugin.gradle", to: buildscript';
13
13
  const GRADLE_REACT_NATIVE_PLUGIN = 'apply plugin: "com.facebook.react.rootproject"';
14
+ exports.GRADLE_APPLY_RUNTIME_SCRIPT = 'apply from: "../../node_modules/@dynatrace/react-native-plugin/files/plugin-runtime.gradle"';
14
15
  const instrumentAndroidPlatform = (pathToGradle, remove) => {
15
16
  const path = FileOperationHelper_1.default.checkIfFileExistsSync(pathToGradle);
16
17
  if (!path.endsWith('.gradle')) {
@@ -135,3 +136,17 @@ const removeOldGradleConfig = (gradleFileContent) => {
135
136
  gradleFileContentLines.splice(gradleConfigIndex[0] + 1, gradleConfigIndex[1] - (gradleConfigIndex[0] + 1));
136
137
  return gradleFileContentLines;
137
138
  };
139
+ const ensureRuntimeScriptApplied = (pathToGradle) => {
140
+ const gradleContent = FileOperationHelper_1.default.readTextFromFileSync(pathToGradle);
141
+ const gradleLines = gradleContent.split('\n');
142
+ const alreadyApplied = gradleLines.some((line) => line.includes(exports.GRADLE_APPLY_RUNTIME_SCRIPT));
143
+ if (!alreadyApplied) {
144
+ gradleLines.push(exports.GRADLE_APPLY_RUNTIME_SCRIPT);
145
+ FileOperationHelper_1.default.writeTextToFileSync(pathToGradle, gradleLines.join('\n'));
146
+ Logger_1.default.logMessageSync(`Added runtime script to ${pathToGradle}`, Logger_1.default.INFO);
147
+ }
148
+ else {
149
+ Logger_1.default.logMessageSync(`Runtime script already present in ${pathToGradle}`, Logger_1.default.INFO);
150
+ }
151
+ };
152
+ exports.ensureRuntimeScriptApplied = ensureRuntimeScriptApplied;
@@ -5,12 +5,24 @@ const GetValuesFromPackage_1 = require("../lib/core/util/GetValuesFromPackage");
5
5
  const PathsConstants_1 = require("../scripts/PathsConstants");
6
6
  const LineOffsetAnalyzeCall_1 = require("./core/LineOffsetAnalyzeCall");
7
7
  module.exports = (() => {
8
+ var _a, _b;
8
9
  const args = process.argv.slice(2);
9
- const appBundleInfo = Object.assign({}, (0, GetValuesFromPackage_1.getHostAppBundleInfo)(PathsConstants_1.default.getPackageJsonFile()));
10
- const pluginInfo = Object.assign({}, (0, GetValuesFromPackage_1.getHostAppBundleInfo)(PathsConstants_1.default.getInternalPackageJsonFile(), true));
11
- appBundleInfo.pluginVersion = ((pluginInfo === null || pluginInfo === void 0 ? void 0 : pluginInfo.version) != null) ? pluginInfo === null || pluginInfo === void 0 ? void 0 : pluginInfo.version : '0';
12
- const projectRoot = args[0] || PathsConstants_1.default.getApplicationPath();
13
- const buildPath = args[1] || PathsConstants_1.default.getBuildPath();
14
- const analyzer = new LineOffsetAnalyzeCall_1.LineOffsetAnalyzer(projectRoot, buildPath, appBundleInfo);
10
+ const parsedArgs = args.reduce((acc, arg) => {
11
+ const [key, value] = arg.split('=');
12
+ if (key && value !== undefined) {
13
+ acc[key] = value;
14
+ }
15
+ return acc;
16
+ }, {});
17
+ const isProd = parsedArgs.env === 'prod';
18
+ const options = {
19
+ isProd,
20
+ projectRoot: parsedArgs.projectRoot || PathsConstants_1.default.getApplicationPath(),
21
+ buildPath: parsedArgs.buildPath || PathsConstants_1.default.getBuildPath(),
22
+ androidSourcemapPath: parsedArgs.androidSourcemapPath || '',
23
+ iosSourcemapPath: parsedArgs.iosSourcemapPath || '',
24
+ appBundleInfo: Object.assign(Object.assign({}, (0, GetValuesFromPackage_1.getHostAppBundleInfo)(PathsConstants_1.default.getPackageJsonFile())), { pluginVersion: (_b = (_a = (0, GetValuesFromPackage_1.getHostAppBundleInfo)(PathsConstants_1.default.getInternalPackageJsonFile(), true)) === null || _a === void 0 ? void 0 : _a.version) !== null && _b !== void 0 ? _b : '0' }),
25
+ };
26
+ const analyzer = new LineOffsetAnalyzeCall_1.LineOffsetAnalyzer(options);
15
27
  analyzer.run();
16
28
  })();
@@ -26,6 +26,7 @@ exports.default = {
26
26
  getConfigFilePath: () => (0, path_1.join)(getApplicationPath(), 'dynatrace.config.js'),
27
27
  getAndroidFolder: () => (0, path_1.join)(getApplicationPath(), 'android'),
28
28
  getAndroidGradleFile: (androidFolder) => (0, path_1.join)(androidFolder, 'build.gradle'),
29
+ getAndroidAppGradleFile: (androidFolder) => (0, path_1.join)(androidFolder, 'app', 'build.gradle'),
29
30
  getIOSFolder: () => (0, path_1.join)(getApplicationPath(), 'ios'),
30
31
  getDynatraceGradleFile: () => (0, path_1.join)(getPluginPath(), PATH_FILES, exports.DYNATRACE_CONFIG_GRADLE_FILE),
31
32
  getCurrentLogPath: () => (0, path_1.join)(getPluginPath(), PATH_LOGS, 'currentLog.txt'),
@@ -16,6 +16,7 @@ const instrumentCommand = () => {
16
16
  (0, InstrumentUtil_1.showVersionOfPlugin)();
17
17
  let pathToConfig = PathsConstants_1.default.getConfigFilePath();
18
18
  let pathToGradle = PathsConstants_1.default.getAndroidGradleFile(PathsConstants_1.default.getAndroidFolder());
19
+ const pathToAppGradle = PathsConstants_1.default.getAndroidAppGradleFile(PathsConstants_1.default.getAndroidFolder());
19
20
  let androidAvailable = true;
20
21
  let pathToPList;
21
22
  let iosAvailable = true;
@@ -54,6 +55,7 @@ const instrumentCommand = () => {
54
55
  Logger_1.default.logMessageSync('Starting Android Instrumentation with Dynatrace!', Logger_1.default.INFO);
55
56
  android.instrumentAndroidPlatform(pathToGradle, false);
56
57
  android.writeGradleConfig(configAgent.android);
58
+ android.ensureRuntimeScriptApplied(pathToAppGradle);
57
59
  android.copyGradleConfigFile(pathToGradle);
58
60
  }
59
61
  catch (e) {
@@ -17,17 +17,19 @@ const Logger_1 = require("../Logger");
17
17
  const InstrumentUtil_1 = require("../util/InstrumentUtil");
18
18
  const FileOperationHelper_1 = require("../../scripts/FileOperationHelper");
19
19
  class LineOffsetAnalyzer {
20
- constructor(rootPath, instrumentedPath, appBundleInfo) {
21
- this.rootDir = (0, path_1.resolve)(rootPath);
22
- this.instrumentedDir = (0, path_1.resolve)(instrumentedPath);
20
+ constructor(options) {
21
+ this.rootDir = (0, path_1.resolve)(options.projectRoot);
22
+ this.instrumentedDir = (0, path_1.resolve)(options.buildPath);
23
23
  this.outputFile = (0, path_1.resolve)(this.instrumentedDir, 'line-offsets.json');
24
24
  this.logFile = (0, path_1.resolve)(this.instrumentedDir, 'debug.log');
25
- this.appBundleInfo = appBundleInfo;
25
+ this.appBundleInfo = options.appBundleInfo;
26
+ this.isProd = options.isProd;
27
+ this.androidSourcemapPath = options.androidSourcemapPath;
28
+ this.iosSourcemapPath = options.iosSourcemapPath;
26
29
  }
27
30
  run() {
28
31
  return __awaiter(this, void 0, void 0, function* () {
29
32
  try {
30
- yield fs.writeFile(this.logFile, '');
31
33
  const buildExists = yield FileOperationHelper_1.default.checkIfFileExists(this.instrumentedDir);
32
34
  if (!buildExists) {
33
35
  yield this.log(`❌ Build directory not found at: ${this.instrumentedDir}`);
@@ -35,6 +37,7 @@ class LineOffsetAnalyzer {
35
37
  console.error('🚫 Build directory missing. Make and instrument the project first.');
36
38
  process.exit(1);
37
39
  }
40
+ yield fs.writeFile(this.logFile, '');
38
41
  const instrumentedFiles = (yield FileOperationHelper_1.default.getAllFiles(this.log, this.instrumentedDir))
39
42
  .filter((filePath) => filePath.endsWith(InstrumentUtil_1.INSTRUMENTED_FILE_EXTENSION));
40
43
  const mappings = {};
@@ -64,20 +67,69 @@ class LineOffsetAnalyzer {
64
67
  }
65
68
  const finalOutput = {
66
69
  generationTime: new Date().toISOString(),
67
- appVersion: this.appBundleInfo ? this.appBundleInfo.version : 'application version not defined',
68
- pluginVersion: this.appBundleInfo ? this.appBundleInfo.pluginVersion : 'plugin version not defined',
70
+ appVersion: this.appBundleInfo !== null ? this.appBundleInfo.version : 'application version not defined',
71
+ pluginVersion: this.appBundleInfo !== null ? this.appBundleInfo.pluginVersion : 'plugin version not defined',
69
72
  mappings: {
70
- [this.appBundleInfo ? this.appBundleInfo.name : 'app name not defined']: mappings,
73
+ [this.appBundleInfo !== null ? this.appBundleInfo.name : 'app name not defined']: mappings,
71
74
  },
72
75
  };
73
76
  yield fs.writeFile(this.outputFile, JSON.stringify(finalOutput, null, 2));
74
77
  yield this.log(`βœ… Line offsets written to ${this.outputFile}`);
78
+ if (this.isProd) {
79
+ yield this.log('πŸ”§ Patching source map with all offset data...');
80
+ const loadedMap = yield this.loadSourceMap();
81
+ if (loadedMap) {
82
+ const { map, path: originalMapPath } = loadedMap;
83
+ map.x_dynatrace_offset = mappings;
84
+ const backupPath = originalMapPath + '.bak';
85
+ const serilalisedPath = originalMapPath + '.serialised';
86
+ yield fs.copyFile(originalMapPath, backupPath);
87
+ yield this.log(`πŸ’Ύ Backup created: ${backupPath}`);
88
+ yield fs.writeFile(originalMapPath, JSON.stringify(map));
89
+ yield fs.writeFile(serilalisedPath, JSON.stringify(map, null, 2));
90
+ yield this.log(`πŸ“ Patched source map written to: ${originalMapPath}`);
91
+ }
92
+ else {
93
+ yield this.log('⚠️ No source map found β€” skipping patching step');
94
+ }
95
+ }
75
96
  }
76
97
  catch (err) {
77
98
  console.error('❌ Unexpected error:', err);
78
99
  }
79
100
  });
80
101
  }
102
+ loadSourceMap() {
103
+ return __awaiter(this, void 0, void 0, function* () {
104
+ const processValue = process.cwd();
105
+ const possiblePaths = [
106
+ (0, path_1.join)(processValue, 'app/build/generated/sourcemaps/react/release/index.android.bundle.map'),
107
+ (0, path_1.join)(this.androidSourcemapPath),
108
+ (0, path_1.join)(this.iosSourcemapPath),
109
+ ];
110
+ let foundAny = false;
111
+ for (const mapPath of possiblePaths) {
112
+ try {
113
+ const exists = yield FileOperationHelper_1.default.checkIfFileExists(mapPath);
114
+ if (!exists) {
115
+ continue;
116
+ }
117
+ foundAny = true;
118
+ const content = yield fs.readFile(mapPath, 'utf-8');
119
+ const parsed = JSON.parse(content);
120
+ yield this.log(`πŸ—ΊοΈ Found and parsed source map at: ${mapPath}`);
121
+ return { map: parsed, path: mapPath };
122
+ }
123
+ catch (err) {
124
+ yield this.log(`⚠️ Failed to load or parse source map at ${mapPath}: ${err.message}`);
125
+ }
126
+ }
127
+ if (!foundAny) {
128
+ yield this.log('❌ No valid source map found in any of the expected locations.');
129
+ }
130
+ return null;
131
+ });
132
+ }
81
133
  log(msg) {
82
134
  return __awaiter(this, void 0, void 0, function* () {
83
135
  Logger_1.default.logMessageSync(msg, Logger_1.default.INFO);