@dynatrace/react-native-plugin 2.333.1 → 2.335.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 +47 -178
- package/android/build.gradle +1 -1
- package/files/plugin-runtime.gradle +27 -13
- package/files/plugin.gradle +1 -1
- package/instrumentation/BabelPluginDynatrace.js +1 -0
- package/instrumentation/DynatraceInstrumentation.js +1 -1
- package/instrumentation/jsx/JsxRuntime.js +4 -4
- package/instrumentation/libs/UserInteraction.js +114 -0
- package/instrumentation/libs/community/gesture-handler/Touchables.InstrInfo.js +2 -0
- package/instrumentation/libs/community/gesture-handler/Touchables.js +3 -1
- package/instrumentation/libs/community/gesture-handler/index.js +3 -1
- package/instrumentation/libs/withOnPressMonitoring.js +6 -0
- package/lib/dynatrace-reporter.js +0 -14
- package/lib/dynatrace-transformer.js +10 -13
- package/lib/features/ui-interaction/Config.js +8 -2
- package/lib/features/ui-interaction/Plugin.Fragment.Test.js +170 -0
- package/lib/features/ui-interaction/Plugin.js +226 -882
- package/lib/features/ui-interaction/Run.js +11 -7
- package/lib/features/ui-interaction/Runtime.js +229 -896
- package/lib/features/ui-interaction/TouchMetaResolver.js +492 -0
- package/lib/features/ui-interaction/Types.js +1 -62
- package/package.json +6 -9
- package/react-native-dynatrace.podspec +1 -1
- package/scripts/Android.js +75 -62
- package/scripts/Config.js +11 -1
- package/scripts/core/InstrumentCall.js +1 -2
- package/scripts/core/LineOffsetAnalyzeCall.js +9 -15
- package/scripts/util/ReactOptions.js +0 -21
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
|
|
|
13
13
|
* User actions for onPress and onLongPress (Touchables, Buttons, Pickers, RefreshControl, Pressable)
|
|
14
14
|
* User actions for class and functional components (lifecycle events such as render(), didMount() and didUpdate())
|
|
15
15
|
* Reporting React Native errors
|
|
16
|
+
* Tracking navigation via `react.navigation.enabled`
|
|
16
17
|
* UI Interaction feature toggle via `react.userInteraction` (enable/disable user interaction capturing at runtime)
|
|
17
18
|
* Manual instrumentation
|
|
18
19
|
* Typescript bindings to add manual instrumentation
|
|
@@ -32,18 +33,18 @@ If you want to start using this plugin and are not a Dynatrace customer yet, hea
|
|
|
32
33
|
* NodeJS 16.0.0+ since our dependencies require NodeJS 16.0.0
|
|
33
34
|
|
|
34
35
|
## Agent Versions
|
|
35
|
-
|
|
36
|
+
These agent versions are configured in this plugin:
|
|
36
37
|
|
|
37
|
-
* Android Agent: 8.
|
|
38
|
-
* iOS Agent: 8.
|
|
38
|
+
* Android Agent: 8.335.1.1001
|
|
39
|
+
* iOS Agent: 8.335.1.1009
|
|
39
40
|
|
|
40
41
|
## Quick Setup
|
|
41
42
|
|
|
42
43
|
1. [Install plugin](#1-install-the-plugin)
|
|
43
|
-
2. [
|
|
44
|
-
3. [
|
|
45
|
-
4. [
|
|
46
|
-
5. [Build and run your app](#
|
|
44
|
+
2. [Setup configuration](#2-setup-dynatraceconfigjs)
|
|
45
|
+
3. [Register babel plugin](#3-register-our-babel-plugin-in-babelconfigjs)
|
|
46
|
+
4. [Register jsx-runtime](#4-register-our-jsx-runtime-in-babelconfigjs)
|
|
47
|
+
5. [Build and run your app](#5-build-and-run-your-app)
|
|
47
48
|
|
|
48
49
|
## Advanced topics
|
|
49
50
|
* [Manual OneAgent Startup](#manual-oneagent-startup)
|
|
@@ -93,6 +94,8 @@ This agent versions are configured in this plugin:
|
|
|
93
94
|
* [Navigation](#navigation)
|
|
94
95
|
* [Source Map](#source-map)
|
|
95
96
|
* [User Interaction](#user-interaction-1)
|
|
97
|
+
* [Debugging our auto-instrumentation](#debugging-our-auto-instrumentation)
|
|
98
|
+
* [Using our legacy jscodeshift auto-instrumentation](#using-our-legacy-jscodeshift-auto-instrumentation)
|
|
96
99
|
* [Android block](#android-block)
|
|
97
100
|
* [iOS block](#ios-block)
|
|
98
101
|
* [Lifecycle modes](#lifecycle)
|
|
@@ -125,9 +128,7 @@ This agent versions are configured in this plugin:
|
|
|
125
128
|
> **Note**: If you are upgrading to React Native v0.70 (or newer) or using the @react-native-community/cli 9.x+ version, be aware that our automated script running before every start/run-android/run-ios command is no longer working. When your *dynatrace.config.js* changed be sure to execute `npx instrumentDynatrace` beforehand.
|
|
126
129
|
|
|
127
130
|
## 1. Install the plugin
|
|
128
|
-
1. Install the plugin by calling
|
|
129
|
-
- React Native v0.60 or newer : `npm install @dynatrace/react-native-plugin`
|
|
130
|
-
- React Native v0.59.x : `react-native install @dynatrace/react-native-plugin`.
|
|
131
|
+
1. Install the plugin by calling `npm install @dynatrace/react-native-plugin`
|
|
131
132
|
2. **iOS only :** If you use pods, you need to go into your `ios` directory and execute `pod install` to install the new Dynatrace dependency to your xCode project.
|
|
132
133
|
|
|
133
134
|
### Troubleshooting
|
|
@@ -135,81 +136,34 @@ This agent versions are configured in this plugin:
|
|
|
135
136
|
- Standalone Project: If you are using React Native standalone and embed it in your native project have a look [here](#configuration-of-standalone-react-native-project).
|
|
136
137
|
- If for some reason (e.g. seperate native projects) `react-native link` doesn't work as expected, [manually add the iOS agent to your project](#manually-adding-ios-oneagent-to-a-project).
|
|
137
138
|
|
|
138
|
-
## 2.
|
|
139
|
+
## 2. Setup dynatrace.config.js
|
|
139
140
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
Depending on your React Native version, you will need to use a different way to register the transformer. If you don't know the version, enter `react-native --version` in your terminal.
|
|
143
|
-
|
|
144
|
-
The following configuration must be added. If you already have a babel transformer (babelTransformerPath) in place, you need to [use the upstreamTransformer property in dynatrace.config.js](#using-a-second-transformer-besides-the-dynatrace-transformer) to use a transformer besides our dynatrace transformer.
|
|
145
|
-
|
|
146
|
-
In your project's root directory, create or extend `metro.config.js` so that it contains the following configuration properties `transformer.babelTransformerPath` and `reporter`:
|
|
147
|
-
|
|
148
|
-
#### For React Native v0.72.1 or newer
|
|
149
|
-
|
|
150
|
-
```js
|
|
151
|
-
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
|
|
152
|
-
const defaultConfig = getDefaultConfig(__dirname);
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Metro configuration
|
|
156
|
-
* https://facebook.github.io/metro/docs/configuration
|
|
157
|
-
*
|
|
158
|
-
* @type {import('metro-config').MetroConfig}
|
|
159
|
-
*/
|
|
160
|
-
const config = {
|
|
161
|
-
transformer: {
|
|
162
|
-
babelTransformerPath: require.resolve(
|
|
163
|
-
'@dynatrace/react-native-plugin/lib/dynatrace-transformer',
|
|
164
|
-
),
|
|
165
|
-
},
|
|
166
|
-
reporter: require('@dynatrace/react-native-plugin/lib/dynatrace-reporter'),
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
module.exports = mergeConfig(defaultConfig, config);
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
#### For Expo
|
|
141
|
+
> **Note**: If you are upgrading from a previous version of this plugin, you'll notice that the file format has changed. Your old configuration is still available in `dynatrace.config` and you have to copy your values to the new `dynatrace.config.js`.
|
|
173
142
|
|
|
174
|
-
|
|
175
|
-
const {getDefaultConfig} = require('expo/metro-config');
|
|
176
|
-
const config = getDefaultConfig(__dirname);
|
|
143
|
+
Define a mobile app in Dynatrace and open the Mobile app instrumentation settings. In the settings you will see a `dynatrace.config.js` file which can be downloaded for React Native. Download and copy this file into the root folder of your application. If you are not sure you can always use `npx configDynatrace` to create a default configuration file.
|
|
177
144
|
|
|
178
|
-
|
|
179
|
-
'@dynatrace/react-native-plugin/lib/dynatrace-transformer',
|
|
180
|
-
);
|
|
145
|
+
> **Note**: Define the components that you want to see lifecycle instrumented ([example](#lifecycle)). This is important as you will only see Application startup and Touches out of the box.
|
|
181
146
|
|
|
182
|
-
|
|
147
|
+
For more details about the configuration, see [Advanced topics](#structure-of-the-dynatracejs-file).
|
|
183
148
|
|
|
184
|
-
|
|
185
|
-
```
|
|
149
|
+
## 3. Register our babel plugin in babel.config.js
|
|
186
150
|
|
|
187
|
-
|
|
151
|
+
Add the Dynatrace babel plugin to your `babel.config.js`:
|
|
188
152
|
|
|
189
153
|
```js
|
|
190
154
|
module.exports = {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
'@dynatrace/react-native-plugin/lib/dynatrace-transformer'
|
|
194
|
-
)
|
|
195
|
-
},
|
|
196
|
-
reporter: require('@dynatrace/react-native-plugin/lib/dynatrace-reporter'),
|
|
155
|
+
...
|
|
156
|
+
plugins: [..., '@dynatrace/react-native-plugin/instrumentation/BabelPluginDynatrace'],
|
|
197
157
|
};
|
|
198
158
|
```
|
|
199
159
|
|
|
200
|
-
|
|
160
|
+
This plugin handles the auto-instrumentation of your React Native code at build time.
|
|
201
161
|
|
|
202
|
-
> **Note**:
|
|
162
|
+
> **Note**: We recently moved our auto-instrumentation from a custom metro transformer to a babel plugin. The code shown above is the new and recommended way to add our auto-instrumentation to your project by adding the babel plugin directly. However, our plugin is backwards compatible in a sense that we keep supporting auto-instrumentation via the Dynatrace transformer and reporter. In short, no configuration change is needed. If you continue using the Dynatrace transformer and reporter, we reroute the instrumentation logic to the babel plugin internally.
|
|
203
163
|
|
|
204
|
-
|
|
164
|
+
## 4. Register our jsx-runtime in babel.config.js
|
|
205
165
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
For more details about the configuration, see [Advanced topics](#structure-of-the-dynatracejs-file).
|
|
209
|
-
|
|
210
|
-
## 4. Update Babel Configuration
|
|
211
|
-
|
|
212
|
-
Depending on your version of Metro or Expo (if used), your babel configuration `babel.config.js` will need to be updated.
|
|
166
|
+
Depending on your version of Metro or Expo (if used), you additionally need to add our jsx-runtime to your babel configuration `babel.config.js`.
|
|
213
167
|
|
|
214
168
|
The changes have to be done in the following cases:
|
|
215
169
|
|
|
@@ -1071,13 +1025,6 @@ To generate a sourcemap:
|
|
|
1071
1025
|
* Then run `npx react-native run-ios --mode Release`, or
|
|
1072
1026
|
* Build for release in Xcode
|
|
1073
1027
|
|
|
1074
|
-
#### Accounting for Auto-Instrumentation
|
|
1075
|
-
|
|
1076
|
-
Since the plugin auto-instruments your code, sourcemap line numbers may be slightly offset. To ensure accurate symbolication:
|
|
1077
|
-
|
|
1078
|
-
* **Android**: Automatic patching is **enabled by default** and patches sourcemaps automatically at the end of every release build (see [Source Map](#source-map) configuration)
|
|
1079
|
-
* **iOS**: There is currently **no automation** available. You **must** execute [`npx lineOffsetDynatrace`](#npx-lineoffsetdynatrace) to patch your sourcemap files before uploading them to Dynatrace. Without this step, line numbers will be slightly off depending on instrumentation in iOS
|
|
1080
|
-
|
|
1081
1028
|
#### Uploading Sourcemaps
|
|
1082
1029
|
|
|
1083
1030
|
Once generated and patched, upload your sourcemaps to Dynatrace. For detailed instructions, see the [symbol file management documentation](https://docs.dynatrace.com/docs/observe/digital-experience/mobile-applications/analyze-and-use/upload-and-manage-symbol-files).
|
|
@@ -1108,20 +1055,6 @@ npx configDynatrace [optional: config=...]
|
|
|
1108
1055
|
|
|
1109
1056
|
* `config=C:\SpecialFolderForDynatrace\dynatrace.config.js`: If you have not got your config file in the root folder of the React Native project but somewhere else.
|
|
1110
1057
|
|
|
1111
|
-
## npx lineOffsetDynatrace
|
|
1112
|
-
|
|
1113
|
-
Our auto-instrumentation modifies your source code during the build process, which causes line numbers in your sourcemaps to become slightly offset from the original source. This can result in incorrect line numbers when viewing crash reports or stack traces in Dynatrace.
|
|
1114
|
-
|
|
1115
|
-
The `npx lineOffsetDynatrace` command patches your sourcemap file with offset information, allowing Dynatrace to accurately map instrumented line numbers back to the original source code. The patching process adds Dynatrace-specific metadata alongside the original sourcemap content without modifying any existing fields, ensuring your sourcemap continues to work as expected with all standard tooling.
|
|
1116
|
-
|
|
1117
|
-
**Usage:**
|
|
1118
|
-
|
|
1119
|
-
```
|
|
1120
|
-
npx lineOffsetDynatrace sourcemapPath=/path/to/your/sourcemap.map
|
|
1121
|
-
```
|
|
1122
|
-
|
|
1123
|
-
* `sourcemapPath=/path/to/your/sourcemap.map`: **(Required)** The path to the sourcemap file that should be patched.
|
|
1124
|
-
|
|
1125
1058
|
## Customizing paths for configuration
|
|
1126
1059
|
|
|
1127
1060
|
> **Note:** This feature works directly on run-android, run-ios or start command only for React Native v0.60.1 or newer until v0.69.x.
|
|
@@ -1269,7 +1202,6 @@ The `react` configuration block contains all settings regarding the react instru
|
|
|
1269
1202
|
|
|
1270
1203
|
```js
|
|
1271
1204
|
react : {
|
|
1272
|
-
|
|
1273
1205
|
input : {
|
|
1274
1206
|
instrument(filename) => {
|
|
1275
1207
|
return true;
|
|
@@ -1311,7 +1243,7 @@ react: {
|
|
|
1311
1243
|
This activates the debug mode. You will get more console output during instrumentation and at runtime.
|
|
1312
1244
|
|
|
1313
1245
|
|
|
1314
|
-
|
|
1246
|
+
#### User Interaction
|
|
1315
1247
|
|
|
1316
1248
|
```js
|
|
1317
1249
|
react: {
|
|
@@ -1322,7 +1254,7 @@ react: {
|
|
|
1322
1254
|
Enables or disables the UI interaction (user interaction) feature.
|
|
1323
1255
|
Set to false to disable capturing of user interactions (e.g., touch/click actions) produced by the React Native UI interaction instrumentation.
|
|
1324
1256
|
|
|
1325
|
-
|
|
1257
|
+
##### What customers will observe after enabling UI Interaction
|
|
1326
1258
|
|
|
1327
1259
|
After setting `react.userInteraction: true` and rebuilding with instrumentation, the expected flow is:
|
|
1328
1260
|
|
|
@@ -1336,7 +1268,7 @@ Notes:
|
|
|
1336
1268
|
- No extra UI needs to be added in customer screens for standard automatic capture.
|
|
1337
1269
|
- If `react.debug` is enabled, additional debug output can appear during instrumentation/runtime.
|
|
1338
1270
|
|
|
1339
|
-
|
|
1271
|
+
##### Runtime switching (config + remote configuration observer)
|
|
1340
1272
|
|
|
1341
1273
|
UI Interaction can be controlled by two layers:
|
|
1342
1274
|
|
|
@@ -1420,33 +1352,32 @@ react: {
|
|
|
1420
1352
|
}
|
|
1421
1353
|
```
|
|
1422
1354
|
|
|
1423
|
-
####
|
|
1424
|
-
|
|
1425
|
-
This feature is enabled by default and patches sourcemap files so that any modifications made through Dynatrace will result in correct line numbers. If this feature is not enabled, line numbers of symbolicated stacktraces in Dynatrace might not match with your original source.
|
|
1355
|
+
#### Debugging our auto-instrumentation
|
|
1426
1356
|
|
|
1427
|
-
|
|
1357
|
+
You can see the changes our auto-instrumentation is making to your code with this flag:
|
|
1428
1358
|
|
|
1429
1359
|
```js
|
|
1430
1360
|
react: {
|
|
1431
|
-
|
|
1432
|
-
enabled: true
|
|
1433
|
-
}
|
|
1361
|
+
debugBabelPlugin: true
|
|
1434
1362
|
}
|
|
1435
1363
|
```
|
|
1436
1364
|
|
|
1437
|
-
|
|
1365
|
+
The changes our auto-instrumentation is making now get dumped into the `node_modules/@dynatrace/react-native-plugin/build` folder when building the Javascript bundle. The `*.dtx` files show what your code looks like after only our auto-instrumentation was applied to your code. The `*.dtx.downstream` files show what your code looks like after both our auto-instrumentation and all other babel plugins were applied to your code.
|
|
1438
1366
|
|
|
1439
|
-
|
|
1367
|
+
> **Note:** This feature increases the time it takes to build the Javascript bundle. Only use it for debugging purposes. Deactivate it otherwise, especially when fast build times are important.
|
|
1368
|
+
|
|
1369
|
+
#### Using our legacy jscodeshift auto-instrumentation
|
|
1370
|
+
|
|
1371
|
+
We recently moved our auto-instrumentation to a babel plugin. In case you need to, you can still switch to the old jscodeshift auto-instrumentation with this flag:
|
|
1440
1372
|
|
|
1441
1373
|
```js
|
|
1442
1374
|
react: {
|
|
1443
|
-
|
|
1444
|
-
enabled: true,
|
|
1445
|
-
androidSourcemapLocation: 'sourcemap.map'
|
|
1446
|
-
}
|
|
1375
|
+
useLegacyJscodeshift: true
|
|
1447
1376
|
}
|
|
1448
1377
|
```
|
|
1449
1378
|
|
|
1379
|
+
> **Note:** When we moved our auto-instrumentation to a babel plugin, we removed documentation that was only relevant for the jscodeshift auto-instrumentation. Most notably, we removed documentation concerning registering a custom metro transformer and patching sourcemaps. If you use the `useLegacyJscodeshift` flag, please refer to the [legacy documentation (v2.333.1)](https://www.npmjs.com/package/@dynatrace/react-native-plugin/v/2.333.1) for details on custom metro transformers and sourcemap patching.
|
|
1380
|
+
|
|
1450
1381
|
### Android block
|
|
1451
1382
|
|
|
1452
1383
|
The Android block is a wrapper for the Android configuration you find in the WebUI (in the Mobile Application Settings). Copy the content into the following block:
|
|
@@ -1745,75 +1676,6 @@ module.exports = {
|
|
|
1745
1676
|
};
|
|
1746
1677
|
```
|
|
1747
1678
|
|
|
1748
|
-
## Using a second transformer besides the dynatrace transformer
|
|
1749
|
-
|
|
1750
|
-
If you want to register the Dynatrace transformer in your configuration and you already have a transformer in place, change the upstreaming transformer for the Dynatrace transformer.
|
|
1751
|
-
|
|
1752
|
-
This can be done via a configuration value in the `dynatrace.config.js`. The following example shows how the configuration might look like for the popular `react-native-svg-transformer`. Be aware that the following example is targeting *React Native v0.72.1* or newer. Be aware if you are using a different second transformer, you need to change `react-native-svg-transformer/react-native` accordingly.
|
|
1753
|
-
|
|
1754
|
-
#### dynatrace.config.js
|
|
1755
|
-
|
|
1756
|
-
```js
|
|
1757
|
-
// The `...` only indicates that there are other values as well, but we've omitted them in this example.
|
|
1758
|
-
module.exports = {
|
|
1759
|
-
react : {
|
|
1760
|
-
upstreamTransformer: require.resolve('react-native-svg-transformer/react-native'),
|
|
1761
|
-
// ...
|
|
1762
|
-
},
|
|
1763
|
-
// ...
|
|
1764
|
-
};
|
|
1765
|
-
```
|
|
1766
|
-
|
|
1767
|
-
#### metro.config.js for React Native v0.72.1 or newer
|
|
1768
|
-
```js
|
|
1769
|
-
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
|
|
1770
|
-
const defaultConfig = getDefaultConfig(__dirname);
|
|
1771
|
-
const {assetExts, sourceExts} = defaultConfig.resolver;
|
|
1772
|
-
|
|
1773
|
-
/**
|
|
1774
|
-
* Metro configuration
|
|
1775
|
-
* https://facebook.github.io/metro/docs/configuration
|
|
1776
|
-
*
|
|
1777
|
-
* @type {import('metro-config').MetroConfig}
|
|
1778
|
-
*/
|
|
1779
|
-
const config = {
|
|
1780
|
-
transformer: {
|
|
1781
|
-
babelTransformerPath: require.resolve(
|
|
1782
|
-
'@dynatrace/react-native-plugin/lib/dynatrace-transformer',
|
|
1783
|
-
),
|
|
1784
|
-
},
|
|
1785
|
-
reporter: require('@dynatrace/react-native-plugin/lib/dynatrace-reporter'),
|
|
1786
|
-
resolver: {
|
|
1787
|
-
assetExts: assetExts.filter((ext) => ext !== 'svg'),
|
|
1788
|
-
sourceExts: [...sourceExts, 'cjs', 'svg'],
|
|
1789
|
-
},
|
|
1790
|
-
};
|
|
1791
|
-
|
|
1792
|
-
module.exports = mergeConfig(defaultConfig, config);
|
|
1793
|
-
```
|
|
1794
|
-
|
|
1795
|
-
#### metro.config.js for React Native v0.59 or newer
|
|
1796
|
-
|
|
1797
|
-
```js
|
|
1798
|
-
const { getDefaultConfig } = require("metro-config");
|
|
1799
|
-
|
|
1800
|
-
module.exports = (async () => {
|
|
1801
|
-
const {
|
|
1802
|
-
resolver: { sourceExts, assetExts }
|
|
1803
|
-
} = await getDefaultConfig();
|
|
1804
|
-
return {
|
|
1805
|
-
transformer: {
|
|
1806
|
-
babelTransformerPath: require.resolve('@dynatrace/react-native-plugin/lib/dynatrace-transformer')
|
|
1807
|
-
},
|
|
1808
|
-
reporter: require('@dynatrace/react-native-plugin/lib/dynatrace-reporter'),
|
|
1809
|
-
resolver: {
|
|
1810
|
-
assetExts: assetExts.filter((ext) => ext !== "svg"),
|
|
1811
|
-
sourceExts: [...sourceExts, "cjs", "svg"]
|
|
1812
|
-
}
|
|
1813
|
-
};
|
|
1814
|
-
})();
|
|
1815
|
-
```
|
|
1816
|
-
|
|
1817
1679
|
## Maven Central in top-level gradle file
|
|
1818
1680
|
|
|
1819
1681
|
Because the Dynatrace Android agent now requires the MavenCentral repository, if either `jcenter()` or `mavenCentral()` is not added inside of **ALL** the repositories blocks via the [top-level build.gradle](https://dt-url.net/jm610pso), the build will fail.
|
|
@@ -2054,7 +1916,14 @@ If you are struggling with a problem, submit a support ticket to Dynatrace (supp
|
|
|
2054
1916
|
<br/><br/>
|
|
2055
1917
|
## Changelog
|
|
2056
1918
|
|
|
2057
|
-
|
|
1919
|
+
2.335.1
|
|
1920
|
+
* Updated Android (8.335.1.1001) & iOS Agent (8.335.1.1009)
|
|
1921
|
+
* Dynatrace Android configuration (`dynatrace.gradle`) is now written directly next to the `build.gradle` file instead of inside `node_modules`. Existing projects with the old path are migrated automatically.
|
|
1922
|
+
* Updated Android Gradle plugin configuration for Gradle 9 compatibility in `plugin-runtime.gradle`.
|
|
1923
|
+
* Moved auto-instrumentation from jscodeshift to a Babel plugin, improvements include:
|
|
1924
|
+
* Significantly faster JS bundle builds
|
|
1925
|
+
* Sourcemaps now natively account for our auto-instrumentation - no patching needed
|
|
1926
|
+
* Added instrumentation for `BorderlessButton` and `BaseButton` from `react-native-gesture-handler`.
|
|
2058
1927
|
|
|
2059
1928
|
2.333.1
|
|
2060
1929
|
* Jetpack Compose support range extended to 1.4 - 1.10 see [Compose Compatibility Note](#compose-compatibility-note)
|
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.335.1.1001'
|
|
76
76
|
implementation "com.facebook.react:react-native:${safeExtGet('reactNative', '+')}"
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -1,19 +1,33 @@
|
|
|
1
|
-
import org.gradle.
|
|
1
|
+
import org.gradle.process.ExecOperations
|
|
2
|
+
import javax.inject.Inject
|
|
3
|
+
|
|
4
|
+
abstract class RunLineOffsetTask extends DefaultTask {
|
|
5
|
+
@Internal
|
|
6
|
+
abstract DirectoryProperty getWorkingDirectory()
|
|
7
|
+
|
|
8
|
+
@Inject
|
|
9
|
+
abstract ExecOperations getExecOperations()
|
|
10
|
+
|
|
11
|
+
@TaskAction
|
|
12
|
+
void run() {
|
|
13
|
+
execOperations.exec {
|
|
14
|
+
workingDir workingDirectory.get().asFile
|
|
15
|
+
if (System.getProperty('os.name').toLowerCase().contains('windows')) {
|
|
16
|
+
commandLine 'cmd', '/c', 'npx', 'lineOffsetDynatrace'
|
|
17
|
+
} else {
|
|
18
|
+
commandLine 'npx', 'lineOffsetDynatrace'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
2
23
|
|
|
3
24
|
android.applicationVariants.all { variant ->
|
|
4
25
|
if (variant.buildType.name == "release") {
|
|
26
|
+
def lineOffsetTask = tasks.register("runLineOffset${variant.name.capitalize()}", RunLineOffsetTask) {
|
|
27
|
+
workingDirectory = layout.projectDirectory
|
|
28
|
+
}
|
|
5
29
|
variant.mergeAssetsProvider.configure { task ->
|
|
6
|
-
task.
|
|
7
|
-
exec {
|
|
8
|
-
workingDir rootDir
|
|
9
|
-
if (DefaultNativePlatform.currentOperatingSystem.isWindows()) {
|
|
10
|
-
// On windows, npx.cmd may not be a true binary executable and may need to be interpreted by a shell instead of executed direclty
|
|
11
|
-
commandLine 'cmd', '/c', 'npx', 'lineOffsetDynatrace'
|
|
12
|
-
} else {
|
|
13
|
-
commandLine 'npx', 'lineOffsetDynatrace'
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
30
|
+
task.dependsOn(lineOffsetTask)
|
|
17
31
|
}
|
|
18
32
|
}
|
|
19
|
-
}
|
|
33
|
+
}
|
package/files/plugin.gradle
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var _templateObject,_templateObject2,_templateObject3,_templateObject4,_templateObject5,_templateObject6,_interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault"),_taggedTemplateLiteral2=_interopRequireDefault(require("@babel/runtime/helpers/taggedTemplateLiteral"));function _createForOfIteratorHelper(e,t){var n,r,a,i,o="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(o)return a=!(r=!0),{s:function(){o=o.call(e)},n:function(){var e=o.next();return r=e.done,e},e:function(e){a=!0,n=e},f:function(){try{r||null==o.return||o.return()}finally{if(a)throw n}}};if(Array.isArray(e)||(o=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length)return o&&(e=o),i=0,{s:t=function(){},n:function(){return i>=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:t};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){var n;if(e)return"string"==typeof e?_arrayLikeToArray(e,t):"Map"===(n="Object"===(n={}.toString.call(e).slice(8,-1))&&e.constructor?e.constructor.name:n)||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}Object.defineProperty(exports,"__esModule",{value:!0});var reactOptions,fspath=require("path"),fs=require("fs"),core_1=require("@babel/core"),generator_1=require("@babel/generator"),PathsConstants_1=require("../scripts/PathsConstants"),Config_1=require("../scripts/Config"),GetValuesFromPackage_1=require("../lib/core/util/GetValuesFromPackage"),Types_1=require("./model/Types"),INSTRUMENTATION_LIBS="@dynatrace/react-native-plugin/instrumentation/libs",hasJSX=function(e){var t=!1;return e.traverse({"JSXElement|JSXFragment":function(){t=!0}}),t},instrumentUserInteraction=function(e){e.traverse({"FunctionDeclaration|ObjectMethod":function(e){var e=e.node,t=core_1.types.isFunctionDeclaration(e)?e.id:e.key;core_1.types.isIdentifier(t,{name:"registerComponent"})&&(t="".concat(INSTRUMENTATION_LIBS,"/UserInteraction"),e.body.body.unshift(core_1.template.statement('componentProvider = require("'.concat(t,'").wrapProvider(componentProvider);'))()))}})},instrumentAppRegistry=function(e){e.traverse({"FunctionDeclaration|ObjectMethod":function(e){var e=e.node,t=core_1.types.isFunctionDeclaration(e)?e.id:e.key;core_1.types.isIdentifier(t,{name:"runApplication"})&&e.body.body.unshift(core_1.template.statement(_templateObject=_templateObject||(0,_taggedTemplateLiteral2.default)(['require("@dynatrace/react-native-plugin").ApplicationHandler.startup();']))())}})},instrumentExceptionsManager=function(e){var t,n=null!=(t=null==(t=null==reactOptions?void 0:reactOptions.errorHandler)?void 0:t.reportFatalErrorAsCrash)&&t,r=(null==reactOptions?void 0:reactOptions.autoStart)&&(null==(t=null==reactOptions?void 0:reactOptions.errorHandler)?void 0:t.enabled);e.traverse({FunctionDeclaration:function(e){var t;core_1.types.isIdentifier(e.node.id,{name:"handleException"})&&(t=core_1.template.statement(_templateObject2=_templateObject2||(0,_taggedTemplateLiteral2.default)(['\n setTimeout(() => BODY, require("@dynatrace/react-native-plugin/lib/core/ErrorHandler")\n .reportErrorToDynatrace(e, isFatal, CRASH, AUTO));\n ']))({BODY:core_1.types.cloneNode(e.node.body),CRASH:core_1.types.booleanLiteral(n),AUTO:core_1.types.booleanLiteral(!!r)}),e.node.body.body=[t])}})},instrumentCssInterop=function(e){e.traverse({CallExpression:function(e){core_1.types.isIdentifier(e.node.callee,{name:"require"})&&(e=e.node.arguments[0],core_1.types.isStringLiteral(e))&&("react/jsx-runtime"===e.value?e.value="@dynatrace/react-native-plugin/jsx-runtime":"react/jsx-dev-runtime"===e.value&&(e.value="@dynatrace/react-native-plugin/jsx-dev-runtime"))}})},instrumentNavigation=function(e){e.traverse({VariableDeclarator:function(e){var t;core_1.types.isIdentifier(e.node.id,{name:"getRootState"})&&(t=core_1.template.statement(_templateObject3=_templateObject3||(0,_taggedTemplateLiteral2.default)(["\n require(PATH).monitorNavigation(getRootState);\n "]))({PATH:core_1.types.stringLiteral("".concat(INSTRUMENTATION_LIBS,"/react-navigation/ReactNavigation"))}),e.parentPath.insertAfter(t))}})},instrumentReactCreateElement=function(e){var t=core_1.template.statement(_templateObject4=_templateObject4||(0,_taggedTemplateLiteral2.default)(["\n require(PATH).instrumentCreateElement(module.exports);\n "]))({PATH:core_1.types.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")});e.pushContainer("body",t)},instrumentComponents=function(e,n){e.traverse({FunctionDeclaration:function(e){var t;hasJSX(e)&&(t=e.node,core_1.types.isIdentifier(t.id))&&null!=(e=e.getStatementParent())&&e.insertAfter(n(t.id.name,Types_1.Types.FunctionalComponent))},ClassDeclaration:function(e){var t;hasJSX(e)&&(t=e.node,core_1.types.isIdentifier(t.id))&&null!=(e=e.getStatementParent())&&e.insertAfter(n(t.id.name,Types_1.Types.ClassComponent))},"FunctionExpression|ArrowFunctionExpression":function(e){var t;hasJSX(e)&&(t=e.parent,void 0!==(t=core_1.types.isVariableDeclarator(t)&&core_1.types.isIdentifier(t.id)?t.id.name:core_1.types.isAssignmentExpression(t)&&core_1.types.isIdentifier(t.left)?t.left.name:void 0))&&null!=(e=e.getStatementParent())&&e.insertAfter(n(t,Types_1.Types.FunctionalComponent))}})},instrumentLifecycle=function(e){instrumentComponents(e,function(e,t){return core_1.template.statement(_templateObject5=_templateObject5||(0,_taggedTemplateLiteral2.default)(["NAME._dtInfo = { type: TYPE, name: 'NAME_STR' }"]))({NAME:core_1.types.identifier(e),TYPE:core_1.types.numericLiteral(t),NAME_STR:core_1.types.stringLiteral(e)})})},instrumentComponentNames=function(e){instrumentComponents(e,function(e){return core_1.template.statement(_templateObject6=_templateObject6||(0,_taggedTemplateLiteral2.default)(["NAME.dtName = 'NAME_STR'"]))({NAME:core_1.types.identifier(e),NAME_STR:core_1.types.stringLiteral(e)})})},instrumentInput=function(e){var l=new Map([["react-native",{proxy:"".concat(INSTRUMENTATION_LIBS,"/react-native/"),components:new Set(["TouchableHighlight","TouchableNativeFeedback","TouchableOpacity","TouchableWithoutFeedback","Button","RefreshControl","Text","Pressable","Switch"])}],["react-native-gesture-handler",{proxy:"".concat(INSTRUMENTATION_LIBS,"/community/gesture-handler/"),components:new Set(["TouchableHighlight","TouchableNativeFeedback","TouchableOpacity","TouchableWithoutFeedback","RectButton","BorderlessButton","BaseButton"])}],["@react-native-picker/picker",{proxy:"".concat(INSTRUMENTATION_LIBS,"/community/Picker"),components:new Set(["Picker","PickerIOS"])}]]);e.traverse({ImportDeclaration:function(e){if(void 0===e.node.processed){var t=e.node.source;if(l.has(t.value)){var r=l.get(t.value),n=e.node.specifiers,a=[],i=[];if(n.forEach(function(e,t){var n;core_1.types.isImportSpecifier(e)&&(n=core_1.types.isIdentifier(e.imported)?e.imported.name:e.imported.value,r.components.has(n)||(a.push(e),i.push(t)))}),a.length!==n.length){var o,s=_createForOfIteratorHelper(i.reverse());try{for(s.s();!(o=s.n()).done;){var c=o.value;n.splice(c,1)}}catch(e){s.e(e)}finally{s.f()}0<a.length&&((t=core_1.types.importDeclaration(a,core_1.types.stringLiteral(t.value))).processed=!0,e.insertBefore(t)),e.node.source=core_1.types.stringLiteral(r.proxy),e.scope.crawl()}}}},CallExpression:function(e){core_1.types.isIdentifier(e.node.callee,{name:"require"})&&(e=e.node.arguments[0],core_1.types.isStringLiteral(e))&&l.has(e.value)&&(e.value=l.get(e.value).proxy)}})},instrumentJsxNames=function(e){e.traverse({JSXOpeningElement:function(e){var t=e.node.name,t=core_1.types.isJSXIdentifier(t)?t.name:core_1.types.isJSXMemberExpression(t)?(0,generator_1.default)(t).code:void 0;t&&e.node.attributes.push(core_1.types.jsxAttribute(core_1.types.jsxIdentifier("dtName"),core_1.types.stringLiteral(t)))}})},instrumentConfigurationPreset=function(e){var t,n=(0,GetValuesFromPackage_1.getHostAppBundleInfo)(PathsConstants_1.default.getPackageJsonFile()),r={getLifecycleUpdate:reactOptions.lifecycle.includeUpdate,getLogLevel:reactOptions.debug?0:1,getBundleName:null!=(t=reactOptions.bundleName)?t:null==n?void 0:n.name,getBundleVersion:null!=(t=reactOptions.bundleVersion)?t:null==n?void 0:n.version,getActionNamePrivacy:reactOptions.input.actionNamePrivacy,isErrorHandlerEnabled:reactOptions.errorHandler.enabled,isReportFatalErrorAsCrash:reactOptions.errorHandler.reportFatalErrorAsCrash,isAutoStartupEnabled:reactOptions.autoStart};e.traverse({ClassMethod:function(e){var t;core_1.types.isIdentifier(e.node.key)&&void 0!==(t=r[e.node.key.name])&&(e=e.node.body.body[0],core_1.types.isReturnStatement(e))&&(e.argument=core_1.types.valueToNode(t))}})};exports.default=function(){return{visitor:{Program:function(e,t){reactOptions=(0,Config_1.readConfigDefault)().react;var n,r,a,i,o,s,c=t.filename;void 0!==c&&(a=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.some(function(e){return c.includes(fspath.join("node_modules",e)+fspath.sep)})},s=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.some(function(e){return c.endsWith(e)})},!(i="")===reactOptions.debugBabelPlugin&&(i=(0,generator_1.default)(e.node).code),a("@dynatrace")&&s("ConfigurationPreset.js")&&instrumentConfigurationPreset(e),a("react-native")&&s("AppRegistry.js","AppRegistryImpl.js")&&(reactOptions.autoStart&&instrumentAppRegistry(e),reactOptions.userInteraction)&&instrumentUserInteraction(e),a("react-native")&&s("ExceptionsManager.js")&&instrumentExceptionsManager(e),a("react-native-css-interop")&&s("jsx-runtime.js","jsx-dev-runtime.js")&&instrumentCssInterop(e),reactOptions.navigation.enabled&&a("@react-navigation")&&s("BaseNavigationContainer.js","BaseNavigationContainer.tsx")&&instrumentNavigation(e),a("react")&&s("index.js")&&instrumentReactCreateElement(e),null!=(n=null==(r=reactOptions.lifecycle)?void 0:r.instrument)&&n.call(r,c)&&(!c.includes("node_modules")||a("react-native")&&s("renderApplication.js"))&&hasJSX(e)&&instrumentLifecycle(e),null==(r=null==(n=reactOptions.input)?void 0:n.instrument)||!r.call(n,c)||c.includes("node_modules")&&!a("@react-navigation","react-native-drawer-layout")||instrumentInput(e),reactOptions.userInteraction&&!c.includes("node_modules")&&(instrumentJsxNames(e),instrumentComponentNames(e)),!0===reactOptions.debugBabelPlugin)&&(o=(0,generator_1.default)(e.node).code)!==i&&(s=fspath.join(PathsConstants_1.default.getBuildPath(),fspath.relative(PathsConstants_1.default.getApplicationPath(),c)+".dtx"),fs.mkdirSync(fspath.dirname(s),{recursive:!0}),fs.writeFileSync(s,o),t.set("fileDidChange",!0))}},post:function(e){var t;!0===reactOptions.debugBabelPlugin&&!0===this.get("fileDidChange")&&(t=(0,generator_1.default)(e.ast).code,e=fspath.join(PathsConstants_1.default.getBuildPath(),fspath.relative(PathsConstants_1.default.getApplicationPath(),e.opts.filename)+".dtx.downstream"),fs.mkdirSync(fspath.dirname(e),{recursive:!0}),fs.writeFileSync(e,t))}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var n=require("@babel/runtime/helpers/interopRequireDefault"),e=n(require("@babel/runtime/helpers/toConsumableArray"));function v(n,e){var r,t,i,u,o="undefined"!=typeof Symbol&&n[Symbol.iterator]||n["@@iterator"];if(o)return i=!(t=!0),{s:function(){o=o.call(n)},n:function(){var n=o.next();return t=n.done,n},e:function(n){i=!0,r=n},f:function(){try{t||null==o.return||o.return()}finally{if(i)throw r}}};if(Array.isArray(n)||(o=a(n))||e&&n&&"number"==typeof n.length)return o&&(n=o),u=0,{s:e=function(){},n:function(){return u>=n.length?{done:!0}:{done:!1,value:n[u++]}},e:function(n){throw n},f:e};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function a(n,e){var r;if(n)return"string"==typeof n?t(n,e):"Map"===(r="Object"===(r={}.toString.call(n).slice(8,-1))&&n.constructor?n.constructor.name:r)||"Set"===r?Array.from(n):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?t(n,e):void 0}function t(n,e){(null==e||e>n.length)&&(e=n.length);for(var r=0,t=Array(e);r<e;r++)t[r]=n[r];return t}Object.defineProperty(exports,"t",{value:!0}),exports.instrument=void 0;var d,p=require("path"),u=require("jscodeshift"),i=require("jscodeshift/src/Collection"),r=require("../scripts/FileOperationHelper"),m=require("../scripts/PathsConstants"),y=require("../lib/core/util/GetValuesFromPackage"),o=require("../scripts/util/InstrumentUtil"),g=require("../lib/features/ui-interaction/Run"),c=require("./libs/react-native/Touchables.InstrInfo"),l=require("./libs/react-native/RefreshControl.InstrInfo"),f=require("./libs/react-native/Switch.InstrInfo"),s=require("./libs/community/gesture-handler/Touchables.InstrInfo"),P=require("./libs/community/Picker.InstrInfo"),b=require("./model/Types"),T=require("./parser/ParserUtil"),q=((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"})(d=d||{}),[]),L=(q.push.apply(q,(0,e.default)(c.instrumentationInfo)),q.push.apply(q,(0,e.default)(l.instrumentationInfo)),q.push.apply(q,(0,e.default)(f.instrumentationInfo)),q.push.apply(q,(0,e.default)(s.instrumentationInfo)),q.push.apply(q,(0,e.default)(P.instrumentationInfo)),new Set(["AppRegistry","AppRegistryImpl","renderApplication","ExceptionsManager"])),M="@dynatrace/react-native-plugin/instrumentation/libs",instrument=function(n,e,r){e=V(e);var t=W(e);if(t!==d.i){var i=!1,u=I(e,n);if(t===d.l)G(u),i=!0;else if(t===d.o)e.endsWith("AppRegistryImpl.js")?null!=r&&r.autoStart&&$(u)&&(i=!0):e.endsWith("AppRegistry.js")?null!=r&&r.autoStart&&z(u)&&(i=!0):e.endsWith("renderApplication.js")?(A(u),i=!0):e.endsWith("ExceptionsManager.js")&&(o=void 0!==r&&r.autoStart&&r.errorHandler.enabled,K(u,r.errorHandler.reportFatalErrorAsCrash,o),i=!0);else if(t===d.v)i=Q(u)||i;else{var o=J(e,r),t=[{isEnabled:function(n,e){return!0===(null==e?void 0:e.userInteraction)},p:function(n,e,r){return(0,g.runDTUserInteraction)(n,e,r)}}].filter(function(n){return n.isEnabled(e,r)});if(r.navigation.enabled&&O(e,u))i=!0;else{if(!o.input&&!o.lifecycle&&0===t.length)return null!=r&&r.debug&&console.log("Dynatrace - Filtered All: ".concat(e)),x(e),n;o.lifecycle&&A(u)&&(i=!0),o.input&&q.forEach(function(n){n=nn(u,n);u=n.root,i=i||n.m})}var a,c=v(t);try{for(c.s();!(a=c.n()).done;){var l=a.value;try{var f=l.p(u,e,r),u=f.root;f.m&&(i=!0)}catch(n){var s=n instanceof Error?n.stack||n.message:String(n);null!=r&&r.debug&&console.log("[DynatraceInstrumentationRaw]: Feature instrumentation failed for ".concat(e,": ").concat(s))}}}catch(n){c.e(n)}finally{c.f()}}var o=i?u.toSource({quote:"single"}):n;i?N(n=o,e):x(e),null!=r&&r.debug&&i&&console.log("Dynatrace - Modified Filename: "+e)}else e.includes(p.join("@dynatrace","react-native-plugin"))&&e.endsWith(p.join("lib","core","configuration","ConfigurationPreset.js"))&&void 0!==r&&(t=(0,y.getHostAppBundleInfo)(m.default.getPackageJsonFile()),o=I(e,n),void 0!==r.lifecycle&&j(o,"getLifecycleUpdate",r.lifecycle.includeUpdate),void 0!==r.debug&&j(o,"getLogLevel",r.debug?0:1),void 0!==r.bundleName?j(o,"getBundleName",r.bundleName):null!==t&&j(o,"getBundleName",null==t?void 0:t.name),void 0!==r.bundleVersion?j(o,"getBundleVersion",r.bundleVersion):null!==t&&j(o,"getBundleVersion",null==t?void 0:t.version),void 0!==r.input&&void 0!==r.input.actionNamePrivacy&&j(o,"getActionNamePrivacy",r.input.actionNamePrivacy),void 0!==r.errorHandler&&(j(o,"isErrorHandlerEnabled",r.errorHandler.enabled),j(o,"isReportFatalErrorAsCrash",r.errorHandler.reportFatalErrorAsCrash)),r.autoStart&&j(o,"isAutoStartupEnabled",r.autoStart),n=o.toSource({quote:"single"}),N(n,e));return n},O=(exports.instrument=instrument,function(n,e){return!!U(n,e)&&(n="import { monitorNavigation } from '".concat(M,"/react-navigation/ReactNavigation';"),e.find(u.ImportDeclaration).at(0).insertBefore(n),!0)}),U=function(n,e){var r=!1;return n.includes("@react-navigation")&&n.includes("core")&&(n.includes("BaseNavigationContainer.js")||n.includes("BaseNavigationContainer.tsx"))&&e.find(u.VariableDeclarator,{id:{name:"getRootState"}}).forEach(function(n){r=!0,n.parent.insertAfter("monitorNavigation(getRootState);")}),r},A=function(n){var e=n.findJSXElements(),t=!1;return 0<e.length&&(n.find(u.FunctionDeclaration).forEach(function(n){var e,r=(0,i.fromPaths)([n]);0<r.findJSXElements().length&&null!=n&&null!=n.value&&null!=n.value.id&&n.value.id.name.toString()&&(e=r.find(u.ClassDeclaration),r=r.find(u.ClassExpression),0===e.length)&&0===r.length&&(h(n,b.Types.FunctionalComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ClassDeclaration).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n&&null!=n.value&&n.value.id&&n.value.id.name.toString()&&(h(n,b.Types.ClassComponent,n.value.id.name.toString()),t=!0)}),n.find(u.ArrowFunctionExpression).forEach(function(n){0<(0,i.fromPaths)([n]).findJSXElements().length&&null!=n.parent&&null!=n.parent.value&&null!=n.parent.value.id&&null!=n.parent.value.id.name&&(h(n,b.Types.FunctionalComponent,n.parent.value.id.name),t=!0)}),n.find(u.FunctionExpression).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,b.Types.FunctionalComponent,n.parent.value.id.name),t=!0)})),t},h=function(n,e,r){for(e=u.expressionStatement(u.assignmentExpression("=",u.memberExpression(u.identifier(r),u.identifier("_dtInfo")),k(e,r)));"body"!==(null==n?void 0:n.parentPath.name);)n=n.parentPath;void 0!==n.parentPath&&n.insertAfter(e)},k=function(n,e){return u.objectExpression([u.objectProperty(u.identifier("type"),u.numericLiteral(n)),u.objectProperty(u.identifier("name"),u.stringLiteral(e))])},j=function(n,e,r){var n=n.find(u.Identifier).filter(function(n){return n.node.name===e});1===n.length&&"ReturnStatement"===(n=n.paths()[0].parent.value.body.body[0]).type&&("boolean"==typeof r&&(n.argument=u.booleanLiteral(r)),"string"==typeof r&&(n.argument=u.stringLiteral(r)),"number"==typeof r)&&(n.argument=u.numericLiteral(r))},I=function(n,e){return u.withParser((0,T.chooseParser)(n,e))(e)},V=function(n){return p.isAbsolute(n)?n.replace(m.default.getApplicationPath()+p.sep,""):n},x=function(n){try{var e=p.join(m.default.getBuildPath(),n+o.INSTRUMENTED_FILE_EXTENSION);r.default.checkIfFileExistsSync(e),r.default.deleteFileSync(e)}catch(n){}},N=function(n,e){e=p.join(m.default.getBuildPath(),e);try{r.default.checkIfFileExistsSync(p.dirname(e))}catch(n){r.default.createDirectorySync(p.dirname(e))}r.default.writeTextToFileSync(e+o.INSTRUMENTED_FILE_EXTENSION,n)},J=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},G=function(n){var e,n=n.find(u.Program);1===n.length&&(e=u.expressionStatement(u.callExpression(u.memberExpression(u.callExpression(u.identifier("require"),[u.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")]),u.identifier("instrumentCreateElement")),[u.memberExpression(u.identifier("module"),u.identifier("exports"))])),n.paths()[0].node.body.push(e))},$=function(n){var e=n.find(u.FunctionDeclaration,{id:{name:"runApplication"}});return 1===e.length&&(D(n,{g:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,w("_DynatraceApplicationHandler","startup",[])),!0)},z=function(n){var e=n.find(u.ObjectMethod,{key:{name:"runApplication"}});return 1===e.length&&(D(n,{g:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),R(e.get().value.body.body,0,w("_DynatraceApplicationHandler","startup",[])),!0)},K=function(n,r,t){var i=u;n.find(i.FunctionDeclaration,{id:{name:"handleException"}}).forEach(function(n){var e=i.callExpression(i.memberExpression(i.callExpression(i.identifier("require"),[i.literal("@dynatrace/react-native-plugin/lib/core/ErrorHandler")]),i.identifier("reportErrorToDynatrace")),[i.identifier("e"),i.identifier("isFatal"),i.literal(r),i.literal(t)]),e=i.expressionStatement(i.callExpression(i.identifier("setTimeout"),[i.arrowFunctionExpression([],i.blockStatement(n.node.body.body)),e]));n.node.body.body=[e]})},Q=function(n){var e=!1,n=n.find(u.CallExpression,{callee:{name:"require"}});return n.find(u.Literal,{value:"react/jsx-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-runtime",e=!0,n}),n.find(u.Literal,{value:"react/jsx-dev-runtime"}).replaceWith(function(n){n=n.node;return n.value="@dynatrace/react-native-plugin/jsx-dev-runtime",e=!0,n}),e},R=function(n,e){for(var r=arguments.length,t=new Array(2<r?r-2:0),i=2;i<r;i++)t[i-2]=arguments[i];return n.splice.apply(n,[e,0].concat(t))},W=function(n){if(n.includes("@dynatrace"))return d.i;var e=p.extname(n);if(".js"!==e&&".ts"!==e&&".tsx"!==e&&".jsx"!==e)return d.i;for(var r=p.parse(n),t=r.dir.split(p.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 L.has(r.name)?d.o:d.i;if("react"===t[i+1]&&"index"===r.name)return d.l;if("react-native-css-interop"===t[i+1]&&("jsx-runtime"===r.name||"jsx-dev-runtime"===r.name))return d.v}return d.u},X=function(n,e,r){var t=Y(n,e,r);return Z(n,e,r)||t},Y=function(n,e,r){var t=en(n,e);return 0<t.length&&(void 0!==(t=C(t,e.reference,!1))&&(r.g=t.localName),cn(n,r),!0)},Z=function(n,e,r){var t=E(n,e.module);if(1===t.length){t=C(t,e.reference,!0);if(void 0!==t)return ln(n,r.defaultImport,t.localName,"ImportNamespaceSpecifier"===t.type),!0}return!1},nn=function(n,e){var r=JSON.parse(JSON.stringify(e.new));return{root:n,m:X(n,e.old,r)||rn(n,e.old,e.new.defaultImport)}},en=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module&&null!=n.node.specifiers&&n.node.specifiers.some(function(n){return S(n)&&n.imported.name===e.reference||n.local&&n.local.name===e.reference})})},S=function(n){return void 0!==n.imported},rn=function(n,e,r){var t=!1;return n.find(u.CallExpression).filter(function(n){return tn(n.node.callee)&&un(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},tn=function(n){return"require"===n.name},un=function(n){return"StringLiteral"===n.type||"Literal"===n.type},E=function(n,e){return n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e})},C=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 S(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):!(!S(n)&&t&&(null!=n.local&&(i={localName:n.local.name.toString(),type:n.type}),1))}),0===n.node.specifiers.length)&&n.prune()}),i},on=function(n,e){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e.module}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(B(e))})},an=function(n,e,r){n.find(u.ImportDeclaration).filter(function(n){return n.node.source.value===e}).forEach(function(n){null!=n.node.specifiers&&n.node.specifiers.push(r)})},H=function(n,e,r){var t=n.find(u.ImportDeclaration);0<t.length?u(t.paths()[0]).insertAfter(_(e,r)):1===(t=n.find(u.Program)).length&&t.paths()[0].node.body.unshift(_(e,r))},cn=function(n,e){0<E(n,e.module).length?on(n,e):H(n,e.module,[B(e)])},ln=function(n,e,r,t){var i=E(n,e),t=(t?yn:mn)(r);0<i.length?an(n,e,t):H(n,e,[t])},D=function(n,e){n=n.find(u.VariableDeclaration);0<n.length&&u(n.paths()[0]).insertAfter(sn(e))},w=function(n,e,r){return u.expressionStatement(fn(n,e,r))},fn=function(n,e,r){return u.callExpression(pn(n,e),r)},sn=function(n){return u.variableDeclaration("var",[vn(n)])},vn=function(n){return u.variableDeclarator(void 0!==n.g?u.identifier(n.g):u.identifier(n.reference),(0<n.reference.length?dn:F)(n))},dn=function(n){return u.memberExpression(F(n),u.identifier(n.reference))},pn=function(n,e){return u.memberExpression(u.identifier(n),u.identifier(e))},F=function(n){return u.callExpression(u.identifier("require"),[u.literal(n.module)])},_=function(n,e){return u.importDeclaration(e,u.literal(n))},B=function(n){return void 0!==n.g?u.importSpecifier(u.identifier(n.reference),u.identifier(n.g)):u.importSpecifier(u.identifier(n.reference))},mn=function(n){return u.importDefaultSpecifier(u.identifier(n))},yn=function(n){return u.importNamespaceSpecifier(u.identifier(n))};
|
|
1
|
+
var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault"),_toConsumableArray2=_interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));function _createForOfIteratorHelper(e,t){var n,r,i,o,a="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(a)return i=!(r=!0),{s:function(){a=a.call(e)},n:function(){var e=a.next();return r=e.done,e},e:function(e){i=!0,n=e},f:function(){try{r||null==a.return||a.return()}finally{if(i)throw n}}};if(Array.isArray(e)||(a=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length)return a&&(e=a),o=0,{s:t=function(){},n:function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function(e){throw e},f:t};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){var n;if(e)return"string"==typeof e?_arrayLikeToArray(e,t):"Map"===(n="Object"===(n={}.toString.call(e).slice(8,-1))&&e.constructor?e.constructor.name:n)||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}Object.defineProperty(exports,"__esModule",{value:!0}),exports.instrument=void 0;var FileType,nodePath=require("path"),jscodeshift=require("jscodeshift"),Collection_1=require("jscodeshift/src/Collection"),FileOperationHelper_1=require("../scripts/FileOperationHelper"),PathsConstants_1=require("../scripts/PathsConstants"),GetValuesFromPackage_1=require("../lib/core/util/GetValuesFromPackage"),InstrumentUtil_1=require("../scripts/util/InstrumentUtil"),Run_1=require("../lib/features/ui-interaction/Run"),Touchables_InstrInfo_1=require("./libs/react-native/Touchables.InstrInfo"),RefreshControl_InstrInfo_1=require("./libs/react-native/RefreshControl.InstrInfo"),Switch_InstrInfo_1=require("./libs/react-native/Switch.InstrInfo"),Touchables_InstrInfo_2=require("./libs/community/gesture-handler/Touchables.InstrInfo"),Picker_InstrInfo_1=require("./libs/community/Picker.InstrInfo"),Types_1=require("./model/Types"),ParserUtil_1=require("./parser/ParserUtil"),referenceListInput=((e=>{e[e.Filtered=-1]="Filtered",e[e.Normal=0]="Normal",e[e.ReactNative=1]="ReactNative",e[e.React=2]="React",e[e.ReactNativeCssInterop=3]="ReactNativeCssInterop"})(FileType=FileType||{}),[]),whiteList=(referenceListInput.push.apply(referenceListInput,(0,_toConsumableArray2.default)(Touchables_InstrInfo_1.instrumentationInfo)),referenceListInput.push.apply(referenceListInput,(0,_toConsumableArray2.default)(RefreshControl_InstrInfo_1.instrumentationInfo)),referenceListInput.push.apply(referenceListInput,(0,_toConsumableArray2.default)(Switch_InstrInfo_1.instrumentationInfo)),referenceListInput.push.apply(referenceListInput,(0,_toConsumableArray2.default)(Touchables_InstrInfo_2.instrumentationInfo)),referenceListInput.push.apply(referenceListInput,(0,_toConsumableArray2.default)(Picker_InstrInfo_1.instrumentationInfo)),new Set(["AppRegistry","AppRegistryImpl","renderApplication","ExceptionsManager"])),instrumentationLibraryFolder="@dynatrace/react-native-plugin/instrumentation/libs",instrument=function(e,t,n){t=correctFilename(t);var r=shouldInstrumentFile(t);if(r!==FileType.Filtered){var i=!1,o=parseSource(t,e);if(r===FileType.React)addCreateElementInstrumentation(o),i=!0;else if(r===FileType.ReactNative)t.endsWith("AppRegistryImpl.js")?null!=n&&n.autoStart&&addStartupCallRegistryImpl(o)&&(i=!0):t.endsWith("AppRegistry.js")?null!=n&&n.autoStart&&addStartupCallRegistry(o)&&(i=!0):t.endsWith("renderApplication.js")?(addInfoToComponent(o),i=!0):t.endsWith("ExceptionsManager.js")&&(a=void 0!==n&&n.autoStart&&n.errorHandler.enabled,addReportErrorToDynatraceCall(o,n.errorHandler.reportFatalErrorAsCrash,a),i=!0);else if(r===FileType.ReactNativeCssInterop)i=replaceReactWithDynatraceJsxRuntime(o)||i;else{var a=getInstrumentationList(t,n),r=[{isEnabled:function(e,t){return!0===(null==t?void 0:t.userInteraction)},run:function(e,t,n){return(0,Run_1.runDTUserInteraction)(e,t,n)}}].filter(function(e){return e.isEnabled(t,n)});if(n.navigation.enabled&&instrumentReactNavigation(t,o))i=!0;else{if(!a.input&&!a.lifecycle&&0===r.length)return null!=n&&n.debug&&console.log("Dynatrace - Filtered All: ".concat(t)),deleteTransformation(t),e;a.lifecycle&&addInfoToComponent(o)&&(i=!0),a.input&&referenceListInput.forEach(function(e){e=swapReferences(o,e);o=e.root,i=i||e.modified})}var s,l=_createForOfIteratorHelper(r);try{for(l.s();!(s=l.n()).done;){var c=s.value;try{var u=c.run(o,t,n),o=u.root;u.modified&&(i=!0)}catch(e){var f=e instanceof Error?e.stack||e.message:String(e);null!=n&&n.debug&&console.log("[DynatraceInstrumentationRaw]: Feature instrumentation failed for ".concat(t,": ").concat(f))}}}catch(e){l.e(e)}finally{l.f()}}var a=i?o.toSource({quote:"single"}):e;i?writeTransformation(e=a,t):deleteTransformation(t),null!=n&&n.debug&&i&&console.log("Dynatrace - Modified Filename: "+t)}else t.includes(nodePath.join("@dynatrace","react-native-plugin"))&&t.endsWith(nodePath.join("lib","core","configuration","ConfigurationPreset.js"))&&void 0!==n&&(r=(0,GetValuesFromPackage_1.getHostAppBundleInfo)(PathsConstants_1.default.getPackageJsonFile()),a=parseSource(t,e),void 0!==n.lifecycle&&changeConfigurationValue(a,"getLifecycleUpdate",n.lifecycle.includeUpdate),void 0!==n.debug&&changeConfigurationValue(a,"getLogLevel",n.debug?0:1),void 0!==n.bundleName?changeConfigurationValue(a,"getBundleName",n.bundleName):null!==r&&changeConfigurationValue(a,"getBundleName",null==r?void 0:r.name),void 0!==n.bundleVersion?changeConfigurationValue(a,"getBundleVersion",n.bundleVersion):null!==r&&changeConfigurationValue(a,"getBundleVersion",null==r?void 0:r.version),void 0!==n.input&&void 0!==n.input.actionNamePrivacy&&changeConfigurationValue(a,"getActionNamePrivacy",n.input.actionNamePrivacy),void 0!==n.errorHandler&&(changeConfigurationValue(a,"isErrorHandlerEnabled",n.errorHandler.enabled),changeConfigurationValue(a,"isReportFatalErrorAsCrash",n.errorHandler.reportFatalErrorAsCrash)),n.autoStart&&changeConfigurationValue(a,"isAutoStartupEnabled",n.autoStart),e=a.toSource({quote:"single"}),writeTransformation(e,t));return e},instrumentReactNavigation=(exports.instrument=instrument,function(e,t){return!!instrumentReactBaseNavigationContainer(e,t)&&(e="import { monitorNavigation } from '".concat(instrumentationLibraryFolder,"/react-navigation/ReactNavigation';"),t.find(jscodeshift.ImportDeclaration).at(0).insertBefore(e),!0)}),instrumentReactBaseNavigationContainer=function(e,t){var n=!1;return e.includes("@react-navigation")&&e.includes("core")&&(e.includes("BaseNavigationContainer.js")||e.includes("BaseNavigationContainer.tsx"))&&t.find(jscodeshift.VariableDeclarator,{id:{name:"getRootState"}}).forEach(function(e){n=!0,e.parent.insertAfter("monitorNavigation(getRootState);")}),n},addInfoToComponent=function(e){var t=e.findJSXElements(),r=!1;return 0<t.length&&(e.find(jscodeshift.FunctionDeclaration).forEach(function(e){var t,n=(0,Collection_1.fromPaths)([e]);0<n.findJSXElements().length&&null!=e&&null!=e.value&&null!=e.value.id&&e.value.id.name.toString()&&(t=n.find(jscodeshift.ClassDeclaration),n=n.find(jscodeshift.ClassExpression),0===t.length)&&0===n.length&&(insertExpressionIntoNextBody(e,Types_1.Types.FunctionalComponent,e.value.id.name.toString()),r=!0)}),e.find(jscodeshift.ClassDeclaration).forEach(function(e){0<(0,Collection_1.fromPaths)([e]).findJSXElements().length&&null!=e&&null!=e.value&&e.value.id&&e.value.id.name.toString()&&(insertExpressionIntoNextBody(e,Types_1.Types.ClassComponent,e.value.id.name.toString()),r=!0)}),e.find(jscodeshift.ArrowFunctionExpression).forEach(function(e){0<(0,Collection_1.fromPaths)([e]).findJSXElements().length&&null!=e.parent&&null!=e.parent.value&&null!=e.parent.value.id&&null!=e.parent.value.id.name&&(insertExpressionIntoNextBody(e,Types_1.Types.FunctionalComponent,e.parent.value.id.name),r=!0)}),e.find(jscodeshift.FunctionExpression).forEach(function(e){0<(0,Collection_1.fromPaths)([e]).findJSXElements().length&&null!=e.parent&&null!=e.parent.value&&null!=e.parent.value.id&&null!=e.parent.value.id.name&&(insertExpressionIntoNextBody(e,Types_1.Types.FunctionalComponent,e.parent.value.id.name),r=!0)})),r},insertExpressionIntoNextBody=function(e,t,n){for(t=jscodeshift.expressionStatement(jscodeshift.assignmentExpression("=",jscodeshift.memberExpression(jscodeshift.identifier(n),jscodeshift.identifier("_dtInfo")),createComponentInfo(t,n)));"body"!==(null==e?void 0:e.parentPath.name);)e=e.parentPath;void 0!==e.parentPath&&e.insertAfter(t)},createComponentInfo=function(e,t){return jscodeshift.objectExpression([jscodeshift.objectProperty(jscodeshift.identifier("type"),jscodeshift.numericLiteral(e)),jscodeshift.objectProperty(jscodeshift.identifier("name"),jscodeshift.stringLiteral(t))])},changeConfigurationValue=function(e,t,n){var e=e.find(jscodeshift.Identifier).filter(function(e){return e.node.name===t});1===e.length&&"ReturnStatement"===(e=e.paths()[0].parent.value.body.body[0]).type&&("boolean"==typeof n&&(e.argument=jscodeshift.booleanLiteral(n)),"string"==typeof n&&(e.argument=jscodeshift.stringLiteral(n)),"number"==typeof n)&&(e.argument=jscodeshift.numericLiteral(n))},parseSource=function(e,t){return jscodeshift.withParser((0,ParserUtil_1.chooseParser)(e,t))(t)},correctFilename=function(e){return nodePath.isAbsolute(e)?e.replace(PathsConstants_1.default.getApplicationPath()+nodePath.sep,""):e},deleteTransformation=function(e){try{var t=nodePath.join(PathsConstants_1.default.getBuildPath(),e+InstrumentUtil_1.INSTRUMENTED_FILE_EXTENSION);FileOperationHelper_1.default.checkIfFileExistsSync(t),FileOperationHelper_1.default.deleteFileSync(t)}catch(e){}},writeTransformation=function(e,t){t=nodePath.join(PathsConstants_1.default.getBuildPath(),t);try{FileOperationHelper_1.default.checkIfFileExistsSync(nodePath.dirname(t))}catch(e){FileOperationHelper_1.default.createDirectorySync(nodePath.dirname(t))}FileOperationHelper_1.default.writeTextToFileSync(t+InstrumentUtil_1.INSTRUMENTED_FILE_EXTENSION,e)},getInstrumentationList=function(e,t){var n={input:!1,lifecycle:!1};return void 0!==t&&(void 0!==t.lifecycle&&void 0!==t.lifecycle.instrument&&t.lifecycle.instrument(e)&&(n.lifecycle=!0),void 0!==t.input)&&void 0!==t.input.instrument&&t.input.instrument(e)&&(n.input=!0),n},addCreateElementInstrumentation=function(e){var t,e=e.find(jscodeshift.Program);1===e.length&&(t=jscodeshift.expressionStatement(jscodeshift.callExpression(jscodeshift.memberExpression(jscodeshift.callExpression(jscodeshift.identifier("require"),[jscodeshift.stringLiteral("@dynatrace/react-native-plugin/instrumentation/jsx/ElementHelper")]),jscodeshift.identifier("instrumentCreateElement")),[jscodeshift.memberExpression(jscodeshift.identifier("module"),jscodeshift.identifier("exports"))])),e.paths()[0].node.body.push(t))},addStartupCallRegistryImpl=function(e){var t=e.find(jscodeshift.FunctionDeclaration,{id:{name:"runApplication"}});return 1===t.length&&(addRequire(e,{customName:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),insertInArray(t.get().value.body.body,0,expressionStatement("_DynatraceApplicationHandler","startup",[])),!0)},addStartupCallRegistry=function(e){var t=e.find(jscodeshift.ObjectMethod,{key:{name:"runApplication"}});return 1===t.length&&(addRequire(e,{customName:"_DynatraceApplicationHandler",module:"@dynatrace/react-native-plugin",reference:"ApplicationHandler"}),insertInArray(t.get().value.body.body,0,expressionStatement("_DynatraceApplicationHandler","startup",[])),!0)},addReportErrorToDynatraceCall=function(e,n,r){var i=jscodeshift;e.find(i.FunctionDeclaration,{id:{name:"handleException"}}).forEach(function(e){var t=i.callExpression(i.memberExpression(i.callExpression(i.identifier("require"),[i.literal("@dynatrace/react-native-plugin/lib/core/ErrorHandler")]),i.identifier("reportErrorToDynatrace")),[i.identifier("e"),i.identifier("isFatal"),i.literal(n),i.literal(r)]),t=i.expressionStatement(i.callExpression(i.identifier("setTimeout"),[i.arrowFunctionExpression([],i.blockStatement(e.node.body.body)),t]));e.node.body.body=[t]})},replaceReactWithDynatraceJsxRuntime=function(e){var t=!1,e=e.find(jscodeshift.CallExpression,{callee:{name:"require"}});return e.find(jscodeshift.Literal,{value:"react/jsx-runtime"}).replaceWith(function(e){e=e.node;return e.value="@dynatrace/react-native-plugin/jsx-runtime",t=!0,e}),e.find(jscodeshift.Literal,{value:"react/jsx-dev-runtime"}).replaceWith(function(e){e=e.node;return e.value="@dynatrace/react-native-plugin/jsx-dev-runtime",t=!0,e}),t},insertInArray=function(e,t){for(var n=arguments.length,r=new Array(2<n?n-2:0),i=2;i<n;i++)r[i-2]=arguments[i];return e.splice.apply(e,[t,0].concat(r))},shouldInstrumentFile=function(e){if(e.includes("@dynatrace"))return FileType.Filtered;var t=nodePath.extname(e);if(".js"!==t&&".ts"!==t&&".tsx"!==t&&".jsx"!==t)return FileType.Filtered;for(var n=nodePath.parse(e),r=n.dir.split(nodePath.sep),i=0;i<r.length;i++)if("node_modules"===r[i]){if("react-native"===r[i+1]||"create-react-class"===r[i+1]||"react-clone-referenced-element"===r[i+1])return whiteList.has(n.name)?FileType.ReactNative:FileType.Filtered;if("react"===r[i+1]&&"index"===n.name)return FileType.React;if("react-native-css-interop"===r[i+1]&&("jsx-runtime"===n.name||"jsx-dev-runtime"===n.name))return FileType.ReactNativeCssInterop}return FileType.Normal},handleImports=function(e,t,n){var r=handleDestructuredImport(e,t,n);return handleDefaultImport(e,t,n)||r},handleDestructuredImport=function(e,t,n){var r=findImportSpecifier(e,t);return 0<r.length&&(void 0!==(r=removeImportSpecifier(r,t.reference,!1))&&(n.customName=r.localName),addReference(e,n),!0)},handleDefaultImport=function(e,t,n){var r=findImportDeclaration(e,t.module);if(1===r.length){r=removeImportSpecifier(r,t.reference,!0);if(void 0!==r)return addDefaultImport(e,n.defaultImport,r.localName,"ImportNamespaceSpecifier"===r.type),!0}return!1},swapReferences=function(e,t){var n=JSON.parse(JSON.stringify(t.new));return{root:e,modified:handleImports(e,t.old,n)||modifyRequireModule(e,t.old,t.new.defaultImport)}},findImportSpecifier=function(e,t){return e.find(jscodeshift.ImportDeclaration).filter(function(e){return e.node.source.value===t.module&&null!=e.node.specifiers&&e.node.specifiers.some(function(e){return isImportSpecifier(e)&&e.imported.name===t.reference||e.local&&e.local.name===t.reference})})},isImportSpecifier=function(e){return void 0!==e.imported},modifyRequireModule=function(e,t,n){var r=!1;return e.find(jscodeshift.CallExpression).filter(function(e){return isRequire(e.node.callee)&&isArgumentALiteral(e.node.arguments[0])&&e.node.arguments[0].value===t.module&&void 0!==e.parent}).forEach(function(e){(void 0===e.parent.value.property||void 0!==e.parent.value.property&&void 0!==e.parent.value.property.name&&e.parent.value.property.name===t.reference)&&(e.node.arguments[0].value=n,r=r||!0)}),r},isRequire=function(e){return"require"===e.name},isArgumentALiteral=function(e){return"StringLiteral"===e.type||"Literal"===e.type},findImportDeclaration=function(e,t){return e.find(jscodeshift.ImportDeclaration).filter(function(e){return e.node.source.value===t})},removeImportSpecifier=function(e,n,r){var i;return e.forEach(function(e){void 0!==e.node.specifiers&&(e.node.specifiers=e.node.specifiers.filter(function(e){var t;return isImportSpecifier(e)&&!r?((t=e.imported.name!==n)||null==e.local||e.imported.name===e.local.name||(i={localName:e.local.name.toString(),type:e.type}),t):!(!isImportSpecifier(e)&&r&&(null!=e.local&&(i={localName:e.local.name.toString(),type:e.type}),1))}),0===e.node.specifiers.length)&&e.prune()}),i},insertImportSpecifier=function(e,t){e.find(jscodeshift.ImportDeclaration).filter(function(e){return e.node.source.value===t.module}).forEach(function(e){null!=e.node.specifiers&&e.node.specifiers.push(importSpecifier(t))})},insertImportDefaultSpecifier=function(e,t,n){e.find(jscodeshift.ImportDeclaration).filter(function(e){return e.node.source.value===t}).forEach(function(e){null!=e.node.specifiers&&e.node.specifiers.push(n)})},insertImportDeclaration=function(e,t,n){var r=e.find(jscodeshift.ImportDeclaration);0<r.length?jscodeshift(r.paths()[0]).insertAfter(importDeclaration(t,n)):1===(r=e.find(jscodeshift.Program)).length&&r.paths()[0].node.body.unshift(importDeclaration(t,n))},addReference=function(e,t){0<findImportDeclaration(e,t.module).length?insertImportSpecifier(e,t):insertImportDeclaration(e,t.module,[importSpecifier(t)])},addDefaultImport=function(e,t,n,r){var i=findImportDeclaration(e,t),r=(r?importNamespaceSpecifier:importDefaultSpecifier)(n);0<i.length?insertImportDefaultSpecifier(e,t,r):insertImportDeclaration(e,t,[r])},addRequire=function(e,t){e=e.find(jscodeshift.VariableDeclaration);0<e.length&&jscodeshift(e.paths()[0]).insertAfter(requireDeclaration(t))},expressionStatement=function(e,t,n){return jscodeshift.expressionStatement(callExpression(e,t,n))},callExpression=function(e,t,n){return jscodeshift.callExpression(memberExpression(e,t),n)},requireDeclaration=function(e){return jscodeshift.variableDeclaration("var",[requireDeclarator(e)])},requireDeclarator=function(e){return jscodeshift.variableDeclarator(void 0!==e.customName?jscodeshift.identifier(e.customName):jscodeshift.identifier(e.reference),(0<e.reference.length?memberExpressionRequire:requireExpression)(e))},memberExpressionRequire=function(e){return jscodeshift.memberExpression(requireExpression(e),jscodeshift.identifier(e.reference))},memberExpression=function(e,t){return jscodeshift.memberExpression(jscodeshift.identifier(e),jscodeshift.identifier(t))},requireExpression=function(e){return jscodeshift.callExpression(jscodeshift.identifier("require"),[jscodeshift.literal(e.module)])},importDeclaration=function(e,t){return jscodeshift.importDeclaration(t,jscodeshift.literal(e))},importSpecifier=function(e){return void 0!==e.customName?jscodeshift.importSpecifier(jscodeshift.identifier(e.reference),jscodeshift.identifier(e.customName)):jscodeshift.importSpecifier(jscodeshift.identifier(e.reference))},importDefaultSpecifier=function(e){return jscodeshift.importDefaultSpecifier(jscodeshift.identifier(e))},importNamespaceSpecifier=function(e){return jscodeshift.importNamespaceSpecifier(jscodeshift.identifier(e))};
|
|
@@ -16,10 +16,10 @@ const instrumentJsxCall = (jsxFunction) => (...args) => {
|
|
|
16
16
|
? args[1].dtActionName
|
|
17
17
|
: args[0]._dtInfo.name;
|
|
18
18
|
if (args[2] !== undefined) {
|
|
19
|
-
return
|
|
19
|
+
return ReactRuntime.jsx(FunctionalComponent_1.DynatraceFunctionalComponent, wrapperProps, args[2] + '_dt');
|
|
20
20
|
}
|
|
21
21
|
else {
|
|
22
|
-
return
|
|
22
|
+
return ReactRuntime.jsx(FunctionalComponent_1.DynatraceFunctionalComponent, wrapperProps);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
else if (args[0]._dtInfo.type === Types_1.Types.ClassComponent &&
|
|
@@ -27,10 +27,10 @@ const instrumentJsxCall = (jsxFunction) => (...args) => {
|
|
|
27
27
|
args[0].prototype.isReactComponent !== undefined) {
|
|
28
28
|
const wrapperProps = Object.assign(Object.assign({}, args[1]), { children: jsxFunction(...args) });
|
|
29
29
|
if (args[2] !== undefined) {
|
|
30
|
-
return
|
|
30
|
+
return ReactRuntime.jsx(ClassComponent_1.DynatraceClassComponent, wrapperProps, args[2] + '_dt');
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
|
-
return
|
|
33
|
+
return ReactRuntime.jsx(ClassComponent_1.DynatraceClassComponent, wrapperProps);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
(0, ElementHelper_1.modifyElement)(args[0], args[1]);
|