This commit is contained in:
parent
55470c090d
commit
6947a1adba
1260 changed files with 111297 additions and 0 deletions
52
@capacitor/cli/dist/android/add.js
vendored
Normal file
52
@capacitor/cli/dist/android/add.js
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createLocalProperties = exports.addAndroid = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const os_1 = require("os");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
const template_1 = require("../util/template");
|
||||
async function addAndroid(config) {
|
||||
await (0, common_1.runTask)(`Adding native android project in ${colors_1.default.strong(config.android.platformDir)}`, async () => {
|
||||
return (0, template_1.extractTemplate)(config.cli.assets.android.platformTemplateArchiveAbs, config.android.platformDirAbs);
|
||||
});
|
||||
}
|
||||
exports.addAndroid = addAndroid;
|
||||
async function createLocalProperties(platformDir) {
|
||||
const defaultAndroidPath = (0, path_1.join)((0, os_1.homedir)(), 'Library/Android/sdk');
|
||||
if (await (0, utils_fs_1.pathExists)(defaultAndroidPath)) {
|
||||
const localSettings = `
|
||||
## This file is automatically generated by Android Studio.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file should *NOT* be checked into Version Control Systems,
|
||||
# as it contains information specific to your local configuration.
|
||||
#
|
||||
# Location of the SDK. This is only used by Gradle.
|
||||
# For customization when using a Version Control System, please read the
|
||||
# header note.
|
||||
sdk.dir=${defaultAndroidPath}
|
||||
`;
|
||||
await (0, utils_fs_1.writeFile)((0, path_1.join)(platformDir, 'local.properties'), localSettings, {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
// Only sync if we were able to create the local properties above, otherwise
|
||||
// this will fail
|
||||
try {
|
||||
await gradleSync(platformDir);
|
||||
}
|
||||
catch (e) {
|
||||
console.error('Error running gradle sync', e);
|
||||
console.error('Unable to infer default Android SDK settings. This is fine, just run npx cap open android and import and sync gradle manually');
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.createLocalProperties = createLocalProperties;
|
||||
async function gradleSync(platformDir) {
|
||||
await (0, subprocess_1.runCommand)(`./gradlew`, [], {
|
||||
cwd: platformDir,
|
||||
});
|
||||
}
|
||||
106
@capacitor/cli/dist/android/build.js
vendored
Normal file
106
@capacitor/cli/dist/android/build.js
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.buildAndroid = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const log_1 = require("../log");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
async function buildAndroid(config, buildOptions) {
|
||||
var _a, _b;
|
||||
const releaseType = (_a = buildOptions.androidreleasetype) !== null && _a !== void 0 ? _a : 'AAB';
|
||||
const releaseTypeIsAAB = releaseType === 'AAB';
|
||||
const flavor = (_b = buildOptions.flavor) !== null && _b !== void 0 ? _b : '';
|
||||
const arg = releaseTypeIsAAB
|
||||
? `:app:bundle${flavor}Release`
|
||||
: `assemble${flavor}Release`;
|
||||
const gradleArgs = [arg];
|
||||
try {
|
||||
await (0, common_1.runTask)('Running Gradle build', async () => (0, subprocess_1.runCommand)('./gradlew', gradleArgs, {
|
||||
cwd: config.android.platformDirAbs,
|
||||
}));
|
||||
}
|
||||
catch (e) {
|
||||
if (e.includes('EACCES')) {
|
||||
throw `gradlew file does not have executable permissions. This can happen if the Android platform was added on a Windows machine. Please run ${colors_1.default.strong(`chmod +x ./${config.android.platformDir}/gradlew`)} and try again.`;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
const releaseDir = releaseTypeIsAAB
|
||||
? flavor !== ''
|
||||
? `${flavor}Release`
|
||||
: 'release'
|
||||
: flavor !== ''
|
||||
? (0, path_1.join)(flavor, 'release')
|
||||
: 'release';
|
||||
const releasePath = (0, path_1.join)(config.android.appDirAbs, 'build', 'outputs', releaseTypeIsAAB ? 'bundle' : 'apk', releaseDir);
|
||||
const unsignedReleaseName = `app${flavor !== '' ? `-${flavor}` : ''}-release${releaseTypeIsAAB ? '' : '-unsigned'}.${releaseType.toLowerCase()}`;
|
||||
const signedReleaseName = unsignedReleaseName.replace(`-release${releaseTypeIsAAB ? '' : '-unsigned'}.${releaseType.toLowerCase()}`, `-release-signed.${releaseType.toLowerCase()}`);
|
||||
if (buildOptions.signingtype == 'jarsigner') {
|
||||
await signWithJarSigner(config, buildOptions, releasePath, signedReleaseName, unsignedReleaseName);
|
||||
}
|
||||
else {
|
||||
await signWithApkSigner(config, buildOptions, releasePath, signedReleaseName, unsignedReleaseName);
|
||||
}
|
||||
(0, log_1.logSuccess)(`Successfully generated ${signedReleaseName} at: ${releasePath}`);
|
||||
}
|
||||
exports.buildAndroid = buildAndroid;
|
||||
async function signWithApkSigner(config, buildOptions, releasePath, signedReleaseName, unsignedReleaseName) {
|
||||
if (!buildOptions.keystorepath || !buildOptions.keystorepass) {
|
||||
throw 'Missing options. Please supply all options for android signing. (Keystore Path, Keystore Password)';
|
||||
}
|
||||
const signingArgs = [
|
||||
'sign',
|
||||
'--ks',
|
||||
buildOptions.keystorepath,
|
||||
'--ks-pass',
|
||||
`pass:${buildOptions.keystorepass}`,
|
||||
'--in',
|
||||
`${(0, path_1.join)(releasePath, unsignedReleaseName)}`,
|
||||
'--out',
|
||||
`${(0, path_1.join)(releasePath, signedReleaseName)}`,
|
||||
];
|
||||
if (buildOptions.keystorealias) {
|
||||
signingArgs.push('--ks-key-alias', buildOptions.keystorealias);
|
||||
}
|
||||
if (buildOptions.keystorealiaspass) {
|
||||
signingArgs.push('--key-pass', `pass:${buildOptions.keystorealiaspass}`);
|
||||
}
|
||||
await (0, common_1.runTask)('Signing Release', async () => {
|
||||
await (0, subprocess_1.runCommand)('apksigner', signingArgs, {
|
||||
cwd: config.android.platformDirAbs,
|
||||
});
|
||||
});
|
||||
}
|
||||
async function signWithJarSigner(config, buildOptions, releasePath, signedReleaseName, unsignedReleaseName) {
|
||||
if (!buildOptions.keystorepath ||
|
||||
!buildOptions.keystorealias ||
|
||||
!buildOptions.keystorealiaspass ||
|
||||
!buildOptions.keystorepass) {
|
||||
throw 'Missing options. Please supply all options for android signing. (Keystore Path, Keystore Password, Keystore Key Alias, Keystore Key Password)';
|
||||
}
|
||||
const signingArgs = [
|
||||
'-sigalg',
|
||||
'SHA1withRSA',
|
||||
'-digestalg',
|
||||
'SHA1',
|
||||
'-keystore',
|
||||
buildOptions.keystorepath,
|
||||
'-keypass',
|
||||
buildOptions.keystorealiaspass,
|
||||
'-storepass',
|
||||
buildOptions.keystorepass,
|
||||
`-signedjar`,
|
||||
`${(0, path_1.join)(releasePath, signedReleaseName)}`,
|
||||
`${(0, path_1.join)(releasePath, unsignedReleaseName)}`,
|
||||
buildOptions.keystorealias,
|
||||
];
|
||||
await (0, common_1.runTask)('Signing Release', async () => {
|
||||
await (0, subprocess_1.runCommand)('jarsigner', signingArgs, {
|
||||
cwd: config.android.platformDirAbs,
|
||||
});
|
||||
});
|
||||
}
|
||||
97
@capacitor/cli/dist/android/common.js
vendored
Normal file
97
@capacitor/cli/dist/android/common.js
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.editProjectSettingsAndroid = exports.resolvePlugin = exports.getAndroidPlugins = exports.checkAndroidPackage = void 0;
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const common_1 = require("../common");
|
||||
const cordova_1 = require("../cordova");
|
||||
const plugin_1 = require("../plugin");
|
||||
const fs_1 = require("../util/fs");
|
||||
async function checkAndroidPackage(config) {
|
||||
return (0, common_1.checkCapacitorPlatform)(config, 'android');
|
||||
}
|
||||
exports.checkAndroidPackage = checkAndroidPackage;
|
||||
async function getAndroidPlugins(allPlugins) {
|
||||
const resolved = await Promise.all(allPlugins.map(async (plugin) => await resolvePlugin(plugin)));
|
||||
return resolved.filter((plugin) => !!plugin);
|
||||
}
|
||||
exports.getAndroidPlugins = getAndroidPlugins;
|
||||
async function resolvePlugin(plugin) {
|
||||
var _a;
|
||||
const platform = 'android';
|
||||
if ((_a = plugin.manifest) === null || _a === void 0 ? void 0 : _a.android) {
|
||||
let pluginFilesPath = plugin.manifest.android.src
|
||||
? plugin.manifest.android.src
|
||||
: platform;
|
||||
const absolutePath = (0, path_1.join)(plugin.rootPath, pluginFilesPath, plugin.id);
|
||||
// Android folder shouldn't have subfolders, but they used to, so search for them for compatibility reasons
|
||||
if (await (0, utils_fs_1.pathExists)(absolutePath)) {
|
||||
pluginFilesPath = (0, path_1.join)(platform, plugin.id);
|
||||
}
|
||||
plugin.android = {
|
||||
type: 0 /* PluginType.Core */,
|
||||
path: (0, fs_1.convertToUnixPath)(pluginFilesPath),
|
||||
};
|
||||
}
|
||||
else if (plugin.xml) {
|
||||
plugin.android = {
|
||||
type: 1 /* PluginType.Cordova */,
|
||||
path: 'src/' + platform,
|
||||
};
|
||||
if ((0, cordova_1.getIncompatibleCordovaPlugins)(platform).includes(plugin.id) ||
|
||||
!(0, plugin_1.getPluginPlatform)(plugin, platform)) {
|
||||
plugin.android.type = 2 /* PluginType.Incompatible */;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
exports.resolvePlugin = resolvePlugin;
|
||||
/**
|
||||
* Update an Android project with the desired app name and appId.
|
||||
* This is a little trickier for Android because the appId becomes
|
||||
* the package name.
|
||||
*/
|
||||
async function editProjectSettingsAndroid(config) {
|
||||
const appId = config.app.appId;
|
||||
const appName = config.app.appName
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/"/g, '\\"')
|
||||
.replace(/'/g, "\\'");
|
||||
const buildGradlePath = (0, path_1.resolve)(config.android.appDirAbs, 'build.gradle');
|
||||
const domainPath = appId.split('.').join('/');
|
||||
// Make the package source path to the new plugin Java file
|
||||
const newJavaPath = (0, path_1.resolve)(config.android.srcMainDirAbs, `java/${domainPath}`);
|
||||
if (!(await (0, utils_fs_1.pathExists)(newJavaPath))) {
|
||||
await (0, utils_fs_1.mkdirp)(newJavaPath);
|
||||
}
|
||||
await (0, utils_fs_1.copy)((0, path_1.resolve)(config.android.srcMainDirAbs, 'java/com/getcapacitor/myapp/MainActivity.java'), (0, path_1.resolve)(newJavaPath, 'MainActivity.java'));
|
||||
if (appId.split('.')[1] !== 'getcapacitor') {
|
||||
await (0, utils_fs_1.remove)((0, path_1.resolve)(config.android.srcMainDirAbs, 'java/com/getcapacitor'));
|
||||
}
|
||||
// Remove our template 'com' folder if their ID doesn't have it
|
||||
if (appId.split('.')[0] !== 'com') {
|
||||
await (0, utils_fs_1.remove)((0, path_1.resolve)(config.android.srcMainDirAbs, 'java/com/'));
|
||||
}
|
||||
// Update the package in the MainActivity java file
|
||||
const activityPath = (0, path_1.resolve)(newJavaPath, 'MainActivity.java');
|
||||
let activityContent = await (0, utils_fs_1.readFile)(activityPath, { encoding: 'utf-8' });
|
||||
activityContent = activityContent.replace(/package ([^;]*)/, `package ${appId}`);
|
||||
await (0, utils_fs_1.writeFile)(activityPath, activityContent, { encoding: 'utf-8' });
|
||||
// Update the applicationId in build.gradle
|
||||
let gradleContent = await (0, utils_fs_1.readFile)(buildGradlePath, { encoding: 'utf-8' });
|
||||
gradleContent = gradleContent.replace(/applicationId "[^"]+"/, `applicationId "${appId}"`);
|
||||
// Update the namespace in build.gradle
|
||||
gradleContent = gradleContent.replace(/namespace "[^"]+"/, `namespace "${appId}"`);
|
||||
await (0, utils_fs_1.writeFile)(buildGradlePath, gradleContent, { encoding: 'utf-8' });
|
||||
// Update the settings in res/values/strings.xml
|
||||
const stringsPath = (0, path_1.resolve)(config.android.resDirAbs, 'values/strings.xml');
|
||||
let stringsContent = await (0, utils_fs_1.readFile)(stringsPath, { encoding: 'utf-8' });
|
||||
stringsContent = stringsContent.replace(/com.getcapacitor.myapp/g, appId);
|
||||
stringsContent = stringsContent.replace(/My App/g, appName);
|
||||
await (0, utils_fs_1.writeFile)(stringsPath, stringsContent);
|
||||
}
|
||||
exports.editProjectSettingsAndroid = editProjectSettingsAndroid;
|
||||
163
@capacitor/cli/dist/android/doctor.js
vendored
Normal file
163
@capacitor/cli/dist/android/doctor.js
vendored
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.doctorAndroid = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
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 xml_1 = require("../util/xml");
|
||||
async function doctorAndroid(config) {
|
||||
var _a;
|
||||
try {
|
||||
await (0, common_1.check)([
|
||||
checkAndroidInstalled,
|
||||
() => checkGradlew(config),
|
||||
() => checkAppSrcDirs(config),
|
||||
]);
|
||||
(0, log_1.logSuccess)('Android looking great! 👌');
|
||||
}
|
||||
catch (e) {
|
||||
if (!(0, errors_1.isFatal)(e)) {
|
||||
(0, errors_1.fatal)((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
exports.doctorAndroid = doctorAndroid;
|
||||
async function checkAppSrcDirs(config) {
|
||||
if (!(await (0, utils_fs_1.pathExists)(config.android.appDirAbs))) {
|
||||
return `${colors_1.default.strong(config.android.appDir)} directory is missing in ${colors_1.default.strong(config.android.platformDir)}`;
|
||||
}
|
||||
if (!(await (0, utils_fs_1.pathExists)(config.android.srcMainDirAbs))) {
|
||||
return `${colors_1.default.strong(config.android.srcMainDir)} directory is missing in ${colors_1.default.strong(config.android.platformDir)}`;
|
||||
}
|
||||
if (!(await (0, utils_fs_1.pathExists)(config.android.assetsDirAbs))) {
|
||||
return `${colors_1.default.strong(config.android.assetsDir)} directory is missing in ${colors_1.default.strong(config.android.platformDir)}`;
|
||||
}
|
||||
if (!(await (0, utils_fs_1.pathExists)(config.android.webDirAbs))) {
|
||||
return `${colors_1.default.strong(config.android.webDir)} directory is missing in ${colors_1.default.strong(config.android.platformDir)}`;
|
||||
}
|
||||
const appSrcMainAssetsWwwIndexHtmlDir = (0, path_1.join)(config.android.webDirAbs, 'index.html');
|
||||
if (!(await (0, utils_fs_1.pathExists)(appSrcMainAssetsWwwIndexHtmlDir))) {
|
||||
return `${colors_1.default.strong('index.html')} file is missing in ${colors_1.default.strong(config.android.webDirAbs)}`;
|
||||
}
|
||||
return checkAndroidManifestFile(config);
|
||||
}
|
||||
async function checkAndroidManifestFile(config) {
|
||||
const manifestFileName = 'AndroidManifest.xml';
|
||||
const manifestFilePath = (0, path_1.join)(config.android.srcMainDirAbs, manifestFileName);
|
||||
if (!(await (0, utils_fs_1.pathExists)(manifestFilePath))) {
|
||||
return `${colors_1.default.strong(manifestFileName)} is missing in ${colors_1.default.strong(config.android.srcMainDir)}`;
|
||||
}
|
||||
try {
|
||||
const xmlData = await (0, xml_1.readXML)(manifestFilePath);
|
||||
return checkAndroidManifestData(config, xmlData);
|
||||
}
|
||||
catch (e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
async function checkAndroidManifestData(config, xmlData) {
|
||||
const manifestNode = xmlData.manifest;
|
||||
if (!manifestNode) {
|
||||
return `Missing ${colors_1.default.input('<manifest>')} XML node in ${colors_1.default.strong(config.android.srcMainDir)}`;
|
||||
}
|
||||
const applicationChildNodes = manifestNode.application;
|
||||
if (!Array.isArray(manifestNode.application)) {
|
||||
return `Missing ${colors_1.default.input('<application>')} XML node as a child node of ${colors_1.default.input('<manifest>')} in ${colors_1.default.strong(config.android.srcMainDir)}`;
|
||||
}
|
||||
let mainActivityClassPath = '';
|
||||
const mainApplicationNode = applicationChildNodes.find(applicationChildNode => {
|
||||
const activityChildNodes = applicationChildNode.activity;
|
||||
if (!Array.isArray(activityChildNodes)) {
|
||||
return false;
|
||||
}
|
||||
const mainActivityNode = activityChildNodes.find(activityChildNode => {
|
||||
const intentFilterChildNodes = activityChildNode['intent-filter'];
|
||||
if (!Array.isArray(intentFilterChildNodes)) {
|
||||
return false;
|
||||
}
|
||||
return intentFilterChildNodes.find(intentFilterChildNode => {
|
||||
const actionChildNodes = intentFilterChildNode.action;
|
||||
if (!Array.isArray(actionChildNodes)) {
|
||||
return false;
|
||||
}
|
||||
const mainActionChildNode = actionChildNodes.find(actionChildNode => {
|
||||
const androidName = actionChildNode.$['android:name'];
|
||||
return androidName === 'android.intent.action.MAIN';
|
||||
});
|
||||
if (!mainActionChildNode) {
|
||||
return false;
|
||||
}
|
||||
const categoryChildNodes = intentFilterChildNode.category;
|
||||
if (!Array.isArray(categoryChildNodes)) {
|
||||
return false;
|
||||
}
|
||||
return categoryChildNodes.find(categoryChildNode => {
|
||||
const androidName = categoryChildNode.$['android:name'];
|
||||
return androidName === 'android.intent.category.LAUNCHER';
|
||||
});
|
||||
});
|
||||
});
|
||||
if (mainActivityNode) {
|
||||
mainActivityClassPath = mainActivityNode.$['android:name'];
|
||||
}
|
||||
return mainActivityNode;
|
||||
});
|
||||
if (!mainApplicationNode) {
|
||||
return `Missing main ${colors_1.default.input('<activity>')} XML node in ${colors_1.default.strong(config.android.srcMainDir)}`;
|
||||
}
|
||||
if (!mainActivityClassPath) {
|
||||
return `Missing ${colors_1.default.input('<activity android:name="">')} attribute for MainActivity class in ${colors_1.default.strong(config.android.srcMainDir)}`;
|
||||
}
|
||||
return checkPackage(config, mainActivityClassPath);
|
||||
}
|
||||
async function checkPackage(config, mainActivityClassPath) {
|
||||
const appSrcMainJavaDir = (0, path_1.join)(config.android.srcMainDirAbs, 'java');
|
||||
if (!(await (0, utils_fs_1.pathExists)(appSrcMainJavaDir))) {
|
||||
return `${colors_1.default.strong('java')} directory is missing in ${colors_1.default.strong(appSrcMainJavaDir)}`;
|
||||
}
|
||||
const mainActivityClassName = mainActivityClassPath.split('.').pop();
|
||||
const srcFiles = await (0, utils_fs_1.readdirp)(appSrcMainJavaDir, {
|
||||
filter: entry => !entry.stats.isDirectory() &&
|
||||
['.java', '.kt'].includes((0, path_1.extname)(entry.path)) &&
|
||||
mainActivityClassName === (0, path_1.parse)(entry.path).name,
|
||||
});
|
||||
if (srcFiles.length == 0) {
|
||||
return `Main activity file (${mainActivityClassName}) is missing`;
|
||||
}
|
||||
return checkBuildGradle(config);
|
||||
}
|
||||
async function checkBuildGradle(config) {
|
||||
const fileName = 'build.gradle';
|
||||
const filePath = (0, path_1.join)(config.android.appDirAbs, fileName);
|
||||
if (!(await (0, utils_fs_1.pathExists)(filePath))) {
|
||||
return `${colors_1.default.strong(fileName)} file is missing in ${colors_1.default.strong(config.android.appDir)}`;
|
||||
}
|
||||
let fileContent = await (0, utils_fs_1.readFile)(filePath, { encoding: 'utf-8' });
|
||||
fileContent = fileContent.replace(/'|"/g, '').replace(/\s+/g, ' ');
|
||||
const searchFor = `applicationId`;
|
||||
if (fileContent.indexOf(searchFor) === -1) {
|
||||
return `${colors_1.default.strong('build.gradle')} file missing ${colors_1.default.input(`applicationId`)} config in ${filePath}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
async function checkGradlew(config) {
|
||||
const fileName = 'gradlew';
|
||||
const filePath = (0, path_1.join)(config.android.platformDirAbs, fileName);
|
||||
if (!(await (0, utils_fs_1.pathExists)(filePath))) {
|
||||
return `${colors_1.default.strong(fileName)} file is missing in ${colors_1.default.strong(config.android.platformDir)}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
async function checkAndroidInstalled() {
|
||||
/*
|
||||
if (!await isInstalled('android')) {
|
||||
return 'Android is not installed. For information: https://developer.android.com/studio/index.html';
|
||||
}
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
28
@capacitor/cli/dist/android/open.js
vendored
Normal file
28
@capacitor/cli/dist/android/open.js
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.openAndroid = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const debug_1 = tslib_1.__importDefault(require("debug"));
|
||||
const open_1 = tslib_1.__importDefault(require("open"));
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const log_1 = require("../log");
|
||||
const debug = (0, debug_1.default)('capacitor:android:open');
|
||||
async function openAndroid(config) {
|
||||
const androidStudioPath = await config.android.studioPath;
|
||||
const dir = config.android.platformDirAbs;
|
||||
try {
|
||||
if (!(await (0, utils_fs_1.pathExists)(androidStudioPath))) {
|
||||
throw new Error(`Android Studio does not exist at: ${androidStudioPath}`);
|
||||
}
|
||||
await (0, open_1.default)(dir, { app: { name: androidStudioPath }, wait: false });
|
||||
log_1.logger.info(`Opening Android project at: ${colors_1.default.strong(config.android.platformDir)}.`);
|
||||
}
|
||||
catch (e) {
|
||||
debug('Error opening Android Studio: %O', e);
|
||||
log_1.logger.error('Unable to launch Android Studio. Is it installed?\n' +
|
||||
`Attempted to open Android Studio at: ${colors_1.default.strong(androidStudioPath)}\n` +
|
||||
`You can configure this with the ${colors_1.default.input('CAPACITOR_ANDROID_STUDIO_PATH')} environment variable.`);
|
||||
}
|
||||
}
|
||||
exports.openAndroid = openAndroid;
|
||||
42
@capacitor/cli/dist/android/run.js
vendored
Normal file
42
@capacitor/cli/dist/android/run.js
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runAndroid = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const debug_1 = tslib_1.__importDefault(require("debug"));
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const native_run_1 = require("../util/native-run");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
const debug = (0, debug_1.default)('capacitor:android:run');
|
||||
async function runAndroid(config, { target: selectedTarget, flavor: selectedFlavor, forwardPorts: selectedPorts, }) {
|
||||
var _a;
|
||||
const target = await (0, common_1.promptForPlatformTarget)(await (0, native_run_1.getPlatformTargets)('android'), selectedTarget);
|
||||
const runFlavor = selectedFlavor || ((_a = config.android) === null || _a === void 0 ? void 0 : _a.flavor) || '';
|
||||
const arg = `assemble${runFlavor}Debug`;
|
||||
const gradleArgs = [arg];
|
||||
debug('Invoking ./gradlew with args: %O', gradleArgs);
|
||||
try {
|
||||
await (0, common_1.runTask)('Running Gradle build', async () => (0, subprocess_1.runCommand)('./gradlew', gradleArgs, {
|
||||
cwd: config.android.platformDirAbs,
|
||||
}));
|
||||
}
|
||||
catch (e) {
|
||||
if (e.includes('EACCES')) {
|
||||
throw `gradlew file does not have executable permissions. This can happen if the Android platform was added on a Windows machine. Please run ${colors_1.default.strong(`chmod +x ./${config.android.platformDir}/gradlew`)} and try again.`;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
const pathToApk = `${config.android.platformDirAbs}/${config.android.appDir}/build/outputs/apk${runFlavor !== '' ? '/' + runFlavor : ''}/debug`;
|
||||
const apkName = (0, common_1.parseApkNameFromFlavor)(runFlavor);
|
||||
const apkPath = (0, path_1.resolve)(pathToApk, apkName);
|
||||
const nativeRunArgs = ['android', '--app', apkPath, '--target', target.id];
|
||||
if (selectedPorts) {
|
||||
nativeRunArgs.push('--forward', `${selectedPorts}`);
|
||||
}
|
||||
debug('Invoking native-run with args: %O', nativeRunArgs);
|
||||
await (0, common_1.runTask)(`Deploying ${colors_1.default.strong(apkName)} to ${colors_1.default.input(target.id)}`, async () => (0, native_run_1.runNativeRun)(nativeRunArgs));
|
||||
}
|
||||
exports.runAndroid = runAndroid;
|
||||
323
@capacitor/cli/dist/android/update.js
vendored
Normal file
323
@capacitor/cli/dist/android/update.js
vendored
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.handleCordovaPluginsGradle = exports.installGradlePlugins = exports.updateAndroid = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const debug_1 = tslib_1.__importDefault(require("debug"));
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const cordova_1 = require("../cordova");
|
||||
const errors_1 = require("../errors");
|
||||
const plugin_1 = require("../plugin");
|
||||
const copy_1 = require("../tasks/copy");
|
||||
const migrate_1 = require("../tasks/migrate");
|
||||
const fs_1 = require("../util/fs");
|
||||
const node_1 = require("../util/node");
|
||||
const template_1 = require("../util/template");
|
||||
const common_2 = require("./common");
|
||||
const platform = 'android';
|
||||
const debug = (0, debug_1.default)('capacitor:android:update');
|
||||
async function updateAndroid(config) {
|
||||
const plugins = await getPluginsTask(config);
|
||||
const capacitorPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 0 /* PluginType.Core */);
|
||||
(0, plugin_1.printPlugins)(capacitorPlugins, 'android');
|
||||
await writePluginsJson(config, capacitorPlugins);
|
||||
await removePluginsNativeFiles(config);
|
||||
const cordovaPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 1 /* PluginType.Cordova */);
|
||||
await (0, migrate_1.patchOldCapacitorPlugins)(config);
|
||||
if (cordovaPlugins.length > 0) {
|
||||
await copyPluginsNativeFiles(config, cordovaPlugins);
|
||||
}
|
||||
if (!(await (0, utils_fs_1.pathExists)(config.android.webDirAbs))) {
|
||||
await (0, copy_1.copy)(config, platform);
|
||||
}
|
||||
await (0, cordova_1.handleCordovaPluginsJS)(cordovaPlugins, config, platform);
|
||||
await (0, cordova_1.checkPluginDependencies)(plugins, platform);
|
||||
await installGradlePlugins(config, capacitorPlugins, cordovaPlugins);
|
||||
await handleCordovaPluginsGradle(config, cordovaPlugins);
|
||||
await (0, cordova_1.writeCordovaAndroidManifest)(cordovaPlugins, config, platform);
|
||||
const incompatibleCordovaPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 2 /* PluginType.Incompatible */);
|
||||
(0, plugin_1.printPlugins)(incompatibleCordovaPlugins, platform, 'incompatible');
|
||||
await (0, common_1.checkPlatformVersions)(config, platform);
|
||||
}
|
||||
exports.updateAndroid = updateAndroid;
|
||||
function getGradlePackageName(id) {
|
||||
return id.replace('@', '').replace('/', '-');
|
||||
}
|
||||
async function writePluginsJson(config, plugins) {
|
||||
const classes = await findAndroidPluginClasses(plugins);
|
||||
const pluginsJsonPath = (0, path_1.resolve)(config.android.assetsDirAbs, 'capacitor.plugins.json');
|
||||
await (0, utils_fs_1.writeJSON)(pluginsJsonPath, classes, { spaces: '\t' });
|
||||
}
|
||||
async function findAndroidPluginClasses(plugins) {
|
||||
const entries = [];
|
||||
for (const plugin of plugins) {
|
||||
entries.push(...(await findAndroidPluginClassesInPlugin(plugin)));
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
async function findAndroidPluginClassesInPlugin(plugin) {
|
||||
if (!plugin.android || (0, plugin_1.getPluginType)(plugin, platform) !== 0 /* PluginType.Core */) {
|
||||
return [];
|
||||
}
|
||||
const srcPath = (0, path_1.resolve)(plugin.rootPath, plugin.android.path, 'src/main');
|
||||
const srcFiles = await (0, utils_fs_1.readdirp)(srcPath, {
|
||||
filter: entry => !entry.stats.isDirectory() &&
|
||||
['.java', '.kt'].includes((0, path_1.extname)(entry.path)),
|
||||
});
|
||||
const classRegex = /^@(?:CapacitorPlugin|NativePlugin)[\s\S]+?class ([\w]+)/gm;
|
||||
const packageRegex = /^package ([\w.]+);?$/gm;
|
||||
debug('Searching %O source files in %O by %O regex', srcFiles.length, srcPath, classRegex);
|
||||
const entries = await Promise.all(srcFiles.map(async (srcFile) => {
|
||||
const srcFileContents = await (0, utils_fs_1.readFile)(srcFile, { encoding: 'utf-8' });
|
||||
classRegex.lastIndex = 0;
|
||||
const classMatch = classRegex.exec(srcFileContents);
|
||||
if (classMatch) {
|
||||
const className = classMatch[1];
|
||||
debug('Searching %O for package by %O regex', srcFile, packageRegex);
|
||||
packageRegex.lastIndex = 0;
|
||||
const packageMatch = packageRegex.exec(srcFileContents.substring(0, classMatch.index));
|
||||
if (!packageMatch) {
|
||||
(0, errors_1.fatal)(`Package could not be parsed from Android plugin.\n` +
|
||||
`Location: ${colors_1.default.strong(srcFile)}`);
|
||||
}
|
||||
const packageName = packageMatch[1];
|
||||
const classpath = `${packageName}.${className}`;
|
||||
debug('%O is a suitable plugin class', classpath);
|
||||
return {
|
||||
pkg: plugin.id,
|
||||
classpath,
|
||||
};
|
||||
}
|
||||
}));
|
||||
return entries.filter((entry) => !!entry);
|
||||
}
|
||||
async function installGradlePlugins(config, capacitorPlugins, cordovaPlugins) {
|
||||
const capacitorAndroidPackagePath = (0, node_1.resolveNode)(config.app.rootDir, '@capacitor/android', 'package.json');
|
||||
if (!capacitorAndroidPackagePath) {
|
||||
(0, errors_1.fatal)(`Unable to find ${colors_1.default.strong('node_modules/@capacitor/android')}.\n` +
|
||||
`Are you sure ${colors_1.default.strong('@capacitor/android')} is installed?`);
|
||||
}
|
||||
const capacitorAndroidPath = (0, path_1.resolve)((0, path_1.dirname)(capacitorAndroidPackagePath), 'capacitor');
|
||||
const settingsPath = config.android.platformDirAbs;
|
||||
const dependencyPath = config.android.appDirAbs;
|
||||
const relativeCapcitorAndroidPath = (0, fs_1.convertToUnixPath)((0, path_1.relative)(settingsPath, capacitorAndroidPath));
|
||||
const settingsLines = `// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
|
||||
include ':capacitor-android'
|
||||
project(':capacitor-android').projectDir = new File('${relativeCapcitorAndroidPath}')
|
||||
${capacitorPlugins
|
||||
.map(p => {
|
||||
if (!p.android) {
|
||||
return '';
|
||||
}
|
||||
const relativePluginPath = (0, fs_1.convertToUnixPath)((0, path_1.relative)(settingsPath, p.rootPath));
|
||||
return `
|
||||
include ':${getGradlePackageName(p.id)}'
|
||||
project(':${getGradlePackageName(p.id)}').projectDir = new File('${relativePluginPath}/${p.android.path}')
|
||||
`;
|
||||
})
|
||||
.join('')}`;
|
||||
const applyArray = [];
|
||||
const frameworksArray = [];
|
||||
let prefsArray = [];
|
||||
cordovaPlugins.map(p => {
|
||||
const relativePluginPath = (0, fs_1.convertToUnixPath)((0, path_1.relative)(dependencyPath, p.rootPath));
|
||||
const frameworks = (0, plugin_1.getPlatformElement)(p, platform, 'framework');
|
||||
frameworks.map((framework) => {
|
||||
if (framework.$.custom &&
|
||||
framework.$.custom === 'true' &&
|
||||
framework.$.type &&
|
||||
framework.$.type === 'gradleReference') {
|
||||
applyArray.push(`apply from: "${relativePluginPath}/${framework.$.src}"`);
|
||||
}
|
||||
else if (!framework.$.type && !framework.$.custom) {
|
||||
if (framework.$.src.startsWith('platform(')) {
|
||||
frameworksArray.push(` implementation ${framework.$.src}`);
|
||||
}
|
||||
else {
|
||||
frameworksArray.push(` implementation "${framework.$.src}"`);
|
||||
}
|
||||
}
|
||||
});
|
||||
prefsArray = prefsArray.concat((0, plugin_1.getAllElements)(p, platform, 'preference'));
|
||||
});
|
||||
let frameworkString = frameworksArray.join('\n');
|
||||
frameworkString = await replaceFrameworkVariables(config, prefsArray, frameworkString);
|
||||
const dependencyLines = `// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
|
||||
|
||||
android {
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
}
|
||||
|
||||
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
|
||||
dependencies {
|
||||
${capacitorPlugins
|
||||
.map(p => {
|
||||
return ` implementation project(':${getGradlePackageName(p.id)}')`;
|
||||
})
|
||||
.join('\n')}
|
||||
${frameworkString}
|
||||
}
|
||||
${applyArray.join('\n')}
|
||||
|
||||
if (hasProperty('postBuildExtras')) {
|
||||
postBuildExtras()
|
||||
}
|
||||
`;
|
||||
await (0, utils_fs_1.writeFile)((0, path_1.join)(settingsPath, 'capacitor.settings.gradle'), settingsLines);
|
||||
await (0, utils_fs_1.writeFile)((0, path_1.join)(dependencyPath, 'capacitor.build.gradle'), dependencyLines);
|
||||
}
|
||||
exports.installGradlePlugins = installGradlePlugins;
|
||||
async function handleCordovaPluginsGradle(config, cordovaPlugins) {
|
||||
var _a, _b, _c;
|
||||
const pluginsGradlePath = (0, path_1.join)(config.android.cordovaPluginsDirAbs, 'build.gradle');
|
||||
const kotlinNeeded = await kotlinNeededCheck(config, cordovaPlugins);
|
||||
const kotlinVersionString = (_c = (_b = (_a = config.app.extConfig.cordova) === null || _a === void 0 ? void 0 : _a.preferences) === null || _b === void 0 ? void 0 : _b.GradlePluginKotlinVersion) !== null && _c !== void 0 ? _c : '1.8.20';
|
||||
const frameworksArray = [];
|
||||
let prefsArray = [];
|
||||
const applyArray = [];
|
||||
applyArray.push(`apply from: "cordova.variables.gradle"`);
|
||||
cordovaPlugins.map(p => {
|
||||
const relativePluginPath = (0, fs_1.convertToUnixPath)((0, path_1.relative)(config.android.cordovaPluginsDirAbs, p.rootPath));
|
||||
const frameworks = (0, plugin_1.getPlatformElement)(p, platform, 'framework');
|
||||
frameworks.map((framework) => {
|
||||
if (!framework.$.type && !framework.$.custom) {
|
||||
frameworksArray.push(framework.$.src);
|
||||
}
|
||||
else if (framework.$.custom &&
|
||||
framework.$.custom === 'true' &&
|
||||
framework.$.type &&
|
||||
framework.$.type === 'gradleReference') {
|
||||
applyArray.push(`apply from: "${relativePluginPath}/${framework.$.src}"`);
|
||||
}
|
||||
});
|
||||
prefsArray = prefsArray.concat((0, plugin_1.getAllElements)(p, platform, 'preference'));
|
||||
});
|
||||
let frameworkString = frameworksArray
|
||||
.map(f => {
|
||||
if (f.startsWith('platform(')) {
|
||||
return ` implementation ${f}`;
|
||||
}
|
||||
else {
|
||||
return ` implementation "${f}"`;
|
||||
}
|
||||
})
|
||||
.join('\n');
|
||||
frameworkString = await replaceFrameworkVariables(config, prefsArray, frameworkString);
|
||||
if (kotlinNeeded) {
|
||||
frameworkString += `\n implementation "androidx.core:core-ktx:$androidxCoreKTXVersion"`;
|
||||
frameworkString += `\n implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"`;
|
||||
}
|
||||
const applyString = applyArray.join('\n');
|
||||
let buildGradle = await (0, utils_fs_1.readFile)(pluginsGradlePath, { encoding: 'utf-8' });
|
||||
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + frameworkString.concat('\n') + ' $2');
|
||||
buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + applyString.concat('\n') + '$2');
|
||||
if (kotlinNeeded) {
|
||||
buildGradle = buildGradle.replace(/(buildscript\s{\n(\t|\s{4})repositories\s{\n((\t{2}|\s{8}).+\n)+(\t|\s{4})}\n(\t|\s{4})dependencies\s{\n(\t{2}|\s{8}).+)\n((\t|\s{4})}\n}\n)/, `$1\n classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"\n$8`);
|
||||
buildGradle = buildGradle.replace(/(ext\s{)/, `$1\n androidxCoreKTXVersion = project.hasProperty('androidxCoreKTXVersion') ? rootProject.ext.androidxCoreKTXVersion : '1.8.0'`);
|
||||
buildGradle = buildGradle.replace(/(buildscript\s{)/, `$1\n ext.kotlin_version = project.hasProperty('kotlin_version') ? rootProject.ext.kotlin_version : '${kotlinVersionString}'`);
|
||||
buildGradle = buildGradle.replace(/(apply\splugin:\s'com\.android\.library')/, `$1\napply plugin: 'kotlin-android'`);
|
||||
buildGradle = buildGradle.replace(/(compileOptions\s{\n((\t{2}|\s{8}).+\n)+(\t|\s{4})})\n(})/, `$1\n sourceSets {\n main.java.srcDirs += 'src/main/kotlin'\n }\n$5`);
|
||||
}
|
||||
await (0, utils_fs_1.writeFile)(pluginsGradlePath, buildGradle);
|
||||
const cordovaVariables = `// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
|
||||
ext {
|
||||
cdvMinSdkVersion = project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : ${config.android.minVersion}
|
||||
// Plugin gradle extensions can append to this to have code run at the end.
|
||||
cdvPluginPostBuildExtras = []
|
||||
cordovaConfig = [:]
|
||||
}`;
|
||||
await (0, utils_fs_1.writeFile)((0, path_1.join)(config.android.cordovaPluginsDirAbs, 'cordova.variables.gradle'), cordovaVariables);
|
||||
}
|
||||
exports.handleCordovaPluginsGradle = handleCordovaPluginsGradle;
|
||||
async function kotlinNeededCheck(config, cordovaPlugins) {
|
||||
var _a, _b;
|
||||
if (((_b = (_a = config.app.extConfig.cordova) === null || _a === void 0 ? void 0 : _a.preferences) === null || _b === void 0 ? void 0 : _b.GradlePluginKotlinEnabled) !==
|
||||
'true') {
|
||||
for (const plugin of cordovaPlugins) {
|
||||
const androidPlatform = (0, plugin_1.getPluginPlatform)(plugin, platform);
|
||||
const sourceFiles = androidPlatform['source-file'];
|
||||
if (sourceFiles) {
|
||||
for (const srcFile of sourceFiles) {
|
||||
if (/^.*\.kt$/.test(srcFile['$'].src)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
async function copyPluginsNativeFiles(config, cordovaPlugins) {
|
||||
const pluginsPath = (0, path_1.join)(config.android.cordovaPluginsDirAbs, 'src', 'main');
|
||||
for (const p of cordovaPlugins) {
|
||||
const androidPlatform = (0, plugin_1.getPluginPlatform)(p, platform);
|
||||
if (androidPlatform) {
|
||||
const sourceFiles = androidPlatform['source-file'];
|
||||
if (sourceFiles) {
|
||||
for (const sourceFile of sourceFiles) {
|
||||
const fileName = sourceFile.$.src.split('/').pop();
|
||||
let baseFolder = 'java/';
|
||||
if (fileName.split('.').pop() === 'aidl') {
|
||||
baseFolder = 'aidl/';
|
||||
}
|
||||
const target = sourceFile.$['target-dir']
|
||||
.replace('app/src/main/', '')
|
||||
.replace('src/', baseFolder);
|
||||
await (0, utils_fs_1.copy)((0, plugin_1.getFilePath)(config, p, sourceFile.$.src), (0, path_1.join)(pluginsPath, target, fileName));
|
||||
}
|
||||
}
|
||||
const resourceFiles = androidPlatform['resource-file'];
|
||||
if (resourceFiles) {
|
||||
for (const resourceFile of resourceFiles) {
|
||||
const target = resourceFile.$['target'];
|
||||
if (resourceFile.$.src.split('.').pop() === 'aar') {
|
||||
await (0, utils_fs_1.copy)((0, plugin_1.getFilePath)(config, p, resourceFile.$.src), (0, path_1.join)(pluginsPath, 'libs', target.split('/').pop()));
|
||||
}
|
||||
else if (target !== '.') {
|
||||
await (0, utils_fs_1.copy)((0, plugin_1.getFilePath)(config, p, resourceFile.$.src), (0, path_1.join)(pluginsPath, target));
|
||||
}
|
||||
}
|
||||
}
|
||||
const libFiles = (0, plugin_1.getPlatformElement)(p, platform, 'lib-file');
|
||||
for (const libFile of libFiles) {
|
||||
await (0, utils_fs_1.copy)((0, plugin_1.getFilePath)(config, p, libFile.$.src), (0, path_1.join)(pluginsPath, 'libs', libFile.$.src.split('/').pop()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async function removePluginsNativeFiles(config) {
|
||||
await (0, utils_fs_1.remove)(config.android.cordovaPluginsDirAbs);
|
||||
await (0, template_1.extractTemplate)(config.cli.assets.android.cordovaPluginsTemplateArchiveAbs, config.android.cordovaPluginsDirAbs);
|
||||
}
|
||||
async function getPluginsTask(config) {
|
||||
return await (0, common_1.runTask)('Updating Android plugins', async () => {
|
||||
const allPlugins = await (0, plugin_1.getPlugins)(config, 'android');
|
||||
const androidPlugins = await (0, common_2.getAndroidPlugins)(allPlugins);
|
||||
return androidPlugins;
|
||||
});
|
||||
}
|
||||
async function getVariablesGradleFile(config) {
|
||||
const variablesFile = (0, path_1.resolve)(config.android.platformDirAbs, 'variables.gradle');
|
||||
let variablesGradle = '';
|
||||
if (await (0, utils_fs_1.pathExists)(variablesFile)) {
|
||||
variablesGradle = await (0, utils_fs_1.readFile)(variablesFile, { encoding: 'utf-8' });
|
||||
}
|
||||
return variablesGradle;
|
||||
}
|
||||
async function replaceFrameworkVariables(config, prefsArray, frameworkString) {
|
||||
const variablesGradle = await getVariablesGradleFile(config);
|
||||
prefsArray.map((preference) => {
|
||||
if (!variablesGradle.includes(preference.$.name)) {
|
||||
frameworkString = frameworkString.replace(new RegExp(('$' + preference.$.name).replace('$', '\\$&'), 'g'), preference.$.default);
|
||||
}
|
||||
});
|
||||
return frameworkString;
|
||||
}
|
||||
26
@capacitor/cli/dist/colors.js
vendored
Normal file
26
@capacitor/cli/dist/colors.js
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ancillary = exports.failure = exports.success = exports.input = exports.weak = exports.strong = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const kleur_1 = tslib_1.__importDefault(require("kleur"));
|
||||
exports.strong = kleur_1.default.bold;
|
||||
exports.weak = kleur_1.default.dim;
|
||||
exports.input = kleur_1.default.cyan;
|
||||
exports.success = kleur_1.default.green;
|
||||
exports.failure = kleur_1.default.red;
|
||||
exports.ancillary = kleur_1.default.cyan;
|
||||
const COLORS = {
|
||||
strong: exports.strong,
|
||||
weak: exports.weak,
|
||||
input: exports.input,
|
||||
success: exports.success,
|
||||
failure: exports.failure,
|
||||
ancillary: exports.ancillary,
|
||||
log: {
|
||||
DEBUG: kleur_1.default.magenta,
|
||||
INFO: kleur_1.default.cyan,
|
||||
WARN: kleur_1.default.yellow,
|
||||
ERROR: kleur_1.default.red,
|
||||
},
|
||||
};
|
||||
exports.default = COLORS;
|
||||
407
@capacitor/cli/dist/common.js
vendored
Normal file
407
@capacitor/cli/dist/common.js
vendored
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseApkNameFromFlavor = exports.checkJDKMajorVersion = exports.resolvePlatform = exports.checkPlatformVersions = exports.getAddedPlatforms = exports.getPlatformTargetName = exports.promptForPlatformTarget = exports.promptForPlatform = exports.isValidEnterprisePlatform = exports.getKnownEnterprisePlatforms = exports.isValidCommunityPlatform = exports.getKnownCommunityPlatforms = exports.isValidPlatform = exports.getKnownPlatforms = exports.selectPlatforms = exports.getProjectPlatformDirectory = exports.getCLIVersion = exports.getCoreVersion = exports.getCapacitorPackageVersion = exports.requireCapacitorPackage = exports.getCapacitorPackage = exports.runTask = exports.runPlatformHook = exports.runHooks = exports.wait = exports.checkAppName = exports.checkAppId = exports.checkAppDir = exports.checkAppConfig = exports.checkCapacitorPlatform = exports.checkPackage = exports.checkWebDir = exports.check = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const utils_terminal_1 = require("@ionic/utils-terminal");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("./colors"));
|
||||
const errors_1 = require("./errors");
|
||||
const log_1 = require("./log");
|
||||
const plugin_1 = require("./plugin");
|
||||
const monorepotools_1 = require("./util/monorepotools");
|
||||
const node_1 = require("./util/node");
|
||||
const subprocess_1 = require("./util/subprocess");
|
||||
async function check(checks) {
|
||||
const results = await Promise.all(checks.map(f => f()));
|
||||
const errors = results.filter(r => r != null);
|
||||
if (errors.length > 0) {
|
||||
throw errors.join('\n');
|
||||
}
|
||||
}
|
||||
exports.check = check;
|
||||
async function checkWebDir(config) {
|
||||
var _a;
|
||||
// We can skip checking the web dir if a server URL is set.
|
||||
if ((_a = config.app.extConfig.server) === null || _a === void 0 ? void 0 : _a.url) {
|
||||
return null;
|
||||
}
|
||||
const invalidFolders = ['', '.', '..', '../', './'];
|
||||
if (invalidFolders.includes(config.app.webDir)) {
|
||||
return `"${config.app.webDir}" is not a valid value for webDir`;
|
||||
}
|
||||
if (!(await (0, utils_fs_1.pathExists)(config.app.webDirAbs))) {
|
||||
return (`Could not find the web assets directory: ${colors_1.default.strong((0, utils_terminal_1.prettyPath)(config.app.webDirAbs))}.\n` +
|
||||
`Please create it and make sure it has an ${colors_1.default.strong('index.html')} file. You can change the path of this directory in ${colors_1.default.strong(config.app.extConfigName)} (${colors_1.default.input('webDir')} option). You may need to compile the web assets for your app (typically ${colors_1.default.input('npm run build')}). More info: ${colors_1.default.strong('https://capacitorjs.com/docs/basics/workflow#sync-your-project')}`);
|
||||
}
|
||||
if (!(await (0, utils_fs_1.pathExists)((0, path_1.join)(config.app.webDirAbs, 'index.html')))) {
|
||||
return (`The web assets directory (${colors_1.default.strong((0, utils_terminal_1.prettyPath)(config.app.webDirAbs))}) must contain an ${colors_1.default.strong('index.html')} file.\n` +
|
||||
`It will be the entry point for the web portion of the Capacitor app.`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.checkWebDir = checkWebDir;
|
||||
async function checkPackage() {
|
||||
if (!(await (0, utils_fs_1.pathExists)('package.json'))) {
|
||||
if (await (0, utils_fs_1.pathExists)('project.json')) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return (`The Capacitor CLI needs to run at the root of an npm package or in a valid NX monorepo.\n` +
|
||||
`Make sure you have a package.json or project.json file in the directory where you run the Capacitor CLI.\n` +
|
||||
`More info: ${colors_1.default.strong('https://docs.npmjs.com/cli/init')}`);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.checkPackage = checkPackage;
|
||||
async function checkCapacitorPlatform(config, platform) {
|
||||
const pkg = await getCapacitorPackage(config, platform);
|
||||
if (!pkg) {
|
||||
return (`Could not find the ${colors_1.default.input(platform)} platform.\n` +
|
||||
`You must install it in your project first, e.g. w/ ${colors_1.default.input(`npm install @capacitor/${platform}`)}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.checkCapacitorPlatform = checkCapacitorPlatform;
|
||||
async function checkAppConfig(config) {
|
||||
if (!config.app.appId) {
|
||||
return (`Missing ${colors_1.default.input('appId')} for new platform.\n` +
|
||||
`Please add it in ${config.app.extConfigName} or run ${colors_1.default.input('npx cap init')}.`);
|
||||
}
|
||||
if (!config.app.appName) {
|
||||
return (`Missing ${colors_1.default.input('appName')} for new platform.\n` +
|
||||
`Please add it in ${config.app.extConfigName} or run ${colors_1.default.input('npx cap init')}.`);
|
||||
}
|
||||
const appIdError = await checkAppId(config, config.app.appId);
|
||||
if (appIdError) {
|
||||
return appIdError;
|
||||
}
|
||||
const appNameError = await checkAppName(config, config.app.appName);
|
||||
if (appNameError) {
|
||||
return appNameError;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.checkAppConfig = checkAppConfig;
|
||||
async function checkAppDir(config, dir) {
|
||||
if (!/^\S*$/.test(dir)) {
|
||||
return `Your app directory should not contain spaces`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.checkAppDir = checkAppDir;
|
||||
async function checkAppId(config, id) {
|
||||
if (!id) {
|
||||
return `Invalid App ID. Must be in Java package form with no dashes (ex: com.example.app)`;
|
||||
}
|
||||
if (/^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+$/.test(id.toLowerCase())) {
|
||||
return null;
|
||||
}
|
||||
return `Invalid App ID "${id}". Must be in Java package form with no dashes (ex: com.example.app)`;
|
||||
}
|
||||
exports.checkAppId = checkAppId;
|
||||
async function checkAppName(config, name) {
|
||||
// We allow pretty much anything right now, have fun
|
||||
if (!(name === null || name === void 0 ? void 0 : name.length)) {
|
||||
return `Must provide an app name. For example: 'Spacebook'`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.checkAppName = checkAppName;
|
||||
async function wait(time) {
|
||||
return new Promise(resolve => setTimeout(resolve, time));
|
||||
}
|
||||
exports.wait = wait;
|
||||
async function runHooks(config, platformName, dir, hook) {
|
||||
await runPlatformHook(config, platformName, dir, hook);
|
||||
const allPlugins = await (0, plugin_1.getPlugins)(config, platformName);
|
||||
allPlugins.forEach(async (p) => {
|
||||
await runPlatformHook(config, platformName, p.rootPath, hook);
|
||||
});
|
||||
}
|
||||
exports.runHooks = runHooks;
|
||||
async function runPlatformHook(config, platformName, platformDir, hook) {
|
||||
var _a;
|
||||
const { spawn } = await Promise.resolve().then(() => tslib_1.__importStar(require('child_process')));
|
||||
let pkg;
|
||||
if ((0, monorepotools_1.isNXMonorepo)(platformDir)) {
|
||||
pkg = await (0, utils_fs_1.readJSON)((0, path_1.join)((0, monorepotools_1.findNXMonorepoRoot)(platformDir), 'package.json'));
|
||||
}
|
||||
else {
|
||||
pkg = await (0, utils_fs_1.readJSON)((0, path_1.join)(platformDir, 'package.json'));
|
||||
}
|
||||
const cmd = (_a = pkg.scripts) === null || _a === void 0 ? void 0 : _a[hook];
|
||||
if (!cmd) {
|
||||
return;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const p = spawn(cmd, {
|
||||
stdio: 'inherit',
|
||||
shell: true,
|
||||
cwd: platformDir,
|
||||
env: {
|
||||
INIT_CWD: platformDir,
|
||||
CAPACITOR_ROOT_DIR: config.app.rootDir,
|
||||
CAPACITOR_WEB_DIR: config.app.webDirAbs,
|
||||
CAPACITOR_CONFIG: JSON.stringify(config.app.extConfig),
|
||||
CAPACITOR_PLATFORM_NAME: platformName,
|
||||
...process.env,
|
||||
},
|
||||
});
|
||||
p.on('close', () => {
|
||||
resolve();
|
||||
});
|
||||
p.on('error', err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.runPlatformHook = runPlatformHook;
|
||||
async function runTask(title, fn) {
|
||||
const chain = log_1.output.createTaskChain();
|
||||
chain.next(title);
|
||||
try {
|
||||
const value = await fn();
|
||||
chain.end();
|
||||
return value;
|
||||
}
|
||||
catch (e) {
|
||||
chain.fail();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
exports.runTask = runTask;
|
||||
async function getCapacitorPackage(config, name) {
|
||||
const packagePath = (0, node_1.resolveNode)(config.app.rootDir, `@capacitor/${name}`, 'package.json');
|
||||
if (!packagePath) {
|
||||
return null;
|
||||
}
|
||||
return (0, utils_fs_1.readJSON)(packagePath);
|
||||
}
|
||||
exports.getCapacitorPackage = getCapacitorPackage;
|
||||
async function requireCapacitorPackage(config, name) {
|
||||
const pkg = await getCapacitorPackage(config, name);
|
||||
if (!pkg) {
|
||||
(0, errors_1.fatal)(`Unable to find node_modules/@capacitor/${name}.\n` +
|
||||
`Are you sure ${colors_1.default.strong(`@capacitor/${name}`)} is installed?`);
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
exports.requireCapacitorPackage = requireCapacitorPackage;
|
||||
async function getCapacitorPackageVersion(config, platform) {
|
||||
return (await requireCapacitorPackage(config, platform)).version;
|
||||
}
|
||||
exports.getCapacitorPackageVersion = getCapacitorPackageVersion;
|
||||
async function getCoreVersion(config) {
|
||||
return getCapacitorPackageVersion(config, 'core');
|
||||
}
|
||||
exports.getCoreVersion = getCoreVersion;
|
||||
async function getCLIVersion(config) {
|
||||
return getCapacitorPackageVersion(config, 'cli');
|
||||
}
|
||||
exports.getCLIVersion = getCLIVersion;
|
||||
function getPlatformDirectory(config, platform) {
|
||||
switch (platform) {
|
||||
case 'android':
|
||||
return config.android.platformDirAbs;
|
||||
case 'ios':
|
||||
return config.ios.platformDirAbs;
|
||||
case 'web':
|
||||
return config.web.platformDirAbs;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
async function getProjectPlatformDirectory(config, platform) {
|
||||
const platformPath = getPlatformDirectory(config, platform);
|
||||
if (platformPath && (await (0, utils_fs_1.pathExists)(platformPath))) {
|
||||
return platformPath;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.getProjectPlatformDirectory = getProjectPlatformDirectory;
|
||||
async function selectPlatforms(config, selectedPlatformName) {
|
||||
if (selectedPlatformName) {
|
||||
// already passed in a platform name
|
||||
const platformName = selectedPlatformName.toLowerCase().trim();
|
||||
if (!(await isValidPlatform(platformName))) {
|
||||
(0, errors_1.fatal)(`Invalid platform: ${colors_1.default.input(platformName)}`);
|
||||
}
|
||||
else if (!(await getProjectPlatformDirectory(config, platformName))) {
|
||||
if (platformName === 'web') {
|
||||
(0, errors_1.fatal)(`Could not find the web platform directory.\n` +
|
||||
`Make sure ${colors_1.default.strong(config.app.webDir)} exists.`);
|
||||
}
|
||||
(0, errors_1.fatal)(`${colors_1.default.strong(platformName)} platform has not been added yet.\n` +
|
||||
`See the docs for adding the ${colors_1.default.strong(platformName)} platform: ${colors_1.default.strong(`https://capacitorjs.com/docs/${platformName}#adding-the-${platformName}-platform`)}`);
|
||||
}
|
||||
// return the platform in an string array
|
||||
return [platformName];
|
||||
}
|
||||
// wasn't given a platform name, so let's
|
||||
// get the platforms that have already been created
|
||||
return getAddedPlatforms(config);
|
||||
}
|
||||
exports.selectPlatforms = selectPlatforms;
|
||||
async function getKnownPlatforms() {
|
||||
return ['web', 'android', 'ios'];
|
||||
}
|
||||
exports.getKnownPlatforms = getKnownPlatforms;
|
||||
async function isValidPlatform(platform) {
|
||||
return (await getKnownPlatforms()).includes(platform);
|
||||
}
|
||||
exports.isValidPlatform = isValidPlatform;
|
||||
async function getKnownCommunityPlatforms() {
|
||||
return ['electron'];
|
||||
}
|
||||
exports.getKnownCommunityPlatforms = getKnownCommunityPlatforms;
|
||||
async function isValidCommunityPlatform(platform) {
|
||||
return (await getKnownCommunityPlatforms()).includes(platform);
|
||||
}
|
||||
exports.isValidCommunityPlatform = isValidCommunityPlatform;
|
||||
async function getKnownEnterprisePlatforms() {
|
||||
return ['windows'];
|
||||
}
|
||||
exports.getKnownEnterprisePlatforms = getKnownEnterprisePlatforms;
|
||||
async function isValidEnterprisePlatform(platform) {
|
||||
return (await getKnownEnterprisePlatforms()).includes(platform);
|
||||
}
|
||||
exports.isValidEnterprisePlatform = isValidEnterprisePlatform;
|
||||
async function promptForPlatform(platforms, promptMessage, selectedPlatformName) {
|
||||
const { prompt } = await Promise.resolve().then(() => tslib_1.__importStar(require('prompts')));
|
||||
if (!selectedPlatformName) {
|
||||
const answers = await prompt([
|
||||
{
|
||||
type: 'select',
|
||||
name: 'mode',
|
||||
message: promptMessage,
|
||||
choices: platforms.map(p => ({ title: p, value: p })),
|
||||
},
|
||||
], { onCancel: () => process.exit(1) });
|
||||
return answers.mode.toLowerCase().trim();
|
||||
}
|
||||
const platformName = selectedPlatformName.toLowerCase().trim();
|
||||
if (!(await isValidPlatform(platformName))) {
|
||||
const knownPlatforms = await getKnownPlatforms();
|
||||
(0, errors_1.fatal)(`Invalid platform: ${colors_1.default.input(platformName)}.\n` +
|
||||
`Valid platforms include: ${knownPlatforms.join(', ')}`);
|
||||
}
|
||||
return platformName;
|
||||
}
|
||||
exports.promptForPlatform = promptForPlatform;
|
||||
async function promptForPlatformTarget(targets, selectedTarget) {
|
||||
const { prompt } = await Promise.resolve().then(() => tslib_1.__importStar(require('prompts')));
|
||||
const validTargets = targets.filter(t => t.id !== undefined);
|
||||
if (!selectedTarget) {
|
||||
if (validTargets.length === 1) {
|
||||
return validTargets[0];
|
||||
}
|
||||
else {
|
||||
const answers = await prompt([
|
||||
{
|
||||
type: 'select',
|
||||
name: 'target',
|
||||
message: 'Please choose a target device:',
|
||||
choices: validTargets.map(t => ({
|
||||
title: `${getPlatformTargetName(t)} (${t.id})`,
|
||||
value: t,
|
||||
})),
|
||||
},
|
||||
], { onCancel: () => process.exit(1) });
|
||||
return answers.target;
|
||||
}
|
||||
}
|
||||
const targetID = selectedTarget.trim();
|
||||
const target = targets.find(t => t.id === targetID);
|
||||
if (!target) {
|
||||
(0, errors_1.fatal)(`Invalid target ID: ${colors_1.default.input(targetID)}.\n` +
|
||||
`Valid targets are: ${targets.map(t => t.id).join(', ')}`);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
exports.promptForPlatformTarget = promptForPlatformTarget;
|
||||
function getPlatformTargetName(target) {
|
||||
var _a, _b, _c;
|
||||
return `${(_c = (_b = (_a = target.name) !== null && _a !== void 0 ? _a : target.model) !== null && _b !== void 0 ? _b : target.id) !== null && _c !== void 0 ? _c : '?'}${target.virtual
|
||||
? ` (${target.platform === 'ios' ? 'simulator' : 'emulator'})`
|
||||
: ''}`;
|
||||
}
|
||||
exports.getPlatformTargetName = getPlatformTargetName;
|
||||
async function getAddedPlatforms(config) {
|
||||
const platforms = [];
|
||||
if (await getProjectPlatformDirectory(config, config.android.name)) {
|
||||
platforms.push(config.android.name);
|
||||
}
|
||||
if (await getProjectPlatformDirectory(config, config.ios.name)) {
|
||||
platforms.push(config.ios.name);
|
||||
}
|
||||
platforms.push(config.web.name);
|
||||
return platforms;
|
||||
}
|
||||
exports.getAddedPlatforms = getAddedPlatforms;
|
||||
async function checkPlatformVersions(config, platform) {
|
||||
const semver = await Promise.resolve().then(() => tslib_1.__importStar(require('semver')));
|
||||
const coreVersion = await getCoreVersion(config);
|
||||
const platformVersion = await getCapacitorPackageVersion(config, platform);
|
||||
if (semver.diff(coreVersion, platformVersion) === 'minor' ||
|
||||
semver.diff(coreVersion, platformVersion) === 'major') {
|
||||
log_1.logger.warn(`${colors_1.default.strong('@capacitor/core')}${colors_1.default.weak(`@${coreVersion}`)} version doesn't match ${colors_1.default.strong(`@capacitor/${platform}`)}${colors_1.default.weak(`@${platformVersion}`)} version.\n` +
|
||||
`Consider updating to a matching version, e.g. w/ ${colors_1.default.input(`npm install @capacitor/core@${platformVersion}`)}`);
|
||||
}
|
||||
}
|
||||
exports.checkPlatformVersions = checkPlatformVersions;
|
||||
function resolvePlatform(config, platform) {
|
||||
if (platform[0] !== '@') {
|
||||
const core = (0, node_1.resolveNode)(config.app.rootDir, `@capacitor/${platform}`, 'package.json');
|
||||
if (core) {
|
||||
return (0, path_1.dirname)(core);
|
||||
}
|
||||
const community = (0, node_1.resolveNode)(config.app.rootDir, `@capacitor-community/${platform}`, 'package.json');
|
||||
if (community) {
|
||||
return (0, path_1.dirname)(community);
|
||||
}
|
||||
const enterprise = (0, node_1.resolveNode)(config.app.rootDir, `@ionic-enterprise/capacitor-${platform}`, 'package.json');
|
||||
if (enterprise) {
|
||||
return (0, path_1.dirname)(enterprise);
|
||||
}
|
||||
}
|
||||
// third-party
|
||||
const thirdParty = (0, node_1.resolveNode)(config.app.rootDir, platform, 'package.json');
|
||||
if (thirdParty) {
|
||||
return (0, path_1.dirname)(thirdParty);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.resolvePlatform = resolvePlatform;
|
||||
async function checkJDKMajorVersion() {
|
||||
try {
|
||||
const string = await (0, subprocess_1.runCommand)('java', ['--version']);
|
||||
const versionRegex = RegExp(/([0-9]+)\.?([0-9]*)\.?([0-9]*)/);
|
||||
const versionMatch = versionRegex.exec(string);
|
||||
if (versionMatch === null) {
|
||||
return -1;
|
||||
}
|
||||
const firstVersionNumber = parseInt(versionMatch[1]);
|
||||
const secondVersionNumber = parseInt(versionMatch[2]);
|
||||
if (typeof firstVersionNumber === 'number' && firstVersionNumber != 1) {
|
||||
return firstVersionNumber;
|
||||
}
|
||||
else if (typeof secondVersionNumber === 'number' &&
|
||||
firstVersionNumber == 1 &&
|
||||
secondVersionNumber < 9) {
|
||||
return secondVersionNumber;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
exports.checkJDKMajorVersion = checkJDKMajorVersion;
|
||||
function parseApkNameFromFlavor(flavor) {
|
||||
const convertedName = flavor.replace(/([A-Z])/g, '$1').toLowerCase();
|
||||
return `app-${convertedName ? `${convertedName}-` : ''}debug.apk`;
|
||||
}
|
||||
exports.parseApkNameFromFlavor = parseApkNameFromFlavor;
|
||||
398
@capacitor/cli/dist/config.js
vendored
Normal file
398
@capacitor/cli/dist/config.js
vendored
Normal file
|
|
@ -0,0 +1,398 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.checkExternalConfig = 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 utils_fs_1 = require("@ionic/utils-fs");
|
||||
const debug_1 = tslib_1.__importDefault(require("debug"));
|
||||
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)(utils_fs_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)(utils_fs_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, utils_fs_1.writeJSON)(extConfigFilePath, extConfig, { spaces: 2 });
|
||||
break;
|
||||
}
|
||||
case '.ts': {
|
||||
await (0, utils_fs_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, utils_fs_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, utils_fs_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)(utils_fs_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, utils_fs_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: '22',
|
||||
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;
|
||||
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';
|
||||
return {
|
||||
name,
|
||||
minVersion: '13.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,
|
||||
};
|
||||
}
|
||||
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, utils_fs_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, utils_fs_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, utils_fs_1.pathExists)((0, path_1.resolve)(rootDir, 'Gemfile'))) {
|
||||
gemfilePath = (0, path_1.resolve)(rootDir, 'Gemfile');
|
||||
}
|
||||
else if (await (0, utils_fs_1.pathExists)((0, path_1.resolve)(platformDir, 'Gemfile'))) {
|
||||
gemfilePath = (0, path_1.resolve)(platformDir, 'Gemfile');
|
||||
}
|
||||
else if (await (0, utils_fs_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, utils_fs_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`;
|
||||
}
|
||||
function checkExternalConfig(config) {
|
||||
if (typeof config.extConfig.bundledWebRuntime !== 'undefined') {
|
||||
let actionMessage = `Can be safely deleted.`;
|
||||
if (config.extConfig.bundledWebRuntime === true) {
|
||||
actionMessage = `Please, use a bundler to bundle Capacitor and its plugins.`;
|
||||
}
|
||||
log_1.logger.warn(`The ${colors_1.default.strong('bundledWebRuntime')} configuration option has been deprecated. ${actionMessage}`);
|
||||
}
|
||||
}
|
||||
exports.checkExternalConfig = checkExternalConfig;
|
||||
830
@capacitor/cli/dist/cordova.js
vendored
Normal file
830
@capacitor/cli/dist/cordova.js
vendored
Normal file
|
|
@ -0,0 +1,830 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.writeCordovaAndroidManifest = exports.getCordovaPreferences = exports.needsStaticPod = exports.getIncompatibleCordovaPlugins = exports.checkPluginDependencies = exports.logCordovaManualSteps = exports.getCordovaPlugins = exports.handleCordovaPluginsJS = exports.autoGenerateConfig = exports.removePluginFiles = exports.createEmptyCordovaJS = exports.copyCordovaJS = exports.copyPluginsJS = exports.generateCordovaPluginsJSFile = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const plist_1 = tslib_1.__importDefault(require("plist"));
|
||||
const prompts_1 = tslib_1.__importDefault(require("prompts"));
|
||||
const common_1 = require("./android/common");
|
||||
const colors_1 = tslib_1.__importDefault(require("./colors"));
|
||||
const errors_1 = require("./errors");
|
||||
const common_2 = require("./ios/common");
|
||||
const log_1 = require("./log");
|
||||
const plugin_1 = require("./plugin");
|
||||
const node_1 = require("./util/node");
|
||||
const term_1 = require("./util/term");
|
||||
const xml_1 = require("./util/xml");
|
||||
/**
|
||||
* Build the root cordova_plugins.js file referencing each Plugin JS file.
|
||||
*/
|
||||
function generateCordovaPluginsJSFile(config, plugins, platform) {
|
||||
const pluginModules = [];
|
||||
const pluginExports = [];
|
||||
plugins.map(p => {
|
||||
const pluginId = p.xml.$.id;
|
||||
const jsModules = (0, plugin_1.getJSModules)(p, platform);
|
||||
jsModules.map((jsModule) => {
|
||||
const clobbers = [];
|
||||
const merges = [];
|
||||
let clobbersModule = '';
|
||||
let mergesModule = '';
|
||||
let runsModule = '';
|
||||
let clobberKey = '';
|
||||
let mergeKey = '';
|
||||
if (jsModule.clobbers) {
|
||||
jsModule.clobbers.map((clobber) => {
|
||||
clobbers.push(clobber.$.target);
|
||||
clobberKey = clobber.$.target;
|
||||
});
|
||||
clobbersModule = `,
|
||||
"clobbers": [
|
||||
"${clobbers.join('",\n "')}"
|
||||
]`;
|
||||
}
|
||||
if (jsModule.merges) {
|
||||
jsModule.merges.map((merge) => {
|
||||
merges.push(merge.$.target);
|
||||
mergeKey = merge.$.target;
|
||||
});
|
||||
mergesModule = `,
|
||||
"merges": [
|
||||
"${merges.join('",\n "')}"
|
||||
]`;
|
||||
}
|
||||
if (jsModule.runs) {
|
||||
runsModule = ',\n "runs": true';
|
||||
}
|
||||
const pluginModule = {
|
||||
clobber: clobberKey,
|
||||
merge: mergeKey,
|
||||
// mimics Cordova's module name logic if the name attr is missing
|
||||
pluginContent: `{
|
||||
"id": "${pluginId +
|
||||
'.' +
|
||||
(jsModule.$.name || jsModule.$.src.match(/([^/]+)\.js/)[1])}",
|
||||
"file": "plugins/${pluginId}/${jsModule.$.src}",
|
||||
"pluginId": "${pluginId}"${clobbersModule}${mergesModule}${runsModule}
|
||||
}`,
|
||||
};
|
||||
pluginModules.push(pluginModule);
|
||||
});
|
||||
pluginExports.push(`"${pluginId}": "${p.xml.$.version}"`);
|
||||
});
|
||||
return `
|
||||
cordova.define('cordova/plugin_list', function(require, exports, module) {
|
||||
module.exports = [
|
||||
${pluginModules
|
||||
.sort((a, b) => a.clobber && b.clobber // Clobbers in alpha order
|
||||
? a.clobber.localeCompare(b.clobber)
|
||||
: a.clobber || b.clobber // Clobbers before anything else
|
||||
? b.clobber.localeCompare(a.clobber)
|
||||
: a.merge.localeCompare(b.merge))
|
||||
.map(e => e.pluginContent)
|
||||
.join(',\n ')}
|
||||
];
|
||||
module.exports.metadata =
|
||||
// TOP OF METADATA
|
||||
{
|
||||
${pluginExports.join(',\n ')}
|
||||
};
|
||||
// BOTTOM OF METADATA
|
||||
});
|
||||
`;
|
||||
}
|
||||
exports.generateCordovaPluginsJSFile = generateCordovaPluginsJSFile;
|
||||
/**
|
||||
* Build the plugins/* files for each Cordova plugin installed.
|
||||
*/
|
||||
async function copyPluginsJS(config, cordovaPlugins, platform) {
|
||||
const webDir = await getWebDir(config, platform);
|
||||
const pluginsDir = (0, path_1.join)(webDir, 'plugins');
|
||||
const cordovaPluginsJSFile = (0, path_1.join)(webDir, 'cordova_plugins.js');
|
||||
await removePluginFiles(config, platform);
|
||||
await Promise.all(cordovaPlugins.map(async (p) => {
|
||||
const pluginId = p.xml.$.id;
|
||||
const pluginDir = (0, path_1.join)(pluginsDir, pluginId, 'www');
|
||||
await (0, utils_fs_1.ensureDir)(pluginDir);
|
||||
const jsModules = (0, plugin_1.getJSModules)(p, platform);
|
||||
await Promise.all(jsModules.map(async (jsModule) => {
|
||||
const filePath = (0, path_1.join)(webDir, 'plugins', pluginId, jsModule.$.src);
|
||||
await (0, utils_fs_1.copy)((0, path_1.join)(p.rootPath, jsModule.$.src), filePath);
|
||||
let data = await (0, utils_fs_1.readFile)(filePath, { encoding: 'utf-8' });
|
||||
data = data.trim();
|
||||
// mimics Cordova's module name logic if the name attr is missing
|
||||
const name = pluginId +
|
||||
'.' +
|
||||
(jsModule.$.name ||
|
||||
(0, path_1.basename)(jsModule.$.src, (0, path_1.extname)(jsModule.$.src)));
|
||||
data = `cordova.define("${name}", function(require, exports, module) { \n${data}\n});`;
|
||||
data = data.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script\s*>/gi, '');
|
||||
await (0, utils_fs_1.writeFile)(filePath, data, { encoding: 'utf-8' });
|
||||
}));
|
||||
const assets = (0, plugin_1.getAssets)(p, platform);
|
||||
await Promise.all(assets.map(async (asset) => {
|
||||
const filePath = (0, path_1.join)(webDir, asset.$.target);
|
||||
await (0, utils_fs_1.copy)((0, path_1.join)(p.rootPath, asset.$.src), filePath);
|
||||
}));
|
||||
}));
|
||||
await (0, utils_fs_1.writeFile)(cordovaPluginsJSFile, generateCordovaPluginsJSFile(config, cordovaPlugins, platform));
|
||||
}
|
||||
exports.copyPluginsJS = copyPluginsJS;
|
||||
async function copyCordovaJS(config, platform) {
|
||||
const cordovaPath = (0, node_1.resolveNode)(config.app.rootDir, '@capacitor/core', 'cordova.js');
|
||||
if (!cordovaPath) {
|
||||
(0, errors_1.fatal)(`Unable to find ${colors_1.default.strong('node_modules/@capacitor/core/cordova.js')}.\n` + `Are you sure ${colors_1.default.strong('@capacitor/core')} is installed?`);
|
||||
}
|
||||
return (0, utils_fs_1.copy)(cordovaPath, (0, path_1.join)(await getWebDir(config, platform), 'cordova.js'));
|
||||
}
|
||||
exports.copyCordovaJS = copyCordovaJS;
|
||||
async function createEmptyCordovaJS(config, platform) {
|
||||
const webDir = await getWebDir(config, platform);
|
||||
await (0, utils_fs_1.writeFile)((0, path_1.join)(webDir, 'cordova.js'), '');
|
||||
await (0, utils_fs_1.writeFile)((0, path_1.join)(webDir, 'cordova_plugins.js'), '');
|
||||
}
|
||||
exports.createEmptyCordovaJS = createEmptyCordovaJS;
|
||||
async function removePluginFiles(config, platform) {
|
||||
const webDir = await getWebDir(config, platform);
|
||||
const pluginsDir = (0, path_1.join)(webDir, 'plugins');
|
||||
const cordovaPluginsJSFile = (0, path_1.join)(webDir, 'cordova_plugins.js');
|
||||
await (0, utils_fs_1.remove)(pluginsDir);
|
||||
await (0, utils_fs_1.remove)(cordovaPluginsJSFile);
|
||||
}
|
||||
exports.removePluginFiles = removePluginFiles;
|
||||
async function autoGenerateConfig(config, cordovaPlugins, platform) {
|
||||
var _a, _b, _c, _d;
|
||||
let xmlDir = (0, path_1.join)(config.android.resDirAbs, 'xml');
|
||||
const fileName = 'config.xml';
|
||||
if (platform === 'ios') {
|
||||
xmlDir = config.ios.nativeTargetDirAbs;
|
||||
}
|
||||
await (0, utils_fs_1.ensureDir)(xmlDir);
|
||||
const cordovaConfigXMLFile = (0, path_1.join)(xmlDir, fileName);
|
||||
await (0, utils_fs_1.remove)(cordovaConfigXMLFile);
|
||||
const pluginEntries = [];
|
||||
cordovaPlugins.map(p => {
|
||||
const currentPlatform = (0, plugin_1.getPluginPlatform)(p, platform);
|
||||
if (currentPlatform) {
|
||||
const configFiles = currentPlatform['config-file'];
|
||||
if (configFiles) {
|
||||
const configXMLEntries = configFiles.filter(function (item) {
|
||||
var _a;
|
||||
return (_a = item.$) === null || _a === void 0 ? void 0 : _a.target.includes(fileName);
|
||||
});
|
||||
configXMLEntries.map((entry) => {
|
||||
if (entry.feature) {
|
||||
const feature = { feature: entry.feature };
|
||||
pluginEntries.push(feature);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
let accessOriginString = [];
|
||||
if ((_b = (_a = config.app.extConfig) === null || _a === void 0 ? void 0 : _a.cordova) === null || _b === void 0 ? void 0 : _b.accessOrigins) {
|
||||
accessOriginString = await Promise.all(config.app.extConfig.cordova.accessOrigins.map(async (host) => {
|
||||
return `
|
||||
<access origin="${host}" />`;
|
||||
}));
|
||||
}
|
||||
else {
|
||||
accessOriginString.push(`<access origin="*" />`);
|
||||
}
|
||||
const pluginEntriesString = await Promise.all(pluginEntries.map(async (item) => {
|
||||
const xmlString = await (0, xml_1.writeXML)(item);
|
||||
return xmlString;
|
||||
}));
|
||||
let pluginPreferencesString = [];
|
||||
if ((_d = (_c = config.app.extConfig) === null || _c === void 0 ? void 0 : _c.cordova) === null || _d === void 0 ? void 0 : _d.preferences) {
|
||||
pluginPreferencesString = await Promise.all(Object.entries(config.app.extConfig.cordova.preferences).map(async ([key, value]) => {
|
||||
return `
|
||||
<preference name="${key}" value="${value}" />`;
|
||||
}));
|
||||
}
|
||||
const content = `<?xml version='1.0' encoding='utf-8'?>
|
||||
<widget version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||
${accessOriginString.join('')}
|
||||
${pluginEntriesString.join('')}
|
||||
${pluginPreferencesString.join('')}
|
||||
</widget>`;
|
||||
await (0, utils_fs_1.writeFile)(cordovaConfigXMLFile, content);
|
||||
}
|
||||
exports.autoGenerateConfig = autoGenerateConfig;
|
||||
async function getWebDir(config, platform) {
|
||||
if (platform === 'ios') {
|
||||
return config.ios.webDirAbs;
|
||||
}
|
||||
if (platform === 'android') {
|
||||
return config.android.webDirAbs;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
async function handleCordovaPluginsJS(cordovaPlugins, config, platform) {
|
||||
const webDir = await getWebDir(config, platform);
|
||||
await (0, utils_fs_1.mkdirp)(webDir);
|
||||
if (cordovaPlugins.length > 0) {
|
||||
(0, plugin_1.printPlugins)(cordovaPlugins, platform, 'cordova');
|
||||
await copyCordovaJS(config, platform);
|
||||
await copyPluginsJS(config, cordovaPlugins, platform);
|
||||
}
|
||||
else {
|
||||
await removePluginFiles(config, platform);
|
||||
await createEmptyCordovaJS(config, platform);
|
||||
}
|
||||
await autoGenerateConfig(config, cordovaPlugins, platform);
|
||||
}
|
||||
exports.handleCordovaPluginsJS = handleCordovaPluginsJS;
|
||||
async function getCordovaPlugins(config, platform) {
|
||||
const allPlugins = await (0, plugin_1.getPlugins)(config, platform);
|
||||
let plugins = [];
|
||||
if (platform === config.ios.name) {
|
||||
plugins = await (0, common_2.getIOSPlugins)(allPlugins);
|
||||
}
|
||||
else if (platform === config.android.name) {
|
||||
plugins = await (0, common_1.getAndroidPlugins)(allPlugins);
|
||||
}
|
||||
return plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 1 /* PluginType.Cordova */);
|
||||
}
|
||||
exports.getCordovaPlugins = getCordovaPlugins;
|
||||
async function logCordovaManualSteps(cordovaPlugins, config, platform) {
|
||||
cordovaPlugins.map(p => {
|
||||
const editConfig = (0, plugin_1.getPlatformElement)(p, platform, 'edit-config');
|
||||
const configFile = (0, plugin_1.getPlatformElement)(p, platform, 'config-file');
|
||||
editConfig.concat(configFile).map(async (configElement) => {
|
||||
if (configElement.$ && !configElement.$.target.includes('config.xml')) {
|
||||
if (platform === config.ios.name) {
|
||||
if (configElement.$.target.includes('Info.plist')) {
|
||||
logiOSPlist(configElement, config, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.logCordovaManualSteps = logCordovaManualSteps;
|
||||
async function logiOSPlist(configElement, config, plugin) {
|
||||
var _a, _b;
|
||||
let plistPath = (0, path_1.resolve)(config.ios.nativeTargetDirAbs, 'Info.plist');
|
||||
if ((_a = config.app.extConfig.ios) === null || _a === void 0 ? void 0 : _a.scheme) {
|
||||
plistPath = (0, path_1.resolve)(config.ios.nativeProjectDirAbs, `${(_b = config.app.extConfig.ios) === null || _b === void 0 ? void 0 : _b.scheme}-Info.plist`);
|
||||
}
|
||||
if (!(await (0, utils_fs_1.pathExists)(plistPath))) {
|
||||
plistPath = (0, path_1.resolve)(config.ios.nativeTargetDirAbs, 'Base.lproj', 'Info.plist');
|
||||
}
|
||||
if (await (0, utils_fs_1.pathExists)(plistPath)) {
|
||||
const xmlMeta = await (0, xml_1.readXML)(plistPath);
|
||||
const data = await (0, utils_fs_1.readFile)(plistPath, { encoding: 'utf-8' });
|
||||
const trimmedPlistData = data.replace(/(\t|\r|\n)/g, '');
|
||||
const plistData = plist_1.default.parse(data);
|
||||
const dict = xmlMeta.plist.dict.pop();
|
||||
if (!dict.key.includes(configElement.$.parent)) {
|
||||
let xml = buildConfigFileXml(configElement);
|
||||
xml = `<key>${configElement.$.parent}</key>${getConfigFileTagContent(xml)}`;
|
||||
log_1.logger.warn(`Configuration required for ${colors_1.default.strong(plugin.id)}.\n` +
|
||||
`Add the following to Info.plist:\n` +
|
||||
xml);
|
||||
}
|
||||
else if (configElement.array || configElement.dict) {
|
||||
if (configElement.array &&
|
||||
configElement.array.length > 0 &&
|
||||
configElement.array[0].string) {
|
||||
let xml = '';
|
||||
configElement.array[0].string.map((element) => {
|
||||
const d = plistData[configElement.$.parent];
|
||||
if (Array.isArray(d) && !d.includes(element)) {
|
||||
xml = xml.concat(`<string>${element}</string>\n`);
|
||||
}
|
||||
});
|
||||
if (xml.length > 0) {
|
||||
log_1.logger.warn(`Configuration required for ${colors_1.default.strong(plugin.id)}.\n` +
|
||||
`Add the following in the existing ${colors_1.default.strong(configElement.$.parent)} array of your Info.plist:\n` +
|
||||
xml);
|
||||
}
|
||||
}
|
||||
else {
|
||||
let xml = buildConfigFileXml(configElement);
|
||||
xml = `<key>${configElement.$.parent}</key>${getConfigFileTagContent(xml)}`;
|
||||
xml = `<plist version="1.0"><dict>${xml}</dict></plist>`;
|
||||
const parseXmlToSearchable = (childElementsObj, arrayToAddTo) => {
|
||||
for (const childElement of childElementsObj) {
|
||||
const childElementName = childElement['#name'];
|
||||
const toAdd = { name: childElementName };
|
||||
if (childElementName === 'key' || childElementName === 'string') {
|
||||
toAdd.value = childElement['_'];
|
||||
}
|
||||
else {
|
||||
if (childElement['$']) {
|
||||
toAdd.attrs = { ...childElement['$'] };
|
||||
}
|
||||
if (childElement['$$']) {
|
||||
toAdd.children = [];
|
||||
parseXmlToSearchable(childElement['$$'], toAdd['children']);
|
||||
}
|
||||
}
|
||||
arrayToAddTo.push(toAdd);
|
||||
}
|
||||
};
|
||||
const existingElements = (0, xml_1.parseXML)(trimmedPlistData, {
|
||||
explicitChildren: true,
|
||||
trim: true,
|
||||
preserveChildrenOrder: true,
|
||||
});
|
||||
const parsedExistingElements = [];
|
||||
const rootKeyOfExistingElements = Object.keys(existingElements)[0];
|
||||
const rootOfExistingElementsToAdd = { name: rootKeyOfExistingElements, children: [] };
|
||||
if (existingElements[rootKeyOfExistingElements]['$']) {
|
||||
rootOfExistingElementsToAdd.attrs = {
|
||||
...existingElements[rootKeyOfExistingElements]['$'],
|
||||
};
|
||||
}
|
||||
parseXmlToSearchable(existingElements[rootKeyOfExistingElements]['$$'], rootOfExistingElementsToAdd['children']);
|
||||
parsedExistingElements.push(rootOfExistingElementsToAdd);
|
||||
const requiredElements = (0, xml_1.parseXML)(xml, {
|
||||
explicitChildren: true,
|
||||
trim: true,
|
||||
preserveChildrenOrder: true,
|
||||
});
|
||||
const parsedRequiredElements = [];
|
||||
const rootKeyOfRequiredElements = Object.keys(requiredElements)[0];
|
||||
const rootOfRequiredElementsToAdd = { name: rootKeyOfRequiredElements, children: [] };
|
||||
if (requiredElements[rootKeyOfRequiredElements]['$']) {
|
||||
rootOfRequiredElementsToAdd.attrs = {
|
||||
...requiredElements[rootKeyOfRequiredElements]['$'],
|
||||
};
|
||||
}
|
||||
parseXmlToSearchable(requiredElements[rootKeyOfRequiredElements]['$$'], rootOfRequiredElementsToAdd['children']);
|
||||
parsedRequiredElements.push(rootOfRequiredElementsToAdd);
|
||||
const doesContainElements = (requiredElementsArray, existingElementsArray) => {
|
||||
for (const requiredElement of requiredElementsArray) {
|
||||
if (requiredElement.name === 'key' ||
|
||||
requiredElement.name === 'string') {
|
||||
let foundMatch = false;
|
||||
for (const existingElement of existingElementsArray) {
|
||||
if (existingElement.name === requiredElement.name &&
|
||||
(existingElement.value === requiredElement.value ||
|
||||
/^[$].{1,}$/.test(requiredElement.value.trim()))) {
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let foundMatch = false;
|
||||
for (const existingElement of existingElementsArray) {
|
||||
if (existingElement.name === requiredElement.name) {
|
||||
if ((requiredElement.children !== undefined) ===
|
||||
(existingElement.children !== undefined)) {
|
||||
if (doesContainElements(requiredElement.children, existingElement.children)) {
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if (!doesContainElements(parsedRequiredElements, parsedExistingElements)) {
|
||||
logPossibleMissingItem(configElement, plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
logPossibleMissingItem(configElement, plugin);
|
||||
}
|
||||
}
|
||||
function logPossibleMissingItem(configElement, plugin) {
|
||||
let xml = buildConfigFileXml(configElement);
|
||||
xml = getConfigFileTagContent(xml);
|
||||
xml = removeOuterTags(xml);
|
||||
log_1.logger.warn(`Configuration might be missing for ${colors_1.default.strong(plugin.id)}.\n` +
|
||||
`Add the following to the existing ${colors_1.default.strong(configElement.$.parent)} entry of Info.plist:\n` +
|
||||
xml);
|
||||
}
|
||||
function buildConfigFileXml(configElement) {
|
||||
return (0, xml_1.buildXmlElement)(configElement, 'config-file');
|
||||
}
|
||||
function getConfigFileTagContent(str) {
|
||||
return str.replace(/<config-file.+">|<\/config-file>/g, '');
|
||||
}
|
||||
function removeOuterTags(str) {
|
||||
const start = str.indexOf('>') + 1;
|
||||
const end = str.lastIndexOf('<');
|
||||
return str.substring(start, end);
|
||||
}
|
||||
async function checkPluginDependencies(plugins, platform) {
|
||||
const pluginDeps = new Map();
|
||||
const cordovaPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 1 /* PluginType.Cordova */);
|
||||
const incompatible = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 2 /* PluginType.Incompatible */);
|
||||
await Promise.all(cordovaPlugins.map(async (p) => {
|
||||
let allDependencies = [];
|
||||
allDependencies = allDependencies.concat((0, plugin_1.getPlatformElement)(p, platform, 'dependency'));
|
||||
if (p.xml['dependency']) {
|
||||
allDependencies = allDependencies.concat(p.xml['dependency']);
|
||||
}
|
||||
allDependencies = allDependencies.filter((dep) => !getIncompatibleCordovaPlugins(platform).includes(dep.$.id) &&
|
||||
incompatible.filter(p => p.id === dep.$.id || p.xml.$.id === dep.$.id)
|
||||
.length === 0);
|
||||
if (allDependencies) {
|
||||
await Promise.all(allDependencies.map(async (dep) => {
|
||||
var _a;
|
||||
let plugin = dep.$.id;
|
||||
let version = dep.$.version;
|
||||
if (plugin.includes('@') && plugin.indexOf('@') !== 0) {
|
||||
[plugin, version] = plugin.split('@');
|
||||
}
|
||||
if (cordovaPlugins.filter(p => p.id === plugin || p.xml.$.id === plugin).length === 0) {
|
||||
if ((_a = dep.$.url) === null || _a === void 0 ? void 0 : _a.startsWith('http')) {
|
||||
plugin = dep.$.url;
|
||||
version = dep.$.commit;
|
||||
}
|
||||
const deps = pluginDeps.get(p.id) || [];
|
||||
deps.push(`${plugin}${version ? colors_1.default.weak(` (${version})`) : ''}`);
|
||||
pluginDeps.set(p.id, deps);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}));
|
||||
if (pluginDeps.size > 0) {
|
||||
let msg = `${colors_1.default.failure(colors_1.default.strong('Plugins are missing dependencies.'))}\n` +
|
||||
`Cordova plugin dependencies must be installed in your project (e.g. w/ ${colors_1.default.input('npm install')}).\n`;
|
||||
for (const [plugin, deps] of pluginDeps.entries()) {
|
||||
msg +=
|
||||
`\n ${colors_1.default.strong(plugin)} is missing dependencies:\n` +
|
||||
deps.map(d => ` - ${d}`).join('\n');
|
||||
}
|
||||
log_1.logger.warn(`${msg}\n`);
|
||||
}
|
||||
}
|
||||
exports.checkPluginDependencies = checkPluginDependencies;
|
||||
function getIncompatibleCordovaPlugins(platform) {
|
||||
const pluginList = [
|
||||
'cordova-plugin-splashscreen',
|
||||
'cordova-plugin-ionic-webview',
|
||||
'cordova-plugin-crosswalk-webview',
|
||||
'cordova-plugin-wkwebview-engine',
|
||||
'cordova-plugin-console',
|
||||
'cordova-plugin-music-controls',
|
||||
'cordova-plugin-add-swift-support',
|
||||
'cordova-plugin-ionic-keyboard',
|
||||
'cordova-plugin-braintree',
|
||||
'@ionic-enterprise/filesystem',
|
||||
'@ionic-enterprise/keyboard',
|
||||
'@ionic-enterprise/splashscreen',
|
||||
'cordova-support-google-services',
|
||||
];
|
||||
if (platform === 'ios') {
|
||||
pluginList.push('cordova-plugin-statusbar', '@ionic-enterprise/statusbar', 'SalesforceMobileSDK-CordovaPlugin');
|
||||
}
|
||||
if (platform === 'android') {
|
||||
pluginList.push('cordova-plugin-compat');
|
||||
}
|
||||
return pluginList;
|
||||
}
|
||||
exports.getIncompatibleCordovaPlugins = getIncompatibleCordovaPlugins;
|
||||
function needsStaticPod(plugin, config) {
|
||||
var _a, _b, _c, _d;
|
||||
let pluginList = [
|
||||
'phonegap-plugin-push',
|
||||
'@batch.com/cordova-plugin',
|
||||
'onesignal-cordova-plugin',
|
||||
];
|
||||
if ((_b = (_a = config.app.extConfig) === null || _a === void 0 ? void 0 : _a.cordova) === null || _b === void 0 ? void 0 : _b.staticPlugins) {
|
||||
log_1.logger.warn('cordova.staticPlugins is deprecated, make sure you are using latest version of the plugin');
|
||||
pluginList = pluginList.concat((_d = (_c = config.app.extConfig) === null || _c === void 0 ? void 0 : _c.cordova) === null || _d === void 0 ? void 0 : _d.staticPlugins);
|
||||
}
|
||||
return pluginList.includes(plugin.id) || useFrameworks(plugin);
|
||||
}
|
||||
exports.needsStaticPod = needsStaticPod;
|
||||
function useFrameworks(plugin) {
|
||||
const podspecs = (0, plugin_1.getPlatformElement)(plugin, 'ios', 'podspec');
|
||||
const frameworkPods = podspecs.filter((podspec) => podspec.pods.filter((pods) => pods.$ && pods.$['use-frameworks'] === 'true').length > 0);
|
||||
return frameworkPods.length > 0;
|
||||
}
|
||||
async function getCordovaPreferences(config) {
|
||||
var _a, _b, _c, _d, _e;
|
||||
const configXml = (0, path_1.join)(config.app.rootDir, 'config.xml');
|
||||
let cordova = {};
|
||||
if (await (0, utils_fs_1.pathExists)(configXml)) {
|
||||
cordova.preferences = {};
|
||||
const xmlMeta = await (0, xml_1.readXML)(configXml);
|
||||
if (xmlMeta.widget.preference) {
|
||||
xmlMeta.widget.preference.map((pref) => {
|
||||
cordova.preferences[pref.$.name] = pref.$.value;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (cordova.preferences && Object.keys(cordova.preferences).length > 0) {
|
||||
if ((0, term_1.isInteractive)()) {
|
||||
const answers = await (0, log_1.logPrompt)(`${colors_1.default.strong(`Cordova preferences can be automatically ported to ${colors_1.default.strong(config.app.extConfigName)}.`)}\n` +
|
||||
`Keep in mind: Not all values can be automatically migrated from ${colors_1.default.strong('config.xml')}. There may be more work to do.\n` +
|
||||
`More info: ${colors_1.default.strong('https://capacitorjs.com/docs/cordova/migrating-from-cordova-to-capacitor')}`, {
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: `Migrate Cordova preferences from config.xml?`,
|
||||
initial: true,
|
||||
});
|
||||
if (answers.confirm) {
|
||||
if ((_b = (_a = config.app.extConfig) === null || _a === void 0 ? void 0 : _a.cordova) === null || _b === void 0 ? void 0 : _b.preferences) {
|
||||
const answers = await (0, prompts_1.default)([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: `${config.app.extConfigName} already contains Cordova preferences. Overwrite?`,
|
||||
},
|
||||
], { onCancel: () => process.exit(1) });
|
||||
if (!answers.confirm) {
|
||||
cordova = (_c = config.app.extConfig) === null || _c === void 0 ? void 0 : _c.cordova;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cordova = (_d = config.app.extConfig) === null || _d === void 0 ? void 0 : _d.cordova;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cordova = (_e = config.app.extConfig) === null || _e === void 0 ? void 0 : _e.cordova;
|
||||
}
|
||||
return cordova;
|
||||
}
|
||||
exports.getCordovaPreferences = getCordovaPreferences;
|
||||
async function writeCordovaAndroidManifest(cordovaPlugins, config, platform, cleartext) {
|
||||
var _a;
|
||||
const manifestPath = (0, path_1.join)(config.android.cordovaPluginsDirAbs, 'src', 'main', 'AndroidManifest.xml');
|
||||
const rootXMLEntries = [];
|
||||
const applicationXMLEntries = [];
|
||||
const applicationXMLAttributes = [];
|
||||
let prefsArray = [];
|
||||
cordovaPlugins.map(async (p) => {
|
||||
const editConfig = (0, plugin_1.getPlatformElement)(p, platform, 'edit-config');
|
||||
const configFile = (0, plugin_1.getPlatformElement)(p, platform, 'config-file');
|
||||
prefsArray = prefsArray.concat((0, plugin_1.getAllElements)(p, platform, 'preference'));
|
||||
editConfig.concat(configFile).map(async (configElement) => {
|
||||
var _a, _b;
|
||||
if (configElement.$ &&
|
||||
(((_a = configElement.$.target) === null || _a === void 0 ? void 0 : _a.includes('AndroidManifest.xml')) ||
|
||||
((_b = configElement.$.file) === null || _b === void 0 ? void 0 : _b.includes('AndroidManifest.xml')))) {
|
||||
const keys = Object.keys(configElement).filter(k => k !== '$');
|
||||
keys.map(k => {
|
||||
configElement[k].map(async (e) => {
|
||||
const xmlElement = (0, xml_1.buildXmlElement)(e, k);
|
||||
const pathParts = getPathParts(configElement.$.parent || configElement.$.target);
|
||||
if (pathParts.length > 1) {
|
||||
if (pathParts.pop() === 'application') {
|
||||
if (configElement.$.mode &&
|
||||
configElement.$.mode === 'merge' &&
|
||||
xmlElement.startsWith('<application')) {
|
||||
Object.keys(e.$).map((ek) => {
|
||||
applicationXMLAttributes.push(`${ek}="${e.$[ek]}"`);
|
||||
});
|
||||
}
|
||||
else if (!applicationXMLEntries.includes(xmlElement) &&
|
||||
!contains(applicationXMLEntries, xmlElement, k)) {
|
||||
applicationXMLEntries.push(xmlElement);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const manifestPathOfCapApp = (0, path_1.join)(config.android.appDirAbs, 'src', 'main', 'AndroidManifest.xml');
|
||||
const manifestContentTrimmed = (await (0, utils_fs_1.readFile)(manifestPathOfCapApp))
|
||||
.toString()
|
||||
.trim()
|
||||
.replace(/\n|\t|\r/g, '')
|
||||
.replace(/[\s]{1,}</g, '<')
|
||||
.replace(/>[\s]{1,}/g, '>')
|
||||
.replace(/[\s]{2,}/g, ' ');
|
||||
const requiredManifestContentTrimmed = xmlElement
|
||||
.trim()
|
||||
.replace(/\n|\t|\r/g, '')
|
||||
.replace(/[\s]{1,}</g, '<')
|
||||
.replace(/>[\s]{1,}/g, '>')
|
||||
.replace(/[\s]{2,}/g, ' ');
|
||||
const pathPartList = getPathParts(configElement.$.parent || configElement.$.target);
|
||||
const doesXmlManifestContainRequiredInfo = (requiredElements, existingElements, pathTarget) => {
|
||||
const findElementsToSearchIn = (existingElements, pathTarget) => {
|
||||
const parts = [...pathTarget];
|
||||
const elementsToSearchNextIn = [];
|
||||
for (const existingElement of existingElements) {
|
||||
if (existingElement.name === pathTarget[0]) {
|
||||
if (existingElement.children) {
|
||||
for (const el of existingElement.children) {
|
||||
elementsToSearchNextIn.push(el);
|
||||
}
|
||||
}
|
||||
else {
|
||||
elementsToSearchNextIn.push(existingElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (elementsToSearchNextIn.length === 0) {
|
||||
return [];
|
||||
}
|
||||
else {
|
||||
parts.splice(0, 1);
|
||||
if (parts.length <= 0) {
|
||||
return elementsToSearchNextIn;
|
||||
}
|
||||
else {
|
||||
return findElementsToSearchIn(elementsToSearchNextIn, parts);
|
||||
}
|
||||
}
|
||||
};
|
||||
const parseXmlToSearchable = (childElementsObj, arrayToAddTo) => {
|
||||
for (const childElementKey of Object.keys(childElementsObj)) {
|
||||
for (const occurannceOfElement of childElementsObj[childElementKey]) {
|
||||
const toAdd = { name: childElementKey };
|
||||
if (occurannceOfElement['$']) {
|
||||
toAdd.attrs = { ...occurannceOfElement['$'] };
|
||||
}
|
||||
if (occurannceOfElement['$$']) {
|
||||
toAdd.children = [];
|
||||
parseXmlToSearchable(occurannceOfElement['$$'], toAdd['children']);
|
||||
}
|
||||
arrayToAddTo.push(toAdd);
|
||||
}
|
||||
}
|
||||
};
|
||||
const doesElementMatch = (requiredElement, existingElement) => {
|
||||
var _a;
|
||||
if (requiredElement.name !== existingElement.name) {
|
||||
return false;
|
||||
}
|
||||
if ((requiredElement.attrs !== undefined) !==
|
||||
(existingElement.attrs !== undefined)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (requiredElement.attrs !== undefined) {
|
||||
const requiredELementAttrKeys = Object.keys(requiredElement.attrs);
|
||||
for (const key of requiredELementAttrKeys) {
|
||||
if (!/^[$].{1,}$/.test(requiredElement.attrs[key].trim())) {
|
||||
if (requiredElement.attrs[key] !==
|
||||
existingElement.attrs[key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((requiredElement.children !== undefined) !==
|
||||
(existingElement.children !== undefined) &&
|
||||
((_a = requiredElement.children) === null || _a === void 0 ? void 0 : _a.length) !== 0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (requiredElement.children !== undefined) {
|
||||
// each req element is in existing element
|
||||
for (const requiredElementItem of requiredElement.children) {
|
||||
let foundRequiredElement = false;
|
||||
for (const existingElementItem of existingElement.children) {
|
||||
const foundRequiredElementIn = doesElementMatch(requiredElementItem, existingElementItem);
|
||||
if (foundRequiredElementIn) {
|
||||
foundRequiredElement = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundRequiredElement) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (requiredElement.children === undefined &&
|
||||
existingElement.children === undefined) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
let foundRequiredElement = false;
|
||||
for (const existingElementItem of existingElement.children) {
|
||||
const foundRequiredElementIn = doesElementMatch(requiredElement, existingElementItem);
|
||||
if (foundRequiredElementIn) {
|
||||
foundRequiredElement = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundRequiredElement) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const parsedExistingElements = [];
|
||||
const rootKeyOfExistingElements = Object.keys(existingElements)[0];
|
||||
const rootOfExistingElementsToAdd = { name: rootKeyOfExistingElements, children: [] };
|
||||
if (existingElements[rootKeyOfExistingElements]['$']) {
|
||||
rootOfExistingElementsToAdd.attrs = {
|
||||
...existingElements[rootKeyOfExistingElements]['$'],
|
||||
};
|
||||
}
|
||||
parseXmlToSearchable(existingElements[rootKeyOfExistingElements]['$$'], rootOfExistingElementsToAdd['children']);
|
||||
parsedExistingElements.push(rootOfExistingElementsToAdd);
|
||||
const parsedRequiredElements = [];
|
||||
const rootKeyOfRequiredElements = Object.keys(requiredElements)[0];
|
||||
const rootOfRequiredElementsToAdd = { name: rootKeyOfRequiredElements, children: [] };
|
||||
if (requiredElements[rootKeyOfRequiredElements]['$']) {
|
||||
rootOfRequiredElementsToAdd.attrs = {
|
||||
...requiredElements[rootKeyOfRequiredElements]['$'],
|
||||
};
|
||||
}
|
||||
if (requiredElements[rootKeyOfRequiredElements]['$$'] !==
|
||||
undefined) {
|
||||
parseXmlToSearchable(requiredElements[rootKeyOfRequiredElements]['$$'], rootOfRequiredElementsToAdd['children']);
|
||||
}
|
||||
parsedRequiredElements.push(rootOfRequiredElementsToAdd);
|
||||
const elementsToSearch = findElementsToSearchIn(parsedExistingElements, pathTarget);
|
||||
for (const requiredElement of parsedRequiredElements) {
|
||||
let foundMatch = false;
|
||||
for (const existingElement of elementsToSearch) {
|
||||
const doesContain = doesElementMatch(requiredElement, existingElement);
|
||||
if (doesContain) {
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if (!doesXmlManifestContainRequiredInfo((0, xml_1.parseXML)(requiredManifestContentTrimmed, {
|
||||
explicitChildren: true,
|
||||
trim: true,
|
||||
}), (0, xml_1.parseXML)(manifestContentTrimmed, {
|
||||
explicitChildren: true,
|
||||
trim: true,
|
||||
}), pathPartList)) {
|
||||
log_1.logger.warn(`Android Configuration required for ${colors_1.default.strong(p.id)}.\n` +
|
||||
`Add the following to AndroidManifest.xml:\n` +
|
||||
xmlElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!rootXMLEntries.includes(xmlElement) &&
|
||||
!contains(rootXMLEntries, xmlElement, k)) {
|
||||
rootXMLEntries.push(xmlElement);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
const cleartextString = 'android:usesCleartextTraffic="true"';
|
||||
const cleartextValue = (cleartext || ((_a = config.app.extConfig.server) === null || _a === void 0 ? void 0 : _a.cleartext)) &&
|
||||
!applicationXMLAttributes.includes(cleartextString)
|
||||
? cleartextString
|
||||
: '';
|
||||
let content = `<?xml version='1.0' encoding='utf-8'?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:amazon="http://schemas.amazon.com/apk/res/android">
|
||||
<application ${applicationXMLAttributes.join('\n')} ${cleartextValue}>
|
||||
${applicationXMLEntries.join('\n')}
|
||||
</application>
|
||||
${rootXMLEntries.join('\n')}
|
||||
</manifest>`;
|
||||
content = content.replace(new RegExp('$PACKAGE_NAME'.replace('$', '\\$&'), 'g'), '${applicationId}');
|
||||
for (const preference of prefsArray) {
|
||||
content = content.replace(new RegExp(('$' + preference.$.name).replace('$', '\\$&'), 'g'), preference.$.default);
|
||||
}
|
||||
if (await (0, utils_fs_1.pathExists)(manifestPath)) {
|
||||
await (0, utils_fs_1.writeFile)(manifestPath, content);
|
||||
}
|
||||
}
|
||||
exports.writeCordovaAndroidManifest = writeCordovaAndroidManifest;
|
||||
function getPathParts(path) {
|
||||
const rootPath = 'manifest';
|
||||
path = path.replace('/*', rootPath);
|
||||
const parts = path.split('/').filter(part => part !== '');
|
||||
if (parts.length > 1 || parts.includes(rootPath)) {
|
||||
return parts;
|
||||
}
|
||||
return [rootPath, path];
|
||||
}
|
||||
function contains(entries, obj, k) {
|
||||
const element = (0, xml_1.parseXML)(obj);
|
||||
for (const entry of entries) {
|
||||
const current = (0, xml_1.parseXML)(entry);
|
||||
if (element &&
|
||||
current &&
|
||||
current[k] &&
|
||||
element[k] &&
|
||||
current[k].$ &&
|
||||
element[k].$ &&
|
||||
element[k].$['android:name'] === current[k].$['android:name']) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
592
@capacitor/cli/dist/declarations.d.ts
vendored
Normal file
592
@capacitor/cli/dist/declarations.d.ts
vendored
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
export interface CapacitorConfig {
|
||||
/**
|
||||
* The unique identifier of your packaged app.
|
||||
*
|
||||
* This is also known as the Bundle ID in iOS and the Application ID in
|
||||
* Android. It must be in reverse domain name notation, generally
|
||||
* representing a domain name that you or your company owns.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
appId?: string;
|
||||
/**
|
||||
* The human-friendly name of your app.
|
||||
*
|
||||
* This should be what you'd see in the App Store, but can be changed after
|
||||
* within each native platform after it is generated.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
appName?: string;
|
||||
/**
|
||||
* The directory of your compiled web assets.
|
||||
*
|
||||
* This directory should contain the final `index.html` of your app.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
webDir?: string;
|
||||
/**
|
||||
* Whether to copy the Capacitor runtime bundle or not.
|
||||
*
|
||||
* If your app is not using a bundler, set this to `true`, then Capacitor
|
||||
* will create a `capacitor.js` file that you'll need to add as a script in
|
||||
* your `index.html` file.
|
||||
*
|
||||
* It's deprecated and will be removed in Capacitor 6
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @deprecated 5.0.0
|
||||
* @default false
|
||||
*/
|
||||
bundledWebRuntime?: boolean;
|
||||
/**
|
||||
* The build configuration (as defined by the native app) under which Capacitor
|
||||
* will send statements to the log system. This applies to log statements in
|
||||
* native code as well as statements redirected from JavaScript (`console.debug`,
|
||||
* `console.error`, etc.). Enabling logging will let statements render in the
|
||||
* Xcode and Android Studio windows but can leak information on device if enabled
|
||||
* in released builds.
|
||||
*
|
||||
* 'none' = logs are never produced
|
||||
* 'debug' = logs are produced in debug builds but not production builds
|
||||
* 'production' = logs are always produced
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @default debug
|
||||
*/
|
||||
loggingBehavior?: 'none' | 'debug' | 'production';
|
||||
/**
|
||||
* User agent of Capacitor Web View.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
overrideUserAgent?: string;
|
||||
/**
|
||||
* String to append to the original user agent of Capacitor Web View.
|
||||
*
|
||||
* This is disregarded if `overrideUserAgent` is used.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
appendUserAgent?: string;
|
||||
/**
|
||||
* Background color of the Capacitor Web View.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
backgroundColor?: string;
|
||||
/**
|
||||
* Enable zooming within the Capacitor Web View.
|
||||
*
|
||||
* @default false
|
||||
* @since 6.0.0
|
||||
*/
|
||||
zoomEnabled?: boolean;
|
||||
android?: {
|
||||
/**
|
||||
* Specify a custom path to the native Android project.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @default android
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* User agent of Capacitor Web View on Android.
|
||||
*
|
||||
* Overrides global `overrideUserAgent` option.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
overrideUserAgent?: string;
|
||||
/**
|
||||
* String to append to the original user agent of Capacitor Web View for Android.
|
||||
*
|
||||
* Overrides global `appendUserAgent` option.
|
||||
*
|
||||
* This is disregarded if `overrideUserAgent` is used.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
appendUserAgent?: string;
|
||||
/**
|
||||
* Background color of the Capacitor Web View for Android.
|
||||
*
|
||||
* Overrides global `backgroundColor` option.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
backgroundColor?: string;
|
||||
/**
|
||||
* Enable zooming within the Capacitor Web View for Android.
|
||||
*
|
||||
* @default false
|
||||
* @since 6.0.0
|
||||
*/
|
||||
zoomEnabled?: boolean;
|
||||
/**
|
||||
* Enable mixed content in the Capacitor Web View for Android.
|
||||
*
|
||||
* [Mixed
|
||||
* content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content)
|
||||
* is disabled by default for security. During development, you may need to
|
||||
* enable it to allow the Web View to load files from different schemes.
|
||||
*
|
||||
* **This is not intended for use in production.**
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @default false
|
||||
*/
|
||||
allowMixedContent?: boolean;
|
||||
/**
|
||||
* This enables a simpler keyboard which may have some limitations.
|
||||
*
|
||||
* This will capture JS keys using an alternative
|
||||
* [`InputConnection`](https://developer.android.com/reference/android/view/inputmethod/InputConnection).
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @default false
|
||||
*/
|
||||
captureInput?: boolean;
|
||||
/**
|
||||
* Always enable debuggable web content.
|
||||
*
|
||||
* This is automatically enabled during development.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @default false
|
||||
*/
|
||||
webContentsDebuggingEnabled?: boolean;
|
||||
/**
|
||||
* The build configuration under which Capacitor will generate logs on Android.
|
||||
*
|
||||
* Overrides global `loggingBehavior` option.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @default debug
|
||||
*/
|
||||
loggingBehavior?: 'none' | 'debug' | 'production';
|
||||
/**
|
||||
* Allowlist of plugins to include during `npx cap sync` for Android.
|
||||
*
|
||||
* Overrides global `includePlugins` option.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
includePlugins?: string[];
|
||||
/**
|
||||
* Android flavor to use.
|
||||
*
|
||||
* If the app has flavors declared in the `build.gradle`
|
||||
* configure the flavor you want to run with `npx cap run` command.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
flavor?: string;
|
||||
/**
|
||||
* Whether to give the webview initial focus.
|
||||
*
|
||||
* @since 3.5.1
|
||||
* @default true
|
||||
*/
|
||||
initialFocus?: boolean;
|
||||
/**
|
||||
* The minimum supported webview version on Android supported by your app.
|
||||
*
|
||||
* The minimum supported cannot be lower than version `55`, which is required for Capacitor.
|
||||
*
|
||||
* If the device uses a lower WebView version, an error message will be shown on Logcat.
|
||||
* If `server.errorPath` is configured, the WebView will redirect to that file, so can be
|
||||
* used to show a custom error.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @default 60
|
||||
*/
|
||||
minWebViewVersion?: number;
|
||||
/**
|
||||
* The minimum supported Huawei webview version on Android supported by your app.
|
||||
*
|
||||
* The minimum supported cannot be lower than version `10`, which is required for Capacitor.
|
||||
*
|
||||
* If the device uses a lower WebView version, an error message will be shown on Logcat.
|
||||
* If `server.errorPath` is configured, the WebView will redirect to that file, so can be
|
||||
* used to show a custom error.
|
||||
*
|
||||
* @since 4.6.4
|
||||
* @default 10
|
||||
*/
|
||||
minHuaweiWebViewVersion?: number;
|
||||
buildOptions?: {
|
||||
/**
|
||||
* Path to your keystore
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
keystorePath?: string;
|
||||
/**
|
||||
* Password to your keystore
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
keystorePassword?: string;
|
||||
/**
|
||||
* Alias in the keystore to use
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
keystoreAlias?: string;
|
||||
/**
|
||||
* Password for the alias in the keystore to use
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
keystoreAliasPassword?: string;
|
||||
/**
|
||||
* Bundle type for your release build
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @default "AAB"
|
||||
*/
|
||||
releaseType?: 'AAB' | 'APK';
|
||||
/**
|
||||
* Program to sign your build with
|
||||
*
|
||||
* @since 5.1.0
|
||||
* @default "jarsigner"
|
||||
*/
|
||||
signingType?: 'apksigner' | 'jarsigner';
|
||||
};
|
||||
/**
|
||||
* Use legacy [addJavascriptInterface](https://developer.android.com/reference/android/webkit/WebView#addJavascriptInterface(java.lang.Object,%20java.lang.String))
|
||||
* instead of the new and more secure [addWebMessageListener](https://developer.android.com/reference/androidx/webkit/WebViewCompat#addWebMessageListener(android.webkit.WebView,java.lang.String,java.util.Set%3Cjava.lang.String%3E,androidx.webkit.WebViewCompat.WebMessageListener))
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @default false
|
||||
*/
|
||||
useLegacyBridge?: boolean;
|
||||
};
|
||||
ios?: {
|
||||
/**
|
||||
* Specify a custom path to the native iOS project.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @default ios
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* iOS build scheme to use.
|
||||
*
|
||||
* Usually this matches your app's target in Xcode. You can use the
|
||||
* following command to list schemes:
|
||||
*
|
||||
* ```shell
|
||||
* xcodebuild -workspace ios/App/App.xcworkspace -list
|
||||
* ```
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @default App
|
||||
*/
|
||||
scheme?: string;
|
||||
/**
|
||||
* User agent of Capacitor Web View on iOS.
|
||||
*
|
||||
* Overrides global `overrideUserAgent` option.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
overrideUserAgent?: string;
|
||||
/**
|
||||
* String to append to the original user agent of Capacitor Web View for iOS.
|
||||
*
|
||||
* Overrides global `appendUserAgent` option.
|
||||
*
|
||||
* This is disregarded if `overrideUserAgent` is used.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
appendUserAgent?: string;
|
||||
/**
|
||||
* Background color of the Capacitor Web View for iOS.
|
||||
*
|
||||
* Overrides global `backgroundColor` option.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
backgroundColor?: string;
|
||||
/**
|
||||
* Enable zooming within the Capacitor Web View for iOS.
|
||||
*
|
||||
* @default false
|
||||
* @since 6.0.0
|
||||
*/
|
||||
zoomEnabled?: boolean;
|
||||
/**
|
||||
* Configure the scroll view's content inset adjustment behavior.
|
||||
*
|
||||
* This will set the
|
||||
* [`contentInsetAdjustmentBehavior`](https://developer.apple.com/documentation/uikit/uiscrollview/2902261-contentinsetadjustmentbehavior)
|
||||
* property on the Web View's
|
||||
* [`UIScrollView`](https://developer.apple.com/documentation/uikit/uiscrollview).
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @default never
|
||||
*/
|
||||
contentInset?: 'automatic' | 'scrollableAxes' | 'never' | 'always';
|
||||
/**
|
||||
* Configure whether the scroll view is scrollable.
|
||||
*
|
||||
* This will set the
|
||||
* [`isScrollEnabled`](https://developer.apple.com/documentation/uikit/uiscrollview/1619395-isscrollenabled)
|
||||
* property on the Web View's
|
||||
* [`UIScrollView`](https://developer.apple.com/documentation/uikit/uiscrollview).
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
scrollEnabled?: boolean;
|
||||
/**
|
||||
* Configure custom linker flags for compiling Cordova plugins.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @default []
|
||||
*/
|
||||
cordovaLinkerFlags?: string[];
|
||||
/**
|
||||
* Allow destination previews when pressing on links.
|
||||
*
|
||||
* This will set the
|
||||
* [`allowsLinkPreview`](https://developer.apple.com/documentation/webkit/wkwebview/1415000-allowslinkpreview)
|
||||
* property on the Web View, instead of using the default value.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
allowsLinkPreview?: boolean;
|
||||
/**
|
||||
* The build configuration under which Capacitor will generate logs on iOS.
|
||||
*
|
||||
* Overrides global `loggingBehavior` option.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @default debug
|
||||
*/
|
||||
loggingBehavior?: 'none' | 'debug' | 'production';
|
||||
/**
|
||||
* Allowlist of plugins to include during `npx cap sync` for iOS.
|
||||
*
|
||||
* Overrides global `includePlugins` option.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
includePlugins?: string[];
|
||||
/**
|
||||
* Sets WKWebView configuration for limitsNavigationsToAppBoundDomains.
|
||||
*
|
||||
* If the Info.plist file includes `WKAppBoundDomains` key, it's recommended to
|
||||
* set this option to true, otherwise some features won't work.
|
||||
* But as side effect, it blocks navigation outside the domains in the
|
||||
* `WKAppBoundDomains` list.
|
||||
* `localhost` (or the value configured as `server.hostname`) also needs to be
|
||||
* added to the `WKAppBoundDomains` list.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @default false
|
||||
*/
|
||||
limitsNavigationsToAppBoundDomains?: boolean;
|
||||
/**
|
||||
* The content mode for the web view to use when it loads and renders web content.
|
||||
*
|
||||
* - 'recommended': The content mode that is appropriate for the current device.
|
||||
* - 'desktop': The content mode that represents a desktop experience.
|
||||
* - 'mobile': The content mode that represents a mobile experience.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @default recommended
|
||||
*/
|
||||
preferredContentMode?: 'recommended' | 'desktop' | 'mobile';
|
||||
/**
|
||||
* Configure if Capacitor will handle local/push notifications.
|
||||
* Set to false if you want to use your own UNUserNotificationCenter to handle notifications.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @default true
|
||||
*/
|
||||
handleApplicationNotifications?: boolean;
|
||||
/**
|
||||
* Using Xcode 14.3, on iOS 16.4 and greater, enable debuggable web content for release builds.
|
||||
*
|
||||
* If not set, it's `true` for development builds.
|
||||
*
|
||||
* @since 4.8.0
|
||||
* @default false
|
||||
*/
|
||||
webContentsDebuggingEnabled?: boolean;
|
||||
};
|
||||
server?: {
|
||||
/**
|
||||
* Configure the local hostname of the device.
|
||||
*
|
||||
* It is recommended to keep this as `localhost` as it allows the use of
|
||||
* Web APIs that would otherwise require a [secure
|
||||
* context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts)
|
||||
* such as
|
||||
* [`navigator.geolocation`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/geolocation)
|
||||
* and
|
||||
* [`MediaDevices.getUserMedia`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia).
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @default localhost
|
||||
*/
|
||||
hostname?: string;
|
||||
/**
|
||||
* Configure the local scheme on iOS.
|
||||
*
|
||||
* [Can't be set to schemes that the WKWebView already handles, such as http or https](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/2875766-seturlschemehandler)
|
||||
* This can be useful when migrating from
|
||||
* [`cordova-plugin-ionic-webview`](https://github.com/ionic-team/cordova-plugin-ionic-webview),
|
||||
* where the default scheme on iOS is `ionic`.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @default capacitor
|
||||
*/
|
||||
iosScheme?: string;
|
||||
/**
|
||||
* Configure the local scheme on Android.
|
||||
*
|
||||
* Custom schemes on Android are unable to change the URL path as of Webview 117. Changing this value from anything other than `http` or `https` can result in your
|
||||
* application unable to resolve routing. If you must change this for some reason, consider using a hash-based url strategy, but there are no guarentees that this
|
||||
* will continue to work long term as allowing non-standard schemes to modify query parameters and url fragments is only allowed for compatibility reasons.
|
||||
* https://ionic.io/blog/capacitor-android-customscheme-issue-with-chrome-117
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @default https
|
||||
*/
|
||||
androidScheme?: string;
|
||||
/**
|
||||
* Load an external URL in the Web View.
|
||||
*
|
||||
* This is intended for use with live-reload servers.
|
||||
*
|
||||
* **This is not intended for use in production.**
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* Allow cleartext traffic in the Web View.
|
||||
*
|
||||
* On Android, all cleartext traffic is disabled by default as of API 28.
|
||||
*
|
||||
* This is intended for use with live-reload servers where unencrypted HTTP
|
||||
* traffic is often used.
|
||||
*
|
||||
* **This is not intended for use in production.**
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @default false
|
||||
*/
|
||||
cleartext?: boolean;
|
||||
/**
|
||||
* Set additional URLs the Web View can navigate to.
|
||||
*
|
||||
* By default, all external URLs are opened in the external browser (not
|
||||
* the Web View).
|
||||
*
|
||||
* **This is not intended for use in production.**
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @default []
|
||||
*/
|
||||
allowNavigation?: string[];
|
||||
/**
|
||||
* Specify path to a local html page to display in case of errors.
|
||||
* On Android the html file won't have access to Capacitor plugins.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @default null
|
||||
*/
|
||||
errorPath?: string;
|
||||
};
|
||||
cordova?: {
|
||||
/**
|
||||
* Populates <access> tags in the config.xml with the origin set to
|
||||
* the values entered here.
|
||||
* If not provided, a single <access origin="*" /> tag gets included.
|
||||
* It only has effect on a few Cordova plugins that respect the whitelist.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*/
|
||||
accessOrigins?: string[];
|
||||
/**
|
||||
* Configure Cordova preferences.
|
||||
*
|
||||
* @since 1.3.0
|
||||
*/
|
||||
preferences?: {
|
||||
[key: string]: string | undefined;
|
||||
};
|
||||
/**
|
||||
* List of Cordova plugins that need to be static but are not
|
||||
* already in the static plugin list.
|
||||
*
|
||||
* It's deprecated and will be removed in Capacitor 7
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @deprecated 6.1.1
|
||||
*/
|
||||
staticPlugins?: string[];
|
||||
};
|
||||
/**
|
||||
* Configure plugins.
|
||||
*
|
||||
* This is an object with configuration values specified by plugin class
|
||||
* name.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
plugins?: PluginsConfig;
|
||||
/**
|
||||
* Allowlist of plugins to include during `npx cap sync`.
|
||||
*
|
||||
* This should be an array of strings representing the npm package name of
|
||||
* plugins to include when running `npx cap sync`. If unset, Capacitor will
|
||||
* inspect `package.json` for a list of potential plugins.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
includePlugins?: string[];
|
||||
}
|
||||
export interface PluginsConfig {
|
||||
/**
|
||||
* Plugin configuration by class name.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
[key: string]: {
|
||||
[key: string]: any;
|
||||
} | undefined;
|
||||
/**
|
||||
* Capacitor Cookies plugin configuration
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
CapacitorCookies?: {
|
||||
/**
|
||||
* Enable CapacitorCookies to override the global `document.cookie` on native.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
enabled?: boolean;
|
||||
};
|
||||
/**
|
||||
* Capacitor Http plugin configuration
|
||||
*
|
||||
* @since 4.3.0
|
||||
*/
|
||||
CapacitorHttp?: {
|
||||
/**
|
||||
* Enable CapacitorHttp to override the global `fetch` and `XMLHttpRequest` on native.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
enabled?: boolean;
|
||||
};
|
||||
}
|
||||
2
@capacitor/cli/dist/declarations.js
vendored
Normal file
2
@capacitor/cli/dist/declarations.js
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
2
@capacitor/cli/dist/definitions.js
vendored
Normal file
2
@capacitor/cli/dist/definitions.js
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
27
@capacitor/cli/dist/errors.js
vendored
Normal file
27
@capacitor/cli/dist/errors.js
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isFatal = exports.fatal = exports.FatalException = exports.BaseException = void 0;
|
||||
class BaseException extends Error {
|
||||
constructor(message, code) {
|
||||
super(message);
|
||||
this.message = message;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
exports.BaseException = BaseException;
|
||||
class FatalException extends BaseException {
|
||||
constructor(message, exitCode = 1) {
|
||||
super(message, 'FATAL');
|
||||
this.message = message;
|
||||
this.exitCode = exitCode;
|
||||
}
|
||||
}
|
||||
exports.FatalException = FatalException;
|
||||
function fatal(message) {
|
||||
throw new FatalException(message);
|
||||
}
|
||||
exports.fatal = fatal;
|
||||
function isFatal(e) {
|
||||
return e && e instanceof FatalException;
|
||||
}
|
||||
exports.isFatal = isFatal;
|
||||
109
@capacitor/cli/dist/framework-configs.js
vendored
Normal file
109
@capacitor/cli/dist/framework-configs.js
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.detectFramework = void 0;
|
||||
const FRAMEWORK_CONFIGS = [
|
||||
{
|
||||
name: 'Angular',
|
||||
isMatch: config => hasDependency(config, '@angular/cli'),
|
||||
webDir: 'dist',
|
||||
priority: 3,
|
||||
},
|
||||
{
|
||||
name: 'Create React App',
|
||||
isMatch: config => hasDependency(config, 'react-scripts'),
|
||||
webDir: 'build',
|
||||
priority: 3,
|
||||
},
|
||||
{
|
||||
name: 'Ember',
|
||||
isMatch: config => hasDependency(config, 'ember-cli'),
|
||||
webDir: 'dist',
|
||||
priority: 3,
|
||||
},
|
||||
{
|
||||
name: 'Gatsby',
|
||||
isMatch: config => hasDependency(config, 'gatsby'),
|
||||
webDir: 'public',
|
||||
priority: 2,
|
||||
},
|
||||
{
|
||||
name: 'Ionic Angular',
|
||||
isMatch: config => hasDependency(config, '@ionic/angular'),
|
||||
webDir: 'www',
|
||||
priority: 1,
|
||||
},
|
||||
{
|
||||
name: 'Ionic React',
|
||||
isMatch: config => hasDependency(config, '@ionic/react'),
|
||||
webDir: 'build',
|
||||
priority: 1,
|
||||
},
|
||||
{
|
||||
name: 'Ionic Vue',
|
||||
isMatch: config => hasDependency(config, '@ionic/vue'),
|
||||
webDir: 'public',
|
||||
priority: 1,
|
||||
},
|
||||
{
|
||||
name: 'Next',
|
||||
isMatch: config => hasDependency(config, 'next'),
|
||||
webDir: 'public',
|
||||
priority: 2,
|
||||
},
|
||||
{
|
||||
name: 'Preact',
|
||||
isMatch: config => hasDependency(config, 'preact-cli'),
|
||||
webDir: 'build',
|
||||
priority: 3,
|
||||
},
|
||||
{
|
||||
name: 'Stencil',
|
||||
isMatch: config => hasDependency(config, '@stencil/core'),
|
||||
webDir: 'www',
|
||||
priority: 3,
|
||||
},
|
||||
{
|
||||
name: 'Svelte',
|
||||
isMatch: config => hasDependency(config, 'svelte') && hasDependency(config, 'sirv-cli'),
|
||||
webDir: 'public',
|
||||
priority: 3,
|
||||
},
|
||||
{
|
||||
name: 'Vite',
|
||||
isMatch: config => hasDependency(config, 'vite'),
|
||||
webDir: 'dist',
|
||||
priority: 2,
|
||||
},
|
||||
{
|
||||
name: 'Vue',
|
||||
isMatch: config => hasDependency(config, '@vue/cli-service'),
|
||||
webDir: 'dist',
|
||||
priority: 3,
|
||||
},
|
||||
];
|
||||
function detectFramework(config) {
|
||||
const frameworks = FRAMEWORK_CONFIGS.filter(f => f.isMatch(config)).sort((a, b) => {
|
||||
if (a.priority < b.priority)
|
||||
return -1;
|
||||
if (a.priority > b.priority)
|
||||
return 1;
|
||||
return 0;
|
||||
});
|
||||
return frameworks[0];
|
||||
}
|
||||
exports.detectFramework = detectFramework;
|
||||
function hasDependency(config, depName) {
|
||||
const deps = getDependencies(config);
|
||||
return deps.includes(depName);
|
||||
}
|
||||
function getDependencies(config) {
|
||||
var _a, _b, _c, _d;
|
||||
const deps = [];
|
||||
if ((_b = (_a = config === null || config === void 0 ? void 0 : config.app) === null || _a === void 0 ? void 0 : _a.package) === null || _b === void 0 ? void 0 : _b.dependencies) {
|
||||
deps.push(...Object.keys(config.app.package.dependencies));
|
||||
}
|
||||
if ((_d = (_c = config === null || config === void 0 ? void 0 : config.app) === null || _c === void 0 ? void 0 : _c.package) === null || _d === void 0 ? void 0 : _d.devDependencies) {
|
||||
deps.push(...Object.keys(config.app.package.devDependencies));
|
||||
}
|
||||
return deps;
|
||||
}
|
||||
224
@capacitor/cli/dist/index.js
vendored
Normal file
224
@capacitor/cli/dist/index.js
vendored
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runProgram = exports.run = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const commander_1 = require("commander");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("./colors"));
|
||||
const config_1 = require("./config");
|
||||
const errors_1 = require("./errors");
|
||||
const ipc_1 = require("./ipc");
|
||||
const log_1 = require("./log");
|
||||
const telemetry_1 = require("./telemetry");
|
||||
const cli_1 = require("./util/cli");
|
||||
const emoji_1 = require("./util/emoji");
|
||||
process.on('unhandledRejection', error => {
|
||||
console.error(colors_1.default.failure('[fatal]'), error);
|
||||
});
|
||||
process.on('message', ipc_1.receive);
|
||||
async function run() {
|
||||
try {
|
||||
const config = await (0, config_1.loadConfig)();
|
||||
runProgram(config);
|
||||
}
|
||||
catch (e) {
|
||||
process.exitCode = (0, errors_1.isFatal)(e) ? e.exitCode : 1;
|
||||
log_1.logger.error(e.message ? e.message : String(e));
|
||||
}
|
||||
}
|
||||
exports.run = run;
|
||||
function runProgram(config) {
|
||||
commander_1.program.version(config.cli.package.version);
|
||||
commander_1.program
|
||||
.command('config', { hidden: true })
|
||||
.description(`print evaluated Capacitor config`)
|
||||
.option('--json', 'Print in JSON format')
|
||||
.action((0, cli_1.wrapAction)(async ({ json }) => {
|
||||
const { configCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/config')));
|
||||
await configCommand(config, json);
|
||||
}));
|
||||
commander_1.program
|
||||
.command('create [directory] [name] [id]', { hidden: true })
|
||||
.description('Creates a new Capacitor project')
|
||||
.action((0, cli_1.wrapAction)(async () => {
|
||||
const { createCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/create')));
|
||||
await createCommand();
|
||||
}));
|
||||
commander_1.program
|
||||
.command('init [appName] [appId]')
|
||||
.description(`Initialize Capacitor configuration`)
|
||||
.option('--web-dir <value>', 'Optional: Directory of your projects built web assets')
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (appName, appId, { webDir }) => {
|
||||
const { initCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/init')));
|
||||
await initCommand(config, appName, appId, webDir);
|
||||
})));
|
||||
commander_1.program
|
||||
.command('serve', { hidden: true })
|
||||
.description('Serves a Capacitor Progressive Web App in the browser')
|
||||
.action((0, cli_1.wrapAction)(async () => {
|
||||
const { serveCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/serve')));
|
||||
await serveCommand();
|
||||
}));
|
||||
commander_1.program
|
||||
.command('sync [platform]')
|
||||
.description(`${colors_1.default.input('copy')} + ${colors_1.default.input('update')}`)
|
||||
.option('--deployment', 'Optional: if provided, pod install will use --deployment option')
|
||||
.option('--inline', 'Optional: if true, all source maps will be inlined for easier debugging on mobile devices', false)
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { deployment, inline }) => {
|
||||
(0, config_1.checkExternalConfig)(config.app);
|
||||
const { syncCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/sync')));
|
||||
await syncCommand(config, platform, deployment, inline);
|
||||
})));
|
||||
commander_1.program
|
||||
.command('update [platform]')
|
||||
.description(`updates the native plugins and dependencies based on ${colors_1.default.strong('package.json')}`)
|
||||
.option('--deployment', 'Optional: if provided, pod install will use --deployment option')
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { deployment }) => {
|
||||
(0, config_1.checkExternalConfig)(config.app);
|
||||
const { updateCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/update')));
|
||||
await updateCommand(config, platform, deployment);
|
||||
})));
|
||||
commander_1.program
|
||||
.command('copy [platform]')
|
||||
.description('copies the web app build into the native app')
|
||||
.option('--inline', 'Optional: if true, all source maps will be inlined for easier debugging on mobile devices', false)
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { inline }) => {
|
||||
(0, config_1.checkExternalConfig)(config.app);
|
||||
const { copyCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/copy')));
|
||||
await copyCommand(config, platform, inline);
|
||||
})));
|
||||
commander_1.program
|
||||
.command('build <platform>')
|
||||
.description('builds the release version of the selected platform')
|
||||
.option('--scheme <schemeToBuild>', 'iOS Scheme to build')
|
||||
.option('--flavor <flavorToBuild>', 'Android Flavor to build')
|
||||
.option('--keystorepath <keystorePath>', 'Path to the keystore')
|
||||
.option('--keystorepass <keystorePass>', 'Password to the keystore')
|
||||
.option('--keystorealias <keystoreAlias>', 'Key Alias in the keystore')
|
||||
.option('--configuration <name>', 'Configuration name of the iOS Scheme')
|
||||
.option('--keystorealiaspass <keystoreAliasPass>', 'Password for the Key Alias')
|
||||
.addOption(new commander_1.Option('--androidreleasetype <androidreleasetype>', 'Android release type; APK or AAB').choices(['AAB', 'APK']))
|
||||
.addOption(new commander_1.Option('--signing-type <signingtype>', 'Program used to sign apps (default: jarsigner)').choices(['apksigner', 'jarsigner']))
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { scheme, flavor, keystorepath, keystorepass, keystorealias, keystorealiaspass, androidreleasetype, signingType, configuration, }) => {
|
||||
const { buildCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/build')));
|
||||
await buildCommand(config, platform, {
|
||||
scheme,
|
||||
flavor,
|
||||
keystorepath,
|
||||
keystorepass,
|
||||
keystorealias,
|
||||
keystorealiaspass,
|
||||
androidreleasetype,
|
||||
signingtype: signingType,
|
||||
configuration,
|
||||
});
|
||||
})));
|
||||
commander_1.program
|
||||
.command(`run [platform]`)
|
||||
.description(`runs ${colors_1.default.input('sync')}, then builds and deploys the native app`)
|
||||
.option('--scheme <schemeName>', 'set the scheme of the iOS project')
|
||||
.option('--flavor <flavorName>', 'set the flavor of the Android project (flavor dimensions not yet supported)')
|
||||
.option('--list', 'list targets, then quit')
|
||||
// TODO: remove once --json is a hidden option (https://github.com/tj/commander.js/issues/1106)
|
||||
.allowUnknownOption(true)
|
||||
.option('--target <id>', 'use a specific target')
|
||||
.option('--no-sync', `do not run ${colors_1.default.input('sync')}`)
|
||||
.option('--forwardPorts <port:port>', 'Automatically run "adb reverse" for better live-reloading support')
|
||||
.option('-l, --live-reload', 'Enable Live Reload')
|
||||
.option('--host <host>', 'Host used for live reload')
|
||||
.option('--port <port>', 'Port used for live reload')
|
||||
.option('--configuration <name>', 'Configuration name of the iOS Scheme')
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { scheme, flavor, list, target, sync, forwardPorts, liveReload, host, port, configuration, }) => {
|
||||
const { runCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/run')));
|
||||
await runCommand(config, platform, {
|
||||
scheme,
|
||||
flavor,
|
||||
list,
|
||||
target,
|
||||
sync,
|
||||
forwardPorts,
|
||||
liveReload,
|
||||
host,
|
||||
port,
|
||||
configuration,
|
||||
});
|
||||
})));
|
||||
commander_1.program
|
||||
.command('open [platform]')
|
||||
.description('opens the native project workspace (Xcode for iOS)')
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform) => {
|
||||
const { openCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/open')));
|
||||
await openCommand(config, platform);
|
||||
})));
|
||||
commander_1.program
|
||||
.command('add [platform]')
|
||||
.description('add a native platform project')
|
||||
.option('--packagemanager <packageManager>', 'The package manager to use for dependency installs (Cocoapods, SPM **experimental**)')
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { packagemanager }) => {
|
||||
(0, config_1.checkExternalConfig)(config.app);
|
||||
const { addCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/add')));
|
||||
const configWritable = config;
|
||||
if (packagemanager === 'SPM') {
|
||||
configWritable.cli.assets.ios.platformTemplateArchive =
|
||||
'ios-spm-template.tar.gz';
|
||||
configWritable.cli.assets.ios.platformTemplateArchiveAbs = (0, path_1.resolve)(configWritable.cli.assetsDirAbs, configWritable.cli.assets.ios.platformTemplateArchive);
|
||||
}
|
||||
await addCommand(configWritable, platform);
|
||||
})));
|
||||
commander_1.program
|
||||
.command('ls [platform]')
|
||||
.description('list installed Cordova and Capacitor plugins')
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform) => {
|
||||
(0, config_1.checkExternalConfig)(config.app);
|
||||
const { listCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/list')));
|
||||
await listCommand(config, platform);
|
||||
})));
|
||||
commander_1.program
|
||||
.command('doctor [platform]')
|
||||
.description('checks the current setup for common errors')
|
||||
.action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform) => {
|
||||
(0, config_1.checkExternalConfig)(config.app);
|
||||
const { doctorCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/doctor')));
|
||||
await doctorCommand(config, platform);
|
||||
})));
|
||||
commander_1.program
|
||||
.command('telemetry [on|off]', { hidden: true })
|
||||
.description('enable or disable telemetry')
|
||||
.action((0, cli_1.wrapAction)(async (onOrOff) => {
|
||||
const { telemetryCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/telemetry')));
|
||||
await telemetryCommand(onOrOff);
|
||||
}));
|
||||
commander_1.program
|
||||
.command('📡', { hidden: true })
|
||||
.description('IPC receiver command')
|
||||
.action(() => {
|
||||
// no-op: IPC messages are received via `process.on('message')`
|
||||
});
|
||||
commander_1.program
|
||||
.command('plugin:generate', { hidden: true })
|
||||
.description('start a new Capacitor plugin')
|
||||
.action((0, cli_1.wrapAction)(async () => {
|
||||
const { newPluginCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/new-plugin')));
|
||||
await newPluginCommand();
|
||||
}));
|
||||
commander_1.program
|
||||
.command('migrate')
|
||||
.option('--noprompt', 'do not prompt for confirmation')
|
||||
.option('--packagemanager <packageManager>', 'The package manager to use for dependency installs (npm, pnpm, yarn)')
|
||||
.description('Migrate your current Capacitor app to the latest major version of Capacitor.')
|
||||
.action((0, cli_1.wrapAction)(async ({ noprompt, packagemanager }) => {
|
||||
const { migrateCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/migrate')));
|
||||
await migrateCommand(config, noprompt, packagemanager);
|
||||
}));
|
||||
commander_1.program.arguments('[command]').action((0, cli_1.wrapAction)(async (cmd) => {
|
||||
if (typeof cmd === 'undefined') {
|
||||
log_1.output.write(`\n ${(0, emoji_1.emoji)('⚡️', '--')} ${colors_1.default.strong('Capacitor - Cross-Platform apps with JavaScript and the Web')} ${(0, emoji_1.emoji)('⚡️', '--')}\n\n`);
|
||||
commander_1.program.outputHelp();
|
||||
}
|
||||
else {
|
||||
(0, errors_1.fatal)(`Unknown command: ${colors_1.default.input(cmd)}`);
|
||||
}
|
||||
}));
|
||||
commander_1.program.parse(process.argv);
|
||||
}
|
||||
exports.runProgram = runProgram;
|
||||
13
@capacitor/cli/dist/ios/add.js
vendored
Normal file
13
@capacitor/cli/dist/ios/add.js
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.addIOS = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const template_1 = require("../util/template");
|
||||
async function addIOS(config) {
|
||||
await (0, common_1.runTask)(`Adding native Xcode project in ${colors_1.default.strong(config.ios.platformDir)}`, () => {
|
||||
return (0, template_1.extractTemplate)(config.cli.assets.ios.platformTemplateArchiveAbs, config.ios.platformDirAbs);
|
||||
});
|
||||
}
|
||||
exports.addIOS = addIOS;
|
||||
70
@capacitor/cli/dist/ios/build.js
vendored
Normal file
70
@capacitor/cli/dist/ios/build.js
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.buildiOS = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const rimraf_1 = tslib_1.__importDefault(require("rimraf"));
|
||||
const common_1 = require("../common");
|
||||
const log_1 = require("../log");
|
||||
const spm_1 = require("../util/spm");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
async function buildiOS(config, buildOptions) {
|
||||
var _a;
|
||||
const theScheme = (_a = buildOptions.scheme) !== null && _a !== void 0 ? _a : 'App';
|
||||
const packageManager = await (0, spm_1.checkPackageManager)(config);
|
||||
let typeOfBuild;
|
||||
let projectName;
|
||||
if (packageManager == 'Cocoapods') {
|
||||
typeOfBuild = '-workspace';
|
||||
projectName = (0, path_1.basename)(await config.ios.nativeXcodeWorkspaceDirAbs);
|
||||
}
|
||||
else {
|
||||
typeOfBuild = '-project';
|
||||
projectName = (0, path_1.basename)(await config.ios.nativeXcodeProjDirAbs);
|
||||
}
|
||||
await (0, common_1.runTask)('Building xArchive', async () => (0, subprocess_1.runCommand)('xcodebuild', [
|
||||
typeOfBuild,
|
||||
projectName,
|
||||
'-scheme',
|
||||
`${theScheme}`,
|
||||
'-destination',
|
||||
`generic/platform=iOS`,
|
||||
'-archivePath',
|
||||
`${theScheme}.xcarchive`,
|
||||
'archive',
|
||||
], {
|
||||
cwd: config.ios.nativeProjectDirAbs,
|
||||
}));
|
||||
const archivePlistContents = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>method</key>
|
||||
<string>app-store</string>
|
||||
</dict>
|
||||
</plist>`;
|
||||
const archivePlistPath = (0, path_1.join)(`${config.ios.nativeProjectDirAbs}`, 'archive.plist');
|
||||
(0, utils_fs_1.writeFileSync)(archivePlistPath, archivePlistContents);
|
||||
await (0, common_1.runTask)('Building IPA', async () => (0, subprocess_1.runCommand)('xcodebuild', [
|
||||
'archive',
|
||||
'-archivePath',
|
||||
`${theScheme}.xcarchive`,
|
||||
'-exportArchive',
|
||||
'-exportOptionsPlist',
|
||||
'archive.plist',
|
||||
'-exportPath',
|
||||
'output',
|
||||
'-allowProvisioningUpdates',
|
||||
'-configuration',
|
||||
buildOptions.configuration,
|
||||
], {
|
||||
cwd: config.ios.nativeProjectDirAbs,
|
||||
}));
|
||||
await (0, common_1.runTask)('Cleaning up', async () => {
|
||||
(0, utils_fs_1.unlinkSync)(archivePlistPath);
|
||||
rimraf_1.default.sync((0, path_1.join)(config.ios.nativeProjectDirAbs, `${theScheme}.xcarchive`));
|
||||
});
|
||||
(0, log_1.logSuccess)(`Successfully generated an IPA at: ${(0, path_1.join)(config.ios.nativeProjectDirAbs, 'output')}`);
|
||||
}
|
||||
exports.buildiOS = buildiOS;
|
||||
103
@capacitor/cli/dist/ios/common.js
vendored
Normal file
103
@capacitor/cli/dist/ios/common.js
vendored
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.editProjectSettingsIOS = exports.resolvePlugin = exports.getIOSPlugins = exports.checkCocoaPods = exports.checkBundler = exports.checkIOSPackage = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const child_process_1 = require("child_process");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const cordova_1 = require("../cordova");
|
||||
const log_1 = require("../log");
|
||||
const plugin_1 = require("../plugin");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
async function checkIOSPackage(config) {
|
||||
return (0, common_1.checkCapacitorPlatform)(config, 'ios');
|
||||
}
|
||||
exports.checkIOSPackage = checkIOSPackage;
|
||||
function execBundler() {
|
||||
try {
|
||||
const bundleOutput = (0, child_process_1.execSync)('bundle &> /dev/null ; echo $?');
|
||||
return parseInt(bundleOutput.toString());
|
||||
}
|
||||
catch (e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
async function checkBundler(config) {
|
||||
if (config.cli.os === "mac" /* OS.Mac */) {
|
||||
let bundlerResult = execBundler();
|
||||
if (bundlerResult === 1) {
|
||||
// Bundler version is outdated
|
||||
log_1.logger.info(`Using ${colors_1.default.strong('Gemfile')}: Bundler update needed...`);
|
||||
await (0, subprocess_1.runCommand)('gem', ['install', 'bundler']);
|
||||
bundlerResult = execBundler();
|
||||
}
|
||||
if (bundlerResult === 0) {
|
||||
// Bundler in use, all gems current
|
||||
log_1.logger.info(`Using ${colors_1.default.strong('Gemfile')}: RubyGems bundle installed`);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.checkBundler = checkBundler;
|
||||
async function checkCocoaPods(config) {
|
||||
if (!(await (0, subprocess_1.isInstalled)(await config.ios.podPath)) &&
|
||||
config.cli.os === "mac" /* OS.Mac */) {
|
||||
return (`CocoaPods is not installed.\n` +
|
||||
`See this install guide: ${colors_1.default.strong('https://capacitorjs.com/docs/getting-started/environment-setup#homebrew')}`);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.checkCocoaPods = checkCocoaPods;
|
||||
async function getIOSPlugins(allPlugins) {
|
||||
const resolved = await Promise.all(allPlugins.map(async (plugin) => await resolvePlugin(plugin)));
|
||||
return resolved.filter((plugin) => !!plugin);
|
||||
}
|
||||
exports.getIOSPlugins = getIOSPlugins;
|
||||
async function resolvePlugin(plugin) {
|
||||
var _a, _b;
|
||||
const platform = 'ios';
|
||||
if ((_a = plugin.manifest) === null || _a === void 0 ? void 0 : _a.ios) {
|
||||
plugin.ios = {
|
||||
name: plugin.name,
|
||||
type: 0 /* PluginType.Core */,
|
||||
path: (_b = plugin.manifest.ios.src) !== null && _b !== void 0 ? _b : platform,
|
||||
};
|
||||
}
|
||||
else if (plugin.xml) {
|
||||
plugin.ios = {
|
||||
name: plugin.name,
|
||||
type: 1 /* PluginType.Cordova */,
|
||||
path: 'src/' + platform,
|
||||
};
|
||||
if ((0, cordova_1.getIncompatibleCordovaPlugins)(platform).includes(plugin.id) ||
|
||||
!(0, plugin_1.getPluginPlatform)(plugin, platform)) {
|
||||
plugin.ios.type = 2 /* PluginType.Incompatible */;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
exports.resolvePlugin = resolvePlugin;
|
||||
/**
|
||||
* Update the native project files with the desired app id and app name
|
||||
*/
|
||||
async function editProjectSettingsIOS(config) {
|
||||
const appId = config.app.appId;
|
||||
const appName = config.app.appName
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
const pbxPath = `${config.ios.nativeXcodeProjDirAbs}/project.pbxproj`;
|
||||
const plistPath = (0, path_1.resolve)(config.ios.nativeTargetDirAbs, 'Info.plist');
|
||||
let plistContent = await (0, utils_fs_1.readFile)(plistPath, { encoding: 'utf-8' });
|
||||
plistContent = plistContent.replace(/<key>CFBundleDisplayName<\/key>[\s\S]?\s+<string>([^<]*)<\/string>/, `<key>CFBundleDisplayName</key>\n <string>${appName}</string>`);
|
||||
let pbxContent = await (0, utils_fs_1.readFile)(pbxPath, { encoding: 'utf-8' });
|
||||
pbxContent = pbxContent.replace(/PRODUCT_BUNDLE_IDENTIFIER = ([^;]+)/g, `PRODUCT_BUNDLE_IDENTIFIER = ${appId}`);
|
||||
await (0, utils_fs_1.writeFile)(plistPath, plistContent, { encoding: 'utf-8' });
|
||||
await (0, utils_fs_1.writeFile)(pbxPath, pbxContent, { encoding: 'utf-8' });
|
||||
}
|
||||
exports.editProjectSettingsIOS = editProjectSettingsIOS;
|
||||
49
@capacitor/cli/dist/ios/doctor.js
vendored
Normal file
49
@capacitor/cli/dist/ios/doctor.js
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.doctorIOS = void 0;
|
||||
const common_1 = require("../common");
|
||||
const errors_1 = require("../errors");
|
||||
const log_1 = require("../log");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
const common_2 = require("./common");
|
||||
async function doctorIOS(config) {
|
||||
var _a;
|
||||
// DOCTOR ideas for iOS:
|
||||
// plugin specific warnings
|
||||
// check cocoapods installed
|
||||
// check projects exist
|
||||
// check content in www === ios/www
|
||||
// check CLI versions
|
||||
// check plugins versions
|
||||
// check native project deps are up-to-date === npm install
|
||||
// check if npm install was updated
|
||||
// check online datebase of common errors
|
||||
// check if www folder is empty (index.html does not exist)
|
||||
try {
|
||||
await (0, common_1.check)([
|
||||
() => (0, common_2.checkBundler)(config) || (0, common_2.checkCocoaPods)(config),
|
||||
() => (0, common_1.checkWebDir)(config),
|
||||
checkXcode,
|
||||
]);
|
||||
(0, log_1.logSuccess)('iOS looking great! 👌');
|
||||
}
|
||||
catch (e) {
|
||||
(0, errors_1.fatal)((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
}
|
||||
exports.doctorIOS = doctorIOS;
|
||||
async function checkXcode() {
|
||||
if (!(await (0, subprocess_1.isInstalled)('xcodebuild'))) {
|
||||
return `Xcode is not installed`;
|
||||
}
|
||||
// const matches = output.match(/^Xcode (.*)/);
|
||||
// if (matches && matches.length === 2) {
|
||||
// const minVersion = '9.0.0';
|
||||
// const semver = await import('semver');
|
||||
// console.log(matches[1]);
|
||||
// if (semver.gt(minVersion, matches[1])) {
|
||||
// return `Xcode version is too old, ${minVersion} is required`;
|
||||
// }
|
||||
// }
|
||||
return null;
|
||||
}
|
||||
17
@capacitor/cli/dist/ios/open.js
vendored
Normal file
17
@capacitor/cli/dist/ios/open.js
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.openIOS = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const open_1 = tslib_1.__importDefault(require("open"));
|
||||
const common_1 = require("../common");
|
||||
const spm_1 = require("../util/spm");
|
||||
async function openIOS(config) {
|
||||
if ((await (0, spm_1.checkPackageManager)(config)) == 'SPM') {
|
||||
await (0, open_1.default)(config.ios.nativeXcodeProjDirAbs, { wait: false });
|
||||
}
|
||||
else {
|
||||
await (0, open_1.default)(await config.ios.nativeXcodeWorkspaceDirAbs, { wait: false });
|
||||
}
|
||||
await (0, common_1.wait)(3000);
|
||||
}
|
||||
exports.openIOS = openIOS;
|
||||
53
@capacitor/cli/dist/ios/run.js
vendored
Normal file
53
@capacitor/cli/dist/ios/run.js
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.runIOS = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const debug_1 = tslib_1.__importDefault(require("debug"));
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const native_run_1 = require("../util/native-run");
|
||||
const spm_1 = require("../util/spm");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
const debug = (0, debug_1.default)('capacitor:ios:run');
|
||||
async function runIOS(config, { target: selectedTarget, scheme: selectedScheme, configuration: selectedConfiguration, }) {
|
||||
const target = await (0, common_1.promptForPlatformTarget)(await (0, native_run_1.getPlatformTargets)('ios'), selectedTarget);
|
||||
const runScheme = selectedScheme || config.ios.scheme;
|
||||
const configuration = selectedConfiguration || 'Debug';
|
||||
const derivedDataPath = (0, path_1.resolve)(config.ios.platformDirAbs, 'DerivedData', target.id);
|
||||
const packageManager = await (0, spm_1.checkPackageManager)(config);
|
||||
let typeOfBuild;
|
||||
let projectName;
|
||||
if (packageManager == 'Cocoapods') {
|
||||
typeOfBuild = '-workspace';
|
||||
projectName = (0, path_1.basename)(await config.ios.nativeXcodeWorkspaceDirAbs);
|
||||
}
|
||||
else {
|
||||
typeOfBuild = '-project';
|
||||
projectName = (0, path_1.basename)(await config.ios.nativeXcodeProjDirAbs);
|
||||
}
|
||||
const xcodebuildArgs = [
|
||||
typeOfBuild,
|
||||
projectName,
|
||||
'-scheme',
|
||||
runScheme,
|
||||
'-configuration',
|
||||
configuration,
|
||||
'-destination',
|
||||
`id=${target.id}`,
|
||||
'-derivedDataPath',
|
||||
derivedDataPath,
|
||||
];
|
||||
debug('Invoking xcodebuild with args: %O', xcodebuildArgs);
|
||||
await (0, common_1.runTask)('Running xcodebuild', async () => (0, subprocess_1.runCommand)('xcrun', ['xcodebuild', ...xcodebuildArgs], {
|
||||
cwd: config.ios.nativeProjectDirAbs,
|
||||
}));
|
||||
const appName = `${runScheme}.app`;
|
||||
const appPath = (0, path_1.resolve)(derivedDataPath, 'Build/Products', target.virtual
|
||||
? `${configuration}-iphonesimulator`
|
||||
: `${configuration}-iphoneos`, appName);
|
||||
const nativeRunArgs = ['ios', '--app', appPath, '--target', target.id];
|
||||
debug('Invoking native-run with args: %O', nativeRunArgs);
|
||||
await (0, common_1.runTask)(`Deploying ${colors_1.default.strong(appName)} to ${colors_1.default.input(target.id)}`, async () => (0, native_run_1.runNativeRun)(nativeRunArgs));
|
||||
}
|
||||
exports.runIOS = runIOS;
|
||||
417
@capacitor/cli/dist/ios/update.js
vendored
Normal file
417
@capacitor/cli/dist/ios/update.js
vendored
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.installCocoaPodsPlugins = exports.updateIOS = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const cordova_1 = require("../cordova");
|
||||
const errors_1 = require("../errors");
|
||||
const log_1 = require("../log");
|
||||
const plugin_1 = require("../plugin");
|
||||
const copy_1 = require("../tasks/copy");
|
||||
const fs_1 = require("../util/fs");
|
||||
const iosplugin_1 = require("../util/iosplugin");
|
||||
const node_1 = require("../util/node");
|
||||
const spm_1 = require("../util/spm");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
const template_1 = require("../util/template");
|
||||
const common_2 = require("./common");
|
||||
const platform = 'ios';
|
||||
async function updateIOS(config, deployment) {
|
||||
const plugins = await getPluginsTask(config);
|
||||
const capacitorPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 0 /* PluginType.Core */);
|
||||
if ((await (0, spm_1.checkPackageManager)(config)) === 'SPM') {
|
||||
await (0, spm_1.generatePackageFile)(config, capacitorPlugins);
|
||||
}
|
||||
else {
|
||||
await updateIOSCocoaPods(config, plugins, deployment);
|
||||
}
|
||||
(0, iosplugin_1.generateIOSPackageJSON)(config, plugins);
|
||||
(0, plugin_1.printPlugins)(capacitorPlugins, 'ios');
|
||||
}
|
||||
exports.updateIOS = updateIOS;
|
||||
async function updateIOSCocoaPods(config, plugins, deployment) {
|
||||
await removePluginsNativeFiles(config);
|
||||
const cordovaPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 1 /* PluginType.Cordova */);
|
||||
if (cordovaPlugins.length > 0) {
|
||||
await copyPluginsNativeFiles(config, cordovaPlugins);
|
||||
}
|
||||
if (!(await (0, utils_fs_1.pathExists)(await config.ios.webDirAbs))) {
|
||||
await (0, copy_1.copy)(config, platform);
|
||||
}
|
||||
await (0, cordova_1.handleCordovaPluginsJS)(cordovaPlugins, config, platform);
|
||||
await (0, cordova_1.checkPluginDependencies)(plugins, platform);
|
||||
await generateCordovaPodspecs(cordovaPlugins, config);
|
||||
await installCocoaPodsPlugins(config, plugins, deployment);
|
||||
await (0, cordova_1.logCordovaManualSteps)(cordovaPlugins, config, platform);
|
||||
const incompatibleCordovaPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 2 /* PluginType.Incompatible */);
|
||||
(0, plugin_1.printPlugins)(incompatibleCordovaPlugins, platform, 'incompatible');
|
||||
await (0, common_1.checkPlatformVersions)(config, platform);
|
||||
}
|
||||
async function installCocoaPodsPlugins(config, plugins, deployment) {
|
||||
await (0, common_1.runTask)(`Updating iOS native dependencies with ${colors_1.default.input(`${await config.ios.podPath} install`)}`, () => {
|
||||
return updatePodfile(config, plugins, deployment);
|
||||
});
|
||||
}
|
||||
exports.installCocoaPodsPlugins = installCocoaPodsPlugins;
|
||||
async function updatePodfile(config, plugins, deployment) {
|
||||
const dependenciesContent = await generatePodFile(config, plugins);
|
||||
const relativeCapacitoriOSPath = await getRelativeCapacitoriOSPath(config);
|
||||
const podfilePath = (0, path_1.join)(config.ios.nativeProjectDirAbs, 'Podfile');
|
||||
let podfileContent = await (0, utils_fs_1.readFile)(podfilePath, { encoding: 'utf-8' });
|
||||
podfileContent = podfileContent.replace(/(def capacitor_pods)[\s\S]+?(\nend)/, `$1${dependenciesContent}$2`);
|
||||
podfileContent = podfileContent.replace(/(require_relative)[\s\S]+?(@capacitor\/ios\/scripts\/pods_helpers')/, `require_relative '${relativeCapacitoriOSPath}/scripts/pods_helpers'`);
|
||||
podfileContent = podfileContent.replace(`def assertDeploymentTarget(installer)
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
# ensure IPHONEOS_DEPLOYMENT_TARGET is at least 13.0
|
||||
deployment_target = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'].to_f
|
||||
should_upgrade = deployment_target < 13.0 && deployment_target != 0.0
|
||||
if should_upgrade
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
|
||||
end
|
||||
end
|
||||
end
|
||||
end`, `require_relative '${relativeCapacitoriOSPath}/scripts/pods_helpers'`);
|
||||
await (0, utils_fs_1.writeFile)(podfilePath, podfileContent, { encoding: 'utf-8' });
|
||||
const podPath = await config.ios.podPath;
|
||||
const useBundler = podPath.startsWith('bundle');
|
||||
const podCommandExists = await (0, subprocess_1.isInstalled)('pod');
|
||||
if (useBundler || podCommandExists) {
|
||||
if (useBundler) {
|
||||
await (0, subprocess_1.runCommand)('bundle', ['exec', 'pod', 'install', ...(deployment ? ['--deployment'] : [])], { cwd: config.ios.nativeProjectDirAbs });
|
||||
}
|
||||
else {
|
||||
await (0, subprocess_1.runCommand)(podPath, ['install', ...(deployment ? ['--deployment'] : [])], { cwd: config.ios.nativeProjectDirAbs });
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_1.logger.warn('Skipping pod install because CocoaPods is not installed');
|
||||
}
|
||||
const isXcodebuildAvailable = await (0, subprocess_1.isInstalled)('xcodebuild');
|
||||
if (isXcodebuildAvailable) {
|
||||
await (0, subprocess_1.runCommand)('xcodebuild', ['-project', (0, path_1.basename)(`${config.ios.nativeXcodeProjDirAbs}`), 'clean'], {
|
||||
cwd: config.ios.nativeProjectDirAbs,
|
||||
});
|
||||
}
|
||||
else {
|
||||
log_1.logger.warn('Unable to find "xcodebuild". Skipping xcodebuild clean step...');
|
||||
}
|
||||
}
|
||||
async function getRelativeCapacitoriOSPath(config) {
|
||||
const capacitoriOSPath = (0, node_1.resolveNode)(config.app.rootDir, '@capacitor/ios', 'package.json');
|
||||
if (!capacitoriOSPath) {
|
||||
(0, errors_1.fatal)(`Unable to find ${colors_1.default.strong('node_modules/@capacitor/ios')}.\n` +
|
||||
`Are you sure ${colors_1.default.strong('@capacitor/ios')} is installed?`);
|
||||
}
|
||||
return (0, fs_1.convertToUnixPath)((0, path_1.relative)(config.ios.nativeProjectDirAbs, await (0, utils_fs_1.realpath)((0, path_1.dirname)(capacitoriOSPath))));
|
||||
}
|
||||
async function generatePodFile(config, plugins) {
|
||||
const relativeCapacitoriOSPath = await getRelativeCapacitoriOSPath(config);
|
||||
const capacitorPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 0 /* PluginType.Core */);
|
||||
const pods = await Promise.all(capacitorPlugins.map(async (p) => {
|
||||
if (!p.ios) {
|
||||
return '';
|
||||
}
|
||||
return ` pod '${p.ios.name}', :path => '${(0, fs_1.convertToUnixPath)((0, path_1.relative)(config.ios.nativeProjectDirAbs, await (0, utils_fs_1.realpath)(p.rootPath)))}'\n`;
|
||||
}));
|
||||
const cordovaPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 1 /* PluginType.Cordova */);
|
||||
cordovaPlugins.map(async (p) => {
|
||||
const podspecs = (0, plugin_1.getPlatformElement)(p, platform, 'podspec');
|
||||
podspecs.map((podspec) => {
|
||||
podspec.pods.map((pPods) => {
|
||||
pPods.pod.map((pod) => {
|
||||
if (pod.$.git) {
|
||||
let gitRef = '';
|
||||
if (pod.$.tag) {
|
||||
gitRef = `, :tag => '${pod.$.tag}'`;
|
||||
}
|
||||
else if (pod.$.branch) {
|
||||
gitRef = `, :branch => '${pod.$.branch}'`;
|
||||
}
|
||||
else if (pod.$.commit) {
|
||||
gitRef = `, :commit => '${pod.$.commit}'`;
|
||||
}
|
||||
pods.push(` pod '${pod.$.name}', :git => '${pod.$.git}'${gitRef}\n`);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
const staticPlugins = cordovaPlugins.filter(p => (0, cordova_1.needsStaticPod)(p, config));
|
||||
const noStaticPlugins = cordovaPlugins.filter(el => !staticPlugins.includes(el));
|
||||
if (noStaticPlugins.length > 0) {
|
||||
pods.push(` pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins'\n`);
|
||||
}
|
||||
if (staticPlugins.length > 0) {
|
||||
pods.push(` pod 'CordovaPluginsStatic', :path => '../capacitor-cordova-ios-plugins'\n`);
|
||||
}
|
||||
const resourcesPlugins = cordovaPlugins.filter(filterResources);
|
||||
if (resourcesPlugins.length > 0) {
|
||||
pods.push(` pod 'CordovaPluginsResources', :path => '../capacitor-cordova-ios-plugins'\n`);
|
||||
}
|
||||
return `
|
||||
pod 'Capacitor', :path => '${relativeCapacitoriOSPath}'
|
||||
pod 'CapacitorCordova', :path => '${relativeCapacitoriOSPath}'
|
||||
${pods.join('').trimRight()}`;
|
||||
}
|
||||
function getFrameworkName(framework) {
|
||||
if (isFramework(framework)) {
|
||||
if (framework.$.custom && framework.$.custom === 'true') {
|
||||
return framework.$.src;
|
||||
}
|
||||
return framework.$.src.substr(0, framework.$.src.indexOf('.'));
|
||||
}
|
||||
return framework.$.src
|
||||
.substr(0, framework.$.src.indexOf('.'))
|
||||
.replace('lib', '');
|
||||
}
|
||||
function isFramework(framework) {
|
||||
return framework.$.src.split('.').pop().includes('framework');
|
||||
}
|
||||
async function generateCordovaPodspecs(cordovaPlugins, config) {
|
||||
const staticPlugins = cordovaPlugins.filter(p => (0, cordova_1.needsStaticPod)(p, config));
|
||||
const noStaticPlugins = cordovaPlugins.filter(el => !staticPlugins.includes(el));
|
||||
generateCordovaPodspec(noStaticPlugins, config, false);
|
||||
generateCordovaPodspec(staticPlugins, config, true);
|
||||
}
|
||||
async function generateCordovaPodspec(cordovaPlugins, config, isStatic) {
|
||||
const weakFrameworks = [];
|
||||
const linkedFrameworks = [];
|
||||
const customFrameworks = [];
|
||||
const systemLibraries = [];
|
||||
const sourceFrameworks = [];
|
||||
const frameworkDeps = [];
|
||||
const compilerFlags = [];
|
||||
let prefsArray = [];
|
||||
let name = 'CordovaPlugins';
|
||||
let sourcesFolderName = 'sources';
|
||||
if (isStatic) {
|
||||
name += 'Static';
|
||||
frameworkDeps.push('s.static_framework = true');
|
||||
sourcesFolderName += 'static';
|
||||
}
|
||||
cordovaPlugins.map((plugin) => {
|
||||
const frameworks = (0, plugin_1.getPlatformElement)(plugin, platform, 'framework');
|
||||
frameworks.map((framework) => {
|
||||
if (!framework.$.type) {
|
||||
const name = getFrameworkName(framework);
|
||||
if (isFramework(framework)) {
|
||||
if (framework.$.weak && framework.$.weak === 'true') {
|
||||
if (!weakFrameworks.includes(name)) {
|
||||
weakFrameworks.push(name);
|
||||
}
|
||||
}
|
||||
else if (framework.$.custom && framework.$.custom === 'true') {
|
||||
const frameworktPath = (0, path_1.join)(sourcesFolderName, plugin.name, name);
|
||||
if (!customFrameworks.includes(frameworktPath)) {
|
||||
customFrameworks.push(frameworktPath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!linkedFrameworks.includes(name)) {
|
||||
linkedFrameworks.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!systemLibraries.includes(name)) {
|
||||
systemLibraries.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (framework.$.type && framework.$.type === 'podspec') {
|
||||
let depString = `s.dependency '${framework.$.src}'`;
|
||||
if (framework.$.spec && framework.$.spec !== '') {
|
||||
depString += `, '${framework.$.spec}'`;
|
||||
}
|
||||
if (!frameworkDeps.includes(depString)) {
|
||||
frameworkDeps.push(depString);
|
||||
}
|
||||
}
|
||||
});
|
||||
prefsArray = prefsArray.concat((0, plugin_1.getAllElements)(plugin, platform, 'preference'));
|
||||
const podspecs = (0, plugin_1.getPlatformElement)(plugin, platform, 'podspec');
|
||||
podspecs.map((podspec) => {
|
||||
podspec.pods.map((pods) => {
|
||||
pods.pod.map((pod) => {
|
||||
let depString = `s.dependency '${pod.$.name}'`;
|
||||
if (pod.$.spec && pod.$.spec !== '') {
|
||||
depString += `, '${pod.$.spec}'`;
|
||||
}
|
||||
if (!frameworkDeps.includes(depString)) {
|
||||
frameworkDeps.push(depString);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
const sourceFiles = (0, plugin_1.getPlatformElement)(plugin, platform, 'source-file');
|
||||
sourceFiles.map((sourceFile) => {
|
||||
if (sourceFile.$.framework && sourceFile.$.framework === 'true') {
|
||||
let fileName = sourceFile.$.src.split('/').pop();
|
||||
if (!fileName.startsWith('lib')) {
|
||||
fileName = 'lib' + fileName;
|
||||
}
|
||||
const frameworktPath = (0, path_1.join)(sourcesFolderName, plugin.name, fileName);
|
||||
if (!sourceFrameworks.includes(frameworktPath)) {
|
||||
sourceFrameworks.push(frameworktPath);
|
||||
}
|
||||
}
|
||||
else if (sourceFile.$['compiler-flags']) {
|
||||
const cFlag = sourceFile.$['compiler-flags'];
|
||||
if (!compilerFlags.includes(cFlag)) {
|
||||
compilerFlags.push(cFlag);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
const onlySystemLibraries = systemLibraries.filter(library => removeNoSystem(library, sourceFrameworks));
|
||||
if (weakFrameworks.length > 0) {
|
||||
frameworkDeps.push(`s.weak_frameworks = '${weakFrameworks.join(`', '`)}'`);
|
||||
}
|
||||
if (linkedFrameworks.length > 0) {
|
||||
frameworkDeps.push(`s.frameworks = '${linkedFrameworks.join(`', '`)}'`);
|
||||
}
|
||||
if (onlySystemLibraries.length > 0) {
|
||||
frameworkDeps.push(`s.libraries = '${onlySystemLibraries.join(`', '`)}'`);
|
||||
}
|
||||
if (customFrameworks.length > 0) {
|
||||
frameworkDeps.push(`s.vendored_frameworks = '${customFrameworks.join(`', '`)}'`);
|
||||
frameworkDeps.push(`s.exclude_files = 'sources/**/*.framework/Headers/*.h', 'sources/**/*.framework/PrivateHeaders/*.h'`);
|
||||
}
|
||||
if (sourceFrameworks.length > 0) {
|
||||
frameworkDeps.push(`s.vendored_libraries = '${sourceFrameworks.join(`', '`)}'`);
|
||||
}
|
||||
if (compilerFlags.length > 0) {
|
||||
frameworkDeps.push(`s.compiler_flags = '${compilerFlags.join(' ')}'`);
|
||||
}
|
||||
const arcPlugins = cordovaPlugins.filter(filterARCFiles);
|
||||
if (arcPlugins.length > 0) {
|
||||
frameworkDeps.push(`s.subspec 'noarc' do |sna|
|
||||
sna.requires_arc = false
|
||||
sna.source_files = 'noarc/**/*.{swift,h,m,c,cc,mm,cpp}'
|
||||
end`);
|
||||
}
|
||||
let frameworksString = frameworkDeps.join('\n ');
|
||||
frameworksString = await replaceFrameworkVariables(config, prefsArray, frameworksString);
|
||||
const content = `
|
||||
Pod::Spec.new do |s|
|
||||
s.name = '${name}'
|
||||
s.version = '${config.cli.package.version}'
|
||||
s.summary = 'Autogenerated spec'
|
||||
s.license = 'Unknown'
|
||||
s.homepage = 'https://example.com'
|
||||
s.authors = { 'Capacitor Generator' => 'hi@example.com' }
|
||||
s.source = { :git => 'https://github.com/ionic-team/does-not-exist.git', :tag => '${config.cli.package.version}' }
|
||||
s.source_files = '${sourcesFolderName}/**/*.{swift,h,m,c,cc,mm,cpp}'
|
||||
s.ios.deployment_target = '${config.ios.minVersion}'
|
||||
s.xcconfig = {'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) COCOAPODS=1 WK_WEB_VIEW_ONLY=1' }
|
||||
s.dependency 'CapacitorCordova'${getLinkerFlags(config)}
|
||||
s.swift_version = '5.1'
|
||||
${frameworksString}
|
||||
end`;
|
||||
await (0, utils_fs_1.writeFile)((0, path_1.join)(config.ios.cordovaPluginsDirAbs, `${name}.podspec`), content);
|
||||
}
|
||||
function getLinkerFlags(config) {
|
||||
var _a;
|
||||
if ((_a = config.app.extConfig.ios) === null || _a === void 0 ? void 0 : _a.cordovaLinkerFlags) {
|
||||
return `\n s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '${config.app.extConfig.ios.cordovaLinkerFlags.join(' ')}' }`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
async function copyPluginsNativeFiles(config, cordovaPlugins) {
|
||||
for (const p of cordovaPlugins) {
|
||||
const sourceFiles = (0, plugin_1.getPlatformElement)(p, platform, 'source-file');
|
||||
const headerFiles = (0, plugin_1.getPlatformElement)(p, platform, 'header-file');
|
||||
const codeFiles = sourceFiles.concat(headerFiles);
|
||||
const frameworks = (0, plugin_1.getPlatformElement)(p, platform, 'framework');
|
||||
let sourcesFolderName = 'sources';
|
||||
if ((0, cordova_1.needsStaticPod)(p, config)) {
|
||||
sourcesFolderName += 'static';
|
||||
}
|
||||
const sourcesFolder = (0, path_1.join)(config.ios.cordovaPluginsDirAbs, sourcesFolderName, p.name);
|
||||
for (const codeFile of codeFiles) {
|
||||
let fileName = codeFile.$.src.split('/').pop();
|
||||
const fileExt = codeFile.$.src.split('.').pop();
|
||||
if (fileExt === 'a' && !fileName.startsWith('lib')) {
|
||||
fileName = 'lib' + fileName;
|
||||
}
|
||||
let destFolder = sourcesFolderName;
|
||||
if (codeFile.$['compiler-flags'] &&
|
||||
codeFile.$['compiler-flags'] === '-fno-objc-arc') {
|
||||
destFolder = 'noarc';
|
||||
}
|
||||
const filePath = (0, plugin_1.getFilePath)(config, p, codeFile.$.src);
|
||||
const fileDest = (0, path_1.join)(config.ios.cordovaPluginsDirAbs, destFolder, p.name, fileName);
|
||||
await (0, utils_fs_1.copy)(filePath, fileDest);
|
||||
if (!codeFile.$.framework) {
|
||||
let fileContent = await (0, utils_fs_1.readFile)(fileDest, { encoding: 'utf-8' });
|
||||
if (fileExt === 'swift') {
|
||||
fileContent = 'import Cordova\n' + fileContent;
|
||||
await (0, utils_fs_1.writeFile)(fileDest, fileContent, { encoding: 'utf-8' });
|
||||
}
|
||||
else {
|
||||
if (fileContent.includes('@import Firebase;')) {
|
||||
fileContent = fileContent.replace('@import Firebase;', '#import <Firebase/Firebase.h>');
|
||||
await (0, utils_fs_1.writeFile)(fileDest, fileContent, { encoding: 'utf-8' });
|
||||
}
|
||||
if (fileContent.includes('[NSBundle bundleForClass:[self class]]') ||
|
||||
fileContent.includes('[NSBundle bundleForClass:[CDVCapture class]]')) {
|
||||
fileContent = fileContent.replace('[NSBundle bundleForClass:[self class]]', '[NSBundle mainBundle]');
|
||||
fileContent = fileContent.replace('[NSBundle bundleForClass:[CDVCapture class]]', '[NSBundle mainBundle]');
|
||||
await (0, utils_fs_1.writeFile)(fileDest, fileContent, { encoding: 'utf-8' });
|
||||
}
|
||||
if (fileContent.includes('[self.webView superview]') ||
|
||||
fileContent.includes('self.webView.superview')) {
|
||||
fileContent = fileContent.replace(/\[self.webView superview\]/g, 'self.viewController.view');
|
||||
fileContent = fileContent.replace(/self.webView.superview/g, 'self.viewController.view');
|
||||
await (0, utils_fs_1.writeFile)(fileDest, fileContent, { encoding: 'utf-8' });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const resourceFiles = (0, plugin_1.getPlatformElement)(p, platform, 'resource-file');
|
||||
for (const resourceFile of resourceFiles) {
|
||||
const fileName = resourceFile.$.src.split('/').pop();
|
||||
await (0, utils_fs_1.copy)((0, plugin_1.getFilePath)(config, p, resourceFile.$.src), (0, path_1.join)(config.ios.cordovaPluginsDirAbs, 'resources', fileName));
|
||||
}
|
||||
for (const framework of frameworks) {
|
||||
if (framework.$.custom && framework.$.custom === 'true') {
|
||||
await (0, utils_fs_1.copy)((0, plugin_1.getFilePath)(config, p, framework.$.src), (0, path_1.join)(sourcesFolder, framework.$.src));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async function removePluginsNativeFiles(config) {
|
||||
await (0, utils_fs_1.remove)(config.ios.cordovaPluginsDirAbs);
|
||||
await (0, template_1.extractTemplate)(config.cli.assets.ios.cordovaPluginsTemplateArchiveAbs, config.ios.cordovaPluginsDirAbs);
|
||||
}
|
||||
function filterResources(plugin) {
|
||||
const resources = (0, plugin_1.getPlatformElement)(plugin, platform, 'resource-file');
|
||||
return resources.length > 0;
|
||||
}
|
||||
function filterARCFiles(plugin) {
|
||||
const sources = (0, plugin_1.getPlatformElement)(plugin, platform, 'source-file');
|
||||
const sourcesARC = sources.filter((sourceFile) => sourceFile.$['compiler-flags'] &&
|
||||
sourceFile.$['compiler-flags'] === '-fno-objc-arc');
|
||||
return sourcesARC.length > 0;
|
||||
}
|
||||
function removeNoSystem(library, sourceFrameworks) {
|
||||
const libraries = sourceFrameworks.filter(framework => framework.includes(library));
|
||||
return libraries.length === 0;
|
||||
}
|
||||
async function getPluginsTask(config) {
|
||||
return await (0, common_1.runTask)('Updating iOS plugins', async () => {
|
||||
const allPlugins = await (0, plugin_1.getPlugins)(config, 'ios');
|
||||
const iosPlugins = await (0, common_2.getIOSPlugins)(allPlugins);
|
||||
return iosPlugins;
|
||||
});
|
||||
}
|
||||
async function replaceFrameworkVariables(config, prefsArray, frameworkString) {
|
||||
prefsArray.map((preference) => {
|
||||
frameworkString = frameworkString.replace(new RegExp(('$' + preference.$.name).replace('$', '\\$&'), 'g'), preference.$.default);
|
||||
});
|
||||
return frameworkString;
|
||||
}
|
||||
61
@capacitor/cli/dist/ipc.js
vendored
Normal file
61
@capacitor/cli/dist/ipc.js
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.receive = exports.send = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const utils_subprocess_1 = require("@ionic/utils-subprocess");
|
||||
const debug_1 = tslib_1.__importDefault(require("debug"));
|
||||
const https_1 = require("https");
|
||||
const path_1 = require("path");
|
||||
const cli_1 = require("./util/cli");
|
||||
const debug = (0, debug_1.default)('capacitor:ipc');
|
||||
/**
|
||||
* Send an IPC message to a forked process.
|
||||
*/
|
||||
async function send(msg) {
|
||||
const dir = cli_1.ENV_PATHS.log;
|
||||
await (0, utils_fs_1.mkdirp)(dir);
|
||||
const logPath = (0, path_1.resolve)(dir, 'ipc.log');
|
||||
debug('Sending %O IPC message to forked process (logs: %O)', msg.type, logPath);
|
||||
const fd = await (0, utils_fs_1.open)(logPath, 'a');
|
||||
const p = (0, utils_subprocess_1.fork)(process.argv[1], ['📡'], { stdio: ['ignore', fd, fd, 'ipc'] });
|
||||
p.send(msg);
|
||||
p.disconnect();
|
||||
p.unref();
|
||||
}
|
||||
exports.send = send;
|
||||
/**
|
||||
* Receive and handle an IPC message.
|
||||
*
|
||||
* Assume minimal context and keep external dependencies to a minimum.
|
||||
*/
|
||||
async function receive(msg) {
|
||||
debug('Received %O IPC message', msg.type);
|
||||
if (msg.type === 'telemetry') {
|
||||
const now = new Date().toISOString();
|
||||
const { data } = msg;
|
||||
// This request is only made if telemetry is on.
|
||||
const req = (0, https_1.request)({
|
||||
hostname: 'api.ionicjs.com',
|
||||
port: 443,
|
||||
path: '/events/metrics',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}, response => {
|
||||
debug('Sent %O metric to events service (status: %O)', data.name, response.statusCode);
|
||||
if (response.statusCode !== 204) {
|
||||
response.on('data', chunk => {
|
||||
debug('Bad response from events service. Request body: %O', chunk.toString());
|
||||
});
|
||||
}
|
||||
});
|
||||
const body = {
|
||||
metrics: [data],
|
||||
sent_at: now,
|
||||
};
|
||||
req.end(JSON.stringify(body));
|
||||
}
|
||||
}
|
||||
exports.receive = receive;
|
||||
41
@capacitor/cli/dist/log.js
vendored
Normal file
41
@capacitor/cli/dist/log.js
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.logSuccess = exports.logPrompt = exports.logger = exports.output = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const cli_framework_output_1 = require("@ionic/cli-framework-output");
|
||||
const colors_1 = tslib_1.__importDefault(require("./colors"));
|
||||
const term_1 = require("./util/term");
|
||||
const options = {
|
||||
colors: colors_1.default,
|
||||
stream: process.argv.includes('--json') ? process.stderr : process.stdout,
|
||||
};
|
||||
exports.output = (0, term_1.isInteractive)()
|
||||
? new cli_framework_output_1.TTYOutputStrategy(options)
|
||||
: new cli_framework_output_1.StreamOutputStrategy(options);
|
||||
exports.logger = (0, cli_framework_output_1.createDefaultLogger)({
|
||||
output: exports.output,
|
||||
formatterOptions: {
|
||||
titleize: false,
|
||||
tags: new Map([
|
||||
[cli_framework_output_1.LOGGER_LEVELS.DEBUG, colors_1.default.log.DEBUG('[debug]')],
|
||||
[cli_framework_output_1.LOGGER_LEVELS.INFO, colors_1.default.log.INFO('[info]')],
|
||||
[cli_framework_output_1.LOGGER_LEVELS.WARN, colors_1.default.log.WARN('[warn]')],
|
||||
[cli_framework_output_1.LOGGER_LEVELS.ERROR, colors_1.default.log.ERROR('[error]')],
|
||||
]),
|
||||
},
|
||||
});
|
||||
async function logPrompt(msg, promptObject) {
|
||||
const { wordWrap } = await Promise.resolve().then(() => tslib_1.__importStar(require('@ionic/cli-framework-output')));
|
||||
const { prompt } = await Promise.resolve().then(() => tslib_1.__importStar(require('prompts')));
|
||||
exports.logger.log({
|
||||
msg: `${colors_1.default.input('[?]')} ${wordWrap(msg, { indentation: 4 })}`,
|
||||
logger: exports.logger,
|
||||
format: false,
|
||||
});
|
||||
return prompt(promptObject, { onCancel: () => process.exit(1) });
|
||||
}
|
||||
exports.logPrompt = logPrompt;
|
||||
function logSuccess(msg) {
|
||||
exports.logger.msg(`${colors_1.default.success('[success]')} ${msg}`);
|
||||
}
|
||||
exports.logSuccess = logSuccess;
|
||||
186
@capacitor/cli/dist/plugin.js
vendored
Normal file
186
@capacitor/cli/dist/plugin.js
vendored
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getAllElements = exports.getFilePath = exports.getAssets = exports.getJSModules = exports.getPluginType = exports.getPlatformElement = exports.getPluginPlatform = exports.printPlugins = exports.fixName = exports.getDependencies = exports.resolvePlugin = exports.getPlugins = exports.getIncludedPluginPackages = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("./colors"));
|
||||
const errors_1 = require("./errors");
|
||||
const log_1 = require("./log");
|
||||
const node_1 = require("./util/node");
|
||||
const xml_1 = require("./util/xml");
|
||||
function getIncludedPluginPackages(config, platform) {
|
||||
var _a, _b, _c, _d;
|
||||
const { extConfig } = config.app;
|
||||
switch (platform) {
|
||||
case 'android':
|
||||
return (_b = (_a = extConfig.android) === null || _a === void 0 ? void 0 : _a.includePlugins) !== null && _b !== void 0 ? _b : extConfig.includePlugins;
|
||||
case 'ios':
|
||||
return (_d = (_c = extConfig.ios) === null || _c === void 0 ? void 0 : _c.includePlugins) !== null && _d !== void 0 ? _d : extConfig.includePlugins;
|
||||
}
|
||||
}
|
||||
exports.getIncludedPluginPackages = getIncludedPluginPackages;
|
||||
async function getPlugins(config, platform) {
|
||||
var _a;
|
||||
const possiblePlugins = (_a = getIncludedPluginPackages(config, platform)) !== null && _a !== void 0 ? _a : getDependencies(config);
|
||||
const resolvedPlugins = await Promise.all(possiblePlugins.map(async (p) => resolvePlugin(config, p)));
|
||||
return resolvedPlugins.filter((p) => !!p);
|
||||
}
|
||||
exports.getPlugins = getPlugins;
|
||||
async function resolvePlugin(config, name) {
|
||||
try {
|
||||
const packagePath = (0, node_1.resolveNode)(config.app.rootDir, name, 'package.json');
|
||||
if (!packagePath) {
|
||||
(0, errors_1.fatal)(`Unable to find ${colors_1.default.strong(`node_modules/${name}`)}.\n` +
|
||||
`Are you sure ${colors_1.default.strong(name)} is installed?`);
|
||||
}
|
||||
const rootPath = (0, path_1.dirname)(packagePath);
|
||||
const meta = await (0, utils_fs_1.readJSON)(packagePath);
|
||||
if (!meta) {
|
||||
return null;
|
||||
}
|
||||
if (meta.capacitor) {
|
||||
return {
|
||||
id: name,
|
||||
name: fixName(name),
|
||||
version: meta.version,
|
||||
rootPath,
|
||||
repository: meta.repository,
|
||||
manifest: meta.capacitor,
|
||||
};
|
||||
}
|
||||
const pluginXMLPath = (0, path_1.join)(rootPath, 'plugin.xml');
|
||||
const xmlMeta = await (0, xml_1.readXML)(pluginXMLPath);
|
||||
return {
|
||||
id: name,
|
||||
name: fixName(name),
|
||||
version: meta.version,
|
||||
rootPath: rootPath,
|
||||
repository: meta.repository,
|
||||
xml: xmlMeta.plugin,
|
||||
};
|
||||
}
|
||||
catch (e) {
|
||||
// ignore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.resolvePlugin = resolvePlugin;
|
||||
function getDependencies(config) {
|
||||
var _a, _b;
|
||||
return [
|
||||
...Object.keys((_a = config.app.package.dependencies) !== null && _a !== void 0 ? _a : {}),
|
||||
...Object.keys((_b = config.app.package.devDependencies) !== null && _b !== void 0 ? _b : {}),
|
||||
];
|
||||
}
|
||||
exports.getDependencies = getDependencies;
|
||||
function fixName(name) {
|
||||
name = name
|
||||
.replace(/\//g, '_')
|
||||
.replace(/-/g, '_')
|
||||
.replace(/@/g, '')
|
||||
.replace(/_\w/g, m => m[1].toUpperCase());
|
||||
return name.charAt(0).toUpperCase() + name.slice(1);
|
||||
}
|
||||
exports.fixName = fixName;
|
||||
function printPlugins(plugins, platform, type = 'capacitor') {
|
||||
if (plugins.length === 0) {
|
||||
return;
|
||||
}
|
||||
let msg;
|
||||
const plural = plugins.length === 1 ? '' : 's';
|
||||
switch (type) {
|
||||
case 'cordova':
|
||||
msg = `Found ${plugins.length} Cordova plugin${plural} for ${colors_1.default.strong(platform)}:\n`;
|
||||
break;
|
||||
case 'incompatible':
|
||||
msg = `Found ${plugins.length} incompatible Cordova plugin${plural} for ${colors_1.default.strong(platform)}, skipped install:\n`;
|
||||
break;
|
||||
case 'capacitor':
|
||||
msg = `Found ${plugins.length} Capacitor plugin${plural} for ${colors_1.default.strong(platform)}:\n`;
|
||||
break;
|
||||
}
|
||||
msg += plugins.map(p => `${p.id}${colors_1.default.weak(`@${p.version}`)}`).join('\n');
|
||||
log_1.logger.info(msg);
|
||||
}
|
||||
exports.printPlugins = printPlugins;
|
||||
function getPluginPlatform(p, platform) {
|
||||
const platforms = p.xml.platform;
|
||||
if (platforms) {
|
||||
const platforms = p.xml.platform.filter(function (item) {
|
||||
return item.$.name === platform;
|
||||
});
|
||||
return platforms[0];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
exports.getPluginPlatform = getPluginPlatform;
|
||||
function getPlatformElement(p, platform, elementName) {
|
||||
const platformTag = getPluginPlatform(p, platform);
|
||||
if (platformTag) {
|
||||
const element = platformTag[elementName];
|
||||
if (element) {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
exports.getPlatformElement = getPlatformElement;
|
||||
function getPluginType(p, platform) {
|
||||
var _a, _b, _c, _d;
|
||||
switch (platform) {
|
||||
case 'ios':
|
||||
return (_b = (_a = p.ios) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : 0 /* PluginType.Core */;
|
||||
case 'android':
|
||||
return (_d = (_c = p.android) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : 0 /* PluginType.Core */;
|
||||
}
|
||||
return 0 /* PluginType.Core */;
|
||||
}
|
||||
exports.getPluginType = getPluginType;
|
||||
/**
|
||||
* Get each JavaScript Module for the given plugin
|
||||
*/
|
||||
function getJSModules(p, platform) {
|
||||
return getAllElements(p, platform, 'js-module');
|
||||
}
|
||||
exports.getJSModules = getJSModules;
|
||||
/**
|
||||
* Get each asset tag for the given plugin
|
||||
*/
|
||||
function getAssets(p, platform) {
|
||||
return getAllElements(p, platform, 'asset');
|
||||
}
|
||||
exports.getAssets = getAssets;
|
||||
function getFilePath(config, plugin, path) {
|
||||
if (path.startsWith('node_modules')) {
|
||||
let pathSegments = path.split('/').slice(1);
|
||||
if (pathSegments[0].startsWith('@')) {
|
||||
pathSegments = [
|
||||
pathSegments[0] + '/' + pathSegments[1],
|
||||
...pathSegments.slice(2),
|
||||
];
|
||||
}
|
||||
const filePath = (0, node_1.resolveNode)(config.app.rootDir, ...pathSegments);
|
||||
if (!filePath) {
|
||||
throw new Error(`Can't resolve module ${pathSegments[0]}`);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
return (0, path_1.join)(plugin.rootPath, path);
|
||||
}
|
||||
exports.getFilePath = getFilePath;
|
||||
/**
|
||||
* For a given plugin, return all the plugin.xml elements with elementName, checking root and specified platform
|
||||
*/
|
||||
function getAllElements(p, platform, elementName) {
|
||||
let modules = [];
|
||||
if (p.xml[elementName]) {
|
||||
modules = modules.concat(p.xml[elementName]);
|
||||
}
|
||||
const platformModules = getPluginPlatform(p, platform);
|
||||
if (platformModules === null || platformModules === void 0 ? void 0 : platformModules[elementName]) {
|
||||
modules = modules.concat(platformModules[elementName]);
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
exports.getAllElements = getAllElements;
|
||||
35
@capacitor/cli/dist/sysconfig.js
vendored
Normal file
35
@capacitor/cli/dist/sysconfig.js
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.writeConfig = exports.readConfig = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const debug_1 = tslib_1.__importDefault(require("debug"));
|
||||
const path_1 = require("path");
|
||||
const cli_1 = require("./util/cli");
|
||||
const uuid_1 = require("./util/uuid");
|
||||
const debug = (0, debug_1.default)('capacitor:sysconfig');
|
||||
const SYSCONFIG_FILE = 'sysconfig.json';
|
||||
const SYSCONFIG_PATH = (0, path_1.resolve)(cli_1.ENV_PATHS.config, SYSCONFIG_FILE);
|
||||
async function readConfig() {
|
||||
debug('Reading from %O', SYSCONFIG_PATH);
|
||||
try {
|
||||
return await (0, utils_fs_1.readJSON)(SYSCONFIG_PATH);
|
||||
}
|
||||
catch (e) {
|
||||
if (e.code !== 'ENOENT') {
|
||||
throw e;
|
||||
}
|
||||
const sysconfig = {
|
||||
machine: (0, uuid_1.uuidv4)(),
|
||||
};
|
||||
await writeConfig(sysconfig);
|
||||
return sysconfig;
|
||||
}
|
||||
}
|
||||
exports.readConfig = readConfig;
|
||||
async function writeConfig(sysconfig) {
|
||||
debug('Writing to %O', SYSCONFIG_PATH);
|
||||
await (0, utils_fs_1.mkdirp)((0, path_1.dirname)(SYSCONFIG_PATH));
|
||||
await (0, utils_fs_1.writeJSON)(SYSCONFIG_PATH, sysconfig, { spaces: '\t' });
|
||||
}
|
||||
exports.writeConfig = writeConfig;
|
||||
122
@capacitor/cli/dist/tasks/add.js
vendored
Normal file
122
@capacitor/cli/dist/tasks/add.js
vendored
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.addCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const utils_terminal_1 = require("@ionic/utils-terminal");
|
||||
const add_1 = require("../android/add");
|
||||
const common_1 = require("../android/common");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_2 = require("../common");
|
||||
const errors_1 = require("../errors");
|
||||
const add_2 = require("../ios/add");
|
||||
const common_3 = require("../ios/common");
|
||||
const log_1 = require("../log");
|
||||
const sync_1 = require("./sync");
|
||||
async function addCommand(config, selectedPlatformName) {
|
||||
var _a;
|
||||
if (selectedPlatformName && !(await (0, common_2.isValidPlatform)(selectedPlatformName))) {
|
||||
const platformDir = (0, common_2.resolvePlatform)(config, selectedPlatformName);
|
||||
if (platformDir) {
|
||||
await (0, common_2.runPlatformHook)(config, selectedPlatformName, platformDir, 'capacitor:add');
|
||||
}
|
||||
else {
|
||||
let msg = `Platform ${colors_1.default.input(selectedPlatformName)} not found.`;
|
||||
if (await (0, common_2.isValidCommunityPlatform)(selectedPlatformName)) {
|
||||
msg += `\nTry installing ${colors_1.default.strong(`@capacitor-community/${selectedPlatformName}`)} and adding the platform again.`;
|
||||
}
|
||||
if (await (0, common_2.isValidEnterprisePlatform)(selectedPlatformName)) {
|
||||
msg +=
|
||||
`\nThis is an enterprise platform and @ionic-enterprise/capacitor-${selectedPlatformName} is not installed.\n` +
|
||||
`To learn how to use this platform, visit https://ionic.io/docs/${selectedPlatformName}`;
|
||||
}
|
||||
log_1.logger.error(msg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const knownPlatforms = await (0, common_2.getKnownPlatforms)();
|
||||
const platformName = await (0, common_2.promptForPlatform)(knownPlatforms, `Please choose a platform to add:`, selectedPlatformName);
|
||||
if (platformName === config.web.name) {
|
||||
webWarning();
|
||||
return;
|
||||
}
|
||||
const existingPlatformDir = await (0, common_2.getProjectPlatformDirectory)(config, platformName);
|
||||
if (existingPlatformDir) {
|
||||
(0, errors_1.fatal)(`${colors_1.default.input(platformName)} platform already exists.\n` +
|
||||
`To re-add this platform, first remove ${colors_1.default.strong((0, utils_terminal_1.prettyPath)(existingPlatformDir))}, then run this command again.\n` +
|
||||
`${colors_1.default.strong('WARNING')}: Your native project will be completely removed.`);
|
||||
}
|
||||
try {
|
||||
await (0, common_2.check)([
|
||||
() => (0, common_2.checkPackage)(),
|
||||
() => (0, common_2.checkAppConfig)(config),
|
||||
...addChecks(config, platformName),
|
||||
]);
|
||||
await doAdd(config, platformName);
|
||||
await editPlatforms(config, platformName);
|
||||
if (await (0, utils_fs_1.pathExists)(config.app.webDirAbs)) {
|
||||
await (0, sync_1.sync)(config, platformName, false, false);
|
||||
if (platformName === config.android.name) {
|
||||
await (0, common_2.runTask)('Syncing Gradle', async () => {
|
||||
return (0, add_1.createLocalProperties)(config.android.platformDirAbs);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_1.logger.warn(`${colors_1.default.success(colors_1.default.strong('sync'))} could not run--missing ${colors_1.default.strong(config.app.webDir)} directory.`);
|
||||
}
|
||||
printNextSteps(platformName);
|
||||
}
|
||||
catch (e) {
|
||||
if (!(0, errors_1.isFatal)(e)) {
|
||||
(0, errors_1.fatal)((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.addCommand = addCommand;
|
||||
function printNextSteps(platformName) {
|
||||
(0, log_1.logSuccess)(`${colors_1.default.strong(platformName)} platform added!`);
|
||||
log_1.output.write(`Follow the Developer Workflow guide to get building:\n${colors_1.default.strong(`https://capacitorjs.com/docs/basics/workflow`)}\n`);
|
||||
}
|
||||
function addChecks(config, platformName) {
|
||||
if (platformName === config.ios.name) {
|
||||
return [
|
||||
() => (0, common_3.checkIOSPackage)(config),
|
||||
() => (0, common_3.checkBundler)(config) || (0, common_3.checkCocoaPods)(config),
|
||||
];
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
return [() => (0, common_1.checkAndroidPackage)(config)];
|
||||
}
|
||||
else if (platformName === config.web.name) {
|
||||
return [];
|
||||
}
|
||||
else {
|
||||
throw `Platform ${platformName} is not valid.`;
|
||||
}
|
||||
}
|
||||
async function doAdd(config, platformName) {
|
||||
await (0, common_2.runTask)(colors_1.default.success(colors_1.default.strong('add')), async () => {
|
||||
if (platformName === config.ios.name) {
|
||||
await (0, add_2.addIOS)(config);
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
await (0, add_1.addAndroid)(config);
|
||||
}
|
||||
});
|
||||
}
|
||||
async function editPlatforms(config, platformName) {
|
||||
if (platformName === config.ios.name) {
|
||||
await (0, common_3.editProjectSettingsIOS)(config);
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
await (0, common_1.editProjectSettingsAndroid)(config);
|
||||
}
|
||||
}
|
||||
function webWarning() {
|
||||
log_1.logger.error(`Not adding platform ${colors_1.default.strong('web')}.\n` +
|
||||
`In Capacitor, the web platform is just your web app! For example, if you have a React or Angular project, the web platform is that project.\n` +
|
||||
`To add Capacitor functionality to your web app, follow the Web Getting Started Guide: ${colors_1.default.strong('https://capacitorjs.com/docs/web')}`);
|
||||
}
|
||||
62
@capacitor/cli/dist/tasks/build.js
vendored
Normal file
62
@capacitor/cli/dist/tasks/build.js
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.build = exports.buildCommand = void 0;
|
||||
const build_1 = require("../android/build");
|
||||
const common_1 = require("../common");
|
||||
const errors_1 = require("../errors");
|
||||
const build_2 = require("../ios/build");
|
||||
async function buildCommand(config, selectedPlatformName, buildOptions) {
|
||||
var _a;
|
||||
const platforms = await (0, common_1.selectPlatforms)(config, selectedPlatformName);
|
||||
let platformName;
|
||||
if (platforms.length === 1) {
|
||||
platformName = platforms[0];
|
||||
}
|
||||
else {
|
||||
platformName = await (0, common_1.promptForPlatform)(platforms.filter(createBuildablePlatformFilter(config)), `Please choose a platform to build for:`);
|
||||
}
|
||||
const buildCommandOptions = {
|
||||
scheme: buildOptions.scheme || config.ios.scheme,
|
||||
flavor: buildOptions.flavor || config.android.flavor,
|
||||
keystorepath: buildOptions.keystorepath || config.android.buildOptions.keystorePath,
|
||||
keystorepass: buildOptions.keystorepass || config.android.buildOptions.keystorePassword,
|
||||
keystorealias: buildOptions.keystorealias || config.android.buildOptions.keystoreAlias,
|
||||
keystorealiaspass: buildOptions.keystorealiaspass ||
|
||||
config.android.buildOptions.keystoreAliasPassword,
|
||||
androidreleasetype: buildOptions.androidreleasetype ||
|
||||
config.android.buildOptions.releaseType ||
|
||||
'AAB',
|
||||
signingtype: buildOptions.signingtype ||
|
||||
config.android.buildOptions.signingType ||
|
||||
'jarsigner',
|
||||
configuration: buildOptions.configuration || 'Release',
|
||||
};
|
||||
try {
|
||||
await build(config, platformName, buildCommandOptions);
|
||||
}
|
||||
catch (e) {
|
||||
if (!(0, errors_1.isFatal)(e)) {
|
||||
(0, errors_1.fatal)((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
exports.buildCommand = buildCommand;
|
||||
async function build(config, platformName, buildOptions) {
|
||||
if (platformName == config.ios.name) {
|
||||
await (0, build_2.buildiOS)(config, buildOptions);
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
await (0, build_1.buildAndroid)(config, buildOptions);
|
||||
}
|
||||
else if (platformName === config.web.name) {
|
||||
throw `Platform "${platformName}" is not available in the build command.`;
|
||||
}
|
||||
else {
|
||||
throw `Platform "${platformName}" is not valid.`;
|
||||
}
|
||||
}
|
||||
exports.build = build;
|
||||
function createBuildablePlatformFilter(config) {
|
||||
return platform => platform === config.ios.name || platform === config.android.name;
|
||||
}
|
||||
31
@capacitor/cli/dist/tasks/config.js
vendored
Normal file
31
@capacitor/cli/dist/tasks/config.js
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.configCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const util_1 = tslib_1.__importDefault(require("util"));
|
||||
const log_1 = require("../log");
|
||||
async function configCommand(config, json) {
|
||||
const evaluatedConfig = await deepAwait(config);
|
||||
if (json) {
|
||||
process.stdout.write(`${JSON.stringify(evaluatedConfig)}\n`);
|
||||
}
|
||||
else {
|
||||
log_1.output.write(`${util_1.default.inspect(evaluatedConfig, { depth: Infinity, colors: true })}\n`);
|
||||
}
|
||||
}
|
||||
exports.configCommand = configCommand;
|
||||
async function deepAwait(obj) {
|
||||
if (obj &&
|
||||
!Array.isArray(obj) &&
|
||||
typeof obj === 'object' &&
|
||||
obj.constructor === Object) {
|
||||
const o = {};
|
||||
for (const [k, v] of Object.entries(obj)) {
|
||||
o[k] = await deepAwait(v);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
else {
|
||||
return await obj;
|
||||
}
|
||||
}
|
||||
216
@capacitor/cli/dist/tasks/copy.js
vendored
Normal file
216
@capacitor/cli/dist/tasks/copy.js
vendored
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.copy = exports.copyCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const cordova_1 = require("../cordova");
|
||||
const errors_1 = require("../errors");
|
||||
const common_2 = require("../ios/common");
|
||||
const log_1 = require("../log");
|
||||
const plugin_1 = require("../plugin");
|
||||
const iosplugin_1 = require("../util/iosplugin");
|
||||
const promise_1 = require("../util/promise");
|
||||
const copy_1 = require("../web/copy");
|
||||
const sourcemaps_1 = require("./sourcemaps");
|
||||
async function copyCommand(config, selectedPlatformName, inline = false) {
|
||||
var _a;
|
||||
if (selectedPlatformName && !(await (0, common_1.isValidPlatform)(selectedPlatformName))) {
|
||||
const platformDir = (0, common_1.resolvePlatform)(config, selectedPlatformName);
|
||||
if (platformDir) {
|
||||
await (0, common_1.runPlatformHook)(config, selectedPlatformName, platformDir, 'capacitor:copy');
|
||||
}
|
||||
else {
|
||||
log_1.logger.error(`Platform ${colors_1.default.input(selectedPlatformName)} not found.`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const platforms = await (0, common_1.selectPlatforms)(config, selectedPlatformName);
|
||||
try {
|
||||
await (0, promise_1.allSerial)(platforms.map(platformName => () => copy(config, platformName, inline)));
|
||||
}
|
||||
catch (e) {
|
||||
if ((0, errors_1.isFatal)(e)) {
|
||||
throw e;
|
||||
}
|
||||
log_1.logger.error((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.copyCommand = copyCommand;
|
||||
async function copy(config, platformName, inline = false) {
|
||||
await (0, common_1.runTask)(colors_1.default.success(colors_1.default.strong(`copy ${platformName}`)), async () => {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
||||
const result = await (0, common_1.checkWebDir)(config);
|
||||
if (result) {
|
||||
throw result;
|
||||
}
|
||||
await (0, common_1.runHooks)(config, platformName, config.app.rootDir, 'capacitor:copy:before');
|
||||
const allPlugins = await (0, plugin_1.getPlugins)(config, platformName);
|
||||
let usesFederatedCapacitor = false;
|
||||
if (allPlugins.filter(plugin => plugin.id === '@ionic-enterprise/federated-capacitor').length > 0) {
|
||||
usesFederatedCapacitor = true;
|
||||
}
|
||||
let usesLiveUpdates = false;
|
||||
if (allPlugins.filter(plugin => plugin.id === '@capacitor/live-updates')
|
||||
.length > 0) {
|
||||
usesLiveUpdates = true;
|
||||
}
|
||||
let usesSSLPinning = false;
|
||||
if (allPlugins.filter(plugin => plugin.id === '@ionic-enterprise/ssl-pinning')
|
||||
.length > 0) {
|
||||
usesSSLPinning = true;
|
||||
}
|
||||
if (platformName === config.ios.name) {
|
||||
if (usesFederatedCapacitor) {
|
||||
await copyFederatedWebDirs(config, await config.ios.webDirAbs);
|
||||
if ((_c = (_b = (_a = config.app.extConfig) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.FederatedCapacitor) === null || _c === void 0 ? void 0 : _c.liveUpdatesKey) {
|
||||
await copySecureLiveUpdatesKey(config.app.extConfig.plugins.FederatedCapacitor.liveUpdatesKey, config.app.rootDir, config.ios.nativeTargetDirAbs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
await copyWebDir(config, await config.ios.webDirAbs, config.app.webDirAbs);
|
||||
}
|
||||
if (usesLiveUpdates && ((_f = (_e = (_d = config.app.extConfig) === null || _d === void 0 ? void 0 : _d.plugins) === null || _e === void 0 ? void 0 : _e.LiveUpdates) === null || _f === void 0 ? void 0 : _f.key)) {
|
||||
await copySecureLiveUpdatesKey(config.app.extConfig.plugins.LiveUpdates.key, config.app.rootDir, config.ios.nativeTargetDirAbs);
|
||||
}
|
||||
if (usesSSLPinning && ((_j = (_h = (_g = config.app.extConfig) === null || _g === void 0 ? void 0 : _g.plugins) === null || _h === void 0 ? void 0 : _h.SSLPinning) === null || _j === void 0 ? void 0 : _j.certs)) {
|
||||
await copySSLCert((_k = config.app.extConfig.plugins.SSLPinning) === null || _k === void 0 ? void 0 : _k.certs, config.app.rootDir, await config.ios.webDirAbs);
|
||||
}
|
||||
await copyCapacitorConfig(config, config.ios.nativeTargetDirAbs);
|
||||
const cordovaPlugins = await (0, cordova_1.getCordovaPlugins)(config, platformName);
|
||||
await (0, cordova_1.handleCordovaPluginsJS)(cordovaPlugins, config, platformName);
|
||||
const iosPlugins = await (0, common_2.getIOSPlugins)(allPlugins);
|
||||
await (0, iosplugin_1.generateIOSPackageJSON)(config, iosPlugins);
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
if (usesFederatedCapacitor) {
|
||||
await copyFederatedWebDirs(config, config.android.webDirAbs);
|
||||
if ((_o = (_m = (_l = config.app.extConfig) === null || _l === void 0 ? void 0 : _l.plugins) === null || _m === void 0 ? void 0 : _m.FederatedCapacitor) === null || _o === void 0 ? void 0 : _o.liveUpdatesKey) {
|
||||
await copySecureLiveUpdatesKey(config.app.extConfig.plugins.FederatedCapacitor.liveUpdatesKey, config.app.rootDir, config.android.assetsDirAbs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
await copyWebDir(config, config.android.webDirAbs, config.app.webDirAbs);
|
||||
}
|
||||
if (usesLiveUpdates && ((_r = (_q = (_p = config.app.extConfig) === null || _p === void 0 ? void 0 : _p.plugins) === null || _q === void 0 ? void 0 : _q.LiveUpdates) === null || _r === void 0 ? void 0 : _r.key)) {
|
||||
await copySecureLiveUpdatesKey(config.app.extConfig.plugins.LiveUpdates.key, config.app.rootDir, config.android.assetsDirAbs);
|
||||
}
|
||||
if (usesSSLPinning && ((_u = (_t = (_s = config.app.extConfig) === null || _s === void 0 ? void 0 : _s.plugins) === null || _t === void 0 ? void 0 : _t.SSLPinning) === null || _u === void 0 ? void 0 : _u.certs)) {
|
||||
await copySSLCert((_v = config.app.extConfig.plugins.SSLPinning) === null || _v === void 0 ? void 0 : _v.certs, config.app.rootDir, config.android.assetsDirAbs);
|
||||
}
|
||||
await copyCapacitorConfig(config, config.android.assetsDirAbs);
|
||||
const cordovaPlugins = await (0, cordova_1.getCordovaPlugins)(config, platformName);
|
||||
await (0, cordova_1.handleCordovaPluginsJS)(cordovaPlugins, config, platformName);
|
||||
await (0, cordova_1.writeCordovaAndroidManifest)(cordovaPlugins, config, platformName);
|
||||
}
|
||||
else if (platformName === config.web.name) {
|
||||
if (usesFederatedCapacitor) {
|
||||
log_1.logger.info('FederatedCapacitor Plugin installed, skipping web bundling...');
|
||||
}
|
||||
else {
|
||||
await (0, copy_1.copyWeb)(config);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw `Platform ${platformName} is not valid.`;
|
||||
}
|
||||
if (inline) {
|
||||
await (0, sourcemaps_1.inlineSourceMaps)(config, platformName);
|
||||
}
|
||||
});
|
||||
await (0, common_1.runHooks)(config, platformName, config.app.rootDir, 'capacitor:copy:after');
|
||||
}
|
||||
exports.copy = copy;
|
||||
async function copyCapacitorConfig(config, nativeAbsDir) {
|
||||
const nativeRelDir = (0, path_1.relative)(config.app.rootDir, nativeAbsDir);
|
||||
const nativeConfigFile = 'capacitor.config.json';
|
||||
const nativeConfigFilePath = (0, path_1.join)(nativeAbsDir, nativeConfigFile);
|
||||
await (0, common_1.runTask)(`Creating ${colors_1.default.strong(nativeConfigFile)} in ${nativeRelDir}`, async () => {
|
||||
var _a;
|
||||
(_a = config.app.extConfig.android) === null || _a === void 0 ? true : delete _a.buildOptions;
|
||||
await (0, utils_fs_1.writeJSON)(nativeConfigFilePath, config.app.extConfig, {
|
||||
spaces: '\t',
|
||||
});
|
||||
});
|
||||
}
|
||||
async function copyWebDir(config, nativeAbsDir, webAbsDir) {
|
||||
var _a;
|
||||
const webRelDir = (0, path_1.basename)(webAbsDir);
|
||||
const nativeRelDir = (0, path_1.relative)(config.app.rootDir, nativeAbsDir);
|
||||
if (((_a = config.app.extConfig.server) === null || _a === void 0 ? void 0 : _a.url) && !(await (0, utils_fs_1.pathExists)(webAbsDir))) {
|
||||
log_1.logger.warn(`Cannot copy web assets from ${colors_1.default.strong(webRelDir)} to ${nativeRelDir}\n` +
|
||||
`Web asset directory specified by ${colors_1.default.input('webDir')} does not exist. This is not an error because ${colors_1.default.input('server.url')} is set in config.`);
|
||||
return;
|
||||
}
|
||||
await (0, common_1.runTask)(`Copying web assets from ${colors_1.default.strong(webRelDir)} to ${nativeRelDir}`, async () => {
|
||||
await (0, utils_fs_1.remove)(nativeAbsDir);
|
||||
return (0, utils_fs_1.copy)(webAbsDir, nativeAbsDir);
|
||||
});
|
||||
}
|
||||
async function copyFederatedWebDirs(config, nativeAbsDir) {
|
||||
var _a, _b;
|
||||
log_1.logger.info('FederatedCapacitor Plugin Loaded - Copying Web Assets');
|
||||
if (!((_b = (_a = config.app.extConfig) === null || _a === void 0 ? void 0 : _a.plugins) === null || _b === void 0 ? void 0 : _b.FederatedCapacitor)) {
|
||||
throw `FederatedCapacitor plugin is present but no valid config is defined.`;
|
||||
}
|
||||
const federatedConfig = config.app.extConfig.plugins.FederatedCapacitor;
|
||||
if (federatedConfig) {
|
||||
if (federatedConfig.shell.name === undefined) {
|
||||
throw `FederatedCapacitor plugin is present but no valid Shell application is defined in the config.`;
|
||||
}
|
||||
if (!federatedConfig.apps.every(isFederatedApp)) {
|
||||
throw `FederatedCapacitor plugin is present but there is a problem with the apps defined in the config.`;
|
||||
}
|
||||
const copyApps = () => {
|
||||
return federatedConfig.apps.map(app => {
|
||||
const appDir = (0, path_1.resolve)(config.app.rootDir, app.webDir);
|
||||
return copyWebDir(config, (0, path_1.resolve)(nativeAbsDir, app.name), appDir);
|
||||
});
|
||||
};
|
||||
const copyShell = () => {
|
||||
return copyWebDir(config, (0, path_1.resolve)(nativeAbsDir, federatedConfig.shell.name), config.app.webDirAbs);
|
||||
};
|
||||
await Promise.all([...copyApps(), copyShell()]);
|
||||
}
|
||||
}
|
||||
function isFederatedApp(config) {
|
||||
return (config.webDir !== undefined &&
|
||||
config.name !== undefined);
|
||||
}
|
||||
async function copySecureLiveUpdatesKey(secureLiveUpdatesKeyFile, rootDir, nativeAbsDir) {
|
||||
const keyAbsFromPath = (0, path_1.join)(rootDir, secureLiveUpdatesKeyFile);
|
||||
const keyAbsToPath = (0, path_1.join)(nativeAbsDir, (0, path_1.basename)(keyAbsFromPath));
|
||||
const keyRelToDir = (0, path_1.relative)(rootDir, nativeAbsDir);
|
||||
if (!(await (0, utils_fs_1.pathExists)(keyAbsFromPath))) {
|
||||
log_1.logger.warn(`Cannot copy Secure Live Updates signature file from ${colors_1.default.strong(keyAbsFromPath)} to ${keyRelToDir}\n` +
|
||||
`Signature file does not exist at specified key path.`);
|
||||
return;
|
||||
}
|
||||
await (0, common_1.runTask)(`Copying Secure Live Updates key from ${colors_1.default.strong(secureLiveUpdatesKeyFile)} to ${keyRelToDir}`, async () => {
|
||||
return (0, utils_fs_1.copy)(keyAbsFromPath, keyAbsToPath);
|
||||
});
|
||||
}
|
||||
async function copySSLCert(sslCertPaths, rootDir, targetDir) {
|
||||
const validCertPaths = [];
|
||||
for (const sslCertPath of sslCertPaths) {
|
||||
const certAbsFromPath = (0, path_1.join)(rootDir, sslCertPath);
|
||||
if (!(await (0, utils_fs_1.pathExists)(certAbsFromPath))) {
|
||||
log_1.logger.warn(`Cannot copy SSL Certificate file from ${colors_1.default.strong(certAbsFromPath)}\n` +
|
||||
`SSL Certificate does not exist at specified path.`);
|
||||
return;
|
||||
}
|
||||
validCertPaths.push(certAbsFromPath);
|
||||
}
|
||||
const certsDirAbsToPath = (0, path_1.join)(targetDir, 'certs');
|
||||
const certsDirRelToDir = (0, path_1.relative)(rootDir, targetDir);
|
||||
await (0, common_1.runTask)(`Copying SSL Certificates from to ${certsDirRelToDir}`, async () => {
|
||||
const promises = [];
|
||||
for (const certPath of validCertPaths) {
|
||||
promises.push((0, utils_fs_1.copy)(certPath, (0, path_1.join)(certsDirAbsToPath, (0, path_1.basename)(certPath))));
|
||||
}
|
||||
return Promise.all(promises);
|
||||
});
|
||||
}
|
||||
11
@capacitor/cli/dist/tasks/create.js
vendored
Normal file
11
@capacitor/cli/dist/tasks/create.js
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const errors_1 = require("../errors");
|
||||
async function createCommand() {
|
||||
(0, errors_1.fatal)(`The create command has been removed.\n` +
|
||||
`Use ${colors_1.default.input('npm init @capacitor/app')}`);
|
||||
}
|
||||
exports.createCommand = createCommand;
|
||||
73
@capacitor/cli/dist/tasks/doctor.js
vendored
Normal file
73
@capacitor/cli/dist/tasks/doctor.js
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.doctor = exports.doctorCore = exports.doctorCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const doctor_1 = require("../android/doctor");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const doctor_2 = require("../ios/doctor");
|
||||
const log_1 = require("../log");
|
||||
const emoji_1 = require("../util/emoji");
|
||||
const node_1 = require("../util/node");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
async function doctorCommand(config, selectedPlatformName) {
|
||||
log_1.output.write(`${(0, emoji_1.emoji)('💊', '')} ${colors_1.default.strong('Capacitor Doctor')} ${(0, emoji_1.emoji)('💊', '')} \n\n`);
|
||||
await doctorCore(config);
|
||||
const platforms = await (0, common_1.selectPlatforms)(config, selectedPlatformName);
|
||||
await Promise.all(platforms.map(platformName => {
|
||||
return doctor(config, platformName);
|
||||
}));
|
||||
}
|
||||
exports.doctorCommand = doctorCommand;
|
||||
async function doctorCore(config) {
|
||||
const [cliVersion, coreVersion, androidVersion, iosVersion] = await Promise.all([
|
||||
(0, subprocess_1.getCommandOutput)('npm', ['info', '@capacitor/cli', 'version']),
|
||||
(0, subprocess_1.getCommandOutput)('npm', ['info', '@capacitor/core', 'version']),
|
||||
(0, subprocess_1.getCommandOutput)('npm', ['info', '@capacitor/android', 'version']),
|
||||
(0, subprocess_1.getCommandOutput)('npm', ['info', '@capacitor/ios', 'version']),
|
||||
]);
|
||||
log_1.output.write(`${colors_1.default.strong('Latest Dependencies:')}\n\n` +
|
||||
` @capacitor/cli: ${colors_1.default.weak(cliVersion !== null && cliVersion !== void 0 ? cliVersion : 'unknown')}\n` +
|
||||
` @capacitor/core: ${colors_1.default.weak(coreVersion !== null && coreVersion !== void 0 ? coreVersion : 'unknown')}\n` +
|
||||
` @capacitor/android: ${colors_1.default.weak(androidVersion !== null && androidVersion !== void 0 ? androidVersion : 'unknown')}\n` +
|
||||
` @capacitor/ios: ${colors_1.default.weak(iosVersion !== null && iosVersion !== void 0 ? iosVersion : 'unknown')}\n\n` +
|
||||
`${colors_1.default.strong('Installed Dependencies:')}\n\n`);
|
||||
await printInstalledPackages(config);
|
||||
log_1.output.write('\n');
|
||||
}
|
||||
exports.doctorCore = doctorCore;
|
||||
async function printInstalledPackages(config) {
|
||||
const packageNames = [
|
||||
'@capacitor/cli',
|
||||
'@capacitor/core',
|
||||
'@capacitor/android',
|
||||
'@capacitor/ios',
|
||||
];
|
||||
await Promise.all(packageNames.map(async (packageName) => {
|
||||
const packagePath = (0, node_1.resolveNode)(config.app.rootDir, packageName, 'package.json');
|
||||
await printPackageVersion(packageName, packagePath);
|
||||
}));
|
||||
}
|
||||
async function printPackageVersion(packageName, packagePath) {
|
||||
let version;
|
||||
if (packagePath) {
|
||||
version = (await (0, utils_fs_1.readJSON)(packagePath)).version;
|
||||
}
|
||||
log_1.output.write(` ${packageName}: ${colors_1.default.weak(version || 'not installed')}\n`);
|
||||
}
|
||||
async function doctor(config, platformName) {
|
||||
if (platformName === config.ios.name) {
|
||||
await (0, doctor_2.doctorIOS)(config);
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
await (0, doctor_1.doctorAndroid)(config);
|
||||
}
|
||||
else if (platformName === config.web.name) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
else {
|
||||
throw `Platform ${platformName} is not valid.`;
|
||||
}
|
||||
}
|
||||
exports.doctor = doctor;
|
||||
139
@capacitor/cli/dist/tasks/init.js
vendored
Normal file
139
@capacitor/cli/dist/tasks/init.js
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.initCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const open_1 = tslib_1.__importDefault(require("open"));
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const config_1 = require("../config");
|
||||
const cordova_1 = require("../cordova");
|
||||
const errors_1 = require("../errors");
|
||||
const framework_configs_1 = require("../framework-configs");
|
||||
const log_1 = require("../log");
|
||||
const sysconfig_1 = require("../sysconfig");
|
||||
const node_1 = require("../util/node");
|
||||
const term_1 = require("../util/term");
|
||||
async function initCommand(config, name, id, webDirFromCLI) {
|
||||
var _a, _b;
|
||||
try {
|
||||
if (!(0, term_1.checkInteractive)(name, id)) {
|
||||
return;
|
||||
}
|
||||
if (config.app.extConfigType !== 'json') {
|
||||
(0, errors_1.fatal)(`Cannot run ${colors_1.default.input('init')} for a project using a non-JSON configuration file.\n` +
|
||||
`Delete ${colors_1.default.strong(config.app.extConfigName)} and try again.`);
|
||||
}
|
||||
const isNewConfig = Object.keys(config.app.extConfig).length === 0;
|
||||
const tsInstalled = !!(0, node_1.resolveNode)(config.app.rootDir, 'typescript');
|
||||
const appName = await getName(config, name);
|
||||
const appId = await getAppId(config, id);
|
||||
const webDir = (0, term_1.isInteractive)()
|
||||
? await getWebDir(config, webDirFromCLI)
|
||||
: (_a = webDirFromCLI !== null && webDirFromCLI !== void 0 ? webDirFromCLI : config.app.extConfig.webDir) !== null && _a !== void 0 ? _a : 'www';
|
||||
await (0, common_1.check)([
|
||||
() => (0, common_1.checkAppName)(config, appName),
|
||||
() => (0, common_1.checkAppId)(config, appId),
|
||||
]);
|
||||
const cordova = await (0, cordova_1.getCordovaPreferences)(config);
|
||||
await runMergeConfig(config, {
|
||||
appId,
|
||||
appName,
|
||||
webDir,
|
||||
cordova,
|
||||
}, isNewConfig && tsInstalled ? 'ts' : 'json');
|
||||
}
|
||||
catch (e) {
|
||||
if (!(0, errors_1.isFatal)(e)) {
|
||||
log_1.output.write('Usage: npx cap init appName appId\n' +
|
||||
'Example: npx cap init "My App" "com.example.myapp"\n\n');
|
||||
(0, errors_1.fatal)((_b = e.stack) !== null && _b !== void 0 ? _b : e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
exports.initCommand = initCommand;
|
||||
async function getName(config, name) {
|
||||
var _a;
|
||||
if (!name) {
|
||||
const answers = await (0, log_1.logPrompt)(`${colors_1.default.strong(`What is the name of your app?`)}\n` +
|
||||
`This should be a human-friendly app name, like what you'd see in the App Store.`, {
|
||||
type: 'text',
|
||||
name: 'name',
|
||||
message: `Name`,
|
||||
initial: config.app.appName
|
||||
? config.app.appName
|
||||
: (_a = config.app.package.name) !== null && _a !== void 0 ? _a : 'App',
|
||||
});
|
||||
return answers.name;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
async function getAppId(config, id) {
|
||||
if (!id) {
|
||||
const answers = await (0, log_1.logPrompt)(`${colors_1.default.strong(`What should be the Package ID for your app?`)}\n` +
|
||||
`Package IDs (aka Bundle ID in iOS and Application ID in Android) are unique identifiers for apps. They must be in reverse domain name notation, generally representing a domain name that you or your company owns.`, {
|
||||
type: 'text',
|
||||
name: 'id',
|
||||
message: `Package ID`,
|
||||
initial: config.app.appId ? config.app.appId : 'com.example.app',
|
||||
});
|
||||
return answers.id;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
async function getWebDir(config, webDir) {
|
||||
if (!webDir) {
|
||||
const framework = (0, framework_configs_1.detectFramework)(config);
|
||||
if (framework === null || framework === void 0 ? void 0 : framework.webDir) {
|
||||
return framework.webDir;
|
||||
}
|
||||
const answers = await (0, log_1.logPrompt)(`${colors_1.default.strong(`What is the web asset directory for your app?`)}\n` +
|
||||
`This directory should contain the final ${colors_1.default.strong('index.html')} of your app.`, {
|
||||
type: 'text',
|
||||
name: 'webDir',
|
||||
message: `Web asset directory`,
|
||||
initial: config.app.webDir ? config.app.webDir : 'www',
|
||||
});
|
||||
return answers.webDir;
|
||||
}
|
||||
return webDir;
|
||||
}
|
||||
async function runMergeConfig(config, extConfig, type) {
|
||||
const configDirectory = (0, path_1.dirname)(config.app.extConfigFilePath);
|
||||
const newConfigPath = (0, path_1.resolve)(configDirectory, type === 'ts' ? config_1.CONFIG_FILE_NAME_TS : config_1.CONFIG_FILE_NAME_JSON);
|
||||
await (0, common_1.runTask)(`Creating ${colors_1.default.strong((0, path_1.basename)(newConfigPath))} in ${colors_1.default.input(config.app.rootDir)}`, async () => {
|
||||
await mergeConfig(config, extConfig, newConfigPath);
|
||||
});
|
||||
printNextSteps((0, path_1.basename)(newConfigPath));
|
||||
if ((0, term_1.isInteractive)()) {
|
||||
let sysconfig = await (0, sysconfig_1.readConfig)();
|
||||
if (typeof sysconfig.signup === 'undefined') {
|
||||
const signup = await promptToSignup();
|
||||
sysconfig = { ...sysconfig, signup };
|
||||
await (0, sysconfig_1.writeConfig)(sysconfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
async function mergeConfig(config, extConfig, newConfigPath) {
|
||||
const oldConfig = { ...config.app.extConfig };
|
||||
const newConfig = { ...oldConfig, ...extConfig };
|
||||
await (0, config_1.writeConfig)(newConfig, newConfigPath);
|
||||
}
|
||||
function printNextSteps(newConfigName) {
|
||||
(0, log_1.logSuccess)(`${colors_1.default.strong(newConfigName)} created!`);
|
||||
log_1.output.write(`\nNext steps: \n${colors_1.default.strong(`https://capacitorjs.com/docs/getting-started#where-to-go-next`)}\n`);
|
||||
}
|
||||
async function promptToSignup() {
|
||||
const answers = await (0, log_1.logPrompt)(`Join the Ionic Community! 💙\n` +
|
||||
`Connect with millions of developers on the Ionic Forum and get access to live events, news updates, and more.`, {
|
||||
type: 'confirm',
|
||||
name: 'create',
|
||||
message: `Create free Ionic account?`,
|
||||
initial: true,
|
||||
});
|
||||
if (answers.create) {
|
||||
(0, open_1.default)(`http://ionicframework.com/signup?source=capacitor`);
|
||||
}
|
||||
return answers.create;
|
||||
}
|
||||
50
@capacitor/cli/dist/tasks/list.js
vendored
Normal file
50
@capacitor/cli/dist/tasks/list.js
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.list = exports.listCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const common_1 = require("../android/common");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_2 = require("../common");
|
||||
const errors_1 = require("../errors");
|
||||
const common_3 = require("../ios/common");
|
||||
const log_1 = require("../log");
|
||||
const plugin_1 = require("../plugin");
|
||||
const promise_1 = require("../util/promise");
|
||||
async function listCommand(config, selectedPlatformName) {
|
||||
var _a;
|
||||
const platforms = await (0, common_2.selectPlatforms)(config, selectedPlatformName);
|
||||
try {
|
||||
await (0, promise_1.allSerial)(platforms.map(platformName => () => list(config, platformName)));
|
||||
}
|
||||
catch (e) {
|
||||
if ((0, errors_1.isFatal)(e)) {
|
||||
throw e;
|
||||
}
|
||||
log_1.logger.error((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
}
|
||||
exports.listCommand = listCommand;
|
||||
async function list(config, platform) {
|
||||
const allPlugins = await (0, plugin_1.getPlugins)(config, platform);
|
||||
let plugins = [];
|
||||
if (platform === config.ios.name) {
|
||||
plugins = await (0, common_3.getIOSPlugins)(allPlugins);
|
||||
}
|
||||
else if (platform === config.android.name) {
|
||||
plugins = await (0, common_1.getAndroidPlugins)(allPlugins);
|
||||
}
|
||||
else if (platform === config.web.name) {
|
||||
log_1.logger.info(`Listing plugins for ${colors_1.default.input(platform)} is not possible.`);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw `Platform ${colors_1.default.input(platform)} is not valid.`;
|
||||
}
|
||||
const capacitorPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 0 /* PluginType.Core */);
|
||||
(0, plugin_1.printPlugins)(capacitorPlugins, platform);
|
||||
const cordovaPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 1 /* PluginType.Cordova */);
|
||||
(0, plugin_1.printPlugins)(cordovaPlugins, platform, 'cordova');
|
||||
const incompatibleCordovaPlugins = plugins.filter(p => (0, plugin_1.getPluginType)(p, platform) === 2 /* PluginType.Incompatible */);
|
||||
(0, plugin_1.printPlugins)(incompatibleCordovaPlugins, platform, 'incompatible');
|
||||
}
|
||||
exports.list = list;
|
||||
575
@capacitor/cli/dist/tasks/migrate.js
vendored
Normal file
575
@capacitor/cli/dist/tasks/migrate.js
vendored
Normal file
|
|
@ -0,0 +1,575 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.patchOldCapacitorPlugins = exports.migrateCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const rimraf_1 = tslib_1.__importDefault(require("rimraf"));
|
||||
const semver_1 = require("semver");
|
||||
const common_1 = require("../android/common");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_2 = require("../common");
|
||||
const errors_1 = require("../errors");
|
||||
const log_1 = require("../log");
|
||||
const plugin_1 = require("../plugin");
|
||||
const fs_1 = require("../util/fs");
|
||||
const node_1 = require("../util/node");
|
||||
const subprocess_1 = require("../util/subprocess");
|
||||
const template_1 = require("../util/template");
|
||||
// eslint-disable-next-line prefer-const
|
||||
let allDependencies = {};
|
||||
const libs = [
|
||||
'@capacitor/core',
|
||||
'@capacitor/cli',
|
||||
'@capacitor/ios',
|
||||
'@capacitor/android',
|
||||
];
|
||||
const plugins = [
|
||||
'@capacitor/action-sheet',
|
||||
'@capacitor/app',
|
||||
'@capacitor/app-launcher',
|
||||
'@capacitor/browser',
|
||||
'@capacitor/camera',
|
||||
'@capacitor/clipboard',
|
||||
'@capacitor/device',
|
||||
'@capacitor/dialog',
|
||||
'@capacitor/filesystem',
|
||||
'@capacitor/geolocation',
|
||||
'@capacitor/haptics',
|
||||
'@capacitor/keyboard',
|
||||
'@capacitor/local-notifications',
|
||||
'@capacitor/motion',
|
||||
'@capacitor/network',
|
||||
'@capacitor/preferences',
|
||||
'@capacitor/push-notifications',
|
||||
'@capacitor/screen-reader',
|
||||
'@capacitor/screen-orientation',
|
||||
'@capacitor/share',
|
||||
'@capacitor/splash-screen',
|
||||
'@capacitor/status-bar',
|
||||
'@capacitor/text-zoom',
|
||||
'@capacitor/toast',
|
||||
];
|
||||
const coreVersion = '^6.0.0';
|
||||
const pluginVersion = '^6.0.0';
|
||||
const gradleVersion = '8.2.1';
|
||||
let installFailed = false;
|
||||
async function migrateCommand(config, noprompt, packagemanager) {
|
||||
if (config === null) {
|
||||
(0, errors_1.fatal)('Config data missing');
|
||||
}
|
||||
const capMajor = await checkCapacitorMajorVersion(config);
|
||||
if (capMajor < 5) {
|
||||
(0, errors_1.fatal)('Migrate can only be used on capacitor 5 and above, please use the CLI in Capacitor 5 to upgrade to 5 first');
|
||||
}
|
||||
const jdkMajor = await (0, common_2.checkJDKMajorVersion)();
|
||||
if (jdkMajor < 17) {
|
||||
log_1.logger.warn('Capacitor 6 requires JDK 17 or higher. Some steps may fail.');
|
||||
}
|
||||
const variablesAndClasspaths = await getAndroidVariablesAndClasspaths(config);
|
||||
if (!variablesAndClasspaths) {
|
||||
(0, errors_1.fatal)('Variable and Classpath info could not be read.');
|
||||
}
|
||||
allDependencies = {
|
||||
...config.app.package.dependencies,
|
||||
...config.app.package.devDependencies,
|
||||
};
|
||||
const monorepoWarning = 'Please note this tool is not intended for use in a mono-repo environment, please check out the Ionic vscode extension for this functionality.';
|
||||
log_1.logger.info(monorepoWarning);
|
||||
const { migrateconfirm } = noprompt
|
||||
? { migrateconfirm: 'y' }
|
||||
: await (0, log_1.logPrompt)(`Capacitor 6 sets a deployment target of iOS 13 and Android 14 (SDK 34). \n`, {
|
||||
type: 'text',
|
||||
name: 'migrateconfirm',
|
||||
message: `Are you sure you want to migrate? (Y/n)`,
|
||||
initial: 'y',
|
||||
});
|
||||
if (typeof migrateconfirm === 'string' &&
|
||||
migrateconfirm.toLowerCase() === 'y') {
|
||||
try {
|
||||
const { depInstallConfirm } = noprompt
|
||||
? { depInstallConfirm: 'y' }
|
||||
: await (0, log_1.logPrompt)(`Would you like the migrator to run npm, yarn, pnpm, or bun install to install the latest versions of capacitor packages? (Those using other package managers should answer N)`, {
|
||||
type: 'text',
|
||||
name: 'depInstallConfirm',
|
||||
message: `Run Dependency Install? (Y/n)`,
|
||||
initial: 'y',
|
||||
});
|
||||
const runNpmInstall = typeof depInstallConfirm === 'string' &&
|
||||
depInstallConfirm.toLowerCase() === 'y';
|
||||
let installerType = 'npm';
|
||||
if (runNpmInstall) {
|
||||
const { manager } = packagemanager
|
||||
? { manager: packagemanager }
|
||||
: await (0, log_1.logPrompt)('What dependency manager do you use?', {
|
||||
type: 'select',
|
||||
name: 'manager',
|
||||
message: `Dependency Management Tool`,
|
||||
choices: [
|
||||
{ title: 'NPM', value: 'npm' },
|
||||
{ title: 'Yarn', value: 'yarn' },
|
||||
{ title: 'PNPM', value: 'pnpm' },
|
||||
{ title: 'Bun', value: 'bun' },
|
||||
],
|
||||
initial: 0,
|
||||
});
|
||||
installerType = manager;
|
||||
}
|
||||
try {
|
||||
await (0, common_2.runTask)(`Installing Latest Modules using ${installerType}.`, () => {
|
||||
return installLatestLibs(installerType, runNpmInstall, config);
|
||||
});
|
||||
}
|
||||
catch (ex) {
|
||||
log_1.logger.error(`${installerType} install failed. Try deleting node_modules folder and running ${colors_1.default.input(`${installerType} install --force`)} manually.`);
|
||||
installFailed = true;
|
||||
}
|
||||
// Update iOS Projects
|
||||
if (allDependencies['@capacitor/ios'] &&
|
||||
(0, utils_fs_1.existsSync)(config.ios.platformDirAbs)) {
|
||||
// ios template changes
|
||||
// Remove NSLocationAlwaysUsageDescription
|
||||
await (0, common_2.runTask)(`Migrating Info.plist by removing NSLocationAlwaysUsageDescription key.`, () => {
|
||||
return removeKey((0, path_1.join)(config.ios.nativeTargetDirAbs, 'Info.plist'), 'NSLocationAlwaysUsageDescription');
|
||||
});
|
||||
}
|
||||
if (!installFailed) {
|
||||
await (0, common_2.runTask)(`Running cap sync.`, () => {
|
||||
return (0, subprocess_1.runCommand)('npx', ['cap', 'sync']);
|
||||
});
|
||||
}
|
||||
else {
|
||||
log_1.logger.warn('Skipped Running cap sync.');
|
||||
}
|
||||
if (allDependencies['@capacitor/android'] &&
|
||||
(0, utils_fs_1.existsSync)(config.android.platformDirAbs)) {
|
||||
const gradleWrapperVersion = getGradleWrapperVersion((0, path_1.join)(config.android.platformDirAbs, 'gradle', 'wrapper', 'gradle-wrapper.properties'));
|
||||
if (!installFailed && (0, semver_1.gt)(gradleVersion, gradleWrapperVersion)) {
|
||||
try {
|
||||
await (0, common_2.runTask)(`Upgrading gradle wrapper files`, () => {
|
||||
return updateGradleWrapperFiles(config.android.platformDirAbs);
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
if (e.includes('EACCES')) {
|
||||
log_1.logger.error(`gradlew file does not have executable permissions. This can happen if the Android platform was added on a Windows machine. Please run ${colors_1.default.input(`chmod +x ./${config.android.platformDir}/gradlew`)} and ${colors_1.default.input(`cd ${config.android.platformDir} && ./gradlew wrapper --distribution-type all --gradle-version ${gradleVersion} --warning-mode all`)} to update the files manually`);
|
||||
}
|
||||
else {
|
||||
log_1.logger.error(`gradle wrapper files were not updated`);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_1.logger.warn('Skipped upgrading gradle wrapper files');
|
||||
}
|
||||
await (0, common_2.runTask)(`Migrating build.gradle file.`, () => {
|
||||
return updateBuildGradle((0, path_1.join)(config.android.platformDirAbs, 'build.gradle'), variablesAndClasspaths);
|
||||
});
|
||||
// Replace deprecated compileSdkVersion
|
||||
await (0, common_2.runTask)('Replacing deprecated compileSdkVersion from build.gradle', () => {
|
||||
return (async () => {
|
||||
const buildGradleFilename = (0, path_1.join)(config.android.platformDirAbs, 'app', 'build.gradle');
|
||||
const buildGradleText = readFile(buildGradleFilename);
|
||||
if (!buildGradleText) {
|
||||
log_1.logger.error(`Could not read ${buildGradleFilename}. Check its permissions and if it exists.`);
|
||||
return;
|
||||
}
|
||||
const compileSdk = `compileSdkVersion rootProject.ext.compileSdkVersion`;
|
||||
if (buildGradleText.includes(compileSdk)) {
|
||||
const buildGradleReplaced = buildGradleText.replace(compileSdk, `compileSdk rootProject.ext.compileSdkVersion`);
|
||||
(0, utils_fs_1.writeFileSync)(buildGradleFilename, buildGradleReplaced, 'utf-8');
|
||||
}
|
||||
})();
|
||||
});
|
||||
// Variables gradle
|
||||
await (0, common_2.runTask)(`Migrating variables.gradle file.`, () => {
|
||||
return (async () => {
|
||||
const variablesPath = (0, path_1.join)(config.android.platformDirAbs, 'variables.gradle');
|
||||
let txt = readFile(variablesPath);
|
||||
if (!txt) {
|
||||
return;
|
||||
}
|
||||
txt = txt.replace(/= {2}'/g, `= '`);
|
||||
(0, utils_fs_1.writeFileSync)(variablesPath, txt, { encoding: 'utf-8' });
|
||||
for (const variable of Object.keys(variablesAndClasspaths.variables)) {
|
||||
let replaceStart = `${variable} = '`;
|
||||
let replaceEnd = `'\n`;
|
||||
if (typeof variablesAndClasspaths.variables[variable] === 'number') {
|
||||
replaceStart = `${variable} = `;
|
||||
replaceEnd = `\n`;
|
||||
}
|
||||
if (txt.includes(replaceStart)) {
|
||||
const first = txt.indexOf(replaceStart) + replaceStart.length;
|
||||
const value = txt.substring(first, txt.indexOf(replaceEnd, first));
|
||||
if ((typeof variablesAndClasspaths.variables[variable] ===
|
||||
'number' &&
|
||||
value <= variablesAndClasspaths.variables[variable]) ||
|
||||
(typeof variablesAndClasspaths.variables[variable] ===
|
||||
'string' &&
|
||||
(0, semver_1.lt)(value, variablesAndClasspaths.variables[variable]))) {
|
||||
await updateFile(config, variablesPath, replaceStart, replaceEnd, variablesAndClasspaths.variables[variable].toString(), true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
let file = readFile(variablesPath);
|
||||
if (file) {
|
||||
file = file.replace('}', ` ${replaceStart}${variablesAndClasspaths.variables[variable].toString()}${replaceEnd}}`);
|
||||
(0, utils_fs_1.writeFileSync)(variablesPath, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
const pluginVariables = {
|
||||
firebaseMessagingVersion: '23.3.1',
|
||||
playServicesLocationVersion: '21.1.0',
|
||||
androidxBrowserVersion: '1.7.0',
|
||||
androidxMaterialVersion: '1.10.0',
|
||||
androidxExifInterfaceVersion: '1.3.6',
|
||||
androidxCoreKTXVersion: '1.12.0',
|
||||
googleMapsPlayServicesVersion: '18.2.0',
|
||||
googleMapsUtilsVersion: '3.8.2',
|
||||
googleMapsKtxVersion: '5.0.0',
|
||||
googleMapsUtilsKtxVersion: '5.0.0',
|
||||
kotlinxCoroutinesVersion: '1.7.3',
|
||||
coreSplashScreenVersion: '1.0.1',
|
||||
};
|
||||
for (const variable of Object.keys(pluginVariables)) {
|
||||
await updateFile(config, variablesPath, `${variable} = '`, `'`, pluginVariables[variable], true);
|
||||
}
|
||||
})();
|
||||
});
|
||||
rimraf_1.default.sync((0, path_1.join)(config.android.appDirAbs, 'build'));
|
||||
if (!installFailed) {
|
||||
await (0, common_2.runTask)('Migrating package from Manifest to build.gradle in Capacitor plugins', () => {
|
||||
return patchOldCapacitorPlugins(config);
|
||||
});
|
||||
}
|
||||
else {
|
||||
log_1.logger.warn('Skipped migrating package from Manifest to build.gradle in Capacitor plugins');
|
||||
}
|
||||
}
|
||||
// Write all breaking changes
|
||||
await (0, common_2.runTask)(`Writing breaking changes.`, () => {
|
||||
return writeBreakingChanges();
|
||||
});
|
||||
if (!installFailed) {
|
||||
(0, log_1.logSuccess)(`Migration to Capacitor ${coreVersion} is complete. Run and test your app!`);
|
||||
}
|
||||
else {
|
||||
log_1.logger.warn(`Migration to Capacitor ${coreVersion} is incomplete. Check the log messages for more information.`);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
(0, errors_1.fatal)(`Failed to migrate: ${err}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
(0, errors_1.fatal)(`User canceled migration.`);
|
||||
}
|
||||
}
|
||||
exports.migrateCommand = migrateCommand;
|
||||
async function checkCapacitorMajorVersion(config) {
|
||||
var _a;
|
||||
const capacitorVersion = await (0, common_2.getCoreVersion)(config);
|
||||
const versionArray = (_a = capacitorVersion.match(/([0-9]+)\.([0-9]+)\.([0-9]+)/)) !== null && _a !== void 0 ? _a : [];
|
||||
const majorVersion = parseInt(versionArray[1]);
|
||||
return majorVersion;
|
||||
}
|
||||
async function installLatestLibs(dependencyManager, runInstall, config) {
|
||||
const pkgJsonPath = (0, path_1.join)(config.app.rootDir, 'package.json');
|
||||
const pkgJsonFile = readFile(pkgJsonPath);
|
||||
if (!pkgJsonFile) {
|
||||
return;
|
||||
}
|
||||
const pkgJson = JSON.parse(pkgJsonFile);
|
||||
for (const devDepKey of Object.keys(pkgJson['devDependencies'] || {})) {
|
||||
if (libs.includes(devDepKey)) {
|
||||
pkgJson['devDependencies'][devDepKey] = coreVersion;
|
||||
}
|
||||
else if (plugins.includes(devDepKey)) {
|
||||
pkgJson['devDependencies'][devDepKey] = pluginVersion;
|
||||
}
|
||||
}
|
||||
for (const depKey of Object.keys(pkgJson['dependencies'] || {})) {
|
||||
if (libs.includes(depKey)) {
|
||||
pkgJson['dependencies'][depKey] = coreVersion;
|
||||
}
|
||||
else if (plugins.includes(depKey)) {
|
||||
pkgJson['dependencies'][depKey] = pluginVersion;
|
||||
}
|
||||
}
|
||||
(0, utils_fs_1.writeFileSync)(pkgJsonPath, JSON.stringify(pkgJson, null, 2), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
if (runInstall) {
|
||||
rimraf_1.default.sync((0, path_1.join)(config.app.rootDir, 'node_modules/@capacitor/!(cli)'));
|
||||
await (0, subprocess_1.runCommand)(dependencyManager, ['install']);
|
||||
if (dependencyManager == 'yarn') {
|
||||
await (0, subprocess_1.runCommand)(dependencyManager, ['upgrade']);
|
||||
}
|
||||
else {
|
||||
await (0, subprocess_1.runCommand)(dependencyManager, ['update']);
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_1.logger.info(`Please run an install command with your package manager of choice. (ex: yarn install)`);
|
||||
}
|
||||
}
|
||||
async function writeBreakingChanges() {
|
||||
const breaking = [
|
||||
'@capacitor/camera',
|
||||
'@capacitor/filesystem',
|
||||
'@capacitor/geolocation',
|
||||
'@capacitor/google-maps',
|
||||
'@capacitor/local-notifications',
|
||||
];
|
||||
const broken = [];
|
||||
for (const lib of breaking) {
|
||||
if (allDependencies[lib]) {
|
||||
broken.push(lib);
|
||||
}
|
||||
}
|
||||
if (broken.length > 0) {
|
||||
log_1.logger.info(`IMPORTANT: Review https://capacitorjs.com/docs/next/updating/6-0#plugins for breaking changes in these plugins that you use: ${broken.join(', ')}.`);
|
||||
}
|
||||
}
|
||||
async function getAndroidVariablesAndClasspaths(config) {
|
||||
const tempAndroidTemplateFolder = (0, path_1.join)(config.cli.assetsDirAbs, 'tempAndroidTemplate');
|
||||
await (0, template_1.extractTemplate)(config.cli.assets.android.platformTemplateArchiveAbs, tempAndroidTemplateFolder);
|
||||
const variablesGradleFile = readFile((0, path_1.join)(tempAndroidTemplateFolder, 'variables.gradle'));
|
||||
const buildGradleFile = readFile((0, path_1.join)(tempAndroidTemplateFolder, 'build.gradle'));
|
||||
if (!variablesGradleFile || !buildGradleFile) {
|
||||
return;
|
||||
}
|
||||
(0, fs_1.deleteFolderRecursive)(tempAndroidTemplateFolder);
|
||||
const firstIndxOfCATBGV = buildGradleFile.indexOf(`classpath 'com.android.tools.build:gradle:`) + 42;
|
||||
const firstIndxOfCGGGS = buildGradleFile.indexOf(`com.google.gms:google-services:`) + 31;
|
||||
const comAndroidToolsBuildGradleVersion = '' +
|
||||
buildGradleFile.substring(firstIndxOfCATBGV, buildGradleFile.indexOf("'", firstIndxOfCATBGV));
|
||||
const comGoogleGmsGoogleServices = '' +
|
||||
buildGradleFile.substring(firstIndxOfCGGGS, buildGradleFile.indexOf("'", firstIndxOfCGGGS));
|
||||
const variablesGradleAsJSON = JSON.parse(variablesGradleFile
|
||||
.replace('ext ', '')
|
||||
.replace(/=/g, ':')
|
||||
.replace(/\n/g, ',')
|
||||
.replace(/,([^:]+):/g, function (_k, p1) {
|
||||
return `,"${p1}":`;
|
||||
})
|
||||
.replace('{,', '{')
|
||||
.replace(',}', '}')
|
||||
.replace(/\s/g, '')
|
||||
.replace(/'/g, '"'));
|
||||
return {
|
||||
'variables': variablesGradleAsJSON,
|
||||
'com.android.tools.build:gradle': comAndroidToolsBuildGradleVersion,
|
||||
'com.google.gms:google-services': comGoogleGmsGoogleServices,
|
||||
};
|
||||
}
|
||||
function readFile(filename) {
|
||||
try {
|
||||
if (!(0, utils_fs_1.existsSync)(filename)) {
|
||||
log_1.logger.error(`Unable to find ${filename}. Try updating it manually`);
|
||||
return;
|
||||
}
|
||||
return (0, utils_fs_1.readFileSync)(filename, 'utf-8');
|
||||
}
|
||||
catch (err) {
|
||||
log_1.logger.error(`Unable to read ${filename}. Verify it is not already open. ${err}`);
|
||||
}
|
||||
}
|
||||
function getGradleWrapperVersion(filename) {
|
||||
var _a;
|
||||
const txt = readFile(filename);
|
||||
if (!txt) {
|
||||
return '0.0.0';
|
||||
}
|
||||
const version = txt.substring(txt.indexOf('gradle-') + 7, txt.indexOf('-all.zip'));
|
||||
const semverVersion = (_a = (0, semver_1.coerce)(version)) === null || _a === void 0 ? void 0 : _a.version;
|
||||
return semverVersion ? semverVersion : '0.0.0';
|
||||
}
|
||||
async function updateGradleWrapperFiles(platformDir) {
|
||||
await (0, subprocess_1.runCommand)(`./gradlew`, [
|
||||
'wrapper',
|
||||
'--distribution-type',
|
||||
'all',
|
||||
'--gradle-version',
|
||||
gradleVersion,
|
||||
'--warning-mode',
|
||||
'all',
|
||||
], {
|
||||
cwd: platformDir,
|
||||
});
|
||||
}
|
||||
async function movePackageFromManifestToBuildGradle(manifestFilename, buildGradleFilename) {
|
||||
const manifestText = readFile(manifestFilename);
|
||||
const buildGradleText = readFile(buildGradleFilename);
|
||||
if (!manifestText) {
|
||||
log_1.logger.error(`Could not read ${manifestFilename}. Check its permissions and if it exists.`);
|
||||
return;
|
||||
}
|
||||
if (!buildGradleText) {
|
||||
log_1.logger.error(`Could not read ${buildGradleFilename}. Check its permissions and if it exists.`);
|
||||
return;
|
||||
}
|
||||
const namespaceExists = new RegExp(/\s+namespace\s+/).test(buildGradleText);
|
||||
if (namespaceExists) {
|
||||
log_1.logger.error('Found namespace in build.gradle already, skipping migration');
|
||||
return;
|
||||
}
|
||||
let packageName;
|
||||
const manifestRegEx = new RegExp(/package="([^"]+)"/);
|
||||
const manifestResults = manifestRegEx.exec(manifestText);
|
||||
if (manifestResults === null) {
|
||||
log_1.logger.error(`Unable to update Android Manifest. Package not found.`);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
packageName = manifestResults[1];
|
||||
}
|
||||
let manifestReplaced = manifestText;
|
||||
manifestReplaced = manifestReplaced.replace(manifestRegEx, '');
|
||||
if (manifestText == manifestReplaced) {
|
||||
log_1.logger.error(`Unable to update Android Manifest: no changes were detected in Android Manifest file`);
|
||||
return;
|
||||
}
|
||||
let buildGradleReplaced = buildGradleText;
|
||||
buildGradleReplaced = setAllStringIn(buildGradleText, 'android {', '\n', `\n namespace "${packageName}"`);
|
||||
if (buildGradleText == buildGradleReplaced) {
|
||||
log_1.logger.error(`Unable to update buildGradleText: no changes were detected in Android Manifest file`);
|
||||
return;
|
||||
}
|
||||
(0, utils_fs_1.writeFileSync)(manifestFilename, manifestReplaced, 'utf-8');
|
||||
(0, utils_fs_1.writeFileSync)(buildGradleFilename, buildGradleReplaced, 'utf-8');
|
||||
}
|
||||
async function updateBuildGradle(filename, variablesAndClasspaths) {
|
||||
const txt = readFile(filename);
|
||||
if (!txt) {
|
||||
return;
|
||||
}
|
||||
const neededDeps = {
|
||||
'com.android.tools.build:gradle': variablesAndClasspaths['com.android.tools.build:gradle'],
|
||||
'com.google.gms:google-services': variablesAndClasspaths['com.google.gms:google-services'],
|
||||
};
|
||||
let replaced = txt;
|
||||
for (const dep of Object.keys(neededDeps)) {
|
||||
if (replaced.includes(`classpath '${dep}`)) {
|
||||
const firstIndex = replaced.indexOf(dep) + dep.length + 1;
|
||||
const existingVersion = '' + replaced.substring(firstIndex, replaced.indexOf("'", firstIndex));
|
||||
if ((0, semver_1.gte)(neededDeps[dep], existingVersion)) {
|
||||
replaced = setAllStringIn(replaced, `classpath '${dep}:`, `'`, neededDeps[dep]);
|
||||
log_1.logger.info(`Set ${dep} = ${neededDeps[dep]}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
(0, utils_fs_1.writeFileSync)(filename, replaced, 'utf-8');
|
||||
}
|
||||
async function updateFile(config, filename, textStart, textEnd, replacement, skipIfNotFound) {
|
||||
if (config === null) {
|
||||
return false;
|
||||
}
|
||||
const path = filename;
|
||||
let txt = readFile(path);
|
||||
if (!txt) {
|
||||
return false;
|
||||
}
|
||||
if (txt.includes(textStart)) {
|
||||
if (replacement) {
|
||||
txt = setAllStringIn(txt, textStart, textEnd, replacement);
|
||||
(0, utils_fs_1.writeFileSync)(path, txt, { encoding: 'utf-8' });
|
||||
}
|
||||
else {
|
||||
// Replacing in code so we need to count the number of brackets to find the end of the function in swift
|
||||
const lines = txt.split('\n');
|
||||
let replaced = '';
|
||||
let keep = true;
|
||||
let brackets = 0;
|
||||
for (const line of lines) {
|
||||
if (line.includes(textStart)) {
|
||||
keep = false;
|
||||
}
|
||||
if (!keep) {
|
||||
brackets += (line.match(/{/g) || []).length;
|
||||
brackets -= (line.match(/}/g) || []).length;
|
||||
if (brackets == 0) {
|
||||
keep = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
replaced += line + '\n';
|
||||
}
|
||||
}
|
||||
(0, utils_fs_1.writeFileSync)(path, replaced, { encoding: 'utf-8' });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (!skipIfNotFound) {
|
||||
log_1.logger.error(`Unable to find "${textStart}" in ${filename}. Try updating it manually`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function setAllStringIn(data, start, end, replacement) {
|
||||
let position = 0;
|
||||
let result = data;
|
||||
let replaced = true;
|
||||
while (replaced) {
|
||||
const foundIdx = result.indexOf(start, position);
|
||||
if (foundIdx == -1) {
|
||||
replaced = false;
|
||||
}
|
||||
else {
|
||||
const idx = foundIdx + start.length;
|
||||
position = idx + replacement.length;
|
||||
result =
|
||||
result.substring(0, idx) +
|
||||
replacement +
|
||||
result.substring(result.indexOf(end, idx));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
async function patchOldCapacitorPlugins(config) {
|
||||
const allPlugins = await (0, plugin_1.getPlugins)(config, 'android');
|
||||
const androidPlugins = await (0, common_1.getAndroidPlugins)(allPlugins);
|
||||
return await Promise.all(androidPlugins.map(async (p) => {
|
||||
var _a, _b;
|
||||
if ((_b = (_a = p.manifest) === null || _a === void 0 ? void 0 : _a.android) === null || _b === void 0 ? void 0 : _b.src) {
|
||||
const buildGradlePath = (0, node_1.resolveNode)(config.app.rootDir, p.id, p.manifest.android.src, 'build.gradle');
|
||||
const manifestPath = (0, node_1.resolveNode)(config.app.rootDir, p.id, p.manifest.android.src, 'src', 'main', 'AndroidManifest.xml');
|
||||
if (buildGradlePath && manifestPath) {
|
||||
const gradleContent = readFile(buildGradlePath);
|
||||
if (!(gradleContent === null || gradleContent === void 0 ? void 0 : gradleContent.includes('namespace'))) {
|
||||
if (plugins.includes(p.id)) {
|
||||
log_1.logger.warn(`You are using an outdated version of ${p.id}, update the plugin to version ${pluginVersion}`);
|
||||
}
|
||||
else {
|
||||
log_1.logger.warn(`${p.id}@${p.version} doesn't officially support Capacitor ${coreVersion} yet, doing our best moving it's package to build.gradle so it builds`);
|
||||
}
|
||||
movePackageFromManifestToBuildGradle(manifestPath, buildGradlePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
exports.patchOldCapacitorPlugins = patchOldCapacitorPlugins;
|
||||
async function removeKey(filename, key) {
|
||||
const txt = readFile(filename);
|
||||
if (!txt) {
|
||||
return;
|
||||
}
|
||||
let lines = txt.split('\n');
|
||||
let removed = false;
|
||||
let removing = false;
|
||||
lines = lines.filter(line => {
|
||||
if (removing && line.includes('</string>')) {
|
||||
removing = false;
|
||||
return false;
|
||||
}
|
||||
if (line.includes(`<key>${key}</key`)) {
|
||||
removing = true;
|
||||
removed = true;
|
||||
}
|
||||
return !removing;
|
||||
});
|
||||
if (removed) {
|
||||
(0, utils_fs_1.writeFileSync)(filename, lines.join('\n'), 'utf-8');
|
||||
}
|
||||
}
|
||||
11
@capacitor/cli/dist/tasks/new-plugin.js
vendored
Normal file
11
@capacitor/cli/dist/tasks/new-plugin.js
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.newPluginCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const errors_1 = require("../errors");
|
||||
async function newPluginCommand() {
|
||||
(0, errors_1.fatal)(`The plugin:generate command has been removed.\n` +
|
||||
`Use ${colors_1.default.input('npm init @capacitor/plugin')}`);
|
||||
}
|
||||
exports.newPluginCommand = newPluginCommand;
|
||||
62
@capacitor/cli/dist/tasks/open.js
vendored
Normal file
62
@capacitor/cli/dist/tasks/open.js
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.open = exports.openCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const open_1 = require("../android/open");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const errors_1 = require("../errors");
|
||||
const open_2 = require("../ios/open");
|
||||
const log_1 = require("../log");
|
||||
async function openCommand(config, selectedPlatformName) {
|
||||
var _a;
|
||||
if (selectedPlatformName && !(await (0, common_1.isValidPlatform)(selectedPlatformName))) {
|
||||
const platformDir = (0, common_1.resolvePlatform)(config, selectedPlatformName);
|
||||
if (platformDir) {
|
||||
await (0, common_1.runPlatformHook)(config, selectedPlatformName, platformDir, 'capacitor:open');
|
||||
}
|
||||
else {
|
||||
log_1.logger.error(`Platform ${colors_1.default.input(selectedPlatformName)} not found.`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const platforms = await (0, common_1.selectPlatforms)(config, selectedPlatformName);
|
||||
let platformName;
|
||||
if (platforms.length === 1) {
|
||||
platformName = platforms[0];
|
||||
}
|
||||
else {
|
||||
platformName = await (0, common_1.promptForPlatform)(platforms.filter(createOpenablePlatformFilter(config)), `Please choose a platform to open:`);
|
||||
}
|
||||
try {
|
||||
await open(config, platformName);
|
||||
}
|
||||
catch (e) {
|
||||
if (!(0, errors_1.isFatal)(e)) {
|
||||
(0, errors_1.fatal)((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.openCommand = openCommand;
|
||||
function createOpenablePlatformFilter(config) {
|
||||
return platform => platform === config.ios.name || platform === config.android.name;
|
||||
}
|
||||
async function open(config, platformName) {
|
||||
if (platformName === config.ios.name) {
|
||||
await (0, common_1.runTask)('Opening the Xcode workspace...', () => {
|
||||
return (0, open_2.openIOS)(config);
|
||||
});
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
return (0, open_1.openAndroid)(config);
|
||||
}
|
||||
else if (platformName === config.web.name) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
else {
|
||||
throw `Platform ${platformName} is not valid.`;
|
||||
}
|
||||
}
|
||||
exports.open = open;
|
||||
114
@capacitor/cli/dist/tasks/run.js
vendored
Normal file
114
@capacitor/cli/dist/tasks/run.js
vendored
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.run = exports.runCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_process_1 = require("@ionic/utils-process");
|
||||
const utils_terminal_1 = require("@ionic/utils-terminal");
|
||||
const run_1 = require("../android/run");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const cordova_1 = require("../cordova");
|
||||
const errors_1 = require("../errors");
|
||||
const run_2 = require("../ios/run");
|
||||
const log_1 = require("../log");
|
||||
const livereload_1 = require("../util/livereload");
|
||||
const native_run_1 = require("../util/native-run");
|
||||
const sync_1 = require("./sync");
|
||||
async function runCommand(config, selectedPlatformName, options) {
|
||||
var _a, _b, _c, _d;
|
||||
options.host =
|
||||
(_b = (_a = options.host) !== null && _a !== void 0 ? _a : livereload_1.CapLiveReloadHelper.getIpAddress()) !== null && _b !== void 0 ? _b : 'localhost';
|
||||
options.port = (_c = options.port) !== null && _c !== void 0 ? _c : '3000';
|
||||
if (selectedPlatformName && !(await (0, common_1.isValidPlatform)(selectedPlatformName))) {
|
||||
const platformDir = (0, common_1.resolvePlatform)(config, selectedPlatformName);
|
||||
if (platformDir) {
|
||||
await (0, common_1.runPlatformHook)(config, selectedPlatformName, platformDir, 'capacitor:run');
|
||||
}
|
||||
else {
|
||||
log_1.logger.error(`Platform ${colors_1.default.input(selectedPlatformName)} not found.`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const platforms = await (0, common_1.selectPlatforms)(config, selectedPlatformName);
|
||||
let platformName;
|
||||
if (platforms.length === 1) {
|
||||
platformName = platforms[0];
|
||||
}
|
||||
else {
|
||||
platformName = await (0, common_1.promptForPlatform)(platforms.filter(createRunnablePlatformFilter(config)), `Please choose a platform to run:`);
|
||||
}
|
||||
if (options.list) {
|
||||
const targets = await (0, native_run_1.getPlatformTargets)(platformName);
|
||||
const outputTargets = targets.map(t => {
|
||||
var _a;
|
||||
return ({
|
||||
name: (0, common_1.getPlatformTargetName)(t),
|
||||
api: `${t.platform === 'ios' ? 'iOS' : 'API'} ${t.sdkVersion}`,
|
||||
id: (_a = t.id) !== null && _a !== void 0 ? _a : '?',
|
||||
});
|
||||
});
|
||||
// TODO: make hidden commander option (https://github.com/tj/commander.js/issues/1106)
|
||||
if (process.argv.includes('--json')) {
|
||||
process.stdout.write(`${JSON.stringify(outputTargets)}\n`);
|
||||
}
|
||||
else {
|
||||
const rows = outputTargets.map(t => [t.name, t.api, t.id]);
|
||||
log_1.output.write(`${(0, utils_terminal_1.columnar)(rows, {
|
||||
headers: ['Name', 'API', 'Target ID'],
|
||||
vsep: ' ',
|
||||
})}\n`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (options.sync) {
|
||||
await (0, sync_1.sync)(config, platformName, false, true);
|
||||
}
|
||||
const cordovaPlugins = await (0, cordova_1.getCordovaPlugins)(config, platformName);
|
||||
if (options.liveReload) {
|
||||
await livereload_1.CapLiveReloadHelper.editCapConfigForLiveReload(config, platformName, options);
|
||||
if (platformName === config.android.name) {
|
||||
await await (0, cordova_1.writeCordovaAndroidManifest)(cordovaPlugins, config, platformName, true);
|
||||
}
|
||||
}
|
||||
await run(config, platformName, options);
|
||||
if (options.liveReload) {
|
||||
new Promise(resolve => process.on('SIGINT', resolve))
|
||||
.then(async () => {
|
||||
await livereload_1.CapLiveReloadHelper.revertCapConfigForLiveReload();
|
||||
if (platformName === config.android.name) {
|
||||
await (0, cordova_1.writeCordovaAndroidManifest)(cordovaPlugins, config, platformName, false);
|
||||
}
|
||||
})
|
||||
.then(() => process.exit());
|
||||
log_1.logger.info(`App running with live reload listing for: http://${options.host}:${options.port}. Press Ctrl+C to quit.`);
|
||||
await (0, utils_process_1.sleepForever)();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
if (!(0, errors_1.isFatal)(e)) {
|
||||
(0, errors_1.fatal)((_d = e.stack) !== null && _d !== void 0 ? _d : e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.runCommand = runCommand;
|
||||
async function run(config, platformName, options) {
|
||||
if (platformName == config.ios.name) {
|
||||
await (0, run_2.runIOS)(config, options);
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
await (0, run_1.runAndroid)(config, options);
|
||||
}
|
||||
else if (platformName === config.web.name) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw `Platform ${platformName} is not valid.`;
|
||||
}
|
||||
}
|
||||
exports.run = run;
|
||||
function createRunnablePlatformFilter(config) {
|
||||
return platform => platform === config.ios.name || platform === config.android.name;
|
||||
}
|
||||
11
@capacitor/cli/dist/tasks/serve.js
vendored
Normal file
11
@capacitor/cli/dist/tasks/serve.js
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.serveCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const errors_1 = require("../errors");
|
||||
async function serveCommand() {
|
||||
(0, errors_1.fatal)(`The serve command has been removed.\n` +
|
||||
`Use a third-party tool for serving single page apps, such as ${colors_1.default.strong('serve')}: ${colors_1.default.strong('https://www.npmjs.com/package/serve')}`);
|
||||
}
|
||||
exports.serveCommand = serveCommand;
|
||||
40
@capacitor/cli/dist/tasks/sourcemaps.js
vendored
Normal file
40
@capacitor/cli/dist/tasks/sourcemaps.js
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.inlineSourceMaps = void 0;
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const log_1 = require("../log");
|
||||
function walkDirectory(dirPath) {
|
||||
const files = (0, utils_fs_1.readdirSync)(dirPath);
|
||||
files.forEach(file => {
|
||||
const targetFile = (0, path_1.join)(dirPath, file);
|
||||
if ((0, utils_fs_1.existsSync)(targetFile) && (0, utils_fs_1.lstatSync)(targetFile).isDirectory()) {
|
||||
walkDirectory(targetFile);
|
||||
}
|
||||
else {
|
||||
const mapFile = (0, path_1.join)(dirPath, `${file}.map`);
|
||||
if ((0, path_1.extname)(file) === '.js' && (0, utils_fs_1.existsSync)(mapFile)) {
|
||||
const bufMap = (0, utils_fs_1.readFileSync)(mapFile).toString('base64');
|
||||
const bufFile = (0, utils_fs_1.readFileSync)(targetFile, 'utf8');
|
||||
const result = bufFile.replace(`sourceMappingURL=${file}.map`, 'sourceMappingURL=data:application/json;charset=utf-8;base64,' +
|
||||
bufMap);
|
||||
(0, utils_fs_1.writeFileSync)(targetFile, result);
|
||||
(0, utils_fs_1.unlinkSync)(mapFile);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
async function inlineSourceMaps(config, platformName) {
|
||||
let buildDir = '';
|
||||
if (platformName == config.ios.name) {
|
||||
buildDir = await config.ios.webDirAbs;
|
||||
}
|
||||
if (platformName == config.android.name) {
|
||||
buildDir = await config.android.webDirAbs;
|
||||
}
|
||||
if (buildDir) {
|
||||
log_1.logger.info('Inlining sourcemaps');
|
||||
walkDirectory(buildDir);
|
||||
}
|
||||
}
|
||||
exports.inlineSourceMaps = inlineSourceMaps;
|
||||
59
@capacitor/cli/dist/tasks/sync.js
vendored
Normal file
59
@capacitor/cli/dist/tasks/sync.js
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.sync = exports.syncCommand = void 0;
|
||||
const common_1 = require("../common");
|
||||
const errors_1 = require("../errors");
|
||||
const log_1 = require("../log");
|
||||
const promise_1 = require("../util/promise");
|
||||
const copy_1 = require("./copy");
|
||||
const update_1 = require("./update");
|
||||
/**
|
||||
* Sync is a copy and an update in one.
|
||||
*/
|
||||
async function syncCommand(config, selectedPlatformName, deployment, inline = false) {
|
||||
var _a, _b;
|
||||
if (selectedPlatformName && !(await (0, common_1.isValidPlatform)(selectedPlatformName))) {
|
||||
try {
|
||||
await (0, copy_1.copyCommand)(config, selectedPlatformName, inline);
|
||||
}
|
||||
catch (e) {
|
||||
log_1.logger.error((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
await (0, update_1.updateCommand)(config, selectedPlatformName, deployment);
|
||||
}
|
||||
else {
|
||||
const then = +new Date();
|
||||
const platforms = await (0, common_1.selectPlatforms)(config, selectedPlatformName);
|
||||
try {
|
||||
await (0, common_1.check)([
|
||||
() => (0, common_1.checkPackage)(),
|
||||
() => (0, common_1.checkWebDir)(config),
|
||||
...(0, update_1.updateChecks)(config, platforms),
|
||||
]);
|
||||
await (0, promise_1.allSerial)(platforms.map(platformName => () => sync(config, platformName, deployment, inline)));
|
||||
const now = +new Date();
|
||||
const diff = (now - then) / 1000;
|
||||
log_1.logger.info(`Sync finished in ${diff}s`);
|
||||
}
|
||||
catch (e) {
|
||||
if (!(0, errors_1.isFatal)(e)) {
|
||||
(0, errors_1.fatal)((_b = e.stack) !== null && _b !== void 0 ? _b : e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.syncCommand = syncCommand;
|
||||
async function sync(config, platformName, deployment, inline = false) {
|
||||
var _a;
|
||||
await (0, common_1.runHooks)(config, platformName, config.app.rootDir, 'capacitor:sync:before');
|
||||
try {
|
||||
await (0, copy_1.copy)(config, platformName, inline);
|
||||
}
|
||||
catch (e) {
|
||||
log_1.logger.error((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
await (0, update_1.update)(config, platformName, deployment);
|
||||
await (0, common_1.runHooks)(config, platformName, config.app.rootDir, 'capacitor:sync:after');
|
||||
}
|
||||
exports.sync = sync;
|
||||
40
@capacitor/cli/dist/tasks/telemetry.js
vendored
Normal file
40
@capacitor/cli/dist/tasks/telemetry.js
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.telemetryCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const errors_1 = require("../errors");
|
||||
const log_1 = require("../log");
|
||||
const sysconfig_1 = require("../sysconfig");
|
||||
const telemetry_1 = require("../telemetry");
|
||||
async function telemetryCommand(onOrOff) {
|
||||
const sysconfig = await (0, sysconfig_1.readConfig)();
|
||||
const enabled = interpretEnabled(onOrOff);
|
||||
if (typeof enabled === 'boolean') {
|
||||
if (sysconfig.telemetry === enabled) {
|
||||
log_1.logger.info(`Telemetry is already ${colors_1.default.strong(enabled ? 'on' : 'off')}`);
|
||||
}
|
||||
else {
|
||||
await (0, sysconfig_1.writeConfig)({ ...sysconfig, telemetry: enabled });
|
||||
(0, log_1.logSuccess)(`You have ${colors_1.default.strong(`opted ${enabled ? 'in' : 'out'}`)} ${enabled ? 'for' : 'of'} telemetry on this machine.`);
|
||||
if (enabled) {
|
||||
log_1.output.write(telemetry_1.THANK_YOU);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
log_1.logger.info(`Telemetry is ${colors_1.default.strong(sysconfig.telemetry ? 'on' : 'off')}`);
|
||||
}
|
||||
}
|
||||
exports.telemetryCommand = telemetryCommand;
|
||||
function interpretEnabled(onOrOff) {
|
||||
switch (onOrOff) {
|
||||
case 'on':
|
||||
return true;
|
||||
case 'off':
|
||||
return false;
|
||||
case undefined:
|
||||
return undefined;
|
||||
}
|
||||
(0, errors_1.fatal)(`Argument must be ${colors_1.default.strong('on')} or ${colors_1.default.strong('off')} (or left unspecified)`);
|
||||
}
|
||||
74
@capacitor/cli/dist/tasks/update.js
vendored
Normal file
74
@capacitor/cli/dist/tasks/update.js
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.update = exports.updateChecks = exports.updateCommand = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const update_1 = require("../android/update");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const errors_1 = require("../errors");
|
||||
const common_2 = require("../ios/common");
|
||||
const update_2 = require("../ios/update");
|
||||
const log_1 = require("../log");
|
||||
const promise_1 = require("../util/promise");
|
||||
async function updateCommand(config, selectedPlatformName, deployment) {
|
||||
var _a;
|
||||
if (selectedPlatformName && !(await (0, common_1.isValidPlatform)(selectedPlatformName))) {
|
||||
const platformDir = (0, common_1.resolvePlatform)(config, selectedPlatformName);
|
||||
if (platformDir) {
|
||||
await (0, common_1.runPlatformHook)(config, selectedPlatformName, platformDir, 'capacitor:update');
|
||||
}
|
||||
else {
|
||||
log_1.logger.error(`Platform ${colors_1.default.input(selectedPlatformName)} not found.`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const then = +new Date();
|
||||
const platforms = await (0, common_1.selectPlatforms)(config, selectedPlatformName);
|
||||
try {
|
||||
await (0, common_1.check)([() => (0, common_1.checkPackage)(), ...updateChecks(config, platforms)]);
|
||||
await (0, promise_1.allSerial)(platforms.map(platformName => async () => await update(config, platformName, deployment)));
|
||||
const now = +new Date();
|
||||
const diff = (now - then) / 1000;
|
||||
log_1.logger.info(`Update finished in ${diff}s`);
|
||||
}
|
||||
catch (e) {
|
||||
if (!(0, errors_1.isFatal)(e)) {
|
||||
(0, errors_1.fatal)((_a = e.stack) !== null && _a !== void 0 ? _a : e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.updateCommand = updateCommand;
|
||||
function updateChecks(config, platforms) {
|
||||
const checks = [];
|
||||
for (const platformName of platforms) {
|
||||
if (platformName === config.ios.name) {
|
||||
checks.push(() => (0, common_2.checkBundler)(config) || (0, common_2.checkCocoaPods)(config));
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
continue;
|
||||
}
|
||||
else if (platformName === config.web.name) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
throw `Platform ${platformName} is not valid.`;
|
||||
}
|
||||
}
|
||||
return checks;
|
||||
}
|
||||
exports.updateChecks = updateChecks;
|
||||
async function update(config, platformName, deployment) {
|
||||
await (0, common_1.runTask)(colors_1.default.success(colors_1.default.strong(`update ${platformName}`)), async () => {
|
||||
await (0, common_1.runHooks)(config, platformName, config.app.rootDir, 'capacitor:update:before');
|
||||
if (platformName === config.ios.name) {
|
||||
await (0, update_2.updateIOS)(config, deployment);
|
||||
}
|
||||
else if (platformName === config.android.name) {
|
||||
await (0, update_1.updateAndroid)(config);
|
||||
}
|
||||
await (0, common_1.runHooks)(config, platformName, config.app.rootDir, 'capacitor:update:after');
|
||||
});
|
||||
}
|
||||
exports.update = update;
|
||||
130
@capacitor/cli/dist/telemetry.js
vendored
Normal file
130
@capacitor/cli/dist/telemetry.js
vendored
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.sendMetric = exports.telemetryAction = exports.THANK_YOU = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const commander_1 = require("commander");
|
||||
const debug_1 = tslib_1.__importDefault(require("debug"));
|
||||
const colors_1 = tslib_1.__importDefault(require("./colors"));
|
||||
const ipc_1 = require("./ipc");
|
||||
const log_1 = require("./log");
|
||||
const sysconfig_1 = require("./sysconfig");
|
||||
const subprocess_1 = require("./util/subprocess");
|
||||
const term_1 = require("./util/term");
|
||||
const debug = (0, debug_1.default)('capacitor:telemetry');
|
||||
exports.THANK_YOU = `\nThank you for helping to make Capacitor better! 💖` +
|
||||
`\nInformation about the data we collect is available on our website: ${colors_1.default.strong('https://capacitorjs.com/telemetry')}\n`;
|
||||
function telemetryAction(config, action) {
|
||||
return async (...actionArgs) => {
|
||||
const start = new Date();
|
||||
// This is how commanderjs works--the command object is either the last
|
||||
// element or second to last if there are additional options (via `.allowUnknownOption()`)
|
||||
const lastArg = actionArgs[actionArgs.length - 1];
|
||||
const cmd = lastArg instanceof commander_1.Command ? lastArg : actionArgs[actionArgs.length - 2];
|
||||
const command = getFullCommandName(cmd);
|
||||
let error;
|
||||
try {
|
||||
await action(...actionArgs);
|
||||
}
|
||||
catch (e) {
|
||||
error = e;
|
||||
}
|
||||
const end = new Date();
|
||||
const duration = end.getTime() - start.getTime();
|
||||
const packages = Object.entries({
|
||||
...config.app.package.devDependencies,
|
||||
...config.app.package.dependencies,
|
||||
});
|
||||
// Only collect packages in the capacitor org:
|
||||
// https://www.npmjs.com/org/capacitor
|
||||
const capacitorPackages = packages.filter(([k]) => k.startsWith('@capacitor/'));
|
||||
const versions = capacitorPackages.map(([k, v]) => [
|
||||
`${k.replace(/^@capacitor\//, '').replace(/-/g, '_')}_version`,
|
||||
v,
|
||||
]);
|
||||
const data = {
|
||||
app_id: await getAppIdentifier(config),
|
||||
command,
|
||||
arguments: cmd.args.join(' '),
|
||||
options: JSON.stringify(cmd.opts()),
|
||||
duration,
|
||||
error: error ? (error.message ? error.message : String(error)) : null,
|
||||
node_version: process.version,
|
||||
os: config.cli.os,
|
||||
...Object.fromEntries(versions),
|
||||
};
|
||||
if ((0, term_1.isInteractive)()) {
|
||||
let sysconfig = await (0, sysconfig_1.readConfig)();
|
||||
if (!error && typeof sysconfig.telemetry === 'undefined') {
|
||||
const confirm = await promptForTelemetry();
|
||||
sysconfig = { ...sysconfig, telemetry: confirm };
|
||||
await (0, sysconfig_1.writeConfig)(sysconfig);
|
||||
}
|
||||
await sendMetric(sysconfig, 'capacitor_cli_command', data);
|
||||
}
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
exports.telemetryAction = telemetryAction;
|
||||
/**
|
||||
* If telemetry is enabled, send a metric via IPC to a forked process for uploading.
|
||||
*/
|
||||
async function sendMetric(sysconfig, name, data) {
|
||||
if (sysconfig.telemetry && (0, term_1.isInteractive)()) {
|
||||
const message = {
|
||||
name,
|
||||
timestamp: new Date().toISOString(),
|
||||
session_id: sysconfig.machine,
|
||||
source: 'capacitor_cli',
|
||||
value: data,
|
||||
};
|
||||
await (0, ipc_1.send)({ type: 'telemetry', data: message });
|
||||
}
|
||||
else {
|
||||
debug('Telemetry is off (user choice, non-interactive terminal, or CI)--not sending metric');
|
||||
}
|
||||
}
|
||||
exports.sendMetric = sendMetric;
|
||||
async function promptForTelemetry() {
|
||||
const { confirm } = await (0, log_1.logPrompt)(`${colors_1.default.strong('Would you like to help improve Capacitor by sharing anonymous usage data? 💖')}\n` +
|
||||
`Read more about what is being collected and why here: ${colors_1.default.strong('https://capacitorjs.com/telemetry')}. You can change your mind at any time by using the ${colors_1.default.input('npx cap telemetry')} command.`, {
|
||||
type: 'confirm',
|
||||
name: 'confirm',
|
||||
message: 'Share anonymous usage data?',
|
||||
initial: true,
|
||||
});
|
||||
if (confirm) {
|
||||
log_1.output.write(exports.THANK_YOU);
|
||||
}
|
||||
return confirm;
|
||||
}
|
||||
/**
|
||||
* Get a unique anonymous identifier for this app.
|
||||
*/
|
||||
async function getAppIdentifier(config) {
|
||||
const { createHash } = await Promise.resolve().then(() => tslib_1.__importStar(require('crypto')));
|
||||
// get the first commit hash, which should be universally unique
|
||||
const output = await (0, subprocess_1.getCommandOutput)('git', ['rev-list', '--max-parents=0', 'HEAD'], { cwd: config.app.rootDir });
|
||||
const firstLine = output === null || output === void 0 ? void 0 : output.split('\n')[0];
|
||||
if (!firstLine) {
|
||||
debug('Could not obtain unique app identifier');
|
||||
return null;
|
||||
}
|
||||
// use sha1 to create a one-way hash to anonymize
|
||||
const id = createHash('sha1').update(firstLine).digest('hex');
|
||||
return id;
|
||||
}
|
||||
/**
|
||||
* Walk through the command's parent tree and construct a space-separated name.
|
||||
*
|
||||
* Probably overkill because we don't have nested commands, but whatever.
|
||||
*/
|
||||
function getFullCommandName(cmd) {
|
||||
const names = [];
|
||||
while (cmd.parent !== null) {
|
||||
names.push(cmd.name());
|
||||
cmd = cmd.parent;
|
||||
}
|
||||
return names.reverse().join(' ');
|
||||
}
|
||||
25
@capacitor/cli/dist/util/cli.js
vendored
Normal file
25
@capacitor/cli/dist/util/cli.js
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.wrapAction = exports.ENV_PATHS = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const env_paths_1 = tslib_1.__importDefault(require("env-paths"));
|
||||
const errors_1 = require("../errors");
|
||||
const log_1 = require("../log");
|
||||
exports.ENV_PATHS = (0, env_paths_1.default)('capacitor', { suffix: '' });
|
||||
function wrapAction(action) {
|
||||
return async (...args) => {
|
||||
try {
|
||||
await action(...args);
|
||||
}
|
||||
catch (e) {
|
||||
if ((0, errors_1.isFatal)(e)) {
|
||||
process.exitCode = e.exitCode;
|
||||
log_1.logger.error(e.message);
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
exports.wrapAction = wrapAction;
|
||||
13
@capacitor/cli/dist/util/emoji.js
vendored
Normal file
13
@capacitor/cli/dist/util/emoji.js
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.emoji = void 0;
|
||||
// Emoji falback, right now just uses fallback on windows,
|
||||
// but could expand to be more sophisticated to allow emoji
|
||||
// on Hyper term on windows, for example.
|
||||
const emoji = (x, fallback) => {
|
||||
if (process.platform === 'win32') {
|
||||
return fallback;
|
||||
}
|
||||
return x;
|
||||
};
|
||||
exports.emoji = emoji;
|
||||
13
@capacitor/cli/dist/util/fn.js
vendored
Normal file
13
@capacitor/cli/dist/util/fn.js
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.tryFn = void 0;
|
||||
const tryFn = async (fn, ...args) => {
|
||||
try {
|
||||
return await fn(...args);
|
||||
}
|
||||
catch {
|
||||
// ignore
|
||||
}
|
||||
return null;
|
||||
};
|
||||
exports.tryFn = tryFn;
|
||||
24
@capacitor/cli/dist/util/fs.js
vendored
Normal file
24
@capacitor/cli/dist/util/fs.js
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.deleteFolderRecursive = exports.convertToUnixPath = void 0;
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const convertToUnixPath = (path) => {
|
||||
return path.replace(/\\/g, '/');
|
||||
};
|
||||
exports.convertToUnixPath = convertToUnixPath;
|
||||
const deleteFolderRecursive = (directoryPath) => {
|
||||
if ((0, utils_fs_1.existsSync)(directoryPath)) {
|
||||
(0, utils_fs_1.readdirSync)(directoryPath).forEach(file => {
|
||||
const curPath = (0, path_1.join)(directoryPath, file);
|
||||
if ((0, utils_fs_1.lstatSync)(curPath).isDirectory()) {
|
||||
(0, exports.deleteFolderRecursive)(curPath);
|
||||
}
|
||||
else {
|
||||
(0, utils_fs_1.unlinkSync)(curPath);
|
||||
}
|
||||
});
|
||||
(0, utils_fs_1.rmdirSync)(directoryPath);
|
||||
}
|
||||
};
|
||||
exports.deleteFolderRecursive = deleteFolderRecursive;
|
||||
66
@capacitor/cli/dist/util/iosplugin.js
vendored
Normal file
66
@capacitor/cli/dist/util/iosplugin.js
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.generateIOSPackageJSON = exports.writePluginJSON = exports.findPluginClasses = exports.getPluginFiles = void 0;
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const cordova_1 = require("../cordova");
|
||||
const plugin_1 = require("../plugin");
|
||||
async function getPluginFiles(plugins) {
|
||||
var _a;
|
||||
let filenameList = [];
|
||||
const options = {
|
||||
filter: item => {
|
||||
if (item.stats.isFile() &&
|
||||
(item.path.endsWith('.swift') || item.path.endsWith('.m'))) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
};
|
||||
for (const plugin of plugins) {
|
||||
if (plugin.ios && (0, plugin_1.getPluginType)(plugin, 'ios') === 0 /* PluginType.Core */) {
|
||||
const pluginPath = (0, path_1.resolve)(plugin.rootPath, (_a = plugin.ios) === null || _a === void 0 ? void 0 : _a.path);
|
||||
const filenames = await (0, utils_fs_1.readdirp)(pluginPath, options);
|
||||
filenameList = filenameList.concat(filenames);
|
||||
}
|
||||
}
|
||||
return filenameList;
|
||||
}
|
||||
exports.getPluginFiles = getPluginFiles;
|
||||
async function findPluginClasses(files) {
|
||||
const classList = [];
|
||||
for (const file of files) {
|
||||
const fileData = (0, utils_fs_1.readFileSync)(file, 'utf-8');
|
||||
const swiftPluginRegex = RegExp(/@objc\(([A-Za-z0-9_-]+)\)/);
|
||||
const objcPluginRegex = RegExp(/CAP_PLUGIN\(([A-Za-z0-9_-]+)/);
|
||||
const swiftMatches = swiftPluginRegex.exec(fileData);
|
||||
if ((swiftMatches === null || swiftMatches === void 0 ? void 0 : swiftMatches[1]) && !classList.includes(swiftMatches[1])) {
|
||||
classList.push(swiftMatches[1]);
|
||||
}
|
||||
const objcMatches = objcPluginRegex.exec(fileData);
|
||||
if ((objcMatches === null || objcMatches === void 0 ? void 0 : objcMatches[1]) && !classList.includes(objcMatches[1])) {
|
||||
classList.push(objcMatches[1]);
|
||||
}
|
||||
}
|
||||
return classList;
|
||||
}
|
||||
exports.findPluginClasses = findPluginClasses;
|
||||
async function writePluginJSON(config, classList) {
|
||||
const capJSONFile = (0, path_1.resolve)(config.ios.nativeTargetDirAbs, 'capacitor.config.json');
|
||||
const capJSON = (0, utils_fs_1.readJSONSync)(capJSONFile);
|
||||
capJSON['packageClassList'] = classList;
|
||||
(0, utils_fs_1.writeJSONSync)(capJSONFile, capJSON, { spaces: '\t' });
|
||||
}
|
||||
exports.writePluginJSON = writePluginJSON;
|
||||
async function generateIOSPackageJSON(config, plugins) {
|
||||
const fileList = await getPluginFiles(plugins);
|
||||
const classList = await findPluginClasses(fileList);
|
||||
const cordovaPlugins = await (0, cordova_1.getCordovaPlugins)(config, 'ios');
|
||||
if (cordovaPlugins.length > 0) {
|
||||
classList.push('CDVPlugin');
|
||||
}
|
||||
writePluginJSON(config, classList);
|
||||
}
|
||||
exports.generateIOSPackageJSON = generateIOSPackageJSON;
|
||||
21
@capacitor/cli/dist/util/js.js
vendored
Normal file
21
@capacitor/cli/dist/util/js.js
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.formatJSObject = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const util_1 = tslib_1.__importDefault(require("util"));
|
||||
function formatJSObject(o) {
|
||||
try {
|
||||
o = JSON.parse(JSON.stringify(o));
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Cannot parse object as JSON: ${e.stack ? e.stack : e}`);
|
||||
}
|
||||
return util_1.default.inspect(o, {
|
||||
compact: false,
|
||||
breakLength: Infinity,
|
||||
depth: Infinity,
|
||||
maxArrayLength: Infinity,
|
||||
maxStringLength: Infinity,
|
||||
});
|
||||
}
|
||||
exports.formatJSObject = formatJSObject;
|
||||
151
@capacitor/cli/dist/util/livereload.js
vendored
Normal file
151
@capacitor/cli/dist/util/livereload.js
vendored
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CapLiveReloadHelper = void 0;
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const os_1 = require("os");
|
||||
const path_1 = require("path");
|
||||
class CapLiveReload {
|
||||
constructor() {
|
||||
this.configJsonToRevertTo = {
|
||||
json: null,
|
||||
platformPath: null,
|
||||
};
|
||||
// nothing to do
|
||||
}
|
||||
getIpAddress(name, family) {
|
||||
var _a;
|
||||
const interfaces = (_a = (0, os_1.networkInterfaces)()) !== null && _a !== void 0 ? _a : {};
|
||||
const _normalizeFamily = (family) => {
|
||||
if (family === 4) {
|
||||
return 'ipv4';
|
||||
}
|
||||
if (family === 6) {
|
||||
return 'ipv6';
|
||||
}
|
||||
return family ? family.toLowerCase() : 'ipv4';
|
||||
};
|
||||
const isLoopback = (addr) => {
|
||||
return (/^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/.test(addr) ||
|
||||
/^fe80::1$/.test(addr) ||
|
||||
/^::1$/.test(addr) ||
|
||||
/^::$/.test(addr));
|
||||
};
|
||||
const isPrivate = (addr) => {
|
||||
return (/^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
|
||||
/^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
|
||||
/^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
|
||||
/^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
|
||||
/^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(addr) ||
|
||||
/^f[cd][0-9a-f]{2}:/i.test(addr) ||
|
||||
/^fe80:/i.test(addr) ||
|
||||
/^::1$/.test(addr) ||
|
||||
/^::$/.test(addr));
|
||||
};
|
||||
const isPublic = (addr) => {
|
||||
return !isPrivate(addr);
|
||||
};
|
||||
const loopback = (family) => {
|
||||
//
|
||||
// Default to `ipv4`
|
||||
//
|
||||
family = _normalizeFamily(family);
|
||||
if (family !== 'ipv4' && family !== 'ipv6') {
|
||||
throw new Error('family must be ipv4 or ipv6');
|
||||
}
|
||||
return family === 'ipv4' ? '127.0.0.1' : 'fe80::1';
|
||||
};
|
||||
//
|
||||
// Default to `ipv4`
|
||||
//
|
||||
family = _normalizeFamily(family);
|
||||
//
|
||||
// If a specific network interface has been named,
|
||||
// return the address.
|
||||
//
|
||||
if (name && name !== 'private' && name !== 'public') {
|
||||
const res = interfaces[name].filter((details) => {
|
||||
const itemFamily = _normalizeFamily(details.family);
|
||||
return itemFamily === family;
|
||||
});
|
||||
if (res.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return res[0].address;
|
||||
}
|
||||
const all = Object.keys(interfaces)
|
||||
.map(nic => {
|
||||
//
|
||||
// Note: name will only be `public` or `private`
|
||||
// when this is called.
|
||||
//
|
||||
const addresses = interfaces[nic].filter((details) => {
|
||||
details.family = _normalizeFamily(details.family);
|
||||
if (details.family !== family || isLoopback(details.address)) {
|
||||
return false;
|
||||
}
|
||||
if (!name) {
|
||||
return true;
|
||||
}
|
||||
return name === 'public'
|
||||
? isPrivate(details.address)
|
||||
: isPublic(details.address);
|
||||
});
|
||||
return addresses.length ? addresses[0].address : undefined;
|
||||
})
|
||||
.filter(Boolean);
|
||||
return !all.length ? loopback(family) : all[0];
|
||||
}
|
||||
// TODO remove on next major as it's unused
|
||||
async editExtConfigForLiveReload(config, platformName, options, rootConfigChange = false) {
|
||||
const platformAbsPath = platformName == config.ios.name
|
||||
? config.ios.nativeTargetDirAbs
|
||||
: platformName == config.android.name
|
||||
? config.android.assetsDirAbs
|
||||
: null;
|
||||
if (platformAbsPath == null)
|
||||
throw new Error('Platform not found.');
|
||||
const capConfigPath = rootConfigChange
|
||||
? config.app.extConfigFilePath
|
||||
: (0, path_1.join)(platformAbsPath, 'capacitor.config.json');
|
||||
const configJson = { ...config.app.extConfig };
|
||||
this.configJsonToRevertTo.json = JSON.stringify(configJson, null, 2);
|
||||
this.configJsonToRevertTo.platformPath = capConfigPath;
|
||||
const url = `http://${options.host}:${options.port}`;
|
||||
configJson.server = {
|
||||
url,
|
||||
};
|
||||
return configJson;
|
||||
}
|
||||
// TODO remove rootConfigChange param on next major as it's unused
|
||||
async editCapConfigForLiveReload(config, platformName, options, rootConfigChange = false) {
|
||||
const platformAbsPath = platformName == config.ios.name
|
||||
? config.ios.nativeTargetDirAbs
|
||||
: platformName == config.android.name
|
||||
? config.android.assetsDirAbs
|
||||
: null;
|
||||
if (platformAbsPath == null)
|
||||
throw new Error('Platform not found.');
|
||||
const capConfigPath = rootConfigChange
|
||||
? config.app.extConfigFilePath
|
||||
: (0, path_1.join)(platformAbsPath, 'capacitor.config.json');
|
||||
const configJson = (0, utils_fs_1.readJSONSync)(capConfigPath);
|
||||
this.configJsonToRevertTo.json = JSON.stringify(configJson, null, 2);
|
||||
this.configJsonToRevertTo.platformPath = capConfigPath;
|
||||
const url = `http://${options.host}:${options.port}`;
|
||||
configJson.server = {
|
||||
url,
|
||||
};
|
||||
(0, utils_fs_1.writeJSONSync)(capConfigPath, configJson, { spaces: '\t' });
|
||||
}
|
||||
async revertCapConfigForLiveReload() {
|
||||
if (this.configJsonToRevertTo.json == null ||
|
||||
this.configJsonToRevertTo.platformPath == null)
|
||||
return;
|
||||
const capConfigPath = this.configJsonToRevertTo.platformPath;
|
||||
const configJson = this.configJsonToRevertTo.json;
|
||||
(0, utils_fs_1.writeJSONSync)(capConfigPath, JSON.parse(configJson), { spaces: '\t' });
|
||||
this.configJsonToRevertTo.json = null;
|
||||
this.configJsonToRevertTo.platformPath = null;
|
||||
}
|
||||
}
|
||||
exports.CapLiveReloadHelper = new CapLiveReload();
|
||||
110
@capacitor/cli/dist/util/monorepotools.js
vendored
Normal file
110
@capacitor/cli/dist/util/monorepotools.js
vendored
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isNXMonorepo = exports.isMonorepo = exports.findPackageRelativePathInMonorepo = exports.findPackagePath = exports.findNXMonorepoRoot = exports.findMonorepoRoot = void 0;
|
||||
const node_fs_1 = require("node:fs");
|
||||
const node_path_1 = require("node:path");
|
||||
/**
|
||||
* Finds the monorepo root from the given path.
|
||||
* @param currentPath - The current path to start searching from.
|
||||
* @returns The path to the monorepo root.
|
||||
* @throws An error if the monorepo root is not found.
|
||||
*/
|
||||
function findMonorepoRoot(currentPath) {
|
||||
const packageJsonPath = (0, node_path_1.join)(currentPath, 'package.json');
|
||||
const pnpmWorkspacePath = (0, node_path_1.join)(currentPath, 'pnpm-workspace.yaml');
|
||||
if ((0, node_fs_1.existsSync)(pnpmWorkspacePath) ||
|
||||
((0, node_fs_1.existsSync)(packageJsonPath) &&
|
||||
JSON.parse((0, node_fs_1.readFileSync)(packageJsonPath, 'utf-8')).workspaces)) {
|
||||
return currentPath;
|
||||
}
|
||||
const parentPath = (0, node_path_1.dirname)(currentPath);
|
||||
if (parentPath === currentPath) {
|
||||
throw new Error('Monorepo root not found');
|
||||
}
|
||||
return findMonorepoRoot(parentPath);
|
||||
}
|
||||
exports.findMonorepoRoot = findMonorepoRoot;
|
||||
/**
|
||||
* Finds the NX monorepo root from the given path.
|
||||
* @param currentPath - The current path to start searching from.
|
||||
* @returns The path to the monorepo root.
|
||||
* @throws An error if the monorepo root is not found.
|
||||
*/
|
||||
function findNXMonorepoRoot(currentPath) {
|
||||
const nxJsonPath = (0, node_path_1.join)(currentPath, 'nx.json');
|
||||
if ((0, node_fs_1.existsSync)(nxJsonPath)) {
|
||||
return currentPath;
|
||||
}
|
||||
const parentPath = (0, node_path_1.dirname)(currentPath);
|
||||
if (parentPath === currentPath) {
|
||||
throw new Error('Monorepo root not found');
|
||||
}
|
||||
return findNXMonorepoRoot(parentPath);
|
||||
}
|
||||
exports.findNXMonorepoRoot = findNXMonorepoRoot;
|
||||
/**
|
||||
* Finds the path to a package within the node_modules folder,
|
||||
* searching up the directory hierarchy until the last possible directory is reached.
|
||||
* @param packageName - The name of the package to find.
|
||||
* @param currentPath - The current path to start searching from.
|
||||
* @param lastPossibleDirectory - The last possible directory to search for the package.
|
||||
* @returns The path to the package, or null if not found.
|
||||
*/
|
||||
function findPackagePath(packageName, currentPath, lastPossibleDirectory) {
|
||||
const nodeModulesPath = (0, node_path_1.join)(currentPath, 'node_modules', packageName);
|
||||
if ((0, node_fs_1.existsSync)(nodeModulesPath)) {
|
||||
return nodeModulesPath;
|
||||
}
|
||||
if (currentPath === lastPossibleDirectory) {
|
||||
return null;
|
||||
}
|
||||
const parentPath = (0, node_path_1.dirname)(currentPath);
|
||||
return findPackagePath(packageName, parentPath, lastPossibleDirectory);
|
||||
}
|
||||
exports.findPackagePath = findPackagePath;
|
||||
/**
|
||||
* Finds the relative path to a package from the current directory,
|
||||
* using the monorepo root as the last possible directory.
|
||||
* @param packageName - The name of the package to find.
|
||||
* @param currentPath - The current path to start searching from.
|
||||
* @returns The relative path to the package, or null if not found.
|
||||
*/
|
||||
function findPackageRelativePathInMonorepo(packageName, currentPath) {
|
||||
const monorepoRoot = findMonorepoRoot(currentPath);
|
||||
const packagePath = findPackagePath(packageName, currentPath, monorepoRoot);
|
||||
if (packagePath) {
|
||||
return (0, node_path_1.relative)(currentPath, packagePath);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.findPackageRelativePathInMonorepo = findPackageRelativePathInMonorepo;
|
||||
/**
|
||||
* Detects if the current directory is part of a monorepo (npm, yarn, pnpm).
|
||||
* @param currentPath - The current path to start searching from.
|
||||
* @returns True if the current directory is part of a monorepo, false otherwise.
|
||||
*/
|
||||
function isMonorepo(currentPath) {
|
||||
try {
|
||||
findMonorepoRoot(currentPath);
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
exports.isMonorepo = isMonorepo;
|
||||
/**
|
||||
* Detects if the current directory is part of a nx integrated monorepo.
|
||||
* @param currentPath - The current path to start searching from.
|
||||
* @returns True if the current directory is part of a monorepo, false otherwise.
|
||||
*/
|
||||
function isNXMonorepo(currentPath) {
|
||||
try {
|
||||
findNXMonorepoRoot(currentPath);
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
exports.isNXMonorepo = isNXMonorepo;
|
||||
53
@capacitor/cli/dist/util/native-run.js
vendored
Normal file
53
@capacitor/cli/dist/util/native-run.js
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getPlatformTargets = exports.runNativeRun = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const errors_1 = require("../errors");
|
||||
const node_1 = require("./node");
|
||||
const subprocess_1 = require("./subprocess");
|
||||
async function runNativeRun(args, options = {}) {
|
||||
const p = (0, node_1.resolveNode)(__dirname, (0, path_1.dirname)('native-run/package'), 'bin/native-run');
|
||||
if (!p) {
|
||||
(0, errors_1.fatal)(`${colors_1.default.input('native-run')} not found.`);
|
||||
}
|
||||
return await (0, subprocess_1.runCommand)(p, args, options);
|
||||
}
|
||||
exports.runNativeRun = runNativeRun;
|
||||
async function getPlatformTargets(platformName) {
|
||||
const errors = [];
|
||||
try {
|
||||
const output = await runNativeRun([platformName, '--list', '--json']);
|
||||
const parsedOutput = JSON.parse(output);
|
||||
if (parsedOutput.devices.length || parsedOutput.virtualDevices.length) {
|
||||
return [
|
||||
...parsedOutput.devices.map((t) => ({ ...t, virtual: false })),
|
||||
...parsedOutput.virtualDevices.map((t) => ({
|
||||
...t,
|
||||
virtual: true,
|
||||
})),
|
||||
];
|
||||
}
|
||||
else {
|
||||
parsedOutput.errors.map((e) => {
|
||||
errors.push(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
const err = JSON.parse(e);
|
||||
errors.push(err);
|
||||
}
|
||||
const plural = errors.length > 1 ? 's' : '';
|
||||
const errMsg = `${colors_1.default.strong('native-run')} failed with error${plural}\n
|
||||
${errors
|
||||
.map((e) => {
|
||||
return `\t${colors_1.default.strong(e.code)}: ${e.error}`;
|
||||
})
|
||||
.join('\n')}
|
||||
\n\tMore details for this error${plural} may be available online: ${colors_1.default.strong('https://github.com/ionic-team/native-run/wiki/Android-Errors')}
|
||||
`;
|
||||
throw errMsg;
|
||||
}
|
||||
exports.getPlatformTargets = getPlatformTargets;
|
||||
54
@capacitor/cli/dist/util/node.js
vendored
Normal file
54
@capacitor/cli/dist/util/node.js
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.resolveNode = exports.requireTS = void 0;
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const fs_1 = require("fs");
|
||||
const path_1 = require("path");
|
||||
/**
|
||||
* @see https://github.com/ionic-team/stencil/blob/HEAD/src/compiler/sys/node-require.ts
|
||||
*/
|
||||
const requireTS = (ts, p) => {
|
||||
const id = (0, path_1.resolve)(p);
|
||||
delete require.cache[id];
|
||||
require.extensions['.ts'] = (module, fileName) => {
|
||||
var _a;
|
||||
let sourceText = (0, utils_fs_1.readFileSync)(fileName, 'utf8');
|
||||
if (fileName.endsWith('.ts')) {
|
||||
const tsResults = ts.transpileModule(sourceText, {
|
||||
fileName,
|
||||
compilerOptions: {
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
moduleResolution: ts.ModuleResolutionKind.NodeJs,
|
||||
esModuleInterop: true,
|
||||
strict: true,
|
||||
target: ts.ScriptTarget.ES2017,
|
||||
},
|
||||
reportDiagnostics: true,
|
||||
});
|
||||
sourceText = tsResults.outputText;
|
||||
}
|
||||
else {
|
||||
// quick hack to turn a modern es module
|
||||
// into and old school commonjs module
|
||||
sourceText = sourceText.replace(/export\s+\w+\s+(\w+)/gm, 'exports.$1');
|
||||
}
|
||||
(_a = module._compile) === null || _a === void 0 ? void 0 : _a.call(module, sourceText, fileName);
|
||||
};
|
||||
const m = require(id); // eslint-disable-line @typescript-eslint/no-var-requires
|
||||
delete require.extensions['.ts'];
|
||||
return m;
|
||||
};
|
||||
exports.requireTS = requireTS;
|
||||
function resolveNode(root, ...pathSegments) {
|
||||
try {
|
||||
return require.resolve(pathSegments.join('/'), { paths: [root] });
|
||||
}
|
||||
catch (e) {
|
||||
const path = [root, 'node_modules', ...pathSegments].join('/');
|
||||
if ((0, fs_1.existsSync)(path)) {
|
||||
return path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
exports.resolveNode = resolveNode;
|
||||
35
@capacitor/cli/dist/util/promise.js
vendored
Normal file
35
@capacitor/cli/dist/util/promise.js
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.lazy = exports.LazyPromise = exports.allSerial = void 0;
|
||||
function allSerial(funcs) {
|
||||
return funcs.reduce((promise, func) => promise.then(result => func().then(x => result.concat(x))), Promise.resolve([]));
|
||||
}
|
||||
exports.allSerial = allSerial;
|
||||
class LazyPromise extends Promise {
|
||||
constructor(executor) {
|
||||
super(() => {
|
||||
/* ignore */
|
||||
});
|
||||
this._executor = executor;
|
||||
}
|
||||
then(onfulfilled, onrejected) {
|
||||
this._promise = this._promise || new Promise(this._executor);
|
||||
return this._promise.then(onfulfilled, onrejected);
|
||||
}
|
||||
catch(onrejected) {
|
||||
this._promise = this._promise || new Promise(this._executor);
|
||||
return this._promise.catch(onrejected);
|
||||
}
|
||||
}
|
||||
exports.LazyPromise = LazyPromise;
|
||||
function lazy(fn) {
|
||||
return new LazyPromise(async (resolve, reject) => {
|
||||
try {
|
||||
resolve(await fn());
|
||||
}
|
||||
catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.lazy = lazy;
|
||||
73
@capacitor/cli/dist/util/spm.js
vendored
Normal file
73
@capacitor/cli/dist/util/spm.js
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.generatePackageFile = exports.findPackageSwiftFile = exports.checkPackageManager = void 0;
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const log_1 = require("../log");
|
||||
async function checkPackageManager(config) {
|
||||
const iosDirectory = config.ios.nativeProjectDirAbs;
|
||||
if ((0, utils_fs_1.existsSync)((0, path_1.resolve)(iosDirectory, 'CapApp-SPM'))) {
|
||||
return 'SPM';
|
||||
}
|
||||
return 'Cocoapods';
|
||||
}
|
||||
exports.checkPackageManager = checkPackageManager;
|
||||
async function findPackageSwiftFile(config) {
|
||||
const packageDirectory = (0, path_1.resolve)(config.ios.nativeProjectDirAbs, 'CapApp-SPM');
|
||||
return (0, path_1.resolve)(packageDirectory, 'Package.swift');
|
||||
}
|
||||
exports.findPackageSwiftFile = findPackageSwiftFile;
|
||||
async function generatePackageFile(config, plugins) {
|
||||
const packageSwiftFile = await findPackageSwiftFile(config);
|
||||
try {
|
||||
log_1.logger.warn('SPM Support is still experimental');
|
||||
const textToWrite = generatePackageText(config, plugins);
|
||||
(0, utils_fs_1.writeFileSync)(packageSwiftFile, textToWrite);
|
||||
}
|
||||
catch (err) {
|
||||
log_1.logger.error(`Unable to write to ${packageSwiftFile}. Verify it is not already open. \n Error: ${err}`);
|
||||
}
|
||||
}
|
||||
exports.generatePackageFile = generatePackageFile;
|
||||
function generatePackageText(config, plugins) {
|
||||
var _a, _b, _c;
|
||||
const pbx = (0, utils_fs_1.readFileSync)((0, path_1.join)(config.ios.nativeXcodeProjDirAbs, 'project.pbxproj'), 'utf-8');
|
||||
const searchString = 'IPHONEOS_DEPLOYMENT_TARGET = ';
|
||||
const iosVersion = pbx.substring(pbx.indexOf(searchString) + searchString.length, pbx.indexOf(searchString) + searchString.length + 2);
|
||||
let packageSwiftText = `// swift-tools-version: 5.9
|
||||
import PackageDescription
|
||||
|
||||
// DO NOT MODIFY THIS FILE - managed by Capacitor CLI commands
|
||||
let package = Package(
|
||||
name: "CapApp-SPM",
|
||||
platforms: [.iOS(.v${iosVersion})],
|
||||
products: [
|
||||
.library(
|
||||
name: "CapApp-SPM",
|
||||
targets: ["CapApp-SPM"])
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", branch: "main")`;
|
||||
for (const plugin of plugins) {
|
||||
const relPath = (0, path_1.relative)(config.ios.nativeXcodeProjDirAbs, plugin.rootPath);
|
||||
packageSwiftText += `,\n .package(name: "${(_a = plugin.ios) === null || _a === void 0 ? void 0 : _a.name}", path: "${relPath}")`;
|
||||
}
|
||||
packageSwiftText += `
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
name: "CapApp-SPM",
|
||||
dependencies: [
|
||||
.product(name: "Capacitor", package: "capacitor-swift-pm"),
|
||||
.product(name: "Cordova", package: "capacitor-swift-pm")`;
|
||||
for (const plugin of plugins) {
|
||||
packageSwiftText += `,\n .product(name: "${(_b = plugin.ios) === null || _b === void 0 ? void 0 : _b.name}", package: "${(_c = plugin.ios) === null || _c === void 0 ? void 0 : _c.name}")`;
|
||||
}
|
||||
packageSwiftText += `
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
`;
|
||||
return packageSwiftText;
|
||||
}
|
||||
43
@capacitor/cli/dist/util/subprocess.js
vendored
Normal file
43
@capacitor/cli/dist/util/subprocess.js
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isInstalled = exports.getCommandOutput = exports.runCommand = void 0;
|
||||
const utils_subprocess_1 = require("@ionic/utils-subprocess");
|
||||
async function runCommand(command, args, options = {}) {
|
||||
const p = new utils_subprocess_1.Subprocess(command, args, options);
|
||||
try {
|
||||
return await p.output();
|
||||
}
|
||||
catch (e) {
|
||||
if (e instanceof utils_subprocess_1.SubprocessError) {
|
||||
// old behavior of just throwing the stdout/stderr strings
|
||||
throw e.output
|
||||
? e.output
|
||||
: e.code
|
||||
? e.code
|
||||
: e.error
|
||||
? e.error.message
|
||||
: 'Unknown error';
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
exports.runCommand = runCommand;
|
||||
async function getCommandOutput(command, args, options = {}) {
|
||||
try {
|
||||
return (await runCommand(command, args, options)).trim();
|
||||
}
|
||||
catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
exports.getCommandOutput = getCommandOutput;
|
||||
async function isInstalled(command) {
|
||||
try {
|
||||
await (0, utils_subprocess_1.which)(command);
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
exports.isInstalled = isInstalled;
|
||||
11
@capacitor/cli/dist/util/template.js
vendored
Normal file
11
@capacitor/cli/dist/util/template.js
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.extractTemplate = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const tar_1 = tslib_1.__importDefault(require("tar"));
|
||||
async function extractTemplate(src, dir) {
|
||||
await (0, utils_fs_1.mkdirp)(dir);
|
||||
await tar_1.default.extract({ file: src, cwd: dir });
|
||||
}
|
||||
exports.extractTemplate = extractTemplate;
|
||||
30
@capacitor/cli/dist/util/term.js
vendored
Normal file
30
@capacitor/cli/dist/util/term.js
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isInteractive = exports.checkInteractive = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_terminal_1 = require("@ionic/utils-terminal");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const log_1 = require("../log");
|
||||
// Given input variables to a command, make sure all are provided if the terminal
|
||||
// is not interactive (because we won't be able to prompt the user)
|
||||
const checkInteractive = (...args) => {
|
||||
if ((0, exports.isInteractive)()) {
|
||||
return true;
|
||||
}
|
||||
// Fail if no args are provided, treat this as just a check of whether the term is
|
||||
// interactive or not.
|
||||
if (!args.length) {
|
||||
return false;
|
||||
}
|
||||
// Make sure none of the provided args are empty, otherwise print the interactive
|
||||
// warning and return false
|
||||
if (args.filter(arg => !arg).length) {
|
||||
log_1.logger.error(`Non-interactive shell detected.\n` +
|
||||
`Run the command with ${colors_1.default.input('--help')} to see a list of arguments that must be provided.`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
exports.checkInteractive = checkInteractive;
|
||||
const isInteractive = () => utils_terminal_1.TERMINAL_INFO.tty && !utils_terminal_1.TERMINAL_INFO.ci;
|
||||
exports.isInteractive = isInteractive;
|
||||
11
@capacitor/cli/dist/util/uuid.js
vendored
Normal file
11
@capacitor/cli/dist/util/uuid.js
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.uuidv4 = void 0;
|
||||
function uuidv4() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
||||
const r = (Math.random() * 16) | 0;
|
||||
const v = c == 'x' ? r : (r & 0x3) | 0x8;
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
exports.uuidv4 = uuidv4;
|
||||
57
@capacitor/cli/dist/util/xml.js
vendored
Normal file
57
@capacitor/cli/dist/util/xml.js
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.buildXmlElement = exports.writeXML = exports.parseXML = exports.readXML = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const xml2js_1 = tslib_1.__importDefault(require("xml2js"));
|
||||
async function readXML(path) {
|
||||
var _a;
|
||||
try {
|
||||
const xmlStr = await (0, utils_fs_1.readFile)(path, { encoding: 'utf-8' });
|
||||
try {
|
||||
return await xml2js_1.default.parseStringPromise(xmlStr);
|
||||
}
|
||||
catch (e) {
|
||||
throw `Error parsing: ${path}, ${(_a = e.stack) !== null && _a !== void 0 ? _a : e}`;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw `Unable to read: ${path}`;
|
||||
}
|
||||
}
|
||||
exports.readXML = readXML;
|
||||
function parseXML(xmlStr, options) {
|
||||
const parser = options !== undefined
|
||||
? new xml2js_1.default.Parser({ ...options })
|
||||
: new xml2js_1.default.Parser();
|
||||
let xmlObj;
|
||||
parser.parseString(xmlStr, (err, result) => {
|
||||
if (!err) {
|
||||
xmlObj = result;
|
||||
}
|
||||
});
|
||||
return xmlObj;
|
||||
}
|
||||
exports.parseXML = parseXML;
|
||||
async function writeXML(object) {
|
||||
return new Promise(resolve => {
|
||||
const builder = new xml2js_1.default.Builder({
|
||||
headless: true,
|
||||
explicitRoot: false,
|
||||
rootName: 'deleteme',
|
||||
});
|
||||
let xml = builder.buildObject(object);
|
||||
xml = xml.replace('<deleteme>', '').replace('</deleteme>', '');
|
||||
resolve(xml);
|
||||
});
|
||||
}
|
||||
exports.writeXML = writeXML;
|
||||
function buildXmlElement(configElement, rootName) {
|
||||
const builder = new xml2js_1.default.Builder({
|
||||
headless: true,
|
||||
explicitRoot: false,
|
||||
rootName: rootName,
|
||||
});
|
||||
return builder.buildObject(configElement);
|
||||
}
|
||||
exports.buildXmlElement = buildXmlElement;
|
||||
22
@capacitor/cli/dist/web/copy.js
vendored
Normal file
22
@capacitor/cli/dist/web/copy.js
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.copyWeb = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const utils_fs_1 = require("@ionic/utils-fs");
|
||||
const path_1 = require("path");
|
||||
const colors_1 = tslib_1.__importDefault(require("../colors"));
|
||||
const common_1 = require("../common");
|
||||
const errors_1 = require("../errors");
|
||||
const node_1 = require("../util/node");
|
||||
async function copyWeb(config) {
|
||||
if (config.app.bundledWebRuntime) {
|
||||
const runtimePath = (0, node_1.resolveNode)(config.app.rootDir, '@capacitor/core', 'dist', 'capacitor.js');
|
||||
if (!runtimePath) {
|
||||
(0, errors_1.fatal)(`Unable to find ${colors_1.default.strong('node_modules/@capacitor/core/dist/capacitor.js')}.\n` + `Are you sure ${colors_1.default.strong('@capacitor/core')} is installed?`);
|
||||
}
|
||||
return (0, common_1.runTask)(`Copying ${colors_1.default.strong('capacitor.js')} to web dir`, () => {
|
||||
return (0, utils_fs_1.copy)(runtimePath, (0, path_1.join)(config.app.webDirAbs, 'capacitor.js'));
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.copyWeb = copyWeb;
|
||||
Loading…
Add table
Add a link
Reference in a new issue