'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.openProjectAsync = exports.openUrlInSimulatorSafeAsync = exports._openUrlInSimulatorAsync = exports.upgradeExpoAsync = exports._uninstallExpoAppFromSimulatorAsync = exports._installExpoOnSimulatorAsync = exports._downloadSimulatorAppAsync = exports._checkExpoUpToDateAsync = exports._expoVersionOnCurrentBootedSimulatorAsync = exports._waitForExpoAppInstalledOnCurrentBootedSimulatorAsync = exports._isExpoAppInstalledOnCurrentBootedSimulatorAsync = exports._quitSimulatorAsync = exports._isSimulatorRunningAsync = exports._openSimulatorAsync = exports._isSimulatorInstalledAsync = undefined; let _xcrunAsync = (() => { var _ref = _asyncToGenerator(function* (args) { try { return yield (0, (_spawnAsync || _load_spawnAsync()).default)('xcrun', args); } catch (e) { if (_isLicenseOutOfDate(e.stdout) || _isLicenseOutOfDate(e.stderr)) { throw new (_XDLError || _load_XDLError()).default((_ErrorCode || _load_ErrorCode()).default.XCODE_LICENSE_NOT_ACCEPTED, 'Xcode license is not accepted. Please run `sudo xcodebuild -license`.'); } else { (_Logger || _load_Logger()).default.global.error(`Error running \`xcrun ${args.join(' ')}\`: ${e.stderr}`); throw e; } } }); return function _xcrunAsync(_x) { return _ref.apply(this, arguments); }; })(); // Simulator installed let _isSimulatorInstalledAsync = exports._isSimulatorInstalledAsync = (() => { var _ref2 = _asyncToGenerator(function* () { let result; try { result = (yield (_osascript || _load_osascript()).default.execAsync('id of app "Simulator"')).trim(); } catch (e) { console.error("Can't determine id of Simulator app; the Simulator is most likely not installed on this machine", e); (_Logger || _load_Logger()).default.global.error(XCODE_NOT_INSTALLED_ERROR); return false; } if (result !== 'com.apple.iphonesimulator') { console.warn("Simulator is installed but is identified as '" + result + "'; don't know what that is."); (_Logger || _load_Logger()).default.global.error(XCODE_NOT_INSTALLED_ERROR); return false; } // check xcode version try { const { stdout } = yield (0, (_spawnAsync || _load_spawnAsync()).default)('xcodebuild', ['-version']); // find something that looks like a dot separated version number let matches = stdout.match(/[\d]{1,2}\.[\d]{1,3}/); if (matches.length === 0) { // very unlikely console.error('No version number found from `xcodebuild -version`.'); (_Logger || _load_Logger()).default.global.error('Unable to check Xcode version. Command ran successfully but no version number was found.'); return false; } // we're cheating to use the semver lib, but it expects a proper patch version which xcode doesn't have const version = matches[0] + '.0'; if (!(_semver || _load_semver()).default.valid(version)) { console.error('Invalid version number found: ' + matches[0]); return false; } if ((_semver || _load_semver()).default.lt(version, SUGGESTED_XCODE_VERSION)) { console.warn(`Found Xcode ${version}, which is older than the recommended Xcode ${SUGGESTED_XCODE_VERSION}.`); } } catch (e) { // how would this happen? presumably if Simulator id is found then xcodebuild is installed console.error(`Unable to check Xcode version: ${e}`); (_Logger || _load_Logger()).default.global.error(XCODE_NOT_INSTALLED_ERROR); return false; } // make sure we can run simctl try { yield _xcrunAsync(['simctl', 'help']); } catch (e) { if (e.isXDLError) { (_Logger || _load_Logger()).default.global.error(e.toString()); } else { console.warn(`Unable to run simctl: ${e.toString()}`); (_Logger || _load_Logger()).default.global.error('xcrun may not be configured correctly. Try running `sudo xcode-select --reset` and running this again.'); } return false; } return true; }); return function _isSimulatorInstalledAsync() { return _ref2.apply(this, arguments); }; })(); // Simulator opened let _openSimulatorAsync = exports._openSimulatorAsync = (() => { var _ref3 = _asyncToGenerator(function* () { if (!(yield _isSimulatorRunningAsync())) { (_Logger || _load_Logger()).default.global.info('Opening iOS simulator'); yield (0, (_spawnAsync || _load_spawnAsync()).default)('open', ['-a', 'Simulator']); yield _waitForSimulatorRunningAsync(); } }); return function _openSimulatorAsync() { return _ref3.apply(this, arguments); }; })(); let _isSimulatorRunningAsync = exports._isSimulatorRunningAsync = (() => { var _ref4 = _asyncToGenerator(function* () { let zeroMeansNo = (yield (_osascript || _load_osascript()).default.execAsync('tell app "System Events" to count processes whose name is "Simulator"')).trim(); if (zeroMeansNo === '0') { return false; } let bootedDevice = yield _bootedSimulatorDeviceAsync(); return !!bootedDevice; }); return function _isSimulatorRunningAsync() { return _ref4.apply(this, arguments); }; })(); let _waitForSimulatorRunningAsync = (() => { var _ref5 = _asyncToGenerator(function* () { if (yield _isSimulatorRunningAsync()) { return true; } else { yield (0, (_delayAsync || _load_delayAsync()).default)(100); return yield _waitForSimulatorRunningAsync(); } }); return function _waitForSimulatorRunningAsync() { return _ref5.apply(this, arguments); }; })(); let _listSimulatorDevicesAsync = (() => { var _ref6 = _asyncToGenerator(function* () { let infoJson = yield _xcrunAsync(['simctl', 'list', 'devices', '--json']); let info = JSON.parse(infoJson.stdout); return info; }); return function _listSimulatorDevicesAsync() { return _ref6.apply(this, arguments); }; })(); let _bootedSimulatorDeviceAsync = (() => { var _ref7 = _asyncToGenerator(function* () { let simulatorDeviceInfo = yield _listSimulatorDevicesAsync(); for (let runtime in simulatorDeviceInfo.devices) { let devices = simulatorDeviceInfo.devices[runtime]; for (let i = 0; i < devices.length; i++) { let device = devices[i]; if (device.state === 'Booted') { return device; } } } return null; }); return function _bootedSimulatorDeviceAsync() { return _ref7.apply(this, arguments); }; })(); let _quitSimulatorAsync = exports._quitSimulatorAsync = (() => { var _ref8 = _asyncToGenerator(function* () { return yield (_osascript || _load_osascript()).default.execAsync('tell application "Simulator" to quit'); }); return function _quitSimulatorAsync() { return _ref8.apply(this, arguments); }; })(); // Expo installed let _isExpoAppInstalledOnCurrentBootedSimulatorAsync = exports._isExpoAppInstalledOnCurrentBootedSimulatorAsync = (() => { var _ref9 = _asyncToGenerator(function* () { let device = yield _bootedSimulatorDeviceAsync(); if (!device) { return false; } let simDir = yield _dirForSimulatorDevice(device.udid); let matches = yield (0, (_globPromise || _load_globPromise()).default)('./data/Containers/Data/Application/*/Library/Caches/Snapshots/host.exp.Exponent', { cwd: simDir }); return matches.length > 0; }); return function _isExpoAppInstalledOnCurrentBootedSimulatorAsync() { return _ref9.apply(this, arguments); }; })(); let _waitForExpoAppInstalledOnCurrentBootedSimulatorAsync = exports._waitForExpoAppInstalledOnCurrentBootedSimulatorAsync = (() => { var _ref10 = _asyncToGenerator(function* () { if (yield _isExpoAppInstalledOnCurrentBootedSimulatorAsync()) { return true; } else { yield (0, (_delayAsync || _load_delayAsync()).default)(100); return yield _waitForExpoAppInstalledOnCurrentBootedSimulatorAsync(); } }); return function _waitForExpoAppInstalledOnCurrentBootedSimulatorAsync() { return _ref10.apply(this, arguments); }; })(); let _expoVersionOnCurrentBootedSimulatorAsync = exports._expoVersionOnCurrentBootedSimulatorAsync = (() => { var _ref11 = _asyncToGenerator(function* () { let device = yield _bootedSimulatorDeviceAsync(); if (!device) { return null; } let simDir = yield _dirForSimulatorDevice(device.udid); let matches = yield (0, (_globPromise || _load_globPromise()).default)('./data/Containers/Bundle/Application/*/Exponent-*.app', { cwd: simDir }); if (matches.length === 0) { return null; } let regex = /Exponent\-([0-9\.]+)\.app/; let regexMatch = regex.exec(matches[0]); if (regexMatch.length < 2) { return null; } return regexMatch[1]; }); return function _expoVersionOnCurrentBootedSimulatorAsync() { return _ref11.apply(this, arguments); }; })(); let _checkExpoUpToDateAsync = exports._checkExpoUpToDateAsync = (() => { var _ref12 = _asyncToGenerator(function* () { let versions = yield (_Api || _load_Api()).default.versionsAsync(); let installedVersion = yield _expoVersionOnCurrentBootedSimulatorAsync(); if (!installedVersion || (_semver || _load_semver()).default.lt(installedVersion, versions.iosVersion)) { (_Logger || _load_Logger()).default.notifications.warn({ code: (_NotificationCode || _load_NotificationCode()).default.OLD_IOS_APP_VERSION }, 'This version of the Expo app is out of date. Uninstall the app and run again to upgrade.'); } }); return function _checkExpoUpToDateAsync() { return _ref12.apply(this, arguments); }; })(); let _downloadSimulatorAppAsync = exports._downloadSimulatorAppAsync = (() => { var _ref13 = _asyncToGenerator(function* (url) { // If specific URL given just always download it and don't use cache if (url) { let dir = _path.default.join(_simulatorCacheDirectory(), `Exponent-tmp.app`); yield (_Api || _load_Api()).default.downloadAsync(url, dir, { extract: true }); return dir; } let versions = yield (_Api || _load_Api()).default.versionsAsync(); let dir = _path.default.join(_simulatorCacheDirectory(), `Exponent-${versions.iosVersion}.app`); if (yield (0, (_existsAsync || _load_existsAsync()).default)(dir)) { let filesInDir = yield (_fsExtra || _load_fsExtra()).default.readdir(dir); if (filesInDir.length > 0) { return dir; } else { (_rimraf || _load_rimraf()).default.sync(dir); } } (_mkdirp || _load_mkdirp()).default.sync(dir); try { yield (_Api || _load_Api()).default.downloadAsync(versions.iosUrl, dir, { extract: true }); } catch (e) { (_rimraf || _load_rimraf()).default.sync(dir); throw e; } return dir; }); return function _downloadSimulatorAppAsync(_x2) { return _ref13.apply(this, arguments); }; })(); // url: Optional URL of Exponent.app tarball to download let _installExpoOnSimulatorAsync = exports._installExpoOnSimulatorAsync = (() => { var _ref14 = _asyncToGenerator(function* (url) { (_Logger || _load_Logger()).default.global.info(`Downloading latest version of Expo`); (_Logger || _load_Logger()).default.notifications.info({ code: (_NotificationCode || _load_NotificationCode()).default.START_LOADING }); let dir = yield _downloadSimulatorAppAsync(url); (_Logger || _load_Logger()).default.notifications.info({ code: (_NotificationCode || _load_NotificationCode()).default.STOP_LOADING }); (_Logger || _load_Logger()).default.global.info('Installing Expo on iOS simulator'); (_Logger || _load_Logger()).default.notifications.info({ code: (_NotificationCode || _load_NotificationCode()).default.START_LOADING }); let result = yield _xcrunAsync(['simctl', 'install', 'booted', dir]); (_Logger || _load_Logger()).default.notifications.info({ code: (_NotificationCode || _load_NotificationCode()).default.STOP_LOADING }); return result; }); return function _installExpoOnSimulatorAsync(_x3) { return _ref14.apply(this, arguments); }; })(); let _uninstallExpoAppFromSimulatorAsync = exports._uninstallExpoAppFromSimulatorAsync = (() => { var _ref15 = _asyncToGenerator(function* () { try { (_Logger || _load_Logger()).default.global.info('Uninstalling Expo from iOS simulator.'); yield _xcrunAsync(['simctl', 'uninstall', 'booted', 'host.exp.Exponent']); } catch (e) { if (e.message && e.message.includes('No devices are booted.')) { return null; } else { console.error(e); throw e; } } }); return function _uninstallExpoAppFromSimulatorAsync() { return _ref15.apply(this, arguments); }; })(); let upgradeExpoAsync = exports.upgradeExpoAsync = (() => { var _ref16 = _asyncToGenerator(function* () { if (!(yield _isSimulatorInstalledAsync())) { return false; } yield _openSimulatorAsync(); yield _uninstallExpoAppFromSimulatorAsync(); let installResult = yield _installExpoOnSimulatorAsync(); if (installResult.status !== 0) { return false; } if (_lastUrl) { (_Logger || _load_Logger()).default.global.info(`Opening ${_lastUrl} in Expo.`); yield _xcrunAsync(['simctl', 'openurl', 'booted', _lastUrl]); _lastUrl = null; } return true; }); return function upgradeExpoAsync() { return _ref16.apply(this, arguments); }; })(); // Open Url let _openUrlInSimulatorAsync = exports._openUrlInSimulatorAsync = (() => { var _ref17 = _asyncToGenerator(function* (url) { return yield _xcrunAsync(['simctl', 'openurl', 'booted', url]); }); return function _openUrlInSimulatorAsync(_x4) { return _ref17.apply(this, arguments); }; })(); let openUrlInSimulatorSafeAsync = exports.openUrlInSimulatorSafeAsync = (() => { var _ref18 = _asyncToGenerator(function* (url, isDetached = false) { if (!(yield _isSimulatorInstalledAsync())) { return { success: false, msg: 'Unable to verify Xcode and Simulator installation.' }; } try { yield _openSimulatorAsync(); if (!isDetached && !(yield _isExpoAppInstalledOnCurrentBootedSimulatorAsync())) { yield _installExpoOnSimulatorAsync(); yield _waitForExpoAppInstalledOnCurrentBootedSimulatorAsync(); } if (!isDetached) { _lastUrl = url; _checkExpoUpToDateAsync(); // let this run in background } (_Logger || _load_Logger()).default.global.info(`Opening ${url} in iOS simulator`); yield _openUrlInSimulatorAsync(url); } catch (e) { if (e.isXDLError) { // Hit some internal error, don't try again. // This includes Xcode license errors (_Logger || _load_Logger()).default.global.error(e.message); return { success: false, msg: `${e.toString()}` }; } if (isDetached) { (_Logger || _load_Logger()).default.global.error(`Error running app. Have you installed the app already using Xcode? Since you are detached you must build manually. ${e.toString()}`); } else { (_Logger || _load_Logger()).default.global.error(`Error installing or running app. ${e.toString()}`); } return { success: false, msg: `${e.toString()}` }; } (_Analytics || _load_Analytics()).logEvent('Open Url on Device', { platform: 'ios' }); return { success: true }; }); return function openUrlInSimulatorSafeAsync(_x5) { return _ref18.apply(this, arguments); }; })(); let openProjectAsync = exports.openProjectAsync = (() => { var _ref19 = _asyncToGenerator(function* (projectRoot) { let projectUrl = yield (_UrlUtils || _load_UrlUtils()).constructManifestUrlAsync(projectRoot, { hostType: 'localhost' }); let { exp } = yield (_ProjectUtils || _load_ProjectUtils()).readConfigJsonAsync(projectRoot); yield openUrlInSimulatorSafeAsync(projectUrl, !!exp.isDetached); }); return function openProjectAsync(_x6) { return _ref19.apply(this, arguments); }; })(); exports.isPlatformSupported = isPlatformSupported; exports._dirForSimulatorDevice = _dirForSimulatorDevice; exports._simulatorCacheDirectory = _simulatorCacheDirectory; var _delayAsync; function _load_delayAsync() { return _delayAsync = _interopRequireDefault(require('delay-async')); } var _existsAsync; function _load_existsAsync() { return _existsAsync = _interopRequireDefault(require('exists-async')); } var _globPromise; function _load_globPromise() { return _globPromise = _interopRequireDefault(require('glob-promise')); } var _homeDir; function _load_homeDir() { return _homeDir = _interopRequireDefault(require('home-dir')); } var _mkdirp; function _load_mkdirp() { return _mkdirp = _interopRequireDefault(require('mkdirp')); } var _osascript; function _load_osascript() { return _osascript = _interopRequireDefault(require('@expo/osascript')); } var _path = _interopRequireDefault(require('path')); var _semver; function _load_semver() { return _semver = _interopRequireDefault(require('semver')); } var _spawnAsync; function _load_spawnAsync() { return _spawnAsync = _interopRequireDefault(require('@expo/spawn-async')); } var _rimraf; function _load_rimraf() { return _rimraf = _interopRequireDefault(require('rimraf')); } var _fsExtra; function _load_fsExtra() { return _fsExtra = _interopRequireDefault(require('fs-extra')); } var _Analytics; function _load_Analytics() { return _Analytics = _interopRequireWildcard(require('./Analytics')); } var _Api; function _load_Api() { return _Api = _interopRequireDefault(require('./Api')); } var _ErrorCode; function _load_ErrorCode() { return _ErrorCode = _interopRequireDefault(require('./ErrorCode')); } var _Logger; function _load_Logger() { return _Logger = _interopRequireDefault(require('./Logger')); } var _NotificationCode; function _load_NotificationCode() { return _NotificationCode = _interopRequireDefault(require('./NotificationCode')); } var _ProjectUtils; function _load_ProjectUtils() { return _ProjectUtils = _interopRequireWildcard(require('./project/ProjectUtils')); } var _UserSettings; function _load_UserSettings() { return _UserSettings = _interopRequireDefault(require('./UserSettings')); } var _XDLError; function _load_XDLError() { return _XDLError = _interopRequireDefault(require('./XDLError')); } var _UrlUtils; function _load_UrlUtils() { return _UrlUtils = _interopRequireWildcard(require('./UrlUtils')); } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } let _lastUrl = null; const SUGGESTED_XCODE_VERSION = `8.2.0`; const XCODE_NOT_INSTALLED_ERROR = 'Simulator not installed. Please visit https://developer.apple.com/xcode/download/ to download Xcode and the iOS simulator. If you already have the latest version of Xcode installed, you may have to run the command `sudo xcode-select -s /Applications/Xcode.app`.'; function isPlatformSupported() { return process.platform === 'darwin'; } function _isLicenseOutOfDate(text) { if (!text) { return false; } let lower = text.toLowerCase(); return lower.includes('xcode') && lower.includes('license'); } function _dirForSimulatorDevice(udid) { return _path.default.resolve((0, (_homeDir || _load_homeDir()).default)(), 'Library/Developer/CoreSimulator/Devices', udid); } function _simulatorCacheDirectory() { let dotExpoHomeDirectory = (_UserSettings || _load_UserSettings()).default.dotExpoHomeDirectory(); let dir = _path.default.join(dotExpoHomeDirectory, 'ios-simulator-app-cache'); (_mkdirp || _load_mkdirp()).default.sync(dir); return dir; } //# sourceMappingURL=__sourcemaps__/Simulator.js.map