@dynatrace/react-native-plugin
Version:
This plugin gives you the ability to use the Dynatrace Mobile agent in your react native application.
203 lines (202 loc) • 10.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const nodePath = require("path");
const plist_1 = require("plist");
const Logger_1 = require("./Logger");
const FileOperationHelper_1 = require("./FileOperationHelper");
const PathsConstants_1 = require("./PathsConstants");
const PlistConstants_1 = require("./util/PlistConstants");
const modifyPListFile = (pathToPList, iosConfig, removeOnly) => {
if (pathToPList === undefined) {
pathToPList = findPListFile();
}
else {
if (!pathToPList.endsWith('.plist')) {
throw new Error("Can't find .plist file. plist path must also include the plist file!");
}
try {
FileOperationHelper_1.default.checkIfFileExistsSync(pathToPList);
}
catch (e) {
throw new Error('Could not read plist file: ' + pathToPList);
}
}
const parsedPList = parsePList(pathToPList);
const configProps = iosConfig === null || iosConfig === void 0 ? void 0 : iosConfig.config;
if (removeOnly) {
removePListConfig(pathToPList);
}
else {
if (iosConfig && (configProps != null)) {
if (hasDuplicateProperties(configProps)) {
throw new Error('Duplicate properties found! Please remove duplicates and try again.');
}
if (isAutoStartEnabled(configProps)) {
if (checkForBeaconUrlAndAppId(configProps)) {
createNewPListIfRequired(parsedPList, configProps, pathToPList);
}
else {
throw new Error('The dynatrace.config.js file does not contain DTXBeaconURL or DTXApplicationID properties. ' +
'If you want to auto-start the iOS agent, please add these two properties at minimum as they are required. ' +
'If you are using a manual startup of the iOS agent, please add just the DTXAutoStart property ' +
'(no other properties are needed and none will be considered) with the value set to false.');
}
}
else {
if (checkForBeaconUrlAndAppId(configProps)) {
throw new Error('The dynatrace.config.js file contains DTXBeaconURL and or DTXApplicationID properties while ' +
'DTXAutoStart is set to false. Any properties that you add to the dynatrace.config.js file will not be used ' +
'if DTXAutoStart is set to false. If you want to manually start the iOS agent, please only add the ' +
'DTXAutoStart property and set the value to false.');
}
else {
createNewPListIfRequired(parsedPList, configProps, pathToPList);
}
}
}
else {
throw new Error("Can't write configuration of iOS agent because it is missing!");
}
}
};
const removePListConfig = (file) => {
const pListContent = FileOperationHelper_1.default.readTextFromFileSync(file);
const pListObj = (0, plist_1.parse)(pListContent);
const pListObjCopy = Object.assign({}, pListObj);
for (const property in pListObj) {
if (property.startsWith('DTX')) {
delete pListObjCopy[property];
}
}
FileOperationHelper_1.default.writeTextToFileSync(file, (0, plist_1.build)(pListObjCopy));
Logger_1.default.logMessageSync('Removed old configuration in plist file: ' + file, Logger_1.default.INFO);
};
const addAgentConfigToPListFile = (file, config) => {
const pListContent = FileOperationHelper_1.default.readTextFromFileSync(file);
const newPListContent = PlistConstants_1.START_PLIST + config + PlistConstants_1.END_PLIST;
FileOperationHelper_1.default.writeTextToFileSync(file, (0, plist_1.build)(Object.assign(Object.assign({}, (0, plist_1.parse)(pListContent)), (0, plist_1.parse)(newPListContent))));
Logger_1.default.logMessageSync('Updated configuration in plist file: ' + file, Logger_1.default.INFO);
};
const findPListFile = () => {
const appJson = FileOperationHelper_1.default.readTextFromFileSync(PathsConstants_1.default.getAppJsonFile());
const appJsonObj = JSON.parse(appJson);
let appName;
if (appJsonObj.expo !== undefined) {
appName = appJsonObj.expo.name;
}
else if (appJsonObj.name !== undefined) {
appName = appJsonObj.name;
}
else {
throw new Error('Name of the application is unknown. Check your app.json file!');
}
const pListPaths = [];
pListPaths.push(nodePath.join(PathsConstants_1.default.getIOSFolder(), appName, 'Info.plist'));
pListPaths.push(nodePath.join(PathsConstants_1.default.getIOSFolder(), appName, 'Supporting', 'Info.plist'));
for (const pListPath of pListPaths) {
try {
FileOperationHelper_1.default.checkIfFileExistsSync(pListPath);
return pListPath;
}
catch (e) {
}
}
throw new Error("Can't find .plist file in iOS Folder! Try to use plist= custom argument. See documentation for help!");
};
const parsePList = (file) => {
const pListContent = FileOperationHelper_1.default.readTextFromFileSync(file);
let pListObj = (0, plist_1.parse)(pListContent);
return pListObj = Object.assign({}, pListObj);
};
const isAutoStartEnabled = (config) => {
if (config !== undefined && config.indexOf(PlistConstants_1.AUTO_START_PROP) >= 0) {
const configObj = PlistConstants_1.START_PLIST + config + PlistConstants_1.END_PLIST;
const configObjCopy = (0, plist_1.parse)(configObj);
const configKeys = Object.keys(configObjCopy);
const configValues = Object.values(configObjCopy);
for (const key in configKeys) {
if (configKeys[key] === 'DTXAutoStart' && typeof configValues[key] === 'boolean') {
return configValues[key];
}
}
}
return true;
};
const checkForBeaconUrlAndAppId = (config) => config != null && config.indexOf('DTXApplicationID') >= 0 && config.indexOf('DTXBeaconURL') >= 0;
const checkForExcludedControls = (config) => config != null && config.indexOf('DTXExcludedControls') >= 0;
const updatedExcludedStr = (config) => {
if (checkForExcludedControls(config)) {
const controlsArr = Object.keys(PlistConstants_1.CONTROLS_PROP_OPTIONS);
let updatedStr = `${PlistConstants_1.START_CONTROLS_PROP}${PlistConstants_1.CONTROLS_PROP_OPTIONS.PickerView}${PlistConstants_1.CONTROLS_PROP_OPTIONS.Switch}`;
for (let index = 0; index < controlsArr.length; index++) {
if (controlsArr[index] !== 'PickerView'
&& controlsArr[index] !== 'Switch'
&& config.indexOf(PlistConstants_1.CONTROLS_PROP_OPTIONS[controlsArr[index]].trim()) >= 0) {
updatedStr = updatedStr + PlistConstants_1.CONTROLS_PROP_OPTIONS[controlsArr[index]];
}
}
return `${updatedStr}${PlistConstants_1.END_CONTROLS_PROP}`;
}
return PlistConstants_1.DEFAULT_CONTROLS_PROP;
};
const isPropertyCountEqual = (parsedPList, config) => {
const configObj = PlistConstants_1.START_PLIST + config + PlistConstants_1.END_PLIST;
const configObjCopy = (0, plist_1.parse)(configObj);
return Object.keys(parsedPList)
.filter((pListDtxKeys) => pListDtxKeys.startsWith('DTX')).length === Object.keys(configObjCopy)
.filter((configDtxKeys) => configDtxKeys.startsWith('DTX')).length;
};
const areConfigsEqual = (parsedPList, configObj) => {
const pListKeys = Object.keys(parsedPList);
for (const property of pListKeys) {
const plistProperty = parsedPList[property];
const configProperty = configObj[property];
const objectProperties = isPropertyAnObject(plistProperty) && isPropertyAnObject(configProperty);
if (objectProperties && !areConfigsEqual(plistProperty, configProperty) ||
!objectProperties && plistProperty !== configProperty) {
return false;
}
}
return true;
};
const comparePListAndConfig = (pListObj, config) => {
const configObj = PlistConstants_1.START_PLIST + config + PlistConstants_1.END_PLIST;
const configObjCopy = (0, plist_1.parse)(configObj);
removeNonDTXProperties(pListObj);
removeNonDTXProperties(configObjCopy);
return areConfigsEqual(pListObj, configObjCopy);
};
const isPropertyAnObject = (propertyObject) => propertyObject != null && typeof propertyObject === 'object';
const removeNonDTXProperties = (propertiesObject) => {
const updatedObject = propertiesObject;
for (const property in propertiesObject) {
if (!property.startsWith('DTX')) {
delete updatedObject[property];
}
}
return updatedObject;
};
const hasDuplicateProperties = (config) => {
const configArr = config.split('\n');
const newConfigArr = configArr.filter((configDtxKeys) => configDtxKeys.startsWith('<key>DTX'));
return !newConfigArr.every((property) => newConfigArr.indexOf(property) === newConfigArr.lastIndexOf(property));
};
const createNewPListIfRequired = (parsedPList, configProps, pathToPList) => {
const configIncludingFlavor = configProps + getAdditionalInternalPluginKeys() + updatedExcludedStr(configProps);
if (isPropertyCountEqual(parsedPList, configIncludingFlavor) && comparePListAndConfig(parsedPList, configIncludingFlavor)) {
Logger_1.default.logMessageSync('Not generating a new plist as the current plist and ' +
' dynatrace.config.js iOS properties are identical!', Logger_1.default.INFO);
}
else {
Logger_1.default.logMessageSync('Generating a new plist as the current plist ' +
'and dynatrace.config.js iOS properties do not match!', Logger_1.default.INFO);
removePListConfig(pathToPList);
addAgentConfigToPListFile(pathToPList, configIncludingFlavor);
}
};
const getAdditionalInternalPluginKeys = () => PlistConstants_1.FLAVOR_PROP + PlistConstants_1.WEBREQUEST_FALLBACK_PROP;
exports.default = {
modifyPListFile,
findPListFile,
};