"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