UNPKG

@dynatrace/react-native-plugin

Version:

This plugin gives you the ability to use the Dynatrace Mobile agent in your react native application.

124 lines (123 loc) â€ĸ 6.58 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LineOffsetAnalyzer = void 0; const fs = require("fs/promises"); const path_1 = require("path"); const diff_1 = require("diff"); const Logger_1 = require("../Logger"); const InstrumentUtil_1 = require("../util/InstrumentUtil"); const FileOperationHelper_1 = require("../../scripts/FileOperationHelper"); class LineOffsetAnalyzer { constructor(rootPath, instrumentedPath, appBundleInfo) { this.rootDir = (0, path_1.resolve)(rootPath); this.instrumentedDir = (0, path_1.resolve)(instrumentedPath); this.outputFile = (0, path_1.resolve)(this.instrumentedDir, 'line-offsets.json'); this.logFile = (0, path_1.resolve)(this.instrumentedDir, 'debug.log'); this.appBundleInfo = appBundleInfo; } run() { return __awaiter(this, void 0, void 0, function* () { try { yield fs.writeFile(this.logFile, ''); const buildExists = yield FileOperationHelper_1.default.checkIfFileExists(this.instrumentedDir); if (!buildExists) { yield this.log(`❌ Build directory not found at: ${this.instrumentedDir}`); yield this.log('đŸ› ī¸ Please run the instrumentation step first!'); console.error('đŸšĢ Build directory missing. Make and instrument the project first.'); process.exit(1); } const instrumentedFiles = (yield FileOperationHelper_1.default.getAllFiles(this.log, this.instrumentedDir)) .filter((filePath) => filePath.endsWith(InstrumentUtil_1.INSTRUMENTED_FILE_EXTENSION)); const mappings = {}; yield this.log(`🔍 Found ${instrumentedFiles.length} instrumented files`); for (const instrRelPath of instrumentedFiles) { const baseRelPath = instrRelPath.slice(0, -InstrumentUtil_1.INSTRUMENTED_FILE_EXTENSION.length); const origPath = (0, path_1.join)(this.rootDir, baseRelPath); const instrPath = (0, path_1.join)(this.instrumentedDir, instrRelPath); const origExists = yield FileOperationHelper_1.default.checkIfFileExists(origPath); if (!origExists) { yield this.log(`âš ī¸ Original file not found for: ${baseRelPath}`); continue; } yield this.log(`📄 Comparing: ${baseRelPath}`); const [originalContent, instrumentedContent] = yield Promise.all([ FileOperationHelper_1.default.readTextFromFile(origPath), FileOperationHelper_1.default.readTextFromFile(instrPath), ]); const offsets = this.computeLineOffsets(originalContent, instrumentedContent); if (offsets.length > 0) { mappings[baseRelPath] = offsets; yield this.log(`✅ Offsets found for ${baseRelPath}: ${offsets.length} entries`); } else { yield this.log(`â„šī¸ No offsets needed for ${baseRelPath}`); } } const finalOutput = { generationTime: new Date().toISOString(), appVersion: this.appBundleInfo ? this.appBundleInfo.version : 'application version not defined', pluginVersion: this.appBundleInfo ? this.appBundleInfo.pluginVersion : 'plugin version not defined', mappings: { [this.appBundleInfo ? this.appBundleInfo.name : 'app name not defined']: mappings, }, }; yield fs.writeFile(this.outputFile, JSON.stringify(finalOutput, null, 2)); yield this.log(`✅ Line offsets written to ${this.outputFile}`); } catch (err) { console.error('❌ Unexpected error:', err); } }); } log(msg) { return __awaiter(this, void 0, void 0, function* () { Logger_1.default.logMessageSync(msg, Logger_1.default.INFO); yield fs.appendFile(this.logFile, msg + '\n'); }); } computeLineOffsets(originalContent, instrumentedContent) { const diffs = (0, diff_1.diffLines)(originalContent, instrumentedContent); let origLine = 0; let instrLine = 0; let offset = 0; let lastRecordedOffset = null; const offsets = []; this.log('🔍 Diff result:'); for (const part of diffs) { const lines = part.value.split('\n').slice(0, -1); if (part.added) { this.log(`➕ Added ${lines.length} lines at instrumented line ${instrLine + 1}`); lines.forEach((line, i) => this.log(` + ${instrLine + 1 + i}: ${line}`)); instrLine += lines.length; offset -= lines.length; } else if (part.removed) { this.log(`➖ Removed ${lines.length} lines at original line ${origLine + 1}`); lines.forEach((line, i) => this.log(` - ${origLine + 1 + i}: ${line}`)); origLine += lines.length; offset += lines.length; } else { for (let i = 0; i < lines.length; i++) { instrLine++; origLine++; if (offset !== 0 && offset !== lastRecordedOffset) { offsets.push({ [instrLine]: offset }); lastRecordedOffset = offset; } } } } return offsets; } } exports.LineOffsetAnalyzer = LineOffsetAnalyzer;