1"use strict"; 2var __importDefault = (this && this.__importDefault) || function (mod) { 3 return (mod && mod.__esModule) ? mod : { "default": mod }; 4}; 5Object.defineProperty(exports, "__esModule", { value: true }); 6const config_plugins_1 = require("@expo/config-plugins"); 7const fs_1 = __importDefault(require("fs")); 8const path_1 = __importDefault(require("path")); 9const DEV_MENU_ANDROID_IMPORT = 'expo.modules.devmenu.react.DevMenuAwareReactActivity'; 10const DEV_MENU_ACTIVITY_CLASS = 'public class MainActivity extends DevMenuAwareReactActivity {'; 11const DEV_MENU_POD_IMPORT = "pod 'expo-dev-menu', path: '../node_modules/expo-dev-menu', :configurations => :debug"; 12const DEV_MENU_IOS_IMPORT = ` 13#if defined(EX_DEV_MENU_ENABLED) 14@import EXDevMenu; 15#endif`; 16const DEV_MENU_IOS_INIT = ` 17#if defined(EX_DEV_MENU_ENABLED) 18 [DevMenuManager configureWithBridge:bridge]; 19#endif`; 20async function readFileAsync(path) { 21 return fs_1.default.promises.readFile(path, 'utf8'); 22} 23async function saveFileAsync(path, content) { 24 return fs_1.default.promises.writeFile(path, content, 'utf8'); 25} 26function addJavaImports(javaSource, javaImports) { 27 const lines = javaSource.split('\n'); 28 const lineIndexWithPackageDeclaration = lines.findIndex(line => line.match(/^package .*;$/)); 29 for (const javaImport of javaImports) { 30 if (!javaSource.includes(javaImport)) { 31 const importStatement = `import ${javaImport};`; 32 lines.splice(lineIndexWithPackageDeclaration + 1, 0, importStatement); 33 } 34 } 35 return lines.join('\n'); 36} 37function addLines(content, find, offset, toAdd) { 38 const lines = content.split('\n'); 39 let lineIndex = lines.findIndex(line => line.match(find)); 40 for (const newLine of toAdd) { 41 if (!content.includes(newLine)) { 42 lines.splice(lineIndex + offset, 0, newLine); 43 lineIndex++; 44 } 45 } 46 return lines.join('\n'); 47} 48async function editPodfile(config, action) { 49 const podfilePath = path_1.default.join(config.modRequest.platformProjectRoot, 'Podfile'); 50 try { 51 const podfile = action(await readFileAsync(podfilePath)); 52 return await saveFileAsync(podfilePath, podfile); 53 } 54 catch (e) { 55 config_plugins_1.WarningAggregator.addWarningIOS('ios-devMenu', `Couldn't modified AppDelegate.m - ${e}.`); 56 } 57} 58async function editAppDelegate(config, action) { 59 const appDelegatePath = path_1.default.join(config.modRequest.platformProjectRoot, config.modRequest.projectName, 'AppDelegate.m'); 60 try { 61 const appDelegate = action(await readFileAsync(appDelegatePath)); 62 return await saveFileAsync(appDelegatePath, appDelegate); 63 } 64 catch (e) { 65 config_plugins_1.WarningAggregator.addWarningIOS('ios-devMenu', `Couldn't modified AppDelegate.m - ${e}.`); 66 } 67} 68const withDevMenuActivity = config => { 69 return config_plugins_1.withMainActivity(config, config => { 70 if (config.modResults.language === 'java') { 71 let content = config.modResults.contents; 72 content = addJavaImports(content, [DEV_MENU_ANDROID_IMPORT]); 73 content = content.replace('public class MainActivity extends ReactActivity {', DEV_MENU_ACTIVITY_CLASS); 74 config.modResults.contents = content; 75 } 76 else { 77 config_plugins_1.WarningAggregator.addWarningAndroid('android-devMenu', `Cannot automatically configure MainActivity if it's not java`); 78 } 79 return config; 80 }); 81}; 82const withDevMenuPodfile = config => { 83 return config_plugins_1.withDangerousMod(config, [ 84 'ios', 85 async (config) => { 86 await editPodfile(config, podfile => { 87 podfile = podfile.replace("platform :ios, '10.0'", "platform :ios, '11.0'"); 88 // Match both variations of Ruby config: 89 // unknown: pod 'expo-dev-menu', path: '../node_modules/expo-dev-menu', :configurations => :debug 90 // Rubocop: pod 'expo-dev-menu', path: '../node_modules/expo-dev-menu', configurations: :debug 91 if (!podfile.match(/pod ['"]expo-dev-menu['"],\s?path: ['"]\.\.\/node_modules\/expo-dev-menu['"],\s?:?configurations:?\s(?:=>\s)?:debug/)) { 92 podfile = addLines(podfile, 'use_react_native', 0, [` ${DEV_MENU_POD_IMPORT}`]); 93 } 94 return podfile; 95 }); 96 return config; 97 }, 98 ]); 99}; 100const withDevMenuAppDelegate = config => { 101 return config_plugins_1.withDangerousMod(config, [ 102 'ios', 103 async (config) => { 104 await editAppDelegate(config, appDelegate => { 105 if (!appDelegate.includes(DEV_MENU_IOS_IMPORT)) { 106 const lines = appDelegate.split('\n'); 107 lines.splice(1, 0, DEV_MENU_IOS_IMPORT); 108 appDelegate = lines.join('\n'); 109 } 110 if (!appDelegate.includes(DEV_MENU_IOS_INIT)) { 111 const lines = appDelegate.split('\n'); 112 const initializeReactNativeAppIndex = lines.findIndex(line => line.includes('- (RCTBridge *)initializeReactNativeApp')); 113 const rootViewControllerIndex = lines.findIndex((line, index) => initializeReactNativeAppIndex < index && line.includes('rootViewController')); 114 lines.splice(rootViewControllerIndex - 1, 0, DEV_MENU_IOS_INIT); 115 appDelegate = lines.join('\n'); 116 } 117 return appDelegate; 118 }); 119 return config; 120 }, 121 ]); 122}; 123const withDevMenu = (config) => { 124 config = withDevMenuActivity(config); 125 config = withDevMenuPodfile(config); 126 config = withDevMenuAppDelegate(config); 127 return config; 128}; 129exports.default = withDevMenu; 130