You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
8.6 KiB
298 lines
8.6 KiB
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.getBundleIdentifier = getBundleIdentifier;
|
|
exports.getBundleIdentifierFromPbxproj = getBundleIdentifierFromPbxproj;
|
|
exports.resetAllPlistBundleIdentifiers = resetAllPlistBundleIdentifiers;
|
|
exports.resetPlistBundleIdentifier = resetPlistBundleIdentifier;
|
|
exports.setBundleIdentifier = setBundleIdentifier;
|
|
exports.setBundleIdentifierForPbxproj = setBundleIdentifierForPbxproj;
|
|
exports.updateBundleIdentifierForPbxproj = updateBundleIdentifierForPbxproj;
|
|
exports.withBundleIdentifier = void 0;
|
|
|
|
function _plist() {
|
|
const data = _interopRequireDefault(require("@expo/plist"));
|
|
|
|
_plist = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _assert() {
|
|
const data = _interopRequireDefault(require("assert"));
|
|
|
|
_assert = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _fs() {
|
|
const data = _interopRequireDefault(require("fs"));
|
|
|
|
_fs = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _xcode() {
|
|
const data = _interopRequireDefault(require("xcode"));
|
|
|
|
_xcode = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _withDangerousMod() {
|
|
const data = require("../plugins/withDangerousMod");
|
|
|
|
_withDangerousMod = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _Paths() {
|
|
const data = require("./Paths");
|
|
|
|
_Paths = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _Target() {
|
|
const data = require("./Target");
|
|
|
|
_Target = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _Xcodeproj() {
|
|
const data = require("./utils/Xcodeproj");
|
|
|
|
_Xcodeproj = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _string() {
|
|
const data = require("./utils/string");
|
|
|
|
_string = function () {
|
|
return data;
|
|
};
|
|
|
|
return data;
|
|
}
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
const withBundleIdentifier = (config, {
|
|
bundleIdentifier
|
|
}) => {
|
|
return (0, _withDangerousMod().withDangerousMod)(config, ['ios', async config => {
|
|
var _config$ios;
|
|
|
|
const bundleId = bundleIdentifier !== null && bundleIdentifier !== void 0 ? bundleIdentifier : (_config$ios = config.ios) === null || _config$ios === void 0 ? void 0 : _config$ios.bundleIdentifier;
|
|
(0, _assert().default)(bundleId, '`bundleIdentifier` must be defined in the app config (`expo.ios.bundleIdentifier`) or passed to the plugin `withBundleIdentifier`.');
|
|
await setBundleIdentifierForPbxproj(config.modRequest.projectRoot, bundleId);
|
|
return config;
|
|
}]);
|
|
};
|
|
|
|
exports.withBundleIdentifier = withBundleIdentifier;
|
|
|
|
function getBundleIdentifier(config) {
|
|
var _config$ios$bundleIde, _config$ios2;
|
|
|
|
return (_config$ios$bundleIde = (_config$ios2 = config.ios) === null || _config$ios2 === void 0 ? void 0 : _config$ios2.bundleIdentifier) !== null && _config$ios$bundleIde !== void 0 ? _config$ios$bundleIde : null;
|
|
}
|
|
/**
|
|
* In Turtle v1 we set the bundleIdentifier directly on Info.plist rather
|
|
* than in pbxproj
|
|
*/
|
|
|
|
|
|
function setBundleIdentifier(config, infoPlist) {
|
|
const bundleIdentifier = getBundleIdentifier(config);
|
|
|
|
if (!bundleIdentifier) {
|
|
return infoPlist;
|
|
}
|
|
|
|
return { ...infoPlist,
|
|
CFBundleIdentifier: bundleIdentifier
|
|
};
|
|
}
|
|
/**
|
|
* Gets the bundle identifier defined in the Xcode project found in the project directory.
|
|
*
|
|
* A bundle identifier is stored as a value in XCBuildConfiguration entry.
|
|
* Those entries exist for every pair (build target, build configuration).
|
|
* Unless target name is passed, the first target defined in the pbxproj is used
|
|
* (to keep compatibility with the inaccurate legacy implementation of this function).
|
|
* The build configuration is usually 'Release' or 'Debug'. However, it could be any arbitrary string.
|
|
* Defaults to 'Release'.
|
|
*
|
|
* @param {string} projectRoot Path to project root containing the ios directory
|
|
* @param {string} targetName Target name
|
|
* @param {string} buildConfiguration Build configuration. Defaults to 'Release'.
|
|
* @returns {string | null} bundle identifier of the Xcode project or null if the project is not configured
|
|
*/
|
|
|
|
|
|
function getBundleIdentifierFromPbxproj(projectRoot, {
|
|
targetName,
|
|
buildConfiguration = 'Release'
|
|
} = {}) {
|
|
let pbxprojPath;
|
|
|
|
try {
|
|
pbxprojPath = (0, _Paths().getPBXProjectPath)(projectRoot);
|
|
} catch {
|
|
return null;
|
|
}
|
|
|
|
const project = _xcode().default.project(pbxprojPath);
|
|
|
|
project.parseSync();
|
|
const xcBuildConfiguration = (0, _Target().getXCBuildConfigurationFromPbxproj)(project, {
|
|
targetName,
|
|
buildConfiguration
|
|
});
|
|
|
|
if (!xcBuildConfiguration) {
|
|
return null;
|
|
}
|
|
|
|
return getProductBundleIdentifierFromBuildConfiguration(xcBuildConfiguration);
|
|
}
|
|
|
|
function getProductBundleIdentifierFromBuildConfiguration(xcBuildConfiguration) {
|
|
const bundleIdentifierRaw = xcBuildConfiguration.buildSettings.PRODUCT_BUNDLE_IDENTIFIER;
|
|
|
|
if (bundleIdentifierRaw) {
|
|
const bundleIdentifier = (0, _string().trimQuotes)(bundleIdentifierRaw); // it's possible to use interpolation for the bundle identifier
|
|
// the most common case is when the last part of the id is set to `$(PRODUCT_NAME:rfc1034identifier)`
|
|
// in this case, PRODUCT_NAME should be replaced with its value
|
|
// the `rfc1034identifier` modifier replaces all non-alphanumeric characters with dashes
|
|
|
|
const bundleIdentifierParts = bundleIdentifier.split('.');
|
|
|
|
if (bundleIdentifierParts[bundleIdentifierParts.length - 1] === '$(PRODUCT_NAME:rfc1034identifier)' && xcBuildConfiguration.buildSettings.PRODUCT_NAME) {
|
|
bundleIdentifierParts[bundleIdentifierParts.length - 1] = xcBuildConfiguration.buildSettings.PRODUCT_NAME.replace(/[^a-zA-Z0-9]/g, '-');
|
|
}
|
|
|
|
return bundleIdentifierParts.join('.');
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
/**
|
|
* Updates the bundle identifier for a given pbxproj
|
|
*
|
|
* @param {string} pbxprojPath Path to pbxproj file
|
|
* @param {string} bundleIdentifier Bundle identifier to set in the pbxproj
|
|
* @param {boolean} [updateProductName=true] Whether to update PRODUCT_NAME
|
|
*/
|
|
|
|
|
|
function updateBundleIdentifierForPbxproj(pbxprojPath, bundleIdentifier, updateProductName = true) {
|
|
const project = _xcode().default.project(pbxprojPath);
|
|
|
|
project.parseSync();
|
|
const [, nativeTarget] = (0, _Target().findFirstNativeTarget)(project);
|
|
(0, _Xcodeproj().getBuildConfigurationsForListId)(project, nativeTarget.buildConfigurationList).forEach(([, item]) => {
|
|
if (item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER === bundleIdentifier) {
|
|
return;
|
|
}
|
|
|
|
item.buildSettings.PRODUCT_BUNDLE_IDENTIFIER = `"${bundleIdentifier}"`;
|
|
|
|
if (updateProductName) {
|
|
const productName = bundleIdentifier.split('.').pop();
|
|
|
|
if (!(productName !== null && productName !== void 0 && productName.includes('$'))) {
|
|
item.buildSettings.PRODUCT_NAME = productName;
|
|
}
|
|
}
|
|
});
|
|
|
|
_fs().default.writeFileSync(pbxprojPath, project.writeSync());
|
|
}
|
|
/**
|
|
* Updates the bundle identifier for pbx projects inside the ios directory of the given project root
|
|
*
|
|
* @param {string} projectRoot Path to project root containing the ios directory
|
|
* @param {string} bundleIdentifier Desired bundle identifier
|
|
* @param {boolean} [updateProductName=true] Whether to update PRODUCT_NAME
|
|
*/
|
|
|
|
|
|
function setBundleIdentifierForPbxproj(projectRoot, bundleIdentifier, updateProductName = true) {
|
|
// Get all pbx projects in the ${projectRoot}/ios directory
|
|
let pbxprojPaths = [];
|
|
|
|
try {
|
|
pbxprojPaths = (0, _Paths().getAllPBXProjectPaths)(projectRoot);
|
|
} catch {}
|
|
|
|
for (const pbxprojPath of pbxprojPaths) {
|
|
updateBundleIdentifierForPbxproj(pbxprojPath, bundleIdentifier, updateProductName);
|
|
}
|
|
}
|
|
/**
|
|
* Reset bundle identifier field in Info.plist to use PRODUCT_BUNDLE_IDENTIFIER, as recommended by Apple.
|
|
*/
|
|
|
|
|
|
const defaultBundleId = '$(PRODUCT_BUNDLE_IDENTIFIER)';
|
|
|
|
function resetAllPlistBundleIdentifiers(projectRoot) {
|
|
const infoPlistPaths = (0, _Paths().getAllInfoPlistPaths)(projectRoot);
|
|
|
|
for (const plistPath of infoPlistPaths) {
|
|
resetPlistBundleIdentifier(plistPath);
|
|
}
|
|
}
|
|
|
|
function resetPlistBundleIdentifier(plistPath) {
|
|
const rawPlist = _fs().default.readFileSync(plistPath, 'utf8');
|
|
|
|
const plistObject = _plist().default.parse(rawPlist);
|
|
|
|
if (plistObject.CFBundleIdentifier) {
|
|
if (plistObject.CFBundleIdentifier === defaultBundleId) return; // attempt to match default Info.plist format
|
|
|
|
const format = {
|
|
pretty: true,
|
|
indent: `\t`
|
|
};
|
|
|
|
const xml = _plist().default.build({ ...plistObject,
|
|
CFBundleIdentifier: defaultBundleId
|
|
}, format);
|
|
|
|
if (xml !== rawPlist) {
|
|
_fs().default.writeFileSync(plistPath, xml);
|
|
}
|
|
}
|
|
}
|
|
//# sourceMappingURL=BundleIdentifier.js.map
|