@capacitor/cli 5.0.0-alpha.1 → 5.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
Binary file
@@ -8,10 +8,13 @@ const common_1 = require("../common");
8
8
  const log_1 = require("../log");
9
9
  const subprocess_1 = require("../util/subprocess");
10
10
  async function buildAndroid(config, buildOptions) {
11
- var _a;
11
+ var _a, _b;
12
12
  const releaseType = (_a = buildOptions.androidreleasetype) !== null && _a !== void 0 ? _a : 'AAB';
13
13
  const releaseTypeIsAAB = releaseType === 'AAB';
14
- const arg = releaseTypeIsAAB ? ':app:bundleRelease' : 'assembleRelease';
14
+ const flavor = (_b = buildOptions.flavor) !== null && _b !== void 0 ? _b : '';
15
+ const arg = releaseTypeIsAAB
16
+ ? `:app:bundle${flavor}Release`
17
+ : `assemble${flavor}Release`;
15
18
  const gradleArgs = [arg];
16
19
  if (!buildOptions.keystorepath ||
17
20
  !buildOptions.keystorealias ||
@@ -32,7 +35,7 @@ async function buildAndroid(config, buildOptions) {
32
35
  throw e;
33
36
  }
34
37
  }
35
- const releasePath = (0, path_1.join)(config.android.appDirAbs, 'build', 'outputs', releaseTypeIsAAB ? 'bundle' : 'apk', 'release');
38
+ const releasePath = (0, path_1.join)(config.android.appDirAbs, 'build', 'outputs', releaseTypeIsAAB ? 'bundle' : 'apk', buildOptions.flavor ? `${flavor}Release` : 'release');
36
39
  const unsignedReleaseName = `app${config.android.flavor ? `-${config.android.flavor}` : ''}-release${releaseTypeIsAAB ? '' : '-unsigned'}.${releaseType.toLowerCase()}`;
37
40
  const signedReleaseName = unsignedReleaseName.replace(`-release${releaseTypeIsAAB ? '' : '-unsigned'}.${releaseType.toLowerCase()}`, `-release-signed.${releaseType.toLowerCase()}`);
38
41
  const signingArgs = [
package/dist/config.js CHANGED
@@ -17,7 +17,7 @@ exports.CONFIG_FILE_NAME_TS = 'capacitor.config.ts';
17
17
  exports.CONFIG_FILE_NAME_JS = 'capacitor.config.js';
18
18
  exports.CONFIG_FILE_NAME_JSON = 'capacitor.config.json';
19
19
  async function loadConfig() {
20
- var _a, _b, _c, _d, _e;
20
+ var _a, _b, _c, _d;
21
21
  const appRootDir = process.cwd();
22
22
  const cliRootDir = (0, path_1.dirname)(__dirname);
23
23
  const conf = await loadExtConfig(appRootDir);
@@ -41,7 +41,6 @@ async function loadConfig() {
41
41
  version: '1.0.0',
42
42
  },
43
43
  ...conf,
44
- bundledWebRuntime: (_e = conf.extConfig.bundledWebRuntime) !== null && _e !== void 0 ? _e : false,
45
44
  },
46
45
  };
47
46
  debug('config: %O', config);
@@ -338,5 +337,12 @@ function checkExternalConfig(config) {
338
337
  log_1.logger.warn(`The ${colors_1.default.strong('hideLogs')} configuration option has been deprecated. ` +
339
338
  `Please update to use ${colors_1.default.strong('loggingBehavior')} instead.`);
340
339
  }
340
+ if (typeof config.extConfig.bundledWebRuntime !== 'undefined') {
341
+ let actionMessage = `Can be safely deleted.`;
342
+ if (config.extConfig.bundledWebRuntime === true) {
343
+ actionMessage = `Please, use a bundler to bundle Capacitor and its plugins.`;
344
+ }
345
+ log_1.logger.warn(`The ${colors_1.default.strong('bundledWebRuntime')} configuration option has been deprecated. ${actionMessage}`);
346
+ }
341
347
  }
342
348
  exports.checkExternalConfig = checkExternalConfig;
package/dist/cordova.js CHANGED
@@ -696,16 +696,22 @@ async function writeCordovaAndroidManifest(cordovaPlugins, config, platform) {
696
696
  }
697
697
  }
698
698
  else {
699
- let foundRequiredElement = false;
700
- for (const existingElementItem of existingElement.children) {
701
- const foundRequiredElementIn = doesElementMatch(requiredElement, existingElementItem);
702
- if (foundRequiredElementIn) {
703
- foundRequiredElement = true;
704
- break;
705
- }
699
+ if (requiredElement.children === undefined &&
700
+ existingElement.children === undefined) {
701
+ return true;
706
702
  }
707
- if (!foundRequiredElement) {
708
- return false;
703
+ else {
704
+ let foundRequiredElement = false;
705
+ for (const existingElementItem of existingElement.children) {
706
+ const foundRequiredElementIn = doesElementMatch(requiredElement, existingElementItem);
707
+ if (foundRequiredElementIn) {
708
+ foundRequiredElement = true;
709
+ break;
710
+ }
711
+ }
712
+ if (!foundRequiredElement) {
713
+ return false;
714
+ }
709
715
  }
710
716
  }
711
717
  }
@@ -780,8 +786,7 @@ async function writeCordovaAndroidManifest(cordovaPlugins, config, platform) {
780
786
  ? cleartextString
781
787
  : '';
782
788
  let content = `<?xml version='1.0' encoding='utf-8'?>
783
- <manifest package="capacitor.android.plugins"
784
- xmlns:android="http://schemas.android.com/apk/res/android"
789
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
785
790
  xmlns:amazon="http://schemas.amazon.com/apk/res/android">
786
791
  <application ${applicationXMLAttributes.join('\n')} ${cleartext}>
787
792
  ${applicationXMLEntries.join('\n')}
@@ -33,7 +33,10 @@ export interface CapacitorConfig {
33
33
  * will create a `capacitor.js` file that you'll need to add as a script in
34
34
  * your `index.html` file.
35
35
  *
36
+ * It's deprecated and will be removed in Capacitor 6
37
+ *
36
38
  * @since 1.0.0
39
+ * @deprecated 5.0.0
37
40
  * @default false
38
41
  */
39
42
  bundledWebRuntime?: boolean;
@@ -204,6 +207,19 @@ export interface CapacitorConfig {
204
207
  * @default 60
205
208
  */
206
209
  minWebViewVersion?: number;
210
+ /**
211
+ * The minimum supported Huawei webview version on Android supported by your app.
212
+ *
213
+ * The minimum supported cannot be lower than version `10`, which is required for Capacitor.
214
+ *
215
+ * If the device uses a lower WebView version, an error message will be shown on Logcat.
216
+ * If `server.errorPath` is configured, the WebView will redirect to that file, so can be
217
+ * used to show a custom error.
218
+ *
219
+ * @since 4.6.4
220
+ * @default 10
221
+ */
222
+ minHuaweiWebViewVersion?: number;
207
223
  buildOptions?: {
208
224
  /**
209
225
  * Path to your keystore
package/dist/index.js CHANGED
@@ -61,7 +61,7 @@ function runProgram(config) {
61
61
  commander_1.program
62
62
  .command('sync [platform]')
63
63
  .description(`${colors_1.default.input('copy')} + ${colors_1.default.input('update')}`)
64
- .option('--deployment', "Optional: if provided, Podfile.lock won't be deleted and pod install will use --deployment option")
64
+ .option('--deployment', 'Optional: if provided, pod install will use --deployment option')
65
65
  .option('--inline', 'Optional: if true, all source maps will be inlined for easier debugging on mobile devices', false)
66
66
  .action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { deployment, inline }) => {
67
67
  (0, config_1.checkExternalConfig)(config.app);
@@ -71,7 +71,7 @@ function runProgram(config) {
71
71
  commander_1.program
72
72
  .command('update [platform]')
73
73
  .description(`updates the native plugins and dependencies based on ${colors_1.default.strong('package.json')}`)
74
- .option('--deployment', "Optional: if provided, Podfile.lock won't be deleted and pod install will use --deployment option")
74
+ .option('--deployment', 'Optional: if provided, pod install will use --deployment option')
75
75
  .action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { deployment }) => {
76
76
  (0, config_1.checkExternalConfig)(config.app);
77
77
  const { updateCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/update')));
@@ -90,6 +90,7 @@ function runProgram(config) {
90
90
  .command('build <platform>')
91
91
  .description('builds the release version of the selected platform')
92
92
  .option('--scheme <schemeToBuild>', 'iOS Scheme to build')
93
+ .option('--flavor <flavorToBuild>', 'Android Flavor to build')
93
94
  .option('--keystorepath <keystorePath>', 'Path to the keystore')
94
95
  .option('--keystorepass <keystorePass>', 'Password to the keystore')
95
96
  .option('--keystorealias <keystoreAlias>', 'Key Alias in the keystore')
@@ -48,15 +48,11 @@ exports.installCocoaPodsPlugins = installCocoaPodsPlugins;
48
48
  async function updatePodfile(config, plugins, deployment) {
49
49
  const dependenciesContent = await generatePodFile(config, plugins);
50
50
  const podfilePath = (0, path_1.join)(config.ios.nativeProjectDirAbs, 'Podfile');
51
- const podfileLockPath = (0, path_1.join)(config.ios.nativeProjectDirAbs, 'Podfile.lock');
52
51
  let podfileContent = await (0, utils_fs_1.readFile)(podfilePath, { encoding: 'utf-8' });
53
52
  podfileContent = podfileContent.replace(/(def capacitor_pods)[\s\S]+?(\nend)/, `$1${dependenciesContent}$2`);
54
53
  await (0, utils_fs_1.writeFile)(podfilePath, podfileContent, { encoding: 'utf-8' });
55
54
  const podCommandExists = await (0, subprocess_1.isInstalled)('pod');
56
55
  if (podCommandExists) {
57
- if (!deployment) {
58
- await (0, utils_fs_1.remove)(podfileLockPath);
59
- }
60
56
  await (0, subprocess_1.runCommand)(config.ios.podPath, ['install', ...(deployment ? ['--deployment'] : [])], { cwd: config.ios.nativeProjectDirAbs });
61
57
  }
62
58
  else {
@@ -17,6 +17,7 @@ async function buildCommand(config, selectedPlatformName, buildOptions) {
17
17
  }
18
18
  const buildCommandOptions = {
19
19
  scheme: buildOptions.scheme || config.ios.scheme,
20
+ flavor: buildOptions.flavor || config.android.flavor,
20
21
  keystorepath: buildOptions.keystorepath || config.android.buildOptions.keystorePath,
21
22
  keystorepass: buildOptions.keystorepass || config.android.buildOptions.keystorePassword,
22
23
  keystorealias: buildOptions.keystorealias || config.android.buildOptions.keystoreAlias,
@@ -41,7 +41,6 @@ async function initCommand(config, name, id, webDirFromCLI) {
41
41
  appId,
42
42
  appName,
43
43
  webDir,
44
- bundledWebRuntime: false,
45
44
  server: {
46
45
  androidScheme: androidScheme,
47
46
  },
@@ -12,7 +12,6 @@ const log_1 = require("../log");
12
12
  const fs_1 = require("../util/fs");
13
13
  const subprocess_1 = require("../util/subprocess");
14
14
  const template_1 = require("../util/template");
15
- const xml_1 = require("../util/xml");
16
15
  // eslint-disable-next-line prefer-const
17
16
  let allDependencies = {};
18
17
  const libs = [
@@ -41,20 +40,25 @@ const plugins = [
41
40
  '@capacitor/preferences',
42
41
  '@capacitor/push-notifications',
43
42
  '@capacitor/screen-reader',
43
+ '@capacitor/screen-orientation',
44
44
  '@capacitor/share',
45
45
  '@capacitor/splash-screen',
46
46
  '@capacitor/status-bar',
47
47
  '@capacitor/text-zoom',
48
48
  '@capacitor/toast',
49
49
  ];
50
- const coreVersion = '^4.0.0';
51
- const pluginVersion = '^4.0.0';
52
- const gradleVersion = '7.4.2';
50
+ const coreVersion = 'next'; // TODO: Update when Capacitor 5 releases
51
+ const pluginVersion = 'next'; // TODO: Update when Capacitor 5 releases
52
+ const gradleVersion = '7.5';
53
53
  async function migrateCommand(config) {
54
54
  if (config === null) {
55
55
  (0, errors_1.fatal)('Config data missing');
56
56
  }
57
- const variablesAndClasspaths = await getAndroidVarriablesAndClasspaths(config);
57
+ const capMajor = await checkCapacitorMajorVersion(config);
58
+ if (capMajor < 4) {
59
+ (0, errors_1.fatal)('Migrate can only be used on capacitor 4 and above, please use the CLI in Capacitor 4 to upgrade to 4 first');
60
+ }
61
+ const variablesAndClasspaths = await getAndroidVariablesAndClasspaths(config);
58
62
  if (!variablesAndClasspaths) {
59
63
  (0, errors_1.fatal)('Variable and Classpath info could not be read.');
60
64
  }
@@ -65,7 +69,7 @@ async function migrateCommand(config) {
65
69
  };
66
70
  const monorepoWarning = 'Please note this tool is not intended for use in a mono-repo enviroment, please check out the Ionic vscode extension for this functionality.';
67
71
  log_1.logger.info(monorepoWarning);
68
- const { migrateconfirm } = await (0, log_1.logPrompt)(`Capacitor 4 sets a deployment target of iOS 13 and Android 12 (SDK 32). \n`, {
72
+ const { migrateconfirm } = await (0, log_1.logPrompt)(`Capacitor 5 sets a deployment target of iOS 13 and Android 13 (SDK 33). \n`, {
69
73
  type: 'text',
70
74
  name: 'migrateconfirm',
71
75
  message: `Are you sure you want to migrate? (Y/n)`,
@@ -74,83 +78,61 @@ async function migrateCommand(config) {
74
78
  if (typeof migrateconfirm === 'string' &&
75
79
  migrateconfirm.toLowerCase() === 'y') {
76
80
  try {
77
- const { npmInstallConfirm } = await (0, log_1.logPrompt)(`Would you like the migrator to run npm install to install the latest versions of capacitor packages? (Those using other package managers should answer N)`, {
81
+ const { depInstallConfirm } = await (0, log_1.logPrompt)(`Would you like the migrator to run npm, yarn, or pnpm install to install the latest versions of capacitor packages? (Those using other package managers should answer N)`, {
78
82
  type: 'text',
79
- name: 'npmInstallConfirm',
80
- message: `Run Npm Install? (Y/n)`,
83
+ name: 'depInstallConfirm',
84
+ message: `Run Dependency Install? (Y/n)`,
81
85
  initial: 'y',
82
86
  });
83
- const runNpmInstall = typeof npmInstallConfirm === 'string' &&
84
- npmInstallConfirm.toLowerCase() === 'y';
85
- try {
86
- await (0, common_1.runTask)(`Installing Latest NPM Modules.`, () => {
87
- return installLatestNPMLibs(runNpmInstall, config);
87
+ const runNpmInstall = typeof depInstallConfirm === 'string' &&
88
+ depInstallConfirm.toLowerCase() === 'y';
89
+ let installerType = 'npm';
90
+ if (runNpmInstall) {
91
+ const { manager } = await (0, log_1.logPrompt)('What dependency manager do you use?', {
92
+ type: 'select',
93
+ name: 'manager',
94
+ message: `Dependency Management Tool`,
95
+ choices: [
96
+ { title: 'NPM', value: 'npm' },
97
+ { title: 'Yarn', value: 'yarn' },
98
+ { title: 'PNPM', value: 'pnpm' },
99
+ ],
100
+ initial: 0,
88
101
  });
89
- }
90
- catch (ex) {
91
- log_1.logger.error(`npm install failed. Try deleting node_modules folder and running ${colors_1.default.input('npm install --force')} manually.`);
102
+ installerType = manager;
92
103
  }
93
104
  try {
94
- await (0, common_1.runTask)(`Migrating @capacitor/storage to @capacitor/preferences.`, () => {
95
- return migrateStoragePluginToPreferences(runNpmInstall);
105
+ await (0, common_1.runTask)(`Installing Latest Modules using ${installerType}.`, () => {
106
+ return installLatestLibs(installerType, runNpmInstall, config);
96
107
  });
97
108
  }
98
109
  catch (ex) {
99
- log_1.logger.error(`@capacitor/preferences failed to install. Try deleting node_modules folder and running ${colors_1.default.input('npm install @capacitor/preferences --force')} manually.`);
110
+ console.log(ex);
111
+ log_1.logger.error(`${installerType} install failed. Try deleting node_modules folder and running ${colors_1.default.input(`${installerType} install --force`)} manually.`);
100
112
  }
113
+ // Update iOS Projects
101
114
  if (allDependencies['@capacitor/ios'] &&
102
115
  (0, utils_fs_1.existsSync)(config.ios.platformDirAbs)) {
103
- // Set deployment target to 13.0
104
- await (0, common_1.runTask)(`Migrating deployment target to 13.0.`, () => {
105
- return updateFile(config, (0, path_1.join)(config.ios.nativeXcodeProjDirAbs, 'project.pbxproj'), 'IPHONEOS_DEPLOYMENT_TARGET = ', ';', '13.0');
106
- });
107
- // Update Podfile to 13.0
108
- await (0, common_1.runTask)(`Migrating Podfile to 13.0.`, () => {
109
- return updateFile(config, (0, path_1.join)(config.ios.nativeProjectDirAbs, 'Podfile'), `platform :ios, '`, `'`, '13.0');
110
- });
111
- await (0, common_1.runTask)(`Migrating Podfile to use post_install script.`, () => {
112
- return podfileAssertDeploymentTarget((0, path_1.join)(config.ios.nativeProjectDirAbs, 'Podfile'));
116
+ //Update icon to single 1024 x 1024 icon
117
+ await (0, common_1.runTask)('Update App Icon to only 1024 x 1024', () => {
118
+ return updateAppIcons(config);
113
119
  });
114
- // Remove touchesBegan
115
- await (0, common_1.runTask)(`Migrating AppDelegate.swift by removing touchesBegan.`, () => {
116
- return updateFile(config, (0, path_1.join)(config.ios.nativeTargetDirAbs, 'AppDelegate.swift'), `override func touchesBegan`, `}`, undefined, true);
117
- });
118
- // Remove NSAppTransportSecurity
119
- await (0, common_1.runTask)(`Migrating Info.plist by removing NSAppTransportSecurity key.`, () => {
120
- return removeKey((0, path_1.join)(config.ios.nativeTargetDirAbs, 'Info.plist'), 'NSAppTransportSecurity');
121
- });
122
- // Remove USE_PUSH
123
- await (0, common_1.runTask)(`Migrating by removing USE_PUSH.`, () => {
124
- return replacePush((0, path_1.join)(config.ios.nativeXcodeProjDirAbs, 'project.pbxproj'));
125
- });
126
- // Remove from App Delegate
127
- await (0, common_1.runTask)(`Migrating App Delegate.`, () => {
128
- return replaceIfUsePush(config);
120
+ //Remove Podfile.lock from .gitignore
121
+ await (0, common_1.runTask)('Remove Podfile.lock from iOS .gitignore', () => {
122
+ return updateIosGitIgnore((0, path_1.join)(config.ios.platformDirAbs, '.gitignore'));
129
123
  });
130
124
  }
131
125
  if (allDependencies['@capacitor/android'] &&
132
126
  (0, utils_fs_1.existsSync)(config.android.platformDirAbs)) {
133
- // AndroidManifest.xml add attribute: <activity android:exported="true"
134
- await (0, common_1.runTask)(`Migrating AndroidManifest.xml by adding android:exported attribute to Activity.`, () => {
135
- return updateAndroidManifest((0, path_1.join)(config.android.srcMainDirAbs, 'AndroidManifest.xml'));
136
- });
137
- // Update build.gradle
138
- const { leaveJCenterPrompt } = await (0, log_1.logPrompt)(`Some projects still require JCenter to function. If your project does, please answer yes below.`, {
139
- type: 'text',
140
- name: 'leaveJCenterPrompt',
141
- message: `Keep JCenter if present? (y/N)`,
142
- initial: 'n',
143
- });
144
127
  await (0, common_1.runTask)(`Migrating build.gradle file.`, () => {
145
- return updateBuildGradle((0, path_1.join)(config.android.platformDirAbs, 'build.gradle'), typeof leaveJCenterPrompt === 'string' &&
146
- leaveJCenterPrompt.toLowerCase() === 'y', variablesAndClasspaths);
128
+ return updateBuildGradle((0, path_1.join)(config.android.platformDirAbs, 'build.gradle'), variablesAndClasspaths);
147
129
  });
148
- // Update app.gradle
149
- await (0, common_1.runTask)(`Migrating app/build.gradle file.`, () => {
150
- return updateAppBuildGradle((0, path_1.join)(config.android.appDirAbs, 'build.gradle'));
130
+ // Remove enableJetifier
131
+ await (0, common_1.runTask)('Remove android.enableJetifier=true from gradle.properties', () => {
132
+ return updateGradleProperties((0, path_1.join)(config.android.platformDirAbs, 'gradle.properties'));
151
133
  });
152
134
  // Update gradle-wrapper.properties
153
- await (0, common_1.runTask)(`Migrating gradle-wrapper.properties by updating gradle version from 7.0 to ${gradleVersion}.`, () => {
135
+ await (0, common_1.runTask)(`Migrating gradle-wrapper.properties by updating gradle version to ${gradleVersion}.`, () => {
154
136
  return updateGradleWrapper((0, path_1.join)(config.android.platformDirAbs, 'gradle', 'wrapper', 'gradle-wrapper.properties'));
155
137
  });
156
138
  // Variables gradle
@@ -176,26 +158,18 @@ async function migrateCommand(config) {
176
158
  }
177
159
  }
178
160
  const pluginVariables = {
179
- firebaseMessagingVersion: '23.0.5',
180
- playServicesLocationVersion: '20.0.0',
181
- androidxBrowserVersion: '1.4.0',
182
- androidxMaterialVersion: '1.6.1',
183
- androidxExifInterfaceVersion: '1.3.3',
161
+ firebaseMessagingVersion: '23.1.2',
162
+ playServicesLocationVersion: '21.0.1',
163
+ androidxBrowserVersion: '1.5.0',
164
+ androidxMaterialVersion: '1.8.0',
165
+ androidxExifInterfaceVersion: '1.3.6',
184
166
  };
185
167
  for (const variable of Object.keys(pluginVariables)) {
186
168
  await updateFile(config, variablesPath, `${variable} = '`, `'`, pluginVariables[variable], true);
187
169
  }
188
170
  })();
189
171
  });
190
- // remove init
191
- await (0, common_1.runTask)('Migrating MainActivity', () => {
192
- return migrateMainActivity(config);
193
- });
194
172
  rimraf_1.default.sync((0, path_1.join)(config.android.appDirAbs, 'build'));
195
- // add new splashscreen
196
- await (0, common_1.runTask)('Migrate to Android 12 Splashscreen and apply DayNight theme.', () => {
197
- return addNewSplashScreen(config);
198
- });
199
173
  }
200
174
  // Run Cap Sync
201
175
  await (0, common_1.runTask)(`Running cap sync.`, () => {
@@ -230,7 +204,14 @@ async function migrateCommand(config) {
230
204
  //*/
231
205
  }
232
206
  exports.migrateCommand = migrateCommand;
233
- async function installLatestNPMLibs(runInstall, config) {
207
+ async function checkCapacitorMajorVersion(config) {
208
+ var _a;
209
+ const capacitorVersion = await (0, common_1.getCoreVersion)(config);
210
+ const versionArray = (_a = capacitorVersion.match(/([0-9]+)\.([0-9]+)\.([0-9]+)/)) !== null && _a !== void 0 ? _a : [];
211
+ const majorVersion = parseInt(versionArray[1]);
212
+ return majorVersion;
213
+ }
214
+ async function installLatestLibs(dependencyManager, runInstall, config) {
234
215
  const pkgJsonPath = (0, path_1.join)(config.app.rootDir, 'package.json');
235
216
  const pkgJsonFile = readFile(pkgJsonPath);
236
217
  if (!pkgJsonFile) {
@@ -258,31 +239,14 @@ async function installLatestNPMLibs(runInstall, config) {
258
239
  });
259
240
  if (runInstall) {
260
241
  rimraf_1.default.sync((0, path_1.join)(config.app.rootDir, 'node_modules/@capacitor/!(cli)'));
261
- await (0, subprocess_1.runCommand)('npm', ['i']);
242
+ await (0, subprocess_1.runCommand)(dependencyManager, ['install']);
262
243
  }
263
244
  else {
264
245
  log_1.logger.info(`Please run an install command with your package manager of choice. (ex: yarn install)`);
265
246
  }
266
247
  }
267
- async function migrateStoragePluginToPreferences(runInstall) {
268
- if (allDependencies['@capacitor/storage']) {
269
- log_1.logger.info('NOTE: @capacitor/storage was renamed to @capacitor/preferences, please be sure to replace occurances in your code.');
270
- if (runInstall) {
271
- await (0, subprocess_1.getCommandOutput)('npm', ['uninstall', '@capacitor/storage']);
272
- await (0, subprocess_1.runCommand)('npm', ['i', `@capacitor/preferences@${pluginVersion}`]);
273
- }
274
- else {
275
- log_1.logger.info(`Please manually uninstall @capacitor/storage and replace it with @capacitor/preferences@${pluginVersion}`);
276
- }
277
- }
278
- }
279
248
  async function writeBreakingChanges() {
280
- const breaking = [
281
- '@capacitor/storage',
282
- '@capacitor/camera',
283
- '@capacitor/push-notifications',
284
- '@capacitor/local-notifications',
285
- ];
249
+ const breaking = ['@capacitor/device'];
286
250
  const broken = [];
287
251
  for (const lib of breaking) {
288
252
  if (allDependencies[lib]) {
@@ -290,98 +254,10 @@ async function writeBreakingChanges() {
290
254
  }
291
255
  }
292
256
  if (broken.length > 0) {
293
- log_1.logger.info(`IMPORTANT: Review https://capacitorjs.com/docs/updating/4-0#plugins for breaking changes in these plugins that you use: ${broken.join(', ')}.`);
294
- }
295
- if (allDependencies['@capacitor/android']) {
296
- log_1.logger.info('Warning: The Android Gradle plugin was updated and it requires Java 11 to run. You may need to select this in Android Studio.');
257
+ log_1.logger.info(`IMPORTANT: Review https://capacitorjs.com/docs/updating/5-0#plugins for breaking changes in these plugins that you use: ${broken.join(', ')}.`);
297
258
  }
298
259
  }
299
- async function updateAndroidManifest(filename) {
300
- const txt = readFile(filename);
301
- if (!txt) {
302
- return;
303
- }
304
- const hasAndroidExportedAlreadySet = new RegExp(/<activity([^>]*(android:exported=")[^>]*)>/g).test(txt);
305
- let isAndroidExportedSetToFalse = false;
306
- if (hasAndroidExportedAlreadySet) {
307
- isAndroidExportedSetToFalse = new RegExp(/<activity([^>]*(android:exported="false")[^>]*)>/g).test(txt);
308
- }
309
- // AndroidManifest.xml add attribute: <activity android:exported="true"
310
- if (hasAndroidExportedAlreadySet && !isAndroidExportedSetToFalse) {
311
- return; // Probably already updated manually
312
- }
313
- let replaced = txt;
314
- if (!hasAndroidExportedAlreadySet) {
315
- replaced = setAllStringIn(txt, '<activity', ' ', `\n android:exported="true"\n`);
316
- }
317
- else {
318
- log_1.logger.info(`Found 'android:exported="false"' in your AndroidManifest.xml, if this is not intentional please update it manually to "true".`);
319
- }
320
- if (txt == replaced) {
321
- log_1.logger.error(`Unable to update Android Manifest. Missing <activity> tag`);
322
- return;
323
- }
324
- (0, utils_fs_1.writeFileSync)(filename, replaced, 'utf-8');
325
- }
326
- async function updateBuildGradle(filename, leaveJCenter, variablesAndClasspaths) {
327
- // In build.gradle add dependencies:
328
- // classpath 'com.android.tools.build:gradle:7.2.1'
329
- // classpath 'com.google.gms:google-services:4.3.13'
330
- const txt = readFile(filename);
331
- if (!txt) {
332
- return;
333
- }
334
- const neededDeps = {
335
- 'com.android.tools.build:gradle': variablesAndClasspaths['com.android.tools.build:gradle'],
336
- 'com.google.gms:google-services': variablesAndClasspaths['com.google.gms:google-services'],
337
- };
338
- let replaced = txt;
339
- for (const dep of Object.keys(neededDeps)) {
340
- if (replaced.includes(`classpath '${dep}`)) {
341
- const semver = await Promise.resolve().then(() => tslib_1.__importStar(require('semver')));
342
- const firstIndex = replaced.indexOf(dep) + dep.length + 1;
343
- const existingVersion = '' + replaced.substring(firstIndex, replaced.indexOf("'", firstIndex));
344
- if (semver.gte(neededDeps[dep], existingVersion)) {
345
- replaced = setAllStringIn(replaced, `classpath '${dep}:`, `'`, neededDeps[dep]);
346
- log_1.logger.info(`Set ${dep} = ${neededDeps[dep]}.`);
347
- }
348
- }
349
- }
350
- // Replace jcenter()
351
- const lines = replaced.split('\n');
352
- let inRepositories = false;
353
- let hasMavenCentral = false;
354
- let final = '';
355
- for (const line of lines) {
356
- if (line.includes('repositories {')) {
357
- inRepositories = true;
358
- hasMavenCentral = false;
359
- }
360
- else if (line.trim() == '}') {
361
- // Make sure we have mavenCentral()
362
- if (inRepositories && !hasMavenCentral) {
363
- final += ' mavenCentral()\n';
364
- log_1.logger.info(`Added mavenCentral().`);
365
- }
366
- inRepositories = false;
367
- }
368
- if (inRepositories && line.trim() === 'mavenCentral()') {
369
- hasMavenCentral = true;
370
- }
371
- if (inRepositories && line.trim() === 'jcenter()' && !leaveJCenter) {
372
- // skip jCentral()
373
- log_1.logger.info(`Removed jcenter().`);
374
- }
375
- else {
376
- final += line + '\n';
377
- }
378
- }
379
- if (txt !== final) {
380
- (0, utils_fs_1.writeFileSync)(filename, final, 'utf-8');
381
- return;
382
- }
383
- }
384
- async function getAndroidVarriablesAndClasspaths(config) {
260
+ async function getAndroidVariablesAndClasspaths(config) {
385
261
  const tempAndroidTemplateFolder = (0, path_1.join)(config.cli.assetsDirAbs, 'tempAndroidTemplate');
386
262
  await (0, template_1.extractTemplate)(config.cli.assets.android.platformTemplateArchiveAbs, tempAndroidTemplateFolder);
387
263
  const variablesGradleFile = readFile((0, path_1.join)(tempAndroidTemplateFolder, 'variables.gradle'));
@@ -425,23 +301,6 @@ function readFile(filename) {
425
301
  log_1.logger.error(`Unable to read ${filename}. Verify it is not already open. ${err}`);
426
302
  }
427
303
  }
428
- async function updateAppBuildGradle(filename) {
429
- const txt = readFile(filename);
430
- if (!txt) {
431
- return;
432
- }
433
- let replaced = txt;
434
- if (!txt.includes('androidx.coordinatorlayout:coordinatorlayout:')) {
435
- replaced = replaced.replace('dependencies {', 'dependencies {\n implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"');
436
- }
437
- if (!txt.includes('androidx.core:core-splashscreen:')) {
438
- replaced = replaced.replace('dependencies {', 'dependencies {\n implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"');
439
- }
440
- // const lines = txt.split('\n');
441
- if (replaced !== txt) {
442
- (0, utils_fs_1.writeFileSync)(filename, replaced, 'utf-8');
443
- }
444
- }
445
304
  async function updateGradleWrapper(filename) {
446
305
  const txt = readFile(filename);
447
306
  if (!txt) {
@@ -465,6 +324,102 @@ async function updateGradleWrapperFiles(platformDir) {
465
324
  cwd: platformDir,
466
325
  });
467
326
  }
327
+ async function updateIosGitIgnore(filename) {
328
+ const txt = readFile(filename);
329
+ if (!txt) {
330
+ return;
331
+ }
332
+ const lines = txt.split('\n');
333
+ let linesToKeep = '';
334
+ for (const line of lines) {
335
+ // check for enableJetifier
336
+ const podfileMatch = line.match(/.+Podfile\.lock/) || [];
337
+ if (podfileMatch.length == 0) {
338
+ linesToKeep += line + '\n';
339
+ }
340
+ }
341
+ (0, utils_fs_1.writeFileSync)(filename, linesToKeep, { encoding: 'utf-8' });
342
+ }
343
+ async function updateAppIcons(config) {
344
+ const iconToKeep = 'AppIcon-512@2x.png';
345
+ const contentsFile = 'Contents.json';
346
+ const newContentsFileContents = `{
347
+ "images" : [
348
+ {
349
+ "filename" : "${iconToKeep}",
350
+ "idiom" : "universal",
351
+ "platform" : "ios",
352
+ "size" : "1024x1024"
353
+ }
354
+ ],
355
+ "info" : {
356
+ "author" : "xcode",
357
+ "version" : 1
358
+ }
359
+ }`;
360
+ const path = (0, path_1.join)(config.ios.platformDirAbs, 'App', 'App', 'Assets.xcassets', 'AppIcon.appiconset');
361
+ if (!(0, utils_fs_1.existsSync)(path)) {
362
+ log_1.logger.error(`Unable to find ${path}. Try updating it manually`);
363
+ return;
364
+ }
365
+ if (!(0, utils_fs_1.existsSync)((0, path_1.join)(path, iconToKeep))) {
366
+ log_1.logger.error(`Unable to find ${iconToKeep}. Try updating it manually`);
367
+ return;
368
+ }
369
+ if (!(0, utils_fs_1.existsSync)((0, path_1.join)(path, contentsFile))) {
370
+ log_1.logger.error(`Unable to find ${path}. Try updating it manually`);
371
+ return;
372
+ }
373
+ const filenames = (0, utils_fs_1.readdirSync)(path);
374
+ for (const filename of filenames) {
375
+ if (filename != iconToKeep && filename != contentsFile) {
376
+ (0, utils_fs_1.removeSync)((0, path_1.join)(path, filename));
377
+ }
378
+ }
379
+ (0, utils_fs_1.writeFileSync)((0, path_1.join)(path, contentsFile), newContentsFileContents);
380
+ }
381
+ async function updateGradleProperties(filename) {
382
+ const txt = readFile(filename);
383
+ if (!txt) {
384
+ return;
385
+ }
386
+ const lines = txt.split('\n');
387
+ let linesToKeep = '';
388
+ for (const line of lines) {
389
+ // check for enableJetifier
390
+ const jetifierMatch = line.match(/android\.enableJetifier\s*=\s*true/) || [];
391
+ const commentMatch = line.match(/# Automatically convert third-party libraries to use AndroidX/) || [];
392
+ if (jetifierMatch.length == 0 && commentMatch.length == 0) {
393
+ linesToKeep += line + '\n';
394
+ }
395
+ }
396
+ (0, utils_fs_1.writeFileSync)(filename, linesToKeep, { encoding: 'utf-8' });
397
+ }
398
+ async function updateBuildGradle(filename, variablesAndClasspaths) {
399
+ // In build.gradle add dependencies:
400
+ // classpath 'com.android.tools.build:gradle:7.4.1'
401
+ // classpath 'com.google.gms:google-services:4.3.13'
402
+ const txt = readFile(filename);
403
+ if (!txt) {
404
+ return;
405
+ }
406
+ const neededDeps = {
407
+ 'com.android.tools.build:gradle': variablesAndClasspaths['com.android.tools.build:gradle'],
408
+ 'com.google.gms:google-services': variablesAndClasspaths['com.google.gms:google-services'],
409
+ };
410
+ let replaced = txt;
411
+ for (const dep of Object.keys(neededDeps)) {
412
+ if (replaced.includes(`classpath '${dep}`)) {
413
+ const semver = await Promise.resolve().then(() => tslib_1.__importStar(require('semver')));
414
+ const firstIndex = replaced.indexOf(dep) + dep.length + 1;
415
+ const existingVersion = '' + replaced.substring(firstIndex, replaced.indexOf("'", firstIndex));
416
+ if (semver.gte(neededDeps[dep], existingVersion)) {
417
+ replaced = setAllStringIn(replaced, `classpath '${dep}:`, `'`, neededDeps[dep]);
418
+ log_1.logger.info(`Set ${dep} = ${neededDeps[dep]}.`);
419
+ }
420
+ }
421
+ }
422
+ }
468
423
  async function updateFile(config, filename, textStart, textEnd, replacement, skipIfNotFound) {
469
424
  if (config === null) {
470
425
  return false;
@@ -529,176 +484,3 @@ function setAllStringIn(data, start, end, replacement) {
529
484
  }
530
485
  return result;
531
486
  }
532
- async function replaceIfUsePush(config) {
533
- const startLine = '#if USE_PUSH';
534
- const endLine = '#endif';
535
- const filename = (0, path_1.join)(config.ios.nativeTargetDirAbs, 'AppDelegate.swift');
536
- const txt = readFile(filename);
537
- if (!txt) {
538
- return;
539
- }
540
- const lines = txt.split('\n');
541
- let startLineIndex = null;
542
- let endLineIndex = null;
543
- for (const [key, item] of lines.entries()) {
544
- if (item.includes(startLine)) {
545
- startLineIndex = key;
546
- break;
547
- }
548
- }
549
- if (startLineIndex !== null) {
550
- for (const [key, item] of lines.entries()) {
551
- if (item.includes(endLine) && key > startLineIndex) {
552
- endLineIndex = key;
553
- break;
554
- }
555
- }
556
- if (endLineIndex !== null) {
557
- lines[endLineIndex] = '';
558
- lines[startLineIndex] = '';
559
- (0, utils_fs_1.writeFileSync)(filename, lines.join('\n'), 'utf-8');
560
- }
561
- }
562
- }
563
- async function replacePush(filename) {
564
- const txt = readFile(filename);
565
- if (!txt) {
566
- return;
567
- }
568
- let replaced = txt;
569
- replaced = replaced.replace('DEBUG USE_PUSH', 'DEBUG');
570
- replaced = replaced.replace('USE_PUSH', '""');
571
- if (replaced != txt) {
572
- (0, utils_fs_1.writeFileSync)(filename, replaced, 'utf-8');
573
- }
574
- }
575
- async function removeKey(filename, key) {
576
- const txt = readFile(filename);
577
- if (!txt) {
578
- return;
579
- }
580
- let lines = txt.split('\n');
581
- let removed = false;
582
- let removing = false;
583
- lines = lines.filter(line => {
584
- if (removing && line.includes('</dict>')) {
585
- removing = false;
586
- return false;
587
- }
588
- if (line.includes(`<key>${key}</key`)) {
589
- removing = true;
590
- removed = true;
591
- }
592
- return !removing;
593
- });
594
- if (removed) {
595
- (0, utils_fs_1.writeFileSync)(filename, lines.join('\n'), 'utf-8');
596
- }
597
- }
598
- async function podfileAssertDeploymentTarget(filename) {
599
- const txt = readFile(filename);
600
- if (!txt) {
601
- return;
602
- }
603
- let replaced = txt;
604
- if (!replaced.includes(`require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers`)) {
605
- replaced =
606
- `require_relative '../../node_modules/@capacitor/ios/scripts/pods_helpers'\n\n` +
607
- txt;
608
- }
609
- if (replaced.includes('post_install do |installer|')) {
610
- if (!replaced.includes(`assertDeploymentTarget(installer)`)) {
611
- replaced = replaced.replace('post_install do |installer|', `post_install do |installer|\n assertDeploymentTarget(installer)\n`);
612
- }
613
- }
614
- else {
615
- replaced =
616
- replaced +
617
- `\n\npost_install do |installer|\n assertDeploymentTarget(installer)\nend\n`;
618
- }
619
- (0, utils_fs_1.writeFileSync)(filename, replaced, 'utf-8');
620
- }
621
- async function migrateMainActivity(config) {
622
- const xmlData = await (0, xml_1.readXML)((0, path_1.join)(config.android.srcMainDirAbs, 'AndroidManifest.xml'));
623
- const manifestNode = xmlData.manifest;
624
- const applicationChildNodes = manifestNode.application;
625
- let mainActivityClassPath = '';
626
- applicationChildNodes.find(applicationChildNode => {
627
- const activityChildNodes = applicationChildNode.activity;
628
- if (!Array.isArray(activityChildNodes)) {
629
- return false;
630
- }
631
- const mainActivityNode = activityChildNodes.find(activityChildNode => {
632
- const intentFilterChildNodes = activityChildNode['intent-filter'];
633
- if (!Array.isArray(intentFilterChildNodes)) {
634
- return false;
635
- }
636
- return intentFilterChildNodes.find(intentFilterChildNode => {
637
- const actionChildNodes = intentFilterChildNode.action;
638
- if (!Array.isArray(actionChildNodes)) {
639
- return false;
640
- }
641
- const mainActionChildNode = actionChildNodes.find(actionChildNode => {
642
- const androidName = actionChildNode.$['android:name'];
643
- return androidName === 'android.intent.action.MAIN';
644
- });
645
- if (!mainActionChildNode) {
646
- return false;
647
- }
648
- const categoryChildNodes = intentFilterChildNode.category;
649
- if (!Array.isArray(categoryChildNodes)) {
650
- return false;
651
- }
652
- return categoryChildNodes.find(categoryChildNode => {
653
- const androidName = categoryChildNode.$['android:name'];
654
- return androidName === 'android.intent.category.LAUNCHER';
655
- });
656
- });
657
- });
658
- if (mainActivityNode) {
659
- mainActivityClassPath = mainActivityNode.$['android:name'];
660
- }
661
- return mainActivityNode;
662
- });
663
- const mainActivityClassName = mainActivityClassPath.split('.').pop();
664
- const mainActivityPathArray = mainActivityClassPath.split('.');
665
- mainActivityPathArray.pop();
666
- const mainActivityClassFileName = `${mainActivityClassName}.java`;
667
- const mainActivityClassFilePath = (0, path_1.join)((0, path_1.join)(config.android.srcMainDirAbs, 'java'), ...mainActivityPathArray, mainActivityClassFileName);
668
- let data = readFile(mainActivityClassFilePath);
669
- if (data) {
670
- const bindex = data.indexOf('this.init(savedInstanceState');
671
- if (bindex !== -1) {
672
- const eindex = data.indexOf('}});', bindex) + 4;
673
- data = data.replace(data.substring(bindex, eindex), '');
674
- data = data.replace('// Initializes the Bridge', '');
675
- }
676
- const rindex = data.indexOf('registerPlugin');
677
- const superLine = 'super.onCreate(savedInstanceState);';
678
- if (rindex !== -1) {
679
- if (data.indexOf(superLine) < rindex) {
680
- const linePadding = rindex - data.indexOf(superLine) - superLine.length - 1;
681
- data = data.replace(`${superLine}\n${' '.repeat(linePadding)}`, '');
682
- const eindex = data.lastIndexOf('.class);') + 8;
683
- data = data.replace(data.substring(bindex, eindex), `${data.substring(bindex, eindex)}\n${' '.repeat(linePadding) + superLine.padStart(linePadding)}`);
684
- }
685
- }
686
- if (bindex == -1 && rindex == -1) {
687
- return;
688
- }
689
- (0, utils_fs_1.writeFileSync)(mainActivityClassFilePath, data);
690
- }
691
- }
692
- async function addNewSplashScreen(config) {
693
- const stylePath = (0, path_1.join)(config.android.srcMainDirAbs, 'res', 'values', 'styles.xml');
694
- let stylesXml = readFile(stylePath);
695
- if (!stylesXml)
696
- return;
697
- stylesXml = stylesXml.replace(`parent="AppTheme.NoActionBar"`, `parent="Theme.SplashScreen"`);
698
- // revert wrong replaces
699
- stylesXml = stylesXml.replace(`name="Theme.SplashScreen"`, `name="AppTheme.NoActionBar"`);
700
- stylesXml = stylesXml.replace(`name="Theme.SplashScreenLaunch"`, `name="AppTheme.NoActionBarLaunch"`);
701
- // Apply DayNight theme
702
- stylesXml = stylesXml.replace(`parent="Theme.AppCompat.NoActionBar"`, `parent="Theme.AppCompat.DayNight.NoActionBar"`);
703
- (0, utils_fs_1.writeFileSync)(stylePath, stylesXml);
704
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/cli",
3
- "version": "5.0.0-alpha.1",
3
+ "version": "5.0.0-alpha.2",
4
4
  "description": "Capacitor: Cross-platform apps with JavaScript and the web",
5
5
  "homepage": "https://capacitorjs.com",
6
6
  "author": "Ionic Team <hi@ionic.io> (https://ionic.io)",
@@ -56,7 +56,7 @@
56
56
  "open": "^8.4.0",
57
57
  "plist": "^3.0.5",
58
58
  "prompts": "^2.4.2",
59
- "rimraf": "^3.0.2",
59
+ "rimraf": "^4.4.1",
60
60
  "semver": "^7.3.7",
61
61
  "tar": "^6.1.11",
62
62
  "tslib": "^2.4.0",
@@ -64,24 +64,26 @@
64
64
  },
65
65
  "devDependencies": {
66
66
  "@types/debug": "^4.1.7",
67
- "@types/jest": "^26.0.4",
67
+ "@types/jest": "^29.5.0",
68
68
  "@types/plist": "^3.0.2",
69
69
  "@types/prompts": "^2.0.14",
70
- "@types/rimraf": "^3.0.2",
71
70
  "@types/semver": "^7.3.10",
72
71
  "@types/tar": "^6.1.1",
73
72
  "@types/tmp": "^0.2.3",
74
73
  "@types/xml2js": "0.4.5",
75
- "jest": "^26.1.0",
74
+ "jest": "^29.5.0",
75
+ "jest-environment-jsdom": "^29.5.0",
76
+ "jest-jasmine2": "^29.5.0",
76
77
  "tmp": "^0.2.1",
77
- "ts-jest": "^26.1.3",
78
- "typescript": "~4.9.5"
78
+ "ts-jest": "^29.0.5",
79
+ "typescript": "~5.0.2"
79
80
  },
80
81
  "jest": {
81
- "preset": "ts-jest"
82
+ "preset": "ts-jest",
83
+ "testRunner": "jest-jasmine2"
82
84
  },
83
85
  "publishConfig": {
84
86
  "access": "public"
85
87
  },
86
- "gitHead": "76202ca81b8e855df0ef8e5f6a36bd65ed1469a4"
88
+ "gitHead": "4e4134c2c9c8c52f40d9251924a419a87eca2924"
87
89
  }