"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; function _fsExtra() { const data = _interopRequireDefault(require("fs-extra")); _fsExtra = function () { return data; }; return data; } function _path() { const data = _interopRequireDefault(require("path")); _path = function () { return data; }; return data; } function _untildify() { const data = _interopRequireDefault(require("untildify")); _untildify = function () { return data; }; return data; } function _xdl() { const data = require("@expo/xdl"); _xdl = function () { return data; }; return data; } function _chalk() { const data = _interopRequireDefault(require("chalk")); _chalk = function () { return data; }; return data; } function _get() { const data = _interopRequireDefault(require("lodash/get")); _get = function () { return data; }; return data; } function _log() { const data = _interopRequireDefault(require("../../log")); _log = function () { return data; }; return data; } function _BuildError() { const data = _interopRequireDefault(require("./BuildError")); _BuildError = function () { return data; }; return data; } function _BaseBuilder() { const data = _interopRequireDefault(require("./BaseBuilder")); _BaseBuilder = function () { return data; }; return data; } function _prompt() { const data = _interopRequireDefault(require("../../prompt")); _prompt = function () { return data; }; return data; } function utils() { const data = _interopRequireWildcard(require("./utils")); utils = function () { return data; }; return data; } function _constants() { const data = require("./constants"); _constants = function () { return data; }; return data; } function _credentials() { const data = require("../../credentials"); _credentials = function () { return data; }; return data; } function _AndroidCredentials() { const data = require("../../credentials/views/AndroidCredentials"); _AndroidCredentials = function () { return data; }; return data; } 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)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const { ANDROID } = _constants().PLATFORMS; class AndroidBuilder extends _BaseBuilder().default { async run() { // Validate project await this.validateProject(); // Check SplashScreen images sizes await _xdl().Android.checkSplashScreenImages(this.projectDir); // Check the status of any current builds await this.checkForBuildInProgress(); // Check for existing credentials, collect any missing credentials, and validate them await this.collectAndValidateCredentials(); // Publish the current experience, if necessary let publishedExpIds = this.options.publicUrl ? undefined : await this.ensureReleaseExists(); if (!this.options.publicUrl) { await this.checkStatusBeforeBuild(); } // Initiate a build await this.build(publishedExpIds); } async validateProject() { await utils().checkIfSdkIsSupported(this.manifest.sdkVersion, ANDROID); if (!(0, _get().default)(this.manifest, 'android.package')) { throw new (_BuildError().default)(`Your project must have an Android package set in app.json See https://docs.expo.io/versions/latest/distribution/building-standalone-apps/#2-configure-appjson`); } const androidPackage = (0, _get().default)(this.manifest, 'android.package'); if (!androidPackage) { throw new (_BuildError().default)('Your project must have an Android package set in app.json.'); } if (!/^[a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_]*)+$/.test(androidPackage)) { throw new (_BuildError().default)("Invalid format of Android package name (only alphanumeric characters, '.' and '_' are allowed, and each '.' must be followed by a letter)"); } } async _clearCredentials() { const credentialMetadata = await _xdl().Credentials.getCredentialMetadataAsync(this.projectDir, ANDROID); _log().default.warn(`Clearing your Android build credentials from our build servers is a ${_chalk().default.red('PERMANENT and IRREVERSIBLE action.')}`); _log().default.warn('Android keystores must be identical to the one previously used to submit your app to the Google Play Store.'); _log().default.warn('Please read https://docs.expo.io/versions/latest/distribution/building-standalone-apps/#if-you-choose-to-build-for-android for more info before proceeding.'); _log().default.warn("We'll store a backup of your Android keystore in this directory in case you decide to delete it from our servers."); let questions = [{ type: 'confirm', name: 'confirm', message: 'Permanently delete the Android build credentials from our servers?' }]; const answers = await (0, _prompt().default)(questions); if (answers.confirm) { (0, _log().default)('Backing up your Android keystore now...'); const ctx = new (_credentials().Context)(); await ctx.init(this.projectDir); const backupKeystoreOutputPath = _path().default.resolve(this.projectDir, `${ctx.manifest.slug}.jks`); const view = new (_AndroidCredentials().DownloadKeystore)(ctx.manifest.slug); await view.fetch(ctx); await view.save(ctx, backupKeystoreOutputPath, true); await _xdl().Credentials.removeCredentialsForPlatform(ANDROID, credentialMetadata); _log().default.warn('Removed existing credentials from Expo servers'); } } async collectAndValidateCredentials() { const credentialMetadata = await _xdl().Credentials.getCredentialMetadataAsync(this.projectDir, ANDROID); const credentialsExist = await _xdl().Credentials.credentialsExistForPlatformAsync(credentialMetadata); if (this.checkEnv()) { await this.collectAndValidateCredentialsFromCI(credentialMetadata); } else if (this.options.clearCredentials || !credentialsExist) { console.log(''); const questions = [{ type: 'rawlist', name: 'uploadKeystore', message: `Would you like to upload a keystore or have us generate one for you?\nIf you don't know what this means, let us handle it! :)\n`, choices: [{ name: 'Let Expo handle the process!', value: false }, { name: 'I want to upload my own keystore!', value: true }] }, { type: 'input', name: 'keystorePath', message: `Path to keystore:`, validate: async keystorePath => { try { const keystorePathStats = await _fsExtra().default.stat(keystorePath); return keystorePathStats.isFile(); } catch (e) { // file does not exist console.log('\nFile does not exist.'); return false; } }, filter: keystorePath => { keystorePath = (0, _untildify().default)(keystorePath); if (!_path().default.isAbsolute(keystorePath)) { keystorePath = _path().default.resolve(keystorePath); } return keystorePath; }, when: answers => answers.uploadKeystore }, { type: 'input', name: 'keystoreAlias', message: `Keystore Alias:`, validate: val => val !== '', when: answers => answers.uploadKeystore }, { type: 'password', name: 'keystorePassword', message: `Keystore Password:`, validate: val => val !== '', when: answers => answers.uploadKeystore }, { type: 'password', name: 'keyPassword', message: `Key Password:`, validate: (password, answers) => { if (password === '') { return false; } // Todo validate keystore passwords return true; }, when: answers => answers.uploadKeystore }]; const answers = await (0, _prompt().default)(questions); if (!answers.uploadKeystore) { if (this.options.clearCredentials && credentialsExist) { await this._clearCredentials(); } // just continue } else { const { keystorePath, keystoreAlias, keystorePassword, keyPassword } = answers; // read the keystore const keystoreData = await _fsExtra().default.readFile(keystorePath); const credentials = { keystore: keystoreData.toString('base64'), keystoreAlias, keystorePassword, keyPassword }; await _xdl().Credentials.updateCredentialsForPlatform(ANDROID, credentials, [], credentialMetadata); } } } checkEnv() { return this.options.keystorePath && this.options.keystoreAlias && process.env.EXPO_ANDROID_KEYSTORE_PASSWORD && process.env.EXPO_ANDROID_KEY_PASSWORD; } async collectAndValidateCredentialsFromCI(credentialMetadata) { const credentials = { keystore: (await _fsExtra().default.readFile(this.options.keystorePath)).toString('base64'), keystoreAlias: this.options.keystoreAlias, keystorePassword: process.env.EXPO_ANDROID_KEYSTORE_PASSWORD, keyPassword: process.env.EXPO_ANDROID_KEY_PASSWORD }; await _xdl().Credentials.updateCredentialsForPlatform(ANDROID, credentials, [], credentialMetadata); } platform() { return ANDROID; } } exports.default = AndroidBuilder; //# sourceMappingURL=../../__sourcemaps__/commands/build/AndroidBuilder.js.map