393 lines
18 KiB
JavaScript
393 lines
18 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.writeConfig = exports.loadConfig = exports.CONFIG_FILE_NAME_JSON = exports.CONFIG_FILE_NAME_JS = exports.CONFIG_FILE_NAME_TS = void 0;
|
|
const tslib_1 = require("tslib");
|
|
const debug_1 = tslib_1.__importDefault(require("debug"));
|
|
const fs_extra_1 = require("fs-extra");
|
|
const path_1 = require("path");
|
|
const colors_1 = tslib_1.__importDefault(require("./colors"));
|
|
const common_1 = require("./common");
|
|
const errors_1 = require("./errors");
|
|
const log_1 = require("./log");
|
|
const fn_1 = require("./util/fn");
|
|
const js_1 = require("./util/js");
|
|
const monorepotools_1 = require("./util/monorepotools");
|
|
const node_1 = require("./util/node");
|
|
const promise_1 = require("./util/promise");
|
|
const subprocess_1 = require("./util/subprocess");
|
|
const debug = (0, debug_1.default)('capacitor:config');
|
|
exports.CONFIG_FILE_NAME_TS = 'capacitor.config.ts';
|
|
exports.CONFIG_FILE_NAME_JS = 'capacitor.config.js';
|
|
exports.CONFIG_FILE_NAME_JSON = 'capacitor.config.json';
|
|
async function loadConfig() {
|
|
var _a, _b, _c, _d;
|
|
const appRootDir = process.cwd();
|
|
const cliRootDir = (0, path_1.dirname)(__dirname);
|
|
const conf = await loadExtConfig(appRootDir);
|
|
const depsForNx = await (async () => {
|
|
var _a, _b;
|
|
if ((0, monorepotools_1.isNXMonorepo)(appRootDir)) {
|
|
const rootOfNXMonorepo = (0, monorepotools_1.findNXMonorepoRoot)(appRootDir);
|
|
const pkgJSONOfMonorepoRoot = await (0, fn_1.tryFn)(fs_extra_1.readJSON, (0, path_1.resolve)(rootOfNXMonorepo, 'package.json'));
|
|
const devDependencies = (_a = pkgJSONOfMonorepoRoot === null || pkgJSONOfMonorepoRoot === void 0 ? void 0 : pkgJSONOfMonorepoRoot.devDependencies) !== null && _a !== void 0 ? _a : {};
|
|
const dependencies = (_b = pkgJSONOfMonorepoRoot === null || pkgJSONOfMonorepoRoot === void 0 ? void 0 : pkgJSONOfMonorepoRoot.dependencies) !== null && _b !== void 0 ? _b : {};
|
|
return {
|
|
devDependencies,
|
|
dependencies,
|
|
};
|
|
}
|
|
return {};
|
|
})();
|
|
const appId = (_a = conf.extConfig.appId) !== null && _a !== void 0 ? _a : '';
|
|
const appName = (_b = conf.extConfig.appName) !== null && _b !== void 0 ? _b : '';
|
|
const webDir = (_c = conf.extConfig.webDir) !== null && _c !== void 0 ? _c : 'www';
|
|
const cli = await loadCLIConfig(cliRootDir);
|
|
const config = {
|
|
android: await loadAndroidConfig(appRootDir, conf.extConfig, cli),
|
|
ios: await loadIOSConfig(appRootDir, conf.extConfig),
|
|
web: await loadWebConfig(appRootDir, webDir),
|
|
cli,
|
|
app: {
|
|
rootDir: appRootDir,
|
|
appId,
|
|
appName,
|
|
webDir,
|
|
webDirAbs: (0, path_1.resolve)(appRootDir, webDir),
|
|
package: (_d = (await (0, fn_1.tryFn)(fs_extra_1.readJSON, (0, path_1.resolve)(appRootDir, 'package.json')))) !== null && _d !== void 0 ? _d : {
|
|
name: appName,
|
|
version: '1.0.0',
|
|
...depsForNx,
|
|
},
|
|
...conf,
|
|
},
|
|
};
|
|
debug('config: %O', config);
|
|
return config;
|
|
}
|
|
exports.loadConfig = loadConfig;
|
|
async function writeConfig(extConfig, extConfigFilePath) {
|
|
switch ((0, path_1.extname)(extConfigFilePath)) {
|
|
case '.json': {
|
|
await (0, fs_extra_1.writeJSON)(extConfigFilePath, extConfig, { spaces: 2 });
|
|
break;
|
|
}
|
|
case '.ts': {
|
|
await (0, fs_extra_1.writeFile)(extConfigFilePath, formatConfigTS(extConfig));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
exports.writeConfig = writeConfig;
|
|
async function loadExtConfigTS(rootDir, extConfigName, extConfigFilePath) {
|
|
var _a;
|
|
try {
|
|
const tsPath = (0, node_1.resolveNode)(rootDir, 'typescript');
|
|
if (!tsPath) {
|
|
(0, errors_1.fatal)('Could not find installation of TypeScript.\n' +
|
|
`To use ${colors_1.default.strong(extConfigName)} files, you must install TypeScript in your project, e.g. w/ ${colors_1.default.input('npm install -D typescript')}`);
|
|
}
|
|
const ts = require(tsPath); // eslint-disable-line @typescript-eslint/no-var-requires
|
|
const extConfigObject = (0, node_1.requireTS)(ts, extConfigFilePath);
|
|
const extConfig = extConfigObject.default ? await extConfigObject.default : extConfigObject;
|
|
return {
|
|
extConfigType: 'ts',
|
|
extConfigName,
|
|
extConfigFilePath: extConfigFilePath,
|
|
extConfig,
|
|
};
|
|
}
|
|
catch (e) {
|
|
if (!(0, errors_1.isFatal)(e)) {
|
|
(0, errors_1.fatal)(`Parsing ${colors_1.default.strong(extConfigName)} failed.\n\n${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`);
|
|
}
|
|
throw e;
|
|
}
|
|
}
|
|
async function loadExtConfigJS(rootDir, extConfigName, extConfigFilePath) {
|
|
var _a;
|
|
try {
|
|
return {
|
|
extConfigType: 'js',
|
|
extConfigName,
|
|
extConfigFilePath: extConfigFilePath,
|
|
extConfig: await require(extConfigFilePath),
|
|
};
|
|
}
|
|
catch (e) {
|
|
(0, errors_1.fatal)(`Parsing ${colors_1.default.strong(extConfigName)} failed.\n\n${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`);
|
|
}
|
|
}
|
|
async function loadExtConfig(rootDir) {
|
|
var _a;
|
|
const extConfigFilePathTS = (0, path_1.resolve)(rootDir, exports.CONFIG_FILE_NAME_TS);
|
|
if (await (0, fs_extra_1.pathExists)(extConfigFilePathTS)) {
|
|
return loadExtConfigTS(rootDir, exports.CONFIG_FILE_NAME_TS, extConfigFilePathTS);
|
|
}
|
|
const extConfigFilePathJS = (0, path_1.resolve)(rootDir, exports.CONFIG_FILE_NAME_JS);
|
|
if (await (0, fs_extra_1.pathExists)(extConfigFilePathJS)) {
|
|
return loadExtConfigJS(rootDir, exports.CONFIG_FILE_NAME_JS, extConfigFilePathJS);
|
|
}
|
|
const extConfigFilePath = (0, path_1.resolve)(rootDir, exports.CONFIG_FILE_NAME_JSON);
|
|
return {
|
|
extConfigType: 'json',
|
|
extConfigName: exports.CONFIG_FILE_NAME_JSON,
|
|
extConfigFilePath: extConfigFilePath,
|
|
extConfig: (_a = (await (0, fn_1.tryFn)(fs_extra_1.readJSON, extConfigFilePath))) !== null && _a !== void 0 ? _a : {},
|
|
};
|
|
}
|
|
async function loadCLIConfig(rootDir) {
|
|
const assetsDir = 'assets';
|
|
const assetsDirAbs = (0, path_1.join)(rootDir, assetsDir);
|
|
const iosPlatformTemplateArchive = 'ios-pods-template.tar.gz';
|
|
const iosCordovaPluginsTemplateArchive = 'capacitor-cordova-ios-plugins.tar.gz';
|
|
const androidPlatformTemplateArchive = 'android-template.tar.gz';
|
|
const androidCordovaPluginsTemplateArchive = 'capacitor-cordova-android-plugins.tar.gz';
|
|
return {
|
|
rootDir,
|
|
assetsDir,
|
|
assetsDirAbs,
|
|
assets: {
|
|
ios: {
|
|
platformTemplateArchive: iosPlatformTemplateArchive,
|
|
platformTemplateArchiveAbs: (0, path_1.resolve)(assetsDirAbs, iosPlatformTemplateArchive),
|
|
cordovaPluginsTemplateArchive: iosCordovaPluginsTemplateArchive,
|
|
cordovaPluginsTemplateArchiveAbs: (0, path_1.resolve)(assetsDirAbs, iosCordovaPluginsTemplateArchive),
|
|
},
|
|
android: {
|
|
platformTemplateArchive: androidPlatformTemplateArchive,
|
|
platformTemplateArchiveAbs: (0, path_1.resolve)(assetsDirAbs, androidPlatformTemplateArchive),
|
|
cordovaPluginsTemplateArchive: androidCordovaPluginsTemplateArchive,
|
|
cordovaPluginsTemplateArchiveAbs: (0, path_1.resolve)(assetsDirAbs, androidCordovaPluginsTemplateArchive),
|
|
},
|
|
},
|
|
package: await (0, fs_extra_1.readJSON)((0, path_1.resolve)(rootDir, 'package.json')),
|
|
os: determineOS(process.platform),
|
|
};
|
|
}
|
|
async function loadAndroidConfig(rootDir, extConfig, cliConfig) {
|
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
|
|
const name = 'android';
|
|
const platformDir = (_b = (_a = extConfig.android) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : 'android';
|
|
const platformDirAbs = (0, path_1.resolve)(rootDir, platformDir);
|
|
const appDir = 'app';
|
|
const srcDir = `${appDir}/src`;
|
|
const srcMainDir = `${srcDir}/main`;
|
|
const assetsDir = `${srcMainDir}/assets`;
|
|
const webDir = `${assetsDir}/public`;
|
|
const resDir = `${srcMainDir}/res`;
|
|
let apkPath = `${appDir}/build/outputs/apk/`;
|
|
const flavor = ((_c = extConfig.android) === null || _c === void 0 ? void 0 : _c.flavor) || '';
|
|
if ((_d = extConfig.android) === null || _d === void 0 ? void 0 : _d.flavor) {
|
|
apkPath = `${apkPath}/${(_e = extConfig.android) === null || _e === void 0 ? void 0 : _e.flavor}`;
|
|
}
|
|
const apkName = (0, common_1.parseApkNameFromFlavor)(flavor);
|
|
const buildOutputDir = `${apkPath}/debug`;
|
|
const cordovaPluginsDir = 'capacitor-cordova-android-plugins';
|
|
const studioPath = (0, promise_1.lazy)(() => determineAndroidStudioPath(cliConfig.os));
|
|
const buildOptions = {
|
|
keystorePath: (_g = (_f = extConfig.android) === null || _f === void 0 ? void 0 : _f.buildOptions) === null || _g === void 0 ? void 0 : _g.keystorePath,
|
|
keystorePassword: (_j = (_h = extConfig.android) === null || _h === void 0 ? void 0 : _h.buildOptions) === null || _j === void 0 ? void 0 : _j.keystorePassword,
|
|
keystoreAlias: (_l = (_k = extConfig.android) === null || _k === void 0 ? void 0 : _k.buildOptions) === null || _l === void 0 ? void 0 : _l.keystoreAlias,
|
|
keystoreAliasPassword: (_o = (_m = extConfig.android) === null || _m === void 0 ? void 0 : _m.buildOptions) === null || _o === void 0 ? void 0 : _o.keystoreAliasPassword,
|
|
signingType: (_q = (_p = extConfig.android) === null || _p === void 0 ? void 0 : _p.buildOptions) === null || _q === void 0 ? void 0 : _q.signingType,
|
|
releaseType: (_s = (_r = extConfig.android) === null || _r === void 0 ? void 0 : _r.buildOptions) === null || _s === void 0 ? void 0 : _s.releaseType,
|
|
};
|
|
return {
|
|
name,
|
|
minVersion: '23',
|
|
studioPath,
|
|
platformDir,
|
|
platformDirAbs,
|
|
cordovaPluginsDir,
|
|
cordovaPluginsDirAbs: (0, path_1.resolve)(platformDirAbs, cordovaPluginsDir),
|
|
appDir,
|
|
appDirAbs: (0, path_1.resolve)(platformDirAbs, appDir),
|
|
srcDir,
|
|
srcDirAbs: (0, path_1.resolve)(platformDirAbs, srcDir),
|
|
srcMainDir,
|
|
srcMainDirAbs: (0, path_1.resolve)(platformDirAbs, srcMainDir),
|
|
assetsDir,
|
|
assetsDirAbs: (0, path_1.resolve)(platformDirAbs, assetsDir),
|
|
webDir,
|
|
webDirAbs: (0, path_1.resolve)(platformDirAbs, webDir),
|
|
resDir,
|
|
resDirAbs: (0, path_1.resolve)(platformDirAbs, resDir),
|
|
apkName,
|
|
buildOutputDir,
|
|
buildOutputDirAbs: (0, path_1.resolve)(platformDirAbs, buildOutputDir),
|
|
flavor,
|
|
buildOptions,
|
|
};
|
|
}
|
|
async function loadIOSConfig(rootDir, extConfig) {
|
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
const name = 'ios';
|
|
const platformDir = (_b = (_a = extConfig.ios) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : 'ios';
|
|
const platformDirAbs = (0, path_1.resolve)(rootDir, platformDir);
|
|
const scheme = (_d = (_c = extConfig.ios) === null || _c === void 0 ? void 0 : _c.scheme) !== null && _d !== void 0 ? _d : 'App';
|
|
const nativeProjectDir = 'App';
|
|
const nativeProjectDirAbs = (0, path_1.resolve)(platformDirAbs, nativeProjectDir);
|
|
const nativeTargetDir = `${nativeProjectDir}/App`;
|
|
const nativeTargetDirAbs = (0, path_1.resolve)(platformDirAbs, nativeTargetDir);
|
|
const nativeXcodeProjDir = `${nativeProjectDir}/App.xcodeproj`;
|
|
const nativeXcodeProjDirAbs = (0, path_1.resolve)(platformDirAbs, nativeXcodeProjDir);
|
|
const nativeXcodeWorkspaceDirAbs = (0, promise_1.lazy)(() => determineXcodeWorkspaceDirAbs(nativeProjectDirAbs));
|
|
const podPath = (0, promise_1.lazy)(() => determineGemfileOrCocoapodPath(rootDir, platformDirAbs, nativeProjectDirAbs));
|
|
const webDirAbs = (0, promise_1.lazy)(() => determineIOSWebDirAbs(nativeProjectDirAbs, nativeTargetDirAbs, nativeXcodeProjDirAbs));
|
|
const cordovaPluginsDir = 'capacitor-cordova-ios-plugins';
|
|
const buildOptions = {
|
|
exportMethod: (_f = (_e = extConfig.ios) === null || _e === void 0 ? void 0 : _e.buildOptions) === null || _f === void 0 ? void 0 : _f.exportMethod,
|
|
xcodeSigningStyle: (_h = (_g = extConfig.ios) === null || _g === void 0 ? void 0 : _g.buildOptions) === null || _h === void 0 ? void 0 : _h.signingStyle,
|
|
signingCertificate: (_k = (_j = extConfig.ios) === null || _j === void 0 ? void 0 : _j.buildOptions) === null || _k === void 0 ? void 0 : _k.signingCertificate,
|
|
provisioningProfile: (_m = (_l = extConfig.ios) === null || _l === void 0 ? void 0 : _l.buildOptions) === null || _m === void 0 ? void 0 : _m.provisioningProfile,
|
|
};
|
|
return {
|
|
name,
|
|
minVersion: '14.0',
|
|
platformDir,
|
|
platformDirAbs,
|
|
scheme,
|
|
cordovaPluginsDir,
|
|
cordovaPluginsDirAbs: (0, path_1.resolve)(platformDirAbs, cordovaPluginsDir),
|
|
nativeProjectDir,
|
|
nativeProjectDirAbs,
|
|
nativeTargetDir,
|
|
nativeTargetDirAbs,
|
|
nativeXcodeProjDir,
|
|
nativeXcodeProjDirAbs,
|
|
nativeXcodeWorkspaceDir: (0, promise_1.lazy)(async () => (0, path_1.relative)(platformDirAbs, await nativeXcodeWorkspaceDirAbs)),
|
|
nativeXcodeWorkspaceDirAbs,
|
|
webDir: (0, promise_1.lazy)(async () => (0, path_1.relative)(platformDirAbs, await webDirAbs)),
|
|
webDirAbs,
|
|
podPath,
|
|
buildOptions,
|
|
};
|
|
}
|
|
async function loadWebConfig(rootDir, webDir) {
|
|
const platformDir = webDir;
|
|
const platformDirAbs = (0, path_1.resolve)(rootDir, platformDir);
|
|
return {
|
|
name: 'web',
|
|
platformDir,
|
|
platformDirAbs,
|
|
};
|
|
}
|
|
function determineOS(os) {
|
|
switch (os) {
|
|
case 'darwin':
|
|
return "mac" /* OS.Mac */;
|
|
case 'win32':
|
|
return "windows" /* OS.Windows */;
|
|
case 'linux':
|
|
return "linux" /* OS.Linux */;
|
|
}
|
|
return "unknown" /* OS.Unknown */;
|
|
}
|
|
async function determineXcodeWorkspaceDirAbs(nativeProjectDirAbs) {
|
|
return (0, path_1.resolve)(nativeProjectDirAbs, 'App.xcworkspace');
|
|
}
|
|
async function determineIOSWebDirAbs(nativeProjectDirAbs, nativeTargetDirAbs, nativeXcodeProjDirAbs) {
|
|
const re = /path\s=\spublic[\s\S]+?sourceTree\s=\s([^;]+)/;
|
|
const pbxprojPath = (0, path_1.resolve)(nativeXcodeProjDirAbs, 'project.pbxproj');
|
|
try {
|
|
const pbxproj = await (0, fs_extra_1.readFile)(pbxprojPath, { encoding: 'utf8' });
|
|
const m = pbxproj.match(re);
|
|
if (m && m[1] === 'SOURCE_ROOT') {
|
|
log_1.logger.warn(`Using the iOS project root for the ${colors_1.default.strong('public')} directory is deprecated.\n` +
|
|
`Please follow the Upgrade Guide to move ${colors_1.default.strong('public')} inside the iOS target directory: ${colors_1.default.strong('https://capacitorjs.com/docs/updating/3-0#move-public-into-the-ios-target-directory')}`);
|
|
return (0, path_1.resolve)(nativeProjectDirAbs, 'public');
|
|
}
|
|
}
|
|
catch (e) {
|
|
// ignore
|
|
}
|
|
return (0, path_1.resolve)(nativeTargetDirAbs, 'public');
|
|
}
|
|
async function determineAndroidStudioPath(os) {
|
|
if (process.env.CAPACITOR_ANDROID_STUDIO_PATH) {
|
|
return process.env.CAPACITOR_ANDROID_STUDIO_PATH;
|
|
}
|
|
switch (os) {
|
|
case "mac" /* OS.Mac */:
|
|
return '/Applications/Android Studio.app';
|
|
case "windows" /* OS.Windows */: {
|
|
const { runCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./util/subprocess')));
|
|
let p = 'C:\\Program Files\\Android\\Android Studio\\bin\\studio64.exe';
|
|
try {
|
|
if (!(await (0, fs_extra_1.pathExists)(p))) {
|
|
let commandResult = await runCommand('REG', [
|
|
'QUERY',
|
|
'HKEY_LOCAL_MACHINE\\SOFTWARE\\Android Studio',
|
|
'/v',
|
|
'Path',
|
|
]);
|
|
commandResult = commandResult.replace(/(\r\n|\n|\r)/gm, '');
|
|
const i = commandResult.indexOf('REG_SZ');
|
|
if (i > 0) {
|
|
p = commandResult.substring(i + 6).trim() + '\\bin\\studio64.exe';
|
|
}
|
|
}
|
|
}
|
|
catch (e) {
|
|
debug(`Error checking registry for Android Studio path: %O`, e);
|
|
break;
|
|
}
|
|
return p;
|
|
}
|
|
case "linux" /* OS.Linux */:
|
|
return '/usr/local/android-studio/bin/studio.sh';
|
|
}
|
|
return '';
|
|
}
|
|
async function determineGemfileOrCocoapodPath(rootDir, platformDir, nativeProjectDirAbs) {
|
|
if (process.env.CAPACITOR_COCOAPODS_PATH) {
|
|
return process.env.CAPACITOR_COCOAPODS_PATH;
|
|
}
|
|
let gemfilePath = '';
|
|
if (await (0, fs_extra_1.pathExists)((0, path_1.resolve)(rootDir, 'Gemfile'))) {
|
|
gemfilePath = (0, path_1.resolve)(rootDir, 'Gemfile');
|
|
}
|
|
else if (await (0, fs_extra_1.pathExists)((0, path_1.resolve)(platformDir, 'Gemfile'))) {
|
|
gemfilePath = (0, path_1.resolve)(platformDir, 'Gemfile');
|
|
}
|
|
else if (await (0, fs_extra_1.pathExists)((0, path_1.resolve)(nativeProjectDirAbs, 'Gemfile'))) {
|
|
gemfilePath = (0, path_1.resolve)(nativeProjectDirAbs, 'Gemfile');
|
|
}
|
|
const appSpecificGemfileExists = gemfilePath != '';
|
|
// Multi-app projects might share a single global 'Gemfile' at the Git repository root directory.
|
|
if (!appSpecificGemfileExists) {
|
|
try {
|
|
const output = await (0, subprocess_1.getCommandOutput)('git', ['rev-parse', '--show-toplevel'], { cwd: rootDir });
|
|
if (output != null) {
|
|
gemfilePath = (0, path_1.resolve)(output, 'Gemfile');
|
|
}
|
|
}
|
|
catch (e) {
|
|
// Nothing
|
|
}
|
|
}
|
|
try {
|
|
const gemfileText = (await (0, fs_extra_1.readFile)(gemfilePath)).toString();
|
|
if (!gemfileText) {
|
|
return 'pod';
|
|
}
|
|
const cocoapodsInGemfile = new RegExp(/gem\s+['"]cocoapods/).test(gemfileText);
|
|
if (cocoapodsInGemfile) {
|
|
return 'bundle exec pod';
|
|
}
|
|
else {
|
|
return 'pod';
|
|
}
|
|
}
|
|
catch {
|
|
return 'pod';
|
|
}
|
|
}
|
|
function formatConfigTS(extConfig) {
|
|
// TODO: <reference> tags
|
|
return `import type { CapacitorConfig } from '@capacitor/cli';
|
|
|
|
const config: CapacitorConfig = ${(0, js_1.formatJSObject)(extConfig)};
|
|
|
|
export default config;\n`;
|
|
}
|