"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CapacitorCommand = void 0;
const utils_fs_1 = require("@ionic/utils-fs");
const utils_subprocess_1 = require("@ionic/utils-subprocess");
const path = require("path");
const color_1 = require("../../lib/color");
const command_1 = require("../../lib/command");
const errors_1 = require("../../lib/errors");
const executor_1 = require("../../lib/executor");
const config_1 = require("../../lib/integrations/capacitor/config");
const utils_1 = require("../../lib/integrations/capacitor/utils");
class CapacitorCommand extends command_1.Command {
get integration() {
if (!this.project) {
throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
}
if (!this._integration) {
this._integration = this.project.requireIntegration('capacitor');
}
return this._integration;
}
getCapacitorConfig() {
if (!this.project) {
throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
}
return new config_1.CapacitorConfig(path.resolve(this.project.directory, config_1.CAPACITOR_CONFIG_FILE));
}
async checkCapacitor(runinfo) {
if (!this.project) {
throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
}
const capacitor = this.project.getIntegration('capacitor');
if (!capacitor) {
await executor_1.runCommand(runinfo, ['integrations', 'enable', 'capacitor']);
}
}
async preRunChecks(runinfo) {
await this.checkCapacitor(runinfo);
}
async runCapacitor(argList) {
try {
return await this._runCapacitor(argList);
}
catch (e) {
if (e instanceof utils_subprocess_1.SubprocessError) {
if (e.code === utils_subprocess_1.ERROR_COMMAND_NOT_FOUND) {
const pkg = '@capacitor/cli';
const requiredMsg = `The Capacitor CLI is required for Capacitor projects.`;
this.env.log.nl();
this.env.log.info(`Looks like ${color_1.input(pkg)} isn't installed in this project.\n` + requiredMsg);
this.env.log.nl();
const installed = await this.promptToInstallCapacitor();
if (!installed) {
throw new errors_1.FatalException(`${color_1.input(pkg)} is required for Capacitor projects.`);
}
return this.runCapacitor(argList);
}
if (e.code === utils_subprocess_1.ERROR_SIGNAL_EXIT) {
return;
}
}
throw e;
}
}
async runBuild(inputs, options) {
if (!this.project) {
throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
}
const conf = this.getCapacitorConfig();
const serverConfig = conf.get('server');
if (serverConfig && serverConfig.url) {
this.env.log.warn(`Capacitor server URL is in use.\n` +
`This may result in unexpected behavior for this build, where an external server is used in the Web View instead of your app. This likely occurred because of ${color_1.input('--livereload')} usage in the past and the CLI improperly exiting without cleaning up.\n\n` +
`Delete the ${color_1.input('server')} key in the ${color_1.strong(config_1.CAPACITOR_CONFIG_FILE)} file if you did not intend to use an external server.`);
this.env.log.nl();
}
if (options['build']) {
try {
const runner = await this.project.requireBuildRunner();
const runnerOpts = runner.createOptionsFromCommandLine(inputs, utils_1.generateOptionsForCapacitorBuild(inputs, options));
await runner.run(runnerOpts);
}
catch (e) {
if (e instanceof errors_1.RunnerException) {
throw new errors_1.FatalException(e.message);
}
throw e;
}
}
}
async checkForPlatformInstallation(platform) {
if (!this.project) {
throw new errors_1.FatalException('Cannot use Capacitor outside a project directory.');
}
if (platform) {
const integrationRoot = this.project.directory;
const platformsToCheck = ['android', 'ios', 'electron'];
const platforms = (await Promise.all(platformsToCheck.map(async (p) => [p, await utils_fs_1.pathExists(path.resolve(integrationRoot, p))])))
.filter(([, e]) => e)
.map(([p]) => p);
if (!platforms.includes(platform)) {
await this._runCapacitor(['add', platform]);
}
}
}
createOptionsFromCommandLine(inputs, options) {
const separatedArgs = options['--'];
const verbose = !!options['verbose'];
const conf = this.getCapacitorConfig();
const server = conf.get('server');
return {
'--': separatedArgs ? separatedArgs : [],
appId: conf.get('appId'),
appName: conf.get('appName'),
server: {
url: server === null || server === void 0 ? void 0 : server.url,
},
verbose,
};
}
async promptToInstallCapacitor() {
if (!this.project) {
throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
}
const { pkgManagerArgs } = await Promise.resolve().then(() => require('../../lib/utils/npm'));
const pkg = '@capacitor/cli';
const [manager, ...managerArgs] = await pkgManagerArgs(this.env.config.get('npmClient'), { pkg, command: 'install', saveDev: true });
const confirm = await this.env.prompt({
name: 'confirm',
message: `Install ${color_1.input(pkg)}?`,
type: 'confirm',
});
if (!confirm) {
this.env.log.warn(`Not installing--here's how to install manually: ${color_1.input(`${manager} ${managerArgs.join(' ')}`)}`);
return false;
}
await this.env.shell.run(manager, managerArgs, { cwd: this.project.directory });
return true;
}
async _runCapacitor(argList) {
if (!this.project) {
throw new errors_1.FatalException(`Cannot use Capacitor outside a project directory.`);
}
await this.env.shell.run('capacitor', argList, { fatalOnNotFound: false, truncateErrorOutput: 5000, stdio: 'inherit', cwd: this.integration.root });
}
}
exports.CapacitorCommand = CapacitorCommand;