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.
575 lines
22 KiB
575 lines
22 KiB
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.actionAsync = actionAsync;
|
|
function _config() {
|
|
const data = require("@expo/config");
|
|
_config = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _configPlugins() {
|
|
const data = require("@expo/config-plugins");
|
|
_configPlugins = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _plist() {
|
|
const data = _interopRequireDefault(require("@expo/plist"));
|
|
_plist = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _spawnAsync() {
|
|
const data = _interopRequireDefault(require("@expo/spawn-async"));
|
|
_spawnAsync = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _chalk() {
|
|
const data = _interopRequireDefault(require("chalk"));
|
|
_chalk = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _commander() {
|
|
const data = _interopRequireDefault(require("commander"));
|
|
_commander = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _fsExtra() {
|
|
const data = _interopRequireDefault(require("fs-extra"));
|
|
_fsExtra = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _npmPackageArg() {
|
|
const data = _interopRequireDefault(require("npm-package-arg"));
|
|
_npmPackageArg = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _path() {
|
|
const data = _interopRequireDefault(require("path"));
|
|
_path = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _stripAnsi() {
|
|
const data = _interopRequireDefault(require("strip-ansi"));
|
|
_stripAnsi = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _terminalLink() {
|
|
const data = _interopRequireDefault(require("terminal-link"));
|
|
_terminalLink = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _xdl() {
|
|
const data = require("xdl");
|
|
_xdl = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _CommandError() {
|
|
const data = _interopRequireWildcard(require("../CommandError"));
|
|
_CommandError = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _log() {
|
|
const data = _interopRequireDefault(require("../log"));
|
|
_log = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _migration() {
|
|
const data = require("../utils/migration");
|
|
_migration = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _ora() {
|
|
const data = require("../utils/ora");
|
|
_ora = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _prompts() {
|
|
const data = _interopRequireWildcard(require("../utils/prompts"));
|
|
_prompts = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _clearNativeFolder() {
|
|
const data = require("./eject/clearNativeFolder");
|
|
_clearNativeFolder = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function CreateApp() {
|
|
const data = _interopRequireWildcard(require("./utils/CreateApp"));
|
|
CreateApp = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _ProjectUtils() {
|
|
const data = require("./utils/ProjectUtils");
|
|
_ProjectUtils = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _extractTemplateAppAsync() {
|
|
const data = require("./utils/extractTemplateAppAsync");
|
|
_extractTemplateAppAsync = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
const FEATURED_TEMPLATES = ['----- Managed workflow -----', {
|
|
shortName: 'blank',
|
|
name: 'expo-template-blank',
|
|
description: 'a minimal app as clean as an empty canvas'
|
|
}, {
|
|
shortName: 'blank (TypeScript)',
|
|
name: 'expo-template-blank-typescript',
|
|
description: 'same as blank but with TypeScript configuration'
|
|
}, {
|
|
shortName: 'tabs (TypeScript)',
|
|
name: 'expo-template-tabs',
|
|
description: 'several example screens and tabs using react-navigation and TypeScript'
|
|
}, '----- Bare workflow -----', {
|
|
shortName: 'minimal',
|
|
name: 'expo-template-bare-minimum',
|
|
description: 'bare and minimal, just the essentials to get you started'
|
|
}];
|
|
const isMacOS = process.platform === 'darwin';
|
|
function assertValidName(folderName) {
|
|
const validation = CreateApp().validateName(folderName);
|
|
if (typeof validation === 'string') {
|
|
throw new (_CommandError().default)(`Cannot create an app named ${_chalk().default.red(`"${folderName}"`)}. ${validation}`);
|
|
}
|
|
const isFolderNameForbidden = CreateApp().isFolderNameForbidden(folderName);
|
|
if (isFolderNameForbidden) {
|
|
throw new (_CommandError().default)(`Cannot create an app named ${_chalk().default.red(`"${folderName}"`)} because it would conflict with a dependency of the same name.`);
|
|
}
|
|
}
|
|
function parseOptions(command) {
|
|
return {
|
|
yes: !!command.yes,
|
|
yarn: !!command.yarn,
|
|
npm: !!command.npm,
|
|
install: !!command.install,
|
|
template: command.template
|
|
};
|
|
}
|
|
async function assertFolderEmptyAsync(projectRoot, folderName) {
|
|
if (!(await CreateApp().assertFolderEmptyAsync({
|
|
projectRoot,
|
|
folderName,
|
|
overwrite: false
|
|
}))) {
|
|
const message = 'Try using a new directory name, or moving these files.';
|
|
_log().default.newLine();
|
|
_log().default.nested(message);
|
|
_log().default.newLine();
|
|
throw new (_CommandError().SilentError)(message);
|
|
}
|
|
}
|
|
async function resolveProjectRootAsync(input) {
|
|
let name = input === null || input === void 0 ? void 0 : input.trim();
|
|
if (!name) {
|
|
try {
|
|
const {
|
|
answer
|
|
} = await (0, _prompts().default)({
|
|
type: 'text',
|
|
name: 'answer',
|
|
message: 'What would you like to name your app?',
|
|
initial: 'my-app',
|
|
validate: name => {
|
|
const validation = CreateApp().validateName(_path().default.basename(_path().default.resolve(name)));
|
|
if (typeof validation === 'string') {
|
|
return 'Invalid project name: ' + validation;
|
|
}
|
|
return true;
|
|
}
|
|
}, {
|
|
nonInteractiveHelp: 'Pass the project name using the first argument `expo init <name>`'
|
|
});
|
|
if (typeof answer === 'string') {
|
|
name = answer.trim();
|
|
}
|
|
} catch (error) {
|
|
// Handle the aborted message in a custom way.
|
|
if (error.code !== 'ABORTED') {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
if (!name) {
|
|
const message = ['', 'Please choose your app name:', ` ${_chalk().default.green(`${_commander().default.name()} init`)} ${_chalk().default.cyan('<app-name>')}`, '', `Run ${_chalk().default.green(`${_commander().default.name()} init --help`)} for more info`, ''].join('\n');
|
|
_log().default.nested(message);
|
|
throw new (_CommandError().SilentError)(message);
|
|
}
|
|
const projectRoot = _path().default.resolve(name);
|
|
const folderName = _path().default.basename(projectRoot);
|
|
assertValidName(folderName);
|
|
await _fsExtra().default.ensureDir(projectRoot);
|
|
await assertFolderEmptyAsync(projectRoot, folderName);
|
|
return projectRoot;
|
|
}
|
|
function padEnd(str, width) {
|
|
// Pulled from commander for overriding
|
|
const len = Math.max(0, width - (0, _stripAnsi().default)(str).length);
|
|
return str + Array(len + 1).join(' ');
|
|
}
|
|
async function resolveTemplateAsync(resolvedTemplate) {
|
|
const {
|
|
version: newestSdkVersion,
|
|
data: newestSdkReleaseData
|
|
} = await _xdl().Versions.newestReleasedSdkVersionAsync();
|
|
|
|
// If the user is opting into a beta then we need to append the template tag explicitly
|
|
// in order to not fall back to the latest tag for templates.
|
|
let versionParam = '';
|
|
if (newestSdkReleaseData !== null && newestSdkReleaseData !== void 0 && newestSdkReleaseData.beta) {
|
|
const majorVersion = parseInt(newestSdkVersion, 10);
|
|
versionParam = `@sdk-${majorVersion}`;
|
|
|
|
// If the --template flag is provided without an explicit version, then opt-in to
|
|
// the beta version
|
|
if (resolvedTemplate && !resolvedTemplate.includes('@')) {
|
|
resolvedTemplate = `${resolvedTemplate}${versionParam}`;
|
|
}
|
|
}
|
|
let templateSpec;
|
|
if (resolvedTemplate) {
|
|
var _templateSpec$name, _templateSpec$fetchSp;
|
|
templateSpec = (0, _npmPackageArg().default)(resolvedTemplate);
|
|
|
|
// For backwards compatibility, 'blank' and 'tabs' are aliases for
|
|
// 'expo-template-blank' and 'expo-template-tabs', respectively.
|
|
if (templateSpec.name && templateSpec.registry && ['blank', 'tabs', 'bare-minimum'].includes(templateSpec.name)) {
|
|
templateSpec.escapedName = `expo-template-${templateSpec.name}`;
|
|
templateSpec.name = templateSpec.escapedName;
|
|
templateSpec.raw = templateSpec.escapedName;
|
|
}
|
|
return `${(_templateSpec$name = templateSpec.name) !== null && _templateSpec$name !== void 0 ? _templateSpec$name : templateSpec.raw}@${(_templateSpec$fetchSp = templateSpec.fetchSpec) !== null && _templateSpec$fetchSp !== void 0 ? _templateSpec$fetchSp : 'latest'}`;
|
|
}
|
|
const descriptionColumn = Math.max(...FEATURED_TEMPLATES.map(t => typeof t === 'object' ? t.shortName.length : 0)) + 2;
|
|
const template = await (0, _prompts().selectAsync)({
|
|
message: 'Choose a template:',
|
|
optionsPerPage: 20,
|
|
choices: FEATURED_TEMPLATES.map(template => {
|
|
if (typeof template === 'string') {
|
|
return _prompts().default.separator(template);
|
|
} else {
|
|
return {
|
|
value: template.name,
|
|
title: _chalk().default.bold(padEnd(template.shortName, descriptionColumn)) + template.description.trim(),
|
|
short: template.name
|
|
};
|
|
}
|
|
})
|
|
}, {
|
|
nonInteractiveHelp: '--template: argument is required in non-interactive mode. Valid choices are: "blank", "tabs", "bare-minimum" or any custom template (name of npm package).'
|
|
});
|
|
return `${template}${versionParam}`;
|
|
}
|
|
async function actionAsync(incomingProjectRoot, command) {
|
|
var _options$template;
|
|
(0, _migration().warnMigration)('npx create-expo-app --template');
|
|
const options = parseOptions(command);
|
|
const deprecatedNameArgument = typeof command.name === 'string' ? command.name : undefined;
|
|
if (deprecatedNameArgument) {
|
|
// Commander doesn't support using the `--name` argument so it shouldn't have been implemented in the first place.
|
|
// Using `--name` will cause other parts of commander to break since it expects a function and `this.name` would be a string.
|
|
|
|
_log().default.error((0, _chalk().default)`Deprecated: Use {bold expo init [name]} instead of {bold --name [name]}.`);
|
|
throw new (_CommandError().AbortCommandError)();
|
|
}
|
|
|
|
// Resolve the name, and projectRoot
|
|
let projectRoot;
|
|
if (!incomingProjectRoot && options.yes) {
|
|
projectRoot = _path().default.resolve(process.cwd());
|
|
const folderName = _path().default.basename(projectRoot);
|
|
assertValidName(folderName);
|
|
await assertFolderEmptyAsync(projectRoot, folderName);
|
|
} else {
|
|
projectRoot = await resolveProjectRootAsync(incomingProjectRoot);
|
|
}
|
|
let resolvedTemplate = (_options$template = options.template) !== null && _options$template !== void 0 ? _options$template : null;
|
|
// @ts-ignore: This guards against someone passing --template without a name after it.
|
|
if (resolvedTemplate === true) {
|
|
throw new (_CommandError().default)('Please specify the template name');
|
|
}
|
|
|
|
// Download and sync templates
|
|
// TODO(Bacon): revisit
|
|
if (options.yes && !resolvedTemplate) {
|
|
resolvedTemplate = 'blank';
|
|
}
|
|
|
|
// Supported templates:
|
|
// `-t tabs` (tabs, blank, bare-minimum, expo-template-blank-typescript)
|
|
// `-t tabs@40`
|
|
// `-t tabs@sdk-40`
|
|
// `-t tabs@latest`
|
|
// `-t expo-template-tabs@latest`
|
|
const npmPackageName = await resolveTemplateAsync(resolvedTemplate);
|
|
_log().default.debug(`Using template: ${npmPackageName}`);
|
|
const projectName = _path().default.basename(projectRoot);
|
|
const initialConfig = {
|
|
// In older templates the `.name` property is set when extracting template files. This is because older templates have the `.name` property set to `HelloWorld`.
|
|
// Newer templates don't need the `.name` property set, so we don't bother with setting it.
|
|
expo: {
|
|
name: projectName,
|
|
slug: projectName
|
|
}
|
|
};
|
|
const extractTemplateStep = (0, _ora().logNewSection)('Downloading template.');
|
|
let projectPath;
|
|
try {
|
|
projectPath = await (0, _extractTemplateAppAsync().extractAndPrepareTemplateAppAsync)(npmPackageName, projectRoot, initialConfig);
|
|
extractTemplateStep.succeed('Downloaded template.');
|
|
} catch (e) {
|
|
extractTemplateStep.fail('Something went wrong while downloading and extracting the template.');
|
|
throw e;
|
|
}
|
|
|
|
// Install dependencies
|
|
|
|
const packageManager = CreateApp().resolvePackageManager(options);
|
|
|
|
// TODO(Bacon): not this
|
|
const isBare = await (0, _clearNativeFolder().directoryExistsAsync)(_path().default.join(projectRoot, 'ios'));
|
|
const workflow = isBare ? 'bare' : 'managed';
|
|
let hasPodsInstalled = false;
|
|
const needsPodsInstalled = _fsExtra().default.existsSync(_path().default.join(projectRoot, 'ios/Podfile'));
|
|
if (options.install) {
|
|
await installNodeDependenciesAsync(projectRoot, packageManager);
|
|
if (needsPodsInstalled) {
|
|
hasPodsInstalled = await CreateApp().installCocoaPodsAsync(projectRoot);
|
|
}
|
|
}
|
|
const cdPath = CreateApp().getChangeDirectoryPath(projectRoot);
|
|
|
|
// Log info
|
|
|
|
_log().default.addNewLineIfNone();
|
|
await logProjectReadyAsync(projectRoot, {
|
|
cdPath,
|
|
packageManager,
|
|
workflow
|
|
});
|
|
|
|
// Log a warning about needing to install node modules
|
|
if (!options.install) {
|
|
logNodeInstallWarning(cdPath, packageManager);
|
|
}
|
|
if (needsPodsInstalled && !hasPodsInstalled) {
|
|
logCocoaPodsWarning(cdPath);
|
|
}
|
|
|
|
// Initialize Git at the end to ensure all lock files are committed.
|
|
await initGitRepoAsync(projectPath);
|
|
}
|
|
async function installNodeDependenciesAsync(projectRoot, packageManager) {
|
|
const installJsDepsStep = (0, _ora().logNewSection)('Installing JavaScript dependencies.');
|
|
try {
|
|
await CreateApp().installNodeDependenciesAsync(projectRoot, packageManager);
|
|
installJsDepsStep.succeed('Installed JavaScript dependencies.');
|
|
} catch {
|
|
installJsDepsStep.fail(`Something went wrong installing JavaScript dependencies. Check your ${packageManager} logs. Continuing to initialize the app.`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if the project is inside an existing Git repo, if so bail out,
|
|
* if not then create a new git repo and commit the initial files.
|
|
*
|
|
* @returns `true` if git is setup.
|
|
*/
|
|
async function initGitRepoAsync(root) {
|
|
// let's see if we're in a git tree
|
|
try {
|
|
await (0, _spawnAsync().default)('git', ['rev-parse', '--is-inside-work-tree'], {
|
|
cwd: root
|
|
});
|
|
// Log a light notice if we're in a git tree.
|
|
_log().default.log(_chalk().default.gray(`Project is already inside of a git repo, skipping ${_chalk().default.bold`git init`}.`));
|
|
// Bail out if inside git repo, this makes monorepos a bit easier to setup.
|
|
return true;
|
|
} catch (e) {
|
|
if (e.errno === 'ENOENT') {
|
|
_log().default.warn('Unable to initialize git repo. `git` not in PATH.');
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// not in git tree, so let's init
|
|
try {
|
|
await (0, _spawnAsync().default)('git', ['init'], {
|
|
cwd: root
|
|
});
|
|
_log().default.debug('Initialized a git repository.');
|
|
await (0, _spawnAsync().default)('git', ['add', '--all'], {
|
|
cwd: root,
|
|
stdio: 'ignore'
|
|
});
|
|
await (0, _spawnAsync().default)('git', ['commit', '-m', 'Created a new Expo app'], {
|
|
cwd: root,
|
|
stdio: 'ignore'
|
|
});
|
|
return true;
|
|
} catch (e) {
|
|
_log().default.debug('git error:', e);
|
|
// no-op -- this is just a convenience and we don't care if it fails
|
|
return false;
|
|
}
|
|
}
|
|
function logNodeInstallWarning(cdPath, packageManager) {
|
|
_log().default.newLine();
|
|
_log().default.nested(`⚠️ Before running your app, make sure you have node modules installed:`);
|
|
_log().default.nested('');
|
|
if (cdPath) {
|
|
// In the case of --yes the project can be created in place so there would be no need to change directories.
|
|
_log().default.nested(` cd ${cdPath}/`);
|
|
}
|
|
_log().default.nested(` ${packageManager === 'npm' ? 'npm install' : 'yarn'}`);
|
|
_log().default.nested('');
|
|
}
|
|
function logCocoaPodsWarning(cdPath) {
|
|
if (process.platform !== 'darwin') {
|
|
return;
|
|
}
|
|
_log().default.newLine();
|
|
_log().default.nested(`⚠️ Before running your app on iOS, make sure you have CocoaPods installed and initialize the project:`);
|
|
_log().default.nested('');
|
|
if (cdPath) {
|
|
// In the case of --yes the project can be created in place so there would be no need to change directories.
|
|
_log().default.nested(` cd ${cdPath}/`);
|
|
}
|
|
_log().default.nested(` npx pod-install`);
|
|
_log().default.nested('');
|
|
}
|
|
async function logProjectReadyAsync(projectRoot, {
|
|
cdPath,
|
|
packageManager,
|
|
workflow
|
|
}) {
|
|
_log().default.nested(_chalk().default.bold(`✅ Your project is ready!`));
|
|
_log().default.newLine();
|
|
|
|
// empty string if project was created in current directory
|
|
if (cdPath) {
|
|
_log().default.nested(`To run your project, navigate to the directory and run one of the following ${packageManager} commands.`);
|
|
_log().default.newLine();
|
|
_log().default.nested(`- ${_chalk().default.bold('cd ' + cdPath)}`);
|
|
} else {
|
|
_log().default.nested(`To run your project, run one of the following ${packageManager} commands.`);
|
|
_log().default.newLine();
|
|
}
|
|
if (workflow === 'managed') {
|
|
_log().default.nested(`- ${_chalk().default.bold(`${packageManager} start`)} ${_chalk().default.dim(`# you can open iOS, Android, or web from here, or run them directly with the commands below.`)}`);
|
|
}
|
|
_log().default.nested(`- ${_chalk().default.bold(packageManager === 'npm' ? 'npm run android' : 'yarn android')}`);
|
|
let macOSComment = '';
|
|
if (!isMacOS && workflow === 'bare') {
|
|
macOSComment = ' # you need to use macOS to build the iOS project - use managed workflow if you need to do iOS development without a Mac';
|
|
} else if (!isMacOS && workflow === 'managed') {
|
|
macOSComment = ' # requires an iOS device or macOS for access to an iOS simulator';
|
|
}
|
|
_log().default.nested(`- ${_chalk().default.bold(packageManager === 'npm' ? 'npm run ios' : 'yarn ios')}${macOSComment}`);
|
|
_log().default.nested(`- ${_chalk().default.bold(packageManager === 'npm' ? 'npm run web' : 'yarn web')}`);
|
|
if (workflow === 'bare') {
|
|
_log().default.newLine();
|
|
_log().default.nested(`💡 You can also open up the projects in the ${_chalk().default.bold('ios')} and ${_chalk().default.bold('android')} directories with their respective IDEs.`);
|
|
await addBareUpdatesWarningsAsync(projectRoot);
|
|
|
|
// TODO: add equivalent of this or some command to wrap it:
|
|
// # ios
|
|
// $ open -a Xcode ./ios/{PROJECT_NAME}.xcworkspace
|
|
// # android
|
|
// $ open -a /Applications/Android\\ Studio.app ./android
|
|
}
|
|
}
|
|
|
|
async function addBareUpdatesWarningsAsync(projectRoot) {
|
|
if (!(await (0, _ProjectUtils().hasExpoUpdatesInstalledAsync)(projectRoot))) {
|
|
return;
|
|
}
|
|
if (await (0, _ProjectUtils().usesOldExpoUpdatesAsync)(projectRoot)) {
|
|
_log().default.nested(`🚀 ${(0, _terminalLink().default)('expo-updates', 'https://github.com/expo/expo/blob/main/packages/expo-updates/README.md')} has been configured in your project. Before you do a release build, make sure you run ${_chalk().default.bold('expo publish')}. ${(0, _terminalLink().default)('Learn more.', 'https://expo.fyi/release-builds-with-expo-updates')}`);
|
|
return;
|
|
}
|
|
let didConfigureUpdatesProjectFiles = false;
|
|
const username = await _xdl().UserManager.getCurrentUsernameAsync();
|
|
if (username) {
|
|
try {
|
|
await configureUpdatesProjectFilesAsync(projectRoot, username);
|
|
didConfigureUpdatesProjectFiles = true;
|
|
} catch {}
|
|
}
|
|
if (didConfigureUpdatesProjectFiles) {
|
|
_log().default.nested(`🚀 ${(0, _terminalLink().default)('expo-updates', 'https://github.com/expo/expo/blob/main/packages/expo-updates/README.md')} has been configured in your project. If you publish this project under a different user account than ${_chalk().default.bold(username)}, you'll need to update the configuration in Expo.plist and AndroidManifest.xml before making a release build.`);
|
|
} else {
|
|
_log().default.nested(`🚀 ${(0, _terminalLink().default)('expo-updates', 'https://github.com/expo/expo/blob/main/packages/expo-updates/README.md')} has been installed in your project. Before you do a release build, you'll need to configure a few values in Expo.plist and AndroidManifest.xml in order for updates to work.`);
|
|
}
|
|
}
|
|
async function configureUpdatesProjectFilesAsync(projectRoot, username) {
|
|
// skipSDKVersionRequirement here so that this will work when you use the
|
|
// --no-install flag. the tradeoff is that the SDK version field won't be
|
|
// filled in, but we should be getting rid of that for expo-updates ASAP
|
|
// anyways.
|
|
const {
|
|
exp
|
|
} = (0, _config().getConfig)(projectRoot, {
|
|
skipSDKVersionRequirement: true
|
|
});
|
|
|
|
// apply Android config
|
|
const androidManifestPath = await _configPlugins().AndroidConfig.Paths.getAndroidManifestAsync(projectRoot);
|
|
const androidManifestJSON = await _configPlugins().AndroidConfig.Manifest.readAndroidManifestAsync(androidManifestPath);
|
|
const result = await _configPlugins().AndroidConfig.Updates.setUpdatesConfig(projectRoot, exp, androidManifestJSON, username);
|
|
await _configPlugins().AndroidConfig.Manifest.writeAndroidManifestAsync(androidManifestPath, result);
|
|
|
|
// apply iOS config
|
|
const iosSourceRoot = _configPlugins().IOSConfig.Paths.getSourceRoot(projectRoot);
|
|
const supportingDirectory = _path().default.join(iosSourceRoot, 'Supporting');
|
|
const plistFilePath = _path().default.join(supportingDirectory, 'Expo.plist');
|
|
let data = _plist().default.parse(_fsExtra().default.readFileSync(plistFilePath, 'utf8'));
|
|
data = _configPlugins().IOSConfig.Updates.setUpdatesConfig(projectRoot, exp, data, username);
|
|
await _fsExtra().default.writeFile(plistFilePath, _plist().default.build(data));
|
|
}
|
|
//# sourceMappingURL=initAsync.js.map
|