@dynatrace/react-native-plugin 2.341.1 β 2.345.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 +674 -668
- package/android/build.gradle +16 -3
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceAppStartModule.kt +9 -31
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceConfigurationModule.kt +1 -0
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +41 -0
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.kt +1 -0
- package/android/src/main/java/com/dynatrace/android/agent/ScreenshotSelfMonitor.kt +175 -0
- package/android/src/main/java/com/dynatrace/android/agent/UIChangeScreenshotListener.kt +124 -0
- package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +33 -0
- package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +40 -0
- package/files/plugin-runtime.gradle +17 -33
- package/files/plugin.gradle +1 -1
- package/instrumentation/BabelPluginDynatrace.js +1 -1
- package/instrumentation/libs/UserInteraction.js +21 -7
- package/instrumentation/libs/react-navigation/ReactNavigation.js +14 -58
- package/instrumentation/libs/withOnPressMonitoring.js +3 -54
- package/internal.d.ts +1 -0
- package/internal.js +3 -1
- package/ios/DTXScreenshotSelfMonitor.h +29 -0
- package/ios/DTXScreenshotSelfMonitor.mm +213 -0
- package/ios/DTXScreenshotSelfMonitorSwizzler.h +15 -0
- package/ios/DTXScreenshotSelfMonitorSwizzler.mm +68 -0
- package/ios/DynatraceRNBridge.h +6 -0
- package/ios/DynatraceRNBridge.mm +62 -0
- package/lib/core/Dynatrace.js +2 -0
- package/lib/core/configuration/ConfigurationHandler.js +0 -21
- package/lib/core/logging/LogMessages.js +42 -0
- package/lib/dynatrace-reporter.js +1 -30
- package/lib/dynatrace-transformer.js +6 -34
- package/lib/next/Dynatrace.js +26 -1
- package/lib/next/configuration/INativeRuntimeConfiguration.js +0 -1
- package/lib/next/configuration/RuntimeConfigurationObserver.js +1 -6
- package/lib/next/events/EventPipeline.js +48 -31
- package/lib/next/events/HttpRequestEventData.js +1 -1
- package/lib/next/events/spec/EventSpecContstants.js +1 -1
- package/lib/next/navigation/NavigationTracker.js +93 -0
- package/lib/next/navigation/useNavigationTracking.js +54 -0
- package/lib/next/userAction/NullUserAction.js +15 -0
- package/lib/next/userAction/UserActionConfiguration.js +10 -0
- package/lib/next/userAction/UserActionImpl.js +70 -0
- package/lib/next/util/TraceContextUtils.js +8 -14
- package/lib/next/util/Utils.js +13 -0
- package/package.json +10 -18
- package/public.js +5 -1
- package/react-native-dynatrace.podspec +10 -3
- package/scripts/Android.js +1 -20
- package/scripts/Config.js +17 -7
- package/scripts/Deprecations.js +18 -0
- package/scripts/Install.js +13 -0
- package/scripts/PathsConstants.js +0 -4
- package/scripts/Uninstall.js +0 -15
- package/scripts/core/InstrumentCall.js +14 -7
- package/scripts/util/DeprecationReport.js +24 -0
- package/src/lib/core/interface/NativeDynatraceBridge.ts +34 -1
- package/types.d.ts +236 -7
- package/instrumentation/DynatraceInstrumentation.js +0 -1
- package/instrumentation/libs/community/Picker.InstrInfo.js +0 -20
- package/instrumentation/libs/community/gesture-handler/Touchables.InstrInfo.js +0 -25
- package/instrumentation/libs/react-native/RefreshControl.InstrInfo.js +0 -12
- package/instrumentation/libs/react-native/Switch.InstrInfo.js +0 -12
- package/instrumentation/libs/react-native/Touchables.InstrInfo.js +0 -25
- package/instrumentation/parser/Babel.js +0 -60
- package/instrumentation/parser/ParserUtil.js +0 -11
- package/lib/features/ui-interaction/Config.js +0 -42
- package/lib/features/ui-interaction/IUserInteractionEvent.js +0 -16
- package/lib/features/ui-interaction/Plugin.Fragment.Test.js +0 -170
- package/lib/features/ui-interaction/Plugin.js +0 -289
- package/lib/features/ui-interaction/RootDetection.js +0 -51
- package/lib/features/ui-interaction/RootWrapper.js +0 -236
- package/lib/features/ui-interaction/Run.js +0 -38
- package/lib/features/ui-interaction/Runtime.js +0 -843
- package/lib/features/ui-interaction/TouchMetaResolver.js +0 -493
- package/lib/features/ui-interaction/Types.js +0 -14
- package/lib/metro/getSourceMapInfo.js +0 -26
- package/scripts/LineOffsetAnalyze.js +0 -25
- package/scripts/core/LineOffsetAnalyzeCall.js +0 -165
- package/scripts/util/SourceMapUtil.js +0 -68
- /package/{instrumentation/model/Reference.js β lib/next/userAction/UserAction.js} +0 -0
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.LineOffsetAnalyzer = void 0;
|
|
13
|
-
const fs = require("fs/promises");
|
|
14
|
-
const path_1 = require("path");
|
|
15
|
-
const diff_1 = require("diff");
|
|
16
|
-
const Logger_1 = require("../Logger");
|
|
17
|
-
const InstrumentUtil_1 = require("../util/InstrumentUtil");
|
|
18
|
-
const FileOperationHelper_1 = require("../../scripts/FileOperationHelper");
|
|
19
|
-
const Config_1 = require("../../scripts/Config");
|
|
20
|
-
class LineOffsetAnalyzer {
|
|
21
|
-
constructor(options) {
|
|
22
|
-
this.rootDir = (0, path_1.resolve)(options.projectRoot);
|
|
23
|
-
this.instrumentedDir = (0, path_1.resolve)(options.buildPath);
|
|
24
|
-
this.outputFile = (0, path_1.resolve)(this.instrumentedDir, 'line-offsets.json');
|
|
25
|
-
this.logFile = (0, path_1.resolve)(this.instrumentedDir, 'debug.log');
|
|
26
|
-
this.appBundleInfo = options.appBundleInfo;
|
|
27
|
-
this.sourcemapPath = options.sourcemapPath;
|
|
28
|
-
this.reactOptions = (0, Config_1.readConfigDefault)();
|
|
29
|
-
}
|
|
30
|
-
run() {
|
|
31
|
-
var _a;
|
|
32
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
-
if (!this.reactOptions.react.useLegacyJscodeshift) {
|
|
34
|
-
console.info('βΉοΈ Skipping line offset analysis since this it not needed anymore for the new babel architecture.');
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
try {
|
|
38
|
-
const buildExists = yield FileOperationHelper_1.default.checkIfFileExists(this.instrumentedDir);
|
|
39
|
-
if (!buildExists) {
|
|
40
|
-
yield this.log(`β Build directory not found at: ${this.instrumentedDir}`, true);
|
|
41
|
-
yield this.log('π οΈ Please run the instrumentation step first!', true);
|
|
42
|
-
console.error('π« Build directory missing. Make and instrument the project first.', true);
|
|
43
|
-
process.exit(1);
|
|
44
|
-
}
|
|
45
|
-
yield fs.writeFile(this.logFile, '');
|
|
46
|
-
const instrumentedFiles = (yield FileOperationHelper_1.default.getAllFiles(this.log, this.instrumentedDir))
|
|
47
|
-
.filter((filePath) => filePath.endsWith(InstrumentUtil_1.INSTRUMENTED_FILE_EXTENSION));
|
|
48
|
-
const mappings = {};
|
|
49
|
-
yield this.log(`π Found ${instrumentedFiles.length} instrumented files`, true);
|
|
50
|
-
for (const instrRelPath of instrumentedFiles) {
|
|
51
|
-
const baseRelPath = instrRelPath.slice(0, -InstrumentUtil_1.INSTRUMENTED_FILE_EXTENSION.length);
|
|
52
|
-
const origPath = (0, path_1.join)(this.rootDir, baseRelPath);
|
|
53
|
-
const instrPath = (0, path_1.join)(this.instrumentedDir, instrRelPath);
|
|
54
|
-
const origExists = yield FileOperationHelper_1.default.checkIfFileExists(origPath);
|
|
55
|
-
if (!origExists) {
|
|
56
|
-
yield this.log(`β οΈ Original file not found for: ${baseRelPath}`, true);
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
yield this.log(`π Comparing: ${baseRelPath}`, true);
|
|
60
|
-
const [originalContent, instrumentedContent] = yield Promise.all([
|
|
61
|
-
FileOperationHelper_1.default.readTextFromFile(origPath),
|
|
62
|
-
FileOperationHelper_1.default.readTextFromFile(instrPath),
|
|
63
|
-
]);
|
|
64
|
-
const offsets = this.computeLineOffsets(originalContent, instrumentedContent);
|
|
65
|
-
if (offsets.length > 0) {
|
|
66
|
-
mappings[origPath] = offsets;
|
|
67
|
-
yield this.log(`β
Offsets found for ${origPath}: ${offsets.length} entries`, true);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
yield this.log(`βΉοΈ No offsets needed for ${origPath}`, true);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
const finalOutput = {
|
|
74
|
-
generationTime: new Date().toISOString(),
|
|
75
|
-
appVersion: this.appBundleInfo !== null ? this.appBundleInfo.version : 'application version not defined',
|
|
76
|
-
pluginVersion: this.appBundleInfo !== null ? this.appBundleInfo.pluginVersion : 'plugin version not defined',
|
|
77
|
-
mappings: {
|
|
78
|
-
[this.appBundleInfo !== null ? this.appBundleInfo.name : 'app name not defined']: mappings,
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
yield fs.writeFile(this.outputFile, JSON.stringify(finalOutput, null, 2));
|
|
82
|
-
yield this.log(`β
Line offsets written to ${this.outputFile}`, true);
|
|
83
|
-
if (!this.sourcemapPath && !this.reactOptions.react.sourcemap.enabled) {
|
|
84
|
-
const message = 'βΉοΈ Automatic sourcemap patching disabled. Skipping sourcemap patching.';
|
|
85
|
-
yield this.log(message);
|
|
86
|
-
console.info(message);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const loadedMap = yield this.loadSourceMap((_a = this.sourcemapPath) !== null && _a !== void 0 ? _a : this.reactOptions.react.sourcemap.androidSourcemapLocation);
|
|
90
|
-
if (loadedMap) {
|
|
91
|
-
const { map, path: originalMapPath } = loadedMap;
|
|
92
|
-
map.x_dynatrace_offset = mappings;
|
|
93
|
-
const backupPath = originalMapPath + '.bak';
|
|
94
|
-
const serilalisedPath = originalMapPath + '.serialised';
|
|
95
|
-
yield fs.copyFile(originalMapPath, backupPath);
|
|
96
|
-
yield this.log(`πΎ Backup created: ${backupPath}`);
|
|
97
|
-
yield fs.writeFile(originalMapPath, JSON.stringify(map));
|
|
98
|
-
yield fs.writeFile(serilalisedPath, JSON.stringify(map, null, 2));
|
|
99
|
-
yield this.log(`π Patched source map written to: ${originalMapPath}`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
catch (err) {
|
|
103
|
-
console.error('β Unexpected error:', err);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
loadSourceMap(mapPath) {
|
|
108
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
-
try {
|
|
110
|
-
const content = yield fs.readFile(mapPath, 'utf-8');
|
|
111
|
-
const parsed = JSON.parse(content);
|
|
112
|
-
yield this.log(`πΊοΈ Found and parsed source map at: ${mapPath}`, true);
|
|
113
|
-
return { map: parsed, path: mapPath };
|
|
114
|
-
}
|
|
115
|
-
catch (err) {
|
|
116
|
-
yield this.log(`β οΈ Failed to load or parse source map at ${mapPath}: ${err.message} - skipping patching step`, true);
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
log(msg, logOnScreen = false) {
|
|
122
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
-
if (this.reactOptions && this.reactOptions.react.debug && logOnScreen) {
|
|
124
|
-
Logger_1.default.logMessageSync(msg, Logger_1.default.INFO);
|
|
125
|
-
}
|
|
126
|
-
yield fs.appendFile(this.logFile, msg + '\n');
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
computeLineOffsets(originalContent, instrumentedContent) {
|
|
130
|
-
const diffs = (0, diff_1.diffLines)(originalContent, instrumentedContent);
|
|
131
|
-
let origLine = 0;
|
|
132
|
-
let instrLine = 0;
|
|
133
|
-
let offset = 0;
|
|
134
|
-
let lastRecordedOffset = null;
|
|
135
|
-
const offsets = [];
|
|
136
|
-
this.log('π Diff result:', true);
|
|
137
|
-
for (const part of diffs) {
|
|
138
|
-
const lines = part.value.split('\n').slice(0, -1);
|
|
139
|
-
if (part.added) {
|
|
140
|
-
this.log(`β Added ${lines.length} lines at instrumented line ${instrLine + 1}`);
|
|
141
|
-
lines.forEach((line, i) => this.log(` + ${instrLine + 1 + i}: ${line}`));
|
|
142
|
-
instrLine += lines.length;
|
|
143
|
-
offset -= lines.length;
|
|
144
|
-
}
|
|
145
|
-
else if (part.removed) {
|
|
146
|
-
this.log(`β Removed ${lines.length} lines at original line ${origLine + 1}`);
|
|
147
|
-
lines.forEach((line, i) => this.log(` - ${origLine + 1 + i}: ${line}`));
|
|
148
|
-
origLine += lines.length;
|
|
149
|
-
offset += lines.length;
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
for (let i = 0; i < lines.length; i++) {
|
|
153
|
-
instrLine++;
|
|
154
|
-
origLine++;
|
|
155
|
-
if (offset !== 0 && offset !== lastRecordedOffset) {
|
|
156
|
-
offsets.push({ [instrLine]: offset });
|
|
157
|
-
lastRecordedOffset = offset;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return offsets;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
exports.LineOffsetAnalyzer = LineOffsetAnalyzer;
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.patchMetroSourceMap = exports.SOURCE_MAP_FILE = exports.SOURCE_MAP_BACKUP_FILE = void 0;
|
|
4
|
-
const node_path_1 = require("node:path");
|
|
5
|
-
const Logger_1 = require("../Logger");
|
|
6
|
-
const PathsConstants_1 = require("../PathsConstants");
|
|
7
|
-
const FileOperationHelper_1 = require("../FileOperationHelper");
|
|
8
|
-
exports.SOURCE_MAP_BACKUP_FILE = 'getSourceMapInfoOrig.js';
|
|
9
|
-
exports.SOURCE_MAP_FILE = 'getSourceMapInfo.js';
|
|
10
|
-
const getMetroResolveLookupPaths = () => {
|
|
11
|
-
const lookupPaths = [];
|
|
12
|
-
let currentPath = process.cwd();
|
|
13
|
-
while (true) {
|
|
14
|
-
lookupPaths.push(currentPath);
|
|
15
|
-
const pnpmLookupPath = (0, node_path_1.join)(currentPath, 'node_modules', '.pnpm', 'node_modules');
|
|
16
|
-
if (!lookupPaths.includes(pnpmLookupPath)) {
|
|
17
|
-
lookupPaths.push(pnpmLookupPath);
|
|
18
|
-
}
|
|
19
|
-
const parentPath = (0, node_path_1.dirname)(currentPath);
|
|
20
|
-
if (parentPath === currentPath) {
|
|
21
|
-
break;
|
|
22
|
-
}
|
|
23
|
-
currentPath = parentPath;
|
|
24
|
-
}
|
|
25
|
-
return lookupPaths;
|
|
26
|
-
};
|
|
27
|
-
const resolveMetroSourceMapPaths = (resolveModule) => {
|
|
28
|
-
const paths = [PathsConstants_1.default.getMetroSouceMapPath()];
|
|
29
|
-
for (const lookupPath of getMetroResolveLookupPaths()) {
|
|
30
|
-
try {
|
|
31
|
-
const resolvedMetroSourceMapFile = resolveModule('metro/src/DeltaBundler/Serializers/helpers/getSourceMapInfo.js', { paths: [lookupPath] });
|
|
32
|
-
const resolvedMetroSourceMapDir = (0, node_path_1.dirname)(resolvedMetroSourceMapFile);
|
|
33
|
-
if (!paths.includes(resolvedMetroSourceMapDir)) {
|
|
34
|
-
paths.push(resolvedMetroSourceMapDir);
|
|
35
|
-
}
|
|
36
|
-
break;
|
|
37
|
-
}
|
|
38
|
-
catch (_a) {
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return paths;
|
|
42
|
-
};
|
|
43
|
-
const patchMetroSourceMap = (resolveModule = require.resolve) => {
|
|
44
|
-
Logger_1.default.logMessageSync('β³ Patching SourceMap generation of Metro .. ', Logger_1.default.INFO);
|
|
45
|
-
const metroSourceMapPaths = resolveMetroSourceMapPaths(resolveModule);
|
|
46
|
-
for (const metroSourceMapPath of metroSourceMapPaths) {
|
|
47
|
-
const origSourceMapPath = (0, node_path_1.join)(metroSourceMapPath, exports.SOURCE_MAP_BACKUP_FILE);
|
|
48
|
-
try {
|
|
49
|
-
FileOperationHelper_1.default.checkIfFileExistsSync(origSourceMapPath);
|
|
50
|
-
Logger_1.default.logMessageSync(' βΉοΈ Patching of SourceMap already happened!', Logger_1.default.INFO);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
catch (_a) {
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
const currentSourceMapPath = (0, node_path_1.join)(metroSourceMapPath, exports.SOURCE_MAP_FILE);
|
|
57
|
-
FileOperationHelper_1.default.checkIfFileExistsSync(currentSourceMapPath);
|
|
58
|
-
FileOperationHelper_1.default.renameFileSync(currentSourceMapPath, origSourceMapPath);
|
|
59
|
-
FileOperationHelper_1.default.copyFileSync(PathsConstants_1.default.getOurSourceMapFile(), currentSourceMapPath);
|
|
60
|
-
Logger_1.default.logMessageSync(' β
Patching of SourceMap successful!', Logger_1.default.INFO);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
catch (_b) {
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
Logger_1.default.logMessageSync(' β Patching of SourceMap generation failed!', Logger_1.default.ERROR);
|
|
67
|
-
};
|
|
68
|
-
exports.patchMetroSourceMap = patchMetroSourceMap;
|
|
File without changes
|