expo-keystore-manager
Version:
A comprehensive Expo config plugin for managing Android release keystore configuration
131 lines (128 loc) • 5.91 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const config_plugins_1 = require("@expo/config-plugins");
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
/**
* Complete Release Keystore Plugin for Expo
* Handles all aspects of Android release keystore configuration
*/
const withKeystore = (config, options) => {
// Validate required options
if (!options.keystoreFile) {
throw new Error("keystoreFile is required for release keystore configuration");
}
if (!options.keystorePassword) {
throw new Error("keystorePassword is required for release keystore configuration");
}
if (!options.keyAlias) {
throw new Error("keyAlias is required for release keystore configuration");
}
if (!options.keyPassword) {
throw new Error("keyPassword is required for release keystore configuration");
}
// Set default values
const keystoreConfig = {
...options,
};
// Apply gradle properties
config = (0, config_plugins_1.withGradleProperties)(config, async (gradleProperties) => {
{
const projectRoot = process.cwd();
const androidAppPath = path_1.default.join(projectRoot, "android", "app");
const sourcePath = path_1.default.join(projectRoot, keystoreConfig.keystoreFile);
const keystoreFileName = path_1.default.basename(sourcePath);
const targetKeystorePath = path_1.default.join(androidAppPath, keystoreFileName);
let properties = gradleProperties.modResults || [];
if (fs_1.default.existsSync(sourcePath)) {
// Ensure android/app directory exists
if (!fs_1.default.existsSync(androidAppPath)) {
fs_1.default.mkdirSync(androidAppPath, { recursive: true });
}
// Copy keystore file
fs_1.default.copyFileSync(keystoreConfig.keystoreFile, targetKeystorePath);
console.log(`✅ Copied keystore from ${keystoreConfig.keystoreFile} to ${targetKeystorePath}`);
// Update keystoreConfig to use the copied file path (just filename)
keystoreConfig.keystoreFile = keystoreFileName;
}
else {
throw new Error(`⚠️ Keystore file not found at: ${keystoreConfig.keystoreFile}`);
}
// Remove existing keystore properties to avoid duplicates
const keystorePropertyKeys = [
"#KeyStore",
"MYAPP_STORE_FILE",
"MYAPP_KEY_ALIAS",
"MYAPP_STORE_PASSWORD",
"MYAPP_KEY_PASSWORD",
"MYAPP_STORE_TYPE",
];
properties = properties.filter((prop) => {
return (prop &&
prop.type === "property" &&
!keystorePropertyKeys.includes(prop.key));
});
// Add new keystore properties
const setGradleProperty = (key, value) => {
if (value !== undefined || value !== null) {
properties.push({
key: key,
value: value,
type: "property",
});
}
};
setGradleProperty("MYAPP_STORE_FILE", keystoreFileName);
setGradleProperty("MYAPP_KEY_ALIAS", keystoreConfig.keyAlias);
setGradleProperty("MYAPP_STORE_PASSWORD", keystoreConfig.keystorePassword);
setGradleProperty("MYAPP_KEY_PASSWORD", keystoreConfig.keyPassword);
gradleProperties.modResults = properties;
return gradleProperties;
}
});
// Configure app/build.gradle for release signing
config = (0, config_plugins_1.withAppBuildGradle)(config, (appBuildGradle) => {
let buildGradleContent = appBuildGradle.modResults.contents;
const signingConfigBlock = `
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
release {
if (project.hasProperty('MYAPP_STORE_FILE')) {
storeFile file(MYAPP_STORE_FILE)
storePassword MYAPP_STORE_PASSWORD
keyAlias MYAPP_KEY_ALIAS
keyPassword MYAPP_KEY_PASSWORD
}
}
}`;
// Remove entire existing signingConfigs block
buildGradleContent = buildGradleContent.replace(/signingConfigs\s*\{[\s\S]*?\}\s*/, "");
// Insert signing config before buildTypes
buildGradleContent = buildGradleContent.replace(/android\s*\{/, `android {${signingConfigBlock}`);
// Update buildTypes to use release signing config
if (buildGradleContent.includes("buildTypes")) {
buildGradleContent = buildGradleContent.replace("signingConfig signingConfigs.debug", "signingConfig signingConfigs.release");
}
// Add proguard configuration if enabled
if (Boolean(keystoreConfig.enableProguard)) {
if (!buildGradleContent.includes("minifyEnabled true")) {
buildGradleContent = buildGradleContent.replace(/(release\s*\{[^}]*signingConfig signingConfigs\.release)/, `$1
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'`);
}
}
appBuildGradle.modResults.contents = buildGradleContent;
return appBuildGradle;
});
return config;
};
exports.default = withKeystore;
//# sourceMappingURL=withKeystore.js.map
;