@dynatrace/react-native-plugin 2.317.2 β 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 +16 -4
- package/android/build.gradle +1 -1
- package/files/plugin-runtime.gradle +22 -0
- package/files/plugin.gradle +2 -1
- package/instrumentation/DynatraceInstrumentation.js +1 -1
- package/instrumentation/libs/react-native/Touchables.js +1 -1
- package/instrumentation/parser/ParserUtil.js +11 -0
- package/lib/dynatrace-reporter.js +27 -1
- package/lib/next/events/EventPipeline.js +1 -1
- package/lib/next/events/modifier/ModifyEventValidation.js +4 -4
- package/lib/next/events/modifier/SendEventValidation.js +2 -2
- package/lib/next/events/modifier/ValueRestrictionModifier.js +1 -1
- package/lib/next/events/spec/EventSpecContstants.js +2 -2
- package/package.json +33 -67
- package/react-native-dynatrace.podspec +1 -1
- package/scripts/Android.js +16 -1
- package/scripts/LineOffsetAnalyze.js +18 -6
- package/scripts/PathsConstants.js +1 -0
- package/scripts/core/InstrumentCall.js +2 -0
- package/scripts/core/LineOffsetAnalyzeCall.js +60 -8
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.
|
|
36
|
-
* iOS Agent: 8.
|
|
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,15 @@ 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
|
+
|
|
1473
|
+
2.319.1
|
|
1474
|
+
* Updated Android (8.319.2.1011) & iOS Agent (8.319.1.1005)
|
|
1475
|
+
|
|
1464
1476
|
2.317.2
|
|
1465
1477
|
* Updated Android (8.317.1.1007) & iOS Agent (8.317.1.1003)
|
|
1466
1478
|
* Webrequest correlation with user action fixed for iOS
|
package/android/build.gradle
CHANGED
|
@@ -72,7 +72,7 @@ repositories {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
dependencies {
|
|
75
|
-
implementation 'com.dynatrace.agent:agent-android:8.
|
|
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
|
+
}
|
package/files/plugin.gradle
CHANGED
|
@@ -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
|
-
|
|
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') {
|
|
@@ -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.
|
|
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.
|
|
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.
|
|
106
|
+
"dt.support.api.overridden_fields",
|
|
107
107
|
overriddenKeys,
|
|
108
108
|
]);
|
|
109
109
|
}
|
|
110
110
|
if (externalException) {
|
|
111
111
|
sizedEntries.push([
|
|
112
|
-
"dt.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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-
|
|
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.
|
|
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.
|
|
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/
|
|
101
|
-
"@babel/plugin-
|
|
102
|
-
"@babel/plugin-
|
|
103
|
-
"@babel/plugin-
|
|
104
|
-
"@babel/
|
|
105
|
-
"@babel/
|
|
106
|
-
"@babel
|
|
107
|
-
"@
|
|
108
|
-
"@
|
|
109
|
-
"@types/
|
|
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.
|
|
115
|
-
"@types/react
|
|
116
|
-
"@types/semver": "^7.
|
|
117
|
-
"@types/shelljs": "^0.8.
|
|
118
|
-
"@types/uglify-js": "^3.17.
|
|
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.
|
|
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": "^
|
|
131
|
-
"jest-each": "^
|
|
132
|
-
"jest-junit": "^
|
|
133
|
-
"jest-mock": "^
|
|
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.
|
|
138
|
-
"ts-jest": "^
|
|
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.
|
|
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.
|
|
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)
|
package/scripts/Android.js
CHANGED
|
@@ -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
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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(
|
|
21
|
-
this.rootDir = (0, path_1.resolve)(
|
|
22
|
-
this.instrumentedDir = (0, path_1.resolve)(
|
|
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);
|