This repository has been archived on 2022-03-12. You can view files and clone it, but cannot push or open issues or pull requests.

409 lines
20 KiB
JavaScript
Raw Normal View History

2021-04-02 02:24:13 +03:00
"use strict";
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const plist_1 = __importDefault(require("@expo/plist"));
const fs_extra_1 = require("fs-extra");
const path_1 = __importDefault(require("path"));
const android_1 = require("../android");
const AndroidPaths = __importStar(require("../android/Paths"));
const Resources_1 = require("../android/Resources");
const Strings_1 = require("../android/Strings");
const Entitlements_1 = require("../ios/Entitlements");
const Paths_1 = require("../ios/Paths");
const Xcodeproj_1 = require("../ios/utils/Xcodeproj");
const XML_1 = require("../utils/XML");
const errors_1 = require("../utils/errors");
const WarningAggregator = __importStar(require("../utils/warnings"));
const core_plugins_1 = require("./core-plugins");
function withBaseMods(config) {
config = applyIOSBaseMods(config);
config = applyAndroidBaseMods(config);
return config;
}
exports.withBaseMods = withBaseMods;
function resolveModResults(results, platformName, modName) {
// If the results came from a mod, they'd be in the form of [config, data].
// Ensure the results are an array and omit the data since it should've been written by a data provider plugin.
const ensuredResults = results;
// Sanity check to help locate non compliant mods.
if (!ensuredResults || typeof ensuredResults !== 'object' || !(ensuredResults === null || ensuredResults === void 0 ? void 0 : ensuredResults.mods)) {
throw new Error(`Mod \`mods.${platformName}.${modName}\` evaluated to an object that is not a valid project config. Instead got: ${JSON.stringify(ensuredResults)}`);
}
return ensuredResults;
}
exports.resolveModResults = resolveModResults;
function applyAndroidBaseMods(config) {
config = withExpoDangerousBaseMod(config, 'android');
config = withAndroidStringsXMLBaseMod(config);
config = exports.withAndroidGradlePropertiesBaseMod(config);
config = withAndroidManifestBaseMod(config);
config = withAndroidMainActivityBaseMod(config);
config = withAndroidSettingsGradleBaseMod(config);
config = withAndroidProjectBuildGradleBaseMod(config);
config = withAndroidAppBuildGradleBaseMod(config);
return config;
}
const withAndroidManifestBaseMod = config => {
// Append a rule to supply AndroidManifest.xml data to mods on `mods.android.manifest`
return core_plugins_1.withInterceptedMod(config, {
platform: 'android',
mod: 'manifest',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
const filePath = await AndroidPaths.getAndroidManifestAsync(modRequest.projectRoot);
let modResults = await android_1.Manifest.readAndroidManifestAsync(filePath);
results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
modResults = results.modResults;
await android_1.Manifest.writeAndroidManifestAsync(filePath, modResults);
}
catch (error) {
console.error(`AndroidManifest.xml mod error:`);
throw error;
}
return results;
},
});
};
exports.withAndroidGradlePropertiesBaseMod = config => {
// Append a rule to supply gradle.properties data to mods on `mods.android.gradleProperties`
return core_plugins_1.withInterceptedMod(config, {
platform: 'android',
mod: 'gradleProperties',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
const filePath = path_1.default.join(modRequest.platformProjectRoot, 'gradle.properties');
const contents = await fs_extra_1.readFile(filePath, 'utf8');
let modResults = android_1.Properties.parsePropertiesFile(contents);
results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
modResults = results.modResults;
await fs_extra_1.writeFile(filePath, android_1.Properties.propertiesListToString(modResults), 'utf8');
}
catch (error) {
console.error(`gradle.properties mod error:`);
throw error;
}
return results;
},
});
};
const withAndroidStringsXMLBaseMod = config => {
// Append a rule to supply strings.xml data to mods on `mods.android.strings`
return core_plugins_1.withInterceptedMod(config, {
platform: 'android',
mod: 'strings',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
const filePath = await Strings_1.getProjectStringsXMLPathAsync(modRequest.projectRoot);
let modResults = await Resources_1.readResourcesXMLAsync({ path: filePath });
results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
modResults = results.modResults;
await XML_1.writeXMLAsync({ path: filePath, xml: modResults });
}
catch (error) {
console.error(`strings.xml mod error:`);
throw error;
}
return results;
},
});
};
const withAndroidProjectBuildGradleBaseMod = config => {
return core_plugins_1.withInterceptedMod(config, {
platform: 'android',
mod: 'projectBuildGradle',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
let modResults = await AndroidPaths.getProjectBuildGradleAsync(modRequest.projectRoot);
// Currently don't support changing the path or language
const filePath = modResults.path;
results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
modResults = results.modResults;
await fs_extra_1.writeFile(filePath, modResults.contents);
}
catch (error) {
console.error(`android/build.gradle mod error:`);
throw error;
}
return results;
},
});
};
const withAndroidSettingsGradleBaseMod = config => {
return core_plugins_1.withInterceptedMod(config, {
platform: 'android',
mod: 'settingsGradle',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
let modResults = await AndroidPaths.getSettingsGradleAsync(modRequest.projectRoot);
// Currently don't support changing the path or language
const filePath = modResults.path;
results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
modResults = results.modResults;
await fs_extra_1.writeFile(filePath, modResults.contents);
}
catch (error) {
console.error(`android/settings.gradle mod error:`);
throw error;
}
return results;
},
});
};
const withAndroidAppBuildGradleBaseMod = config => {
return core_plugins_1.withInterceptedMod(config, {
platform: 'android',
mod: 'appBuildGradle',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
let modResults = await AndroidPaths.getAppBuildGradleAsync(modRequest.projectRoot);
// Currently don't support changing the path or language
const filePath = modResults.path;
results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
modResults = results.modResults;
await fs_extra_1.writeFile(filePath, modResults.contents);
}
catch (error) {
console.error(`android/app/build.gradle mod error:`);
throw error;
}
return results;
},
});
};
const withAndroidMainActivityBaseMod = config => {
return core_plugins_1.withInterceptedMod(config, {
platform: 'android',
mod: 'mainActivity',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
let modResults = await AndroidPaths.getMainActivityAsync(modRequest.projectRoot);
// Currently don't support changing the path or language
const filePath = modResults.path;
results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
modResults = results.modResults;
await fs_extra_1.writeFile(filePath, modResults.contents);
}
catch (error) {
console.error(`MainActivity mod error:`);
throw error;
}
return results;
},
});
};
function applyIOSBaseMods(config) {
config = withExpoDangerousBaseMod(config, 'ios');
config = withAppDelegateBaseMod(config);
config = withIosInfoPlistBaseMod(config);
config = withExpoPlistBaseMod(config);
config = withXcodeProjectBaseMod(config);
config = withEntitlementsBaseMod(config);
return config;
}
const withExpoDangerousBaseMod = (config, platform) => {
// Used for scheduling when dangerous mods run.
return core_plugins_1.withInterceptedMod(config, {
platform,
mod: 'dangerous',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
const results = await nextMod(Object.assign(Object.assign({}, config), { modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
return results;
},
});
};
const withAppDelegateBaseMod = config => {
return core_plugins_1.withInterceptedMod(config, {
platform: 'ios',
mod: 'appDelegate',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
let modResults = Paths_1.getAppDelegate(modRequest.projectRoot);
// Currently don't support changing the path or language
const filePath = modResults.path;
results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
modResults = results.modResults;
await fs_extra_1.writeFile(filePath, modResults.contents);
}
catch (error) {
console.error(`AppDelegate mod error:`);
throw error;
}
return results;
},
});
};
const withExpoPlistBaseMod = config => {
// Append a rule to supply Expo.plist data to mods on `mods.ios.expoPlist`
return core_plugins_1.withInterceptedMod(config, {
platform: 'ios',
mod: 'expoPlist',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
const supportingDirectory = path_1.default.join(modRequest.platformProjectRoot, modRequest.projectName, 'Supporting');
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
const filePath = path_1.default.resolve(supportingDirectory, 'Expo.plist');
let modResults = plist_1.default.parse(await fs_extra_1.readFile(filePath, 'utf8'));
// TODO: Fix type
results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
modResults = results.modResults;
await fs_extra_1.writeFile(filePath, plist_1.default.build(modResults));
}
catch (error) {
WarningAggregator.addWarningIOS('updates', 'Expo.plist configuration could not be applied. You will need to create Expo.plist if it does not exist and add Updates configuration manually.', 'https://docs.expo.io/bare/updating-your-app/#configuration-options');
}
return results;
},
});
};
const withXcodeProjectBaseMod = config => {
// Append a rule to supply .xcodeproj data to mods on `mods.ios.xcodeproj`
return core_plugins_1.withInterceptedMod(config, {
platform: 'ios',
mod: 'xcodeproj',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
const modResults = Xcodeproj_1.getPbxproj(modRequest.projectRoot);
// TODO: Fix type
const results = await nextMod(Object.assign(Object.assign({}, config), { modResults,
modRequest }));
resolveModResults(results, modRequest.platform, modRequest.modName);
const resultData = results.modResults;
await fs_extra_1.writeFile(resultData.filepath, resultData.writeSync());
return results;
},
});
};
const withIosInfoPlistBaseMod = config => {
// Append a rule to supply Info.plist data to mods on `mods.ios.infoPlist`
return core_plugins_1.withInterceptedMod(config, {
platform: 'ios',
mod: 'infoPlist',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
const filePath = Paths_1.getInfoPlistPath(modRequest.projectRoot);
let results = Object.assign(Object.assign({}, config), { modRequest });
// Apply all of the Info.plist values to the expo.ios.infoPlist object
// TODO: Remove this in favor of just overwriting the Info.plist with the Expo object. This will enable people to actually remove values.
if (!config.ios) {
config.ios = {};
}
if (!config.ios.infoPlist) {
config.ios.infoPlist = {};
}
const contents = await fs_extra_1.readFile(filePath, 'utf8');
errors_1.assert(contents, 'Info.plist is empty');
let data = plist_1.default.parse(contents);
config.ios.infoPlist = Object.assign(Object.assign({}, (data || {})), config.ios.infoPlist);
// TODO: Fix type
results = await nextMod(Object.assign(Object.assign({}, config), { modRequest, modResults: config.ios.infoPlist }));
resolveModResults(results, modRequest.platform, modRequest.modName);
data = results.modResults;
await fs_extra_1.writeFile(filePath, plist_1.default.build(data));
return results;
},
});
};
const withEntitlementsBaseMod = config => {
// Append a rule to supply .entitlements data to mods on `mods.ios.entitlements`
return core_plugins_1.withInterceptedMod(config, {
platform: 'ios',
mod: 'entitlements',
skipEmptyMod: true,
async action(_a) {
var _b = _a.modRequest, { nextMod } = _b, modRequest = __rest(_b, ["nextMod"]), config = __rest(_a, ["modRequest"]);
const entitlementsPath = Entitlements_1.getEntitlementsPath(modRequest.projectRoot);
let results = Object.assign(Object.assign({}, config), { modRequest });
try {
const data = plist_1.default.parse(await fs_extra_1.readFile(entitlementsPath, 'utf8'));
// Apply all of the .entitlements values to the expo.ios.entitlements object
// TODO: Remove this in favor of just overwriting the .entitlements with the Expo object. This will enable people to actually remove values.
if (!config.ios) {
config.ios = {};
}
if (!config.ios.entitlements) {
config.ios.entitlements = {};
}
config.ios.entitlements = Object.assign(Object.assign({}, (data || {})), config.ios.entitlements);
// TODO: Fix type
results = await nextMod(Object.assign(Object.assign({}, config), { modRequest, modResults: config.ios.entitlements }));
resolveModResults(results, modRequest.platform, modRequest.modName);
await fs_extra_1.writeFile(entitlementsPath, plist_1.default.build(results.modResults));
}
catch (error) {
console.error(`${path_1.default.basename(entitlementsPath)} mod error:`);
throw error;
}
return results;
},
});
};
//# sourceMappingURL=compiler-plugins.js.map