@capacitor/cli 9.0.0-alpha.5 → 9.0.0-alpha.7

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.
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.setAllStringIn = exports.migrateCommand = void 0;
3
+ exports.__testables = exports.setAllStringIn = exports.migrateCommand = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const fs_extra_1 = require("fs-extra");
6
6
  const path_1 = require("path");
7
- const rimraf_1 = tslib_1.__importDefault(require("rimraf"));
7
+ const rimraf_1 = require("rimraf");
8
8
  const semver_1 = require("semver");
9
9
  const colors_1 = tslib_1.__importDefault(require("../colors"));
10
10
  const common_1 = require("../common");
@@ -14,6 +14,8 @@ const log_1 = require("../log");
14
14
  const fs_1 = require("../util/fs");
15
15
  const subprocess_1 = require("../util/subprocess");
16
16
  const template_1 = require("../util/template");
17
+ const migrate_edge_to_edge_1 = require("./migrate-edge-to-edge");
18
+ const migrate_swiftui_1 = require("./migrate-swiftui");
17
19
  // eslint-disable-next-line prefer-const
18
20
  let allDependencies = {};
19
21
  const libs = ['@capacitor/core', '@capacitor/cli', '@capacitor/ios', '@capacitor/android'];
@@ -44,23 +46,39 @@ const plugins = [
44
46
  '@capacitor/text-zoom',
45
47
  '@capacitor/toast',
46
48
  ];
47
- const coreVersion = '^8.0.0';
48
- const pluginVersion = '^8.0.0';
49
+ const coreVersion = 'next';
50
+ const pluginVersion = 'next';
49
51
  const gradleVersion = '9.5.1';
50
52
  const iOSVersion = '16';
51
- const kotlinVersion = '2.4.0';
52
53
  let installFailed = false;
54
+ // AGP 9 changed the defaults of these properties and Android Studio's AGP Upgrade Assistant
55
+ // writes them into gradle.properties as compatibility shims. Capacitor apps need none of them,
56
+ // most are deprecated and will be removed in AGP 10, and some (android.builtInKotlin,
57
+ // android.sdk.defaultTargetSdkToCompileSdkIfUnset) break a Capacitor 9 build.
58
+ const agpMigrationAssistantProperties = [
59
+ 'android.builtInKotlin',
60
+ 'android.defaults.buildfeatures.resvalues',
61
+ 'android.dependency.useConstraints',
62
+ 'android.enableAppCompileTimeRClass',
63
+ 'android.newDsl',
64
+ 'android.r8.optimizedResourceShrinking',
65
+ 'android.r8.strictFullModeForKeepRules',
66
+ 'android.sdk.defaultTargetSdkToCompileSdkIfUnset',
67
+ 'android.uniquePackageNames',
68
+ 'android.usesSdkInManifest.disallowed',
69
+ ];
70
+ const jcenterLine = /^jcenter\(\)\s*(\/\/.*)?$/;
53
71
  async function migrateCommand(config, noprompt, packagemanager) {
54
72
  if (config === null) {
55
73
  (0, errors_1.fatal)('Config data missing');
56
74
  }
57
75
  const capMajor = await checkCapacitorMajorVersion(config);
58
- if (capMajor < 7) {
59
- (0, errors_1.fatal)('Migrate can only be used on Capacitor 7, please use the CLI in Capacitor 7 to upgrade to 7 first');
76
+ if (capMajor < 8) {
77
+ (0, errors_1.fatal)('Migrate can only be used on Capacitor 8, please use the CLI in Capacitor 8 to upgrade to 8 first');
60
78
  }
61
79
  const jdkMajor = await (0, common_1.checkJDKMajorVersion)();
62
80
  if (jdkMajor < 21) {
63
- log_1.logger.warn('Capacitor 8 requires JDK 21 or higher. Some steps may fail.');
81
+ log_1.logger.warn('Capacitor 9 requires JDK 21 or higher. Some steps may fail.');
64
82
  }
65
83
  const variablesAndClasspaths = await getAndroidVariablesAndClasspaths(config);
66
84
  if (!variablesAndClasspaths) {
@@ -70,11 +88,11 @@ async function migrateCommand(config, noprompt, packagemanager) {
70
88
  ...config.app.package.dependencies,
71
89
  ...config.app.package.devDependencies,
72
90
  };
73
- const monorepoWarning = 'Please note this tool is not intended for use in a mono-repo environment, you should migrate manually instead. Refer to https://capacitorjs.com/docs/next/updating/8-0';
91
+ const monorepoWarning = 'Please note this tool is not intended for use in a mono-repo environment, you should migrate manually instead. Refer to https://capacitorjs.com/docs/next/updating/9-0';
74
92
  log_1.logger.info(monorepoWarning);
75
93
  const { migrateconfirm } = noprompt
76
94
  ? { migrateconfirm: 'y' }
77
- : await (0, log_1.logPrompt)(`Capacitor 8 sets a deployment target of iOS ${iOSVersion} and Android 17 (SDK 37). \n`, {
95
+ : await (0, log_1.logPrompt)(`Capacitor 9 sets a deployment target of iOS ${iOSVersion} and Android 17 (SDK 37). \n`, {
78
96
  type: 'text',
79
97
  name: 'migrateconfirm',
80
98
  message: `Are you sure you want to migrate? (Y/n)`,
@@ -136,6 +154,10 @@ async function migrateCommand(config, noprompt, packagemanager) {
136
154
  else {
137
155
  log_1.logger.warn('Skipped updating deployment target');
138
156
  }
157
+ await (0, common_1.runTask)(`Migrating AppDelegate.swift`, () => {
158
+ return updateAppDelegate((0, path_1.join)(config.ios.nativeTargetDirAbs, 'AppDelegate.swift'));
159
+ });
160
+ await (0, migrate_swiftui_1.migrateToSwiftUI)(config);
139
161
  }
140
162
  if (!installFailed) {
141
163
  await (0, common_1.runTask)(`Running cap sync.`, () => {
@@ -150,8 +172,44 @@ async function migrateCommand(config, noprompt, packagemanager) {
150
172
  await (0, common_1.runTask)(`Migrating AndroidManifest.xml by adding density to Activity configChanges.`, () => {
151
173
  return updateAndroidManifest((0, path_1.join)(config.android.srcMainDirAbs, 'AndroidManifest.xml'));
152
174
  });
153
- const gradleWrapperVersion = getGradleWrapperVersion((0, path_1.join)(config.android.platformDirAbs, 'gradle', 'wrapper', 'gradle-wrapper.properties'));
154
- if (!installFailed && (0, semver_1.gte)(gradleVersion, gradleWrapperVersion)) {
175
+ await (0, common_1.runTask)(`Migrating the main Activity to enable edge-to-edge.`, () => {
176
+ return (0, migrate_edge_to_edge_1.migrateToEdgeToEdge)(config);
177
+ });
178
+ const gradleWrapperPath = (0, path_1.join)(config.android.platformDirAbs, 'gradle', 'wrapper', 'gradle-wrapper.properties');
179
+ const gradleWrapperVersion = getGradleWrapperVersion(gradleWrapperPath);
180
+ const outdatedGradle = (0, semver_1.gte)(gradleVersion, gradleWrapperVersion);
181
+ if (outdatedGradle) {
182
+ await (0, common_1.runTask)(`Updating gradle-wrapper.properties`, () => {
183
+ return updateFile(config, gradleWrapperPath, 'services.gradle.org/distributions/gradle-', '.zip', `${gradleVersion}-all`);
184
+ });
185
+ }
186
+ await (0, common_1.runTask)(`Migrating app build.gradle file.`, () => {
187
+ return updateAppBuildGradle((0, path_1.join)(config.android.appDirAbs, 'build.gradle'));
188
+ });
189
+ // settings.gradle
190
+ await (0, common_1.runTask)(`Migrating settings.gradle file.`, () => {
191
+ return (async () => {
192
+ const settingsPath = (0, path_1.join)(config.android.platformDirAbs, 'settings.gradle');
193
+ let txt = readFile(settingsPath);
194
+ if (!txt) {
195
+ return;
196
+ }
197
+ txt = txt.replace(`include ':capacitor-cordova-android-plugins'\n`, '');
198
+ txt = txt.replace(`project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/')\n`, '');
199
+ (0, fs_extra_1.writeFileSync)(settingsPath, txt, { encoding: 'utf-8' });
200
+ })();
201
+ });
202
+ // gradle.properties
203
+ await (0, common_1.runTask)(`Migrating gradle.properties file.`, () => {
204
+ return updateGradleProperties((0, path_1.join)(config.android.platformDirAbs, 'gradle.properties'));
205
+ });
206
+ // Gradle 9 removed jcenter(), so it has to go before the wrapper upgrade below or the
207
+ // wrapper task itself fails at the configuration phase once it runs on Gradle 9
208
+ await (0, common_1.runTask)(`Removing jcenter() from gradle files.`, () => {
209
+ return removeJCenter(config);
210
+ });
211
+ // Always run before root build.gradle changes as the AGP update could be incompatible with current gradle
212
+ if (!installFailed && outdatedGradle) {
155
213
  try {
156
214
  await (0, common_1.runTask)(`Upgrading gradle wrapper`, () => {
157
215
  return updateGradleWrapperFiles(config.android.platformDirAbs);
@@ -166,7 +224,7 @@ async function migrateCommand(config, noprompt, packagemanager) {
166
224
  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`);
167
225
  }
168
226
  else {
169
- log_1.logger.error(`gradle wrapper files were not updated`);
227
+ log_1.logger.error(`gradle wrapper files were not updated\n${e}`);
170
228
  }
171
229
  }
172
230
  }
@@ -176,9 +234,6 @@ async function migrateCommand(config, noprompt, packagemanager) {
176
234
  await (0, common_1.runTask)(`Migrating root build.gradle file.`, () => {
177
235
  return updateBuildGradle((0, path_1.join)(config.android.platformDirAbs, 'build.gradle'), variablesAndClasspaths);
178
236
  });
179
- await (0, common_1.runTask)(`Migrating app build.gradle file.`, () => {
180
- return updateAppBuildGradle((0, path_1.join)(config.android.appDirAbs, 'build.gradle'));
181
- });
182
237
  // Variables gradle
183
238
  await (0, common_1.runTask)(`Migrating variables.gradle file.`, () => {
184
239
  return (async () => {
@@ -216,16 +271,15 @@ async function migrateCommand(config, noprompt, packagemanager) {
216
271
  }
217
272
  const pluginVariables = {
218
273
  firebaseMessagingVersion: '25.0.1',
219
- playServicesLocationVersion: '21.3.0',
220
- androidxBrowserVersion: '1.9.0',
221
- androidxMaterialVersion: '1.13.0',
222
- androidxExifInterfaceVersion: '1.4.1',
223
- androidxCoreKTXVersion: '1.17.0',
224
- googleMapsPlayServicesVersion: '19.2.0',
225
- googleMapsUtilsVersion: '3.19.1',
226
- googleMapsKtxVersion: '5.2.1',
227
- googleMapsUtilsKtxVersion: '5.2.1',
228
- kotlinxCoroutinesVersion: '1.10.2',
274
+ playServicesLocationVersion: '21.4.0',
275
+ androidxBrowserVersion: '1.10.0',
276
+ androidxMaterialVersion: '1.14.0',
277
+ androidxExifInterfaceVersion: '1.4.2',
278
+ googleMapsPlayServicesVersion: '20.0.0',
279
+ googleMapsUtilsVersion: '5.0.0',
280
+ googleMapsKtxVersion: '6.0.1',
281
+ googleMapsUtilsKtxVersion: '6.0.1',
282
+ kotlinxCoroutinesVersion: '1.11.0',
229
283
  coreSplashScreenVersion: '1.2.0',
230
284
  };
231
285
  for (const variable of Object.keys(pluginVariables)) {
@@ -233,7 +287,7 @@ async function migrateCommand(config, noprompt, packagemanager) {
233
287
  }
234
288
  })();
235
289
  });
236
- rimraf_1.default.sync((0, path_1.join)(config.android.appDirAbs, 'build'));
290
+ rimraf_1.rimraf.sync((0, path_1.join)(config.android.appDirAbs, 'build'));
237
291
  }
238
292
  // Write all breaking changes
239
293
  await (0, common_1.runTask)(`Writing breaking changes.`, () => {
@@ -273,7 +327,9 @@ async function installLatestLibs(dependencyManager, runInstall, config) {
273
327
  if (libs.includes(devDepKey)) {
274
328
  pkgJson['devDependencies'][devDepKey] = coreVersion;
275
329
  }
276
- else if (plugins.includes(devDepKey)) {
330
+ else if (plugins.includes(devDepKey) &&
331
+ !(pkgJson['devDependencies'][devDepKey].startsWith('file:') ||
332
+ pkgJson['devDependencies'][devDepKey].startsWith('workspace:'))) {
277
333
  pkgJson['devDependencies'][devDepKey] = pluginVersion;
278
334
  }
279
335
  }
@@ -281,7 +337,8 @@ async function installLatestLibs(dependencyManager, runInstall, config) {
281
337
  if (libs.includes(depKey)) {
282
338
  pkgJson['dependencies'][depKey] = coreVersion;
283
339
  }
284
- else if (plugins.includes(depKey)) {
340
+ else if (plugins.includes(depKey) &&
341
+ !(pkgJson['dependencies'][depKey].startsWith('file:') || pkgJson['dependencies'][depKey].startsWith('workspace:'))) {
285
342
  pkgJson['dependencies'][depKey] = pluginVersion;
286
343
  }
287
344
  }
@@ -289,7 +346,7 @@ async function installLatestLibs(dependencyManager, runInstall, config) {
289
346
  encoding: 'utf-8',
290
347
  });
291
348
  if (runInstall) {
292
- rimraf_1.default.sync((0, path_1.join)(config.app.rootDir, 'node_modules/@capacitor/!(cli)'));
349
+ rimraf_1.rimraf.sync((0, path_1.join)(config.app.rootDir, 'node_modules/@capacitor/!(cli)'));
293
350
  await (0, subprocess_1.runCommand)(dependencyManager, ['install']);
294
351
  if (dependencyManager == 'yarn') {
295
352
  await (0, subprocess_1.runCommand)(dependencyManager, ['upgrade']);
@@ -310,10 +367,9 @@ async function writeBreakingChanges() {
310
367
  '@capacitor/camera',
311
368
  '@capacitor/geolocation',
312
369
  '@capacitor/google-maps',
370
+ '@capacitor/inappbrowser',
313
371
  '@capacitor/push-notifications',
314
- '@capacitor/screen-orientation',
315
372
  '@capacitor/splash-screen',
316
- '@capacitor/status-bar',
317
373
  ];
318
374
  const broken = [];
319
375
  for (const lib of breaking) {
@@ -322,7 +378,16 @@ async function writeBreakingChanges() {
322
378
  }
323
379
  }
324
380
  if (broken.length > 0) {
325
- log_1.logger.info(`IMPORTANT: Review https://capacitorjs.com/docs/next/updating/8-0#plugins for breaking changes in these plugins that you use: ${broken.join(', ')}.`);
381
+ log_1.logger.info(`IMPORTANT: Review https://capacitorjs.com/docs/next/updating/9-0#plugins for breaking changes in these plugins that you use: ${broken.join(', ')}.`);
382
+ }
383
+ if (allDependencies['@capacitor/android']) {
384
+ log_1.logger.info(`IMPORTANT: The SystemBars 'insetsHandling' option now defaults to 'native' instead of 'css'. ` +
385
+ `If your app reads the '--safe-area-inset-*' CSS variables that Capacitor injected, ` +
386
+ `set 'plugins.SystemBars.insetsHandling' to 'css' in your Capacitor configuration file.`);
387
+ }
388
+ if (allDependencies['@capacitor/ios']) {
389
+ log_1.logger.info('IMPORTANT: Capacitor 9.0 boots iOS apps from a SwiftUI App struct with UIScene. ' +
390
+ 'See https://capacitorjs.com/docs/next/updating/9-0 for the full migration guide.');
326
391
  }
327
392
  }
328
393
  async function getAndroidVariablesAndClasspaths(config) {
@@ -373,7 +438,7 @@ function getGradleWrapperVersion(filename) {
373
438
  if (!txt) {
374
439
  return '0.0.0';
375
440
  }
376
- const version = txt.substring(txt.indexOf('gradle-') + 7, txt.indexOf('-all.zip'));
441
+ const version = txt.substring(txt.indexOf('gradle-') + 7, txt.indexOf('.zip', txt.indexOf('gradle-')));
377
442
  const semverVersion = (_a = (0, semver_1.coerce)(version)) === null || _a === void 0 ? void 0 : _a.version;
378
443
  return semverVersion ? semverVersion : '0.0.0';
379
444
  }
@@ -402,40 +467,87 @@ async function updateBuildGradle(filename, variablesAndClasspaths) {
402
467
  }
403
468
  }
404
469
  }
405
- const beforeKotlinVersionUpdate = replaced;
406
- replaced = replaceVersion(replaced, /(ext\.kotlin_version\s*=\s*['"])([^'"]+)(['"])/, kotlinVersion);
407
- replaced = replaceVersion(replaced, /(org\.jetbrains\.kotlin:kotlin[^:]*:)([\d.]+)(['"])/, kotlinVersion);
408
- if (beforeKotlinVersionUpdate !== replaced) {
409
- log_1.logger.info(`Set Kotlin version to ${kotlinVersion}`);
410
- }
411
470
  (0, fs_extra_1.writeFileSync)(filename, replaced, 'utf-8');
412
471
  }
413
- function replaceVersion(text, regex, newVersion) {
414
- return text.replace(regex, (match, prefix, currentVersion, suffix) => {
415
- var _a;
416
- const semVer = (_a = (0, semver_1.coerce)(currentVersion)) === null || _a === void 0 ? void 0 : _a.version;
417
- if ((0, semver_1.gte)(newVersion, semVer ? semVer : '0.0.0')) {
418
- return `${prefix || ''}${newVersion}${suffix || ''}`;
419
- }
420
- return match;
421
- });
422
- }
423
472
  async function updateAppBuildGradle(filename) {
424
473
  const txt = readFile(filename);
425
474
  if (!txt) {
426
475
  return;
427
476
  }
428
477
  let replaced = txt;
429
- const gradlePproperties = ['compileSdk', 'namespace', 'ignoreAssetsPattern'];
430
- for (const prop of gradlePproperties) {
431
- // Use updated Groovy DSL syntax with " = " assignment
432
- const regex = new RegExp(`(^\\s*${prop})\\s+(?!=)(.+)$`, 'gm');
433
- replaced = replaced.replace(regex, (_match, key, value) => {
434
- return `${key} = ${value.trim()}`;
435
- });
478
+ replaced = replaced.replace(`proguard-android.txt`, `proguard-android-optimize.txt`);
479
+ replaced = replaced.replace(' targetSdkVersion rootProject.ext.targetSdkVersion\n', '');
480
+ replaced = replaced.replace(` implementation project(':capacitor-cordova-android-plugins')\n`, '');
481
+ replaced = replaced.replace(`repositories {
482
+ flatDir{
483
+ dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
484
+ }
485
+ }
486
+
487
+ `, '');
488
+ if (!replaced.includes('def androidxAppCompatVersion = rootProject.ext.androidxAppCompatVersion')) {
489
+ replaced = replaced.replace(`apply plugin: 'com.android.application'\n\n`, `apply plugin: 'com.android.application'
490
+
491
+ def androidxAppCompatVersion = rootProject.ext.androidxAppCompatVersion
492
+ def androidxCoordinatorLayoutVersion = rootProject.ext.androidxCoordinatorLayoutVersion
493
+ def coreSplashScreenVersion = rootProject.ext.coreSplashScreenVersion
494
+ def junitVersion = rootProject.ext.junitVersion
495
+ def androidxJunitVersion = rootProject.ext.androidxJunitVersion
496
+ def androidxEspressoCoreVersion = rootProject.ext.androidxEspressoCoreVersion
497
+
498
+ `);
436
499
  }
437
500
  (0, fs_extra_1.writeFileSync)(filename, replaced, 'utf-8');
438
501
  }
502
+ async function updateGradleProperties(filename) {
503
+ const txt = readFile(filename);
504
+ if (!txt) {
505
+ return;
506
+ }
507
+ const replaced = removeAGPMigrationProperties(txt);
508
+ if (replaced !== txt) {
509
+ (0, fs_extra_1.writeFileSync)(filename, replaced, 'utf-8');
510
+ }
511
+ }
512
+ function removeAGPMigrationProperties(txt) {
513
+ return txt
514
+ .split('\n')
515
+ .filter((line) => {
516
+ const property = line.split('=')[0].trim();
517
+ if (!agpMigrationAssistantProperties.includes(property)) {
518
+ return true;
519
+ }
520
+ log_1.logger.info(`Removed ${property} from gradle.properties.`);
521
+ return false;
522
+ })
523
+ .join('\n');
524
+ }
525
+ async function removeJCenter(config) {
526
+ // jcenter() has only ever been in the root build.gradle of our templates, never in app/build.gradle
527
+ const filename = (0, path_1.join)(config.android.platformDirAbs, 'build.gradle');
528
+ const txt = readFile(filename);
529
+ if (!txt) {
530
+ return;
531
+ }
532
+ const replaced = removeJCenterFromGradleFile(txt);
533
+ if (replaced !== txt) {
534
+ (0, fs_extra_1.writeFileSync)(filename, replaced, 'utf-8');
535
+ }
536
+ }
537
+ // mavenCentral() is not added back: it has been in the template since Capacitor 4 and the
538
+ // 3 to 4 migrator always added it, so every app is assumed to declare it already
539
+ function removeJCenterFromGradleFile(txt) {
540
+ return txt
541
+ .split('\n')
542
+ .filter((line) => {
543
+ if (!jcenterLine.test(line.trim())) {
544
+ return true;
545
+ }
546
+ log_1.logger.info(`Removed jcenter().`);
547
+ return false;
548
+ })
549
+ .join('\n');
550
+ }
439
551
  async function updateFile(config, filename, textStart, textEnd, replacement, skipIfNotFound) {
440
552
  if (config === null) {
441
553
  return false;
@@ -517,3 +629,26 @@ async function updateAndroidManifest(filename) {
517
629
  (0, fs_extra_1.writeFileSync)(filename, replaced, 'utf-8');
518
630
  }
519
631
  }
632
+ async function updateAppDelegate(filename) {
633
+ const txt = readFile(filename);
634
+ if (!txt) {
635
+ return;
636
+ }
637
+ if (txt.includes('@main')) {
638
+ return; // Probably already updated
639
+ }
640
+ const replaced = txt.replace('@UIApplicationMain', '@main');
641
+ if (!replaced.includes('@main')) {
642
+ log_1.logger.error(`Unable to replace @UIApplicationMain to @main in ${filename}. Try replacing it manually`);
643
+ }
644
+ else {
645
+ (0, fs_extra_1.writeFileSync)(filename, replaced, 'utf-8');
646
+ }
647
+ }
648
+ exports.__testables = {
649
+ agpMigrationAssistantProperties,
650
+ removeAGPMigrationProperties,
651
+ removeJCenter,
652
+ removeJCenterFromGradleFile,
653
+ updateGradleProperties,
654
+ };