UNPKG

@expo/cli

Version:
163 lines (162 loc) 7.89 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "ExpoGoInstaller", { enumerable: true, get: ()=>ExpoGoInstaller }); function _semver() { const data = /*#__PURE__*/ _interopRequireDefault(require("semver")); _semver = function() { return data; }; return data; } const _getVersions = require("../../api/getVersions"); const _log = /*#__PURE__*/ _interopRequireWildcard(require("../../log")); const _downloadExpoGoAsync = require("../../utils/downloadExpoGoAsync"); const _env = require("../../utils/env"); const _errors = require("../../utils/errors"); const _link = require("../../utils/link"); const _ora = require("../../utils/ora"); const _prompts = require("../../utils/prompts"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for(var key in obj){ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } const debug = require("debug")("expo:utils:ExpoGoInstaller"); class ExpoGoInstaller { // Keep a list of [platform-deviceId] so we can prevent asking multiple times if a user wants to upgrade. // This can prevent annoying interactions when they don't want to upgrade for whatever reason. static cache = {}; constructor(platform, appId, sdkVersion){ this.platform = platform; this.appId = appId; this.sdkVersion = sdkVersion; } /** Returns true if the installed app matching the previously provided `appId` is outdated. */ isInstalledClientVersionMismatched(installedVersion, expectedExpoGoVersion) { if (!installedVersion) { return true; } debug(`Expected Expo Go version: ${expectedExpoGoVersion}, installed version: ${installedVersion}`); return expectedExpoGoVersion ? !_semver().default.eq(installedVersion, expectedExpoGoVersion) : true; } /** Returns the expected version of Expo Go given the project SDK Version. Exposed for testing. */ async getExpectedExpoGoClientVersionAsync() { var ref, ref1; const versions = await (0, _getVersions.getVersionsAsync)(); // Like `sdkVersions['44.0.0']['androidClientVersion'] = '1.0.0'` const specificVersion = versions == null ? void 0 : (ref = versions.sdkVersions) == null ? void 0 : (ref1 = ref[this.sdkVersion]) == null ? void 0 : ref1[`${this.platform}ClientVersion`]; const latestVersion = versions[`${this.platform}Version`]; var ref2; return (ref2 = specificVersion != null ? specificVersion : latestVersion) != null ? ref2 : null; } /** Returns a boolean indicating if Expo Go should be installed. Returns `true` if the app was uninstalled. */ async promptForUninstallExpoGoIfInstalledClientVersionMismatchedAndReturnShouldInstallAsync(deviceManager, { containerPath } = {}) { const cacheId = `${this.platform}-${deviceManager.identifier}`; if (ExpoGoInstaller.cache[cacheId]) { debug("skipping subsequent upgrade check"); return false; } ExpoGoInstaller.cache[cacheId] = true; const [installedExpoGoVersion, expectedExpoGoVersion] = await Promise.all([ deviceManager.getAppVersionAsync(this.appId, { containerPath }), this.getExpectedExpoGoClientVersionAsync(), ]); if (this.isInstalledClientVersionMismatched(installedExpoGoVersion, expectedExpoGoVersion)) { if (this.sdkVersion === "UNVERSIONED") { // This should only happen in the expo/expo repo, e.g. `apps/test-suite` _log.log(`Skipping Expo Go upgrade check for UNVERSIONED project. Manually ensure the Expo Go app is built from source.`); return false; } // Only prompt once per device, per run. const confirm = await (0, _prompts.confirmAsync)({ initial: true, message: `Expo Go ${expectedExpoGoVersion} is recommended for SDK ${this.sdkVersion} (${deviceManager.name} is using ${installedExpoGoVersion}). ${(0, _link.learnMore)("https://docs.expo.dev/get-started/expo-go/#sdk-versions")}. Install the recommended Expo Go version?` }); if (confirm) { // Don't need to uninstall to update on iOS. if (this.platform !== "ios") { _log.log(`Uninstalling Expo Go from ${this.platform} device ${deviceManager.name}.`); await deviceManager.uninstallAppAsync(this.appId); } return true; } } return false; } /** Check if a given device has Expo Go installed, if not then download and install it. */ async ensureAsync(deviceManager) { const isExpoGoInstalledAndIfSoContainerPathForIOS = await deviceManager.isAppInstalledAndIfSoReturnContainerPathForIOSAsync(this.appId); let shouldInstall = !isExpoGoInstalledAndIfSoContainerPathForIOS; if (_env.env.EXPO_OFFLINE) { if (isExpoGoInstalledAndIfSoContainerPathForIOS) { _log.warn(`Skipping Expo Go version validation in offline mode`); return false; } throw new _errors.CommandError("NO_EXPO_GO", `Expo Go is not installed on device "${deviceManager.name}", while running in offline mode. Manually install Expo Go or run without --offline flag (or EXPO_OFFLINE environment variable).`); } if (isExpoGoInstalledAndIfSoContainerPathForIOS) { shouldInstall = await this.promptForUninstallExpoGoIfInstalledClientVersionMismatchedAndReturnShouldInstallAsync(deviceManager, { // iOS optimization to prevent duplicate calls to `getContainerPathAsync`. containerPath: typeof isExpoGoInstalledAndIfSoContainerPathForIOS === "string" ? isExpoGoInstalledAndIfSoContainerPathForIOS : undefined }); } if (shouldInstall) { // Download the Expo Go app from the Expo servers. const binaryPath = await (0, _downloadExpoGoAsync.downloadExpoGoAsync)(this.platform, { sdkVersion: this.sdkVersion }); // Install the app on the device. const ora = (0, _ora.logNewSection)(`Installing Expo Go on ${deviceManager.name}`); try { await deviceManager.installAppAsync(binaryPath); } finally{ ora.stop(); } return true; } return false; } } //# sourceMappingURL=ExpoGoInstaller.js.map