@capacitor-plus/cli 8.0.7 → 8.3.3

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
Binary file
package/dist/config.js CHANGED
@@ -232,7 +232,8 @@ async function loadIOSConfig(rootDir, extConfig) {
232
232
  const nativeXcodeProjDir = `${nativeProjectDir}/App.xcodeproj`;
233
233
  const nativeXcodeProjDirAbs = (0, path_1.resolve)(platformDirAbs, nativeXcodeProjDir);
234
234
  const nativeXcodeWorkspaceDirAbs = (0, promise_1.lazy)(() => determineXcodeWorkspaceDirAbs(nativeProjectDirAbs));
235
- const podPath = (0, promise_1.lazy)(() => determineGemfileOrCocoapodPath(rootDir, platformDirAbs, nativeProjectDirAbs));
235
+ const podPath = (0, promise_1.lazy)(() => determineCocoapodPath());
236
+ const packageManager = (0, promise_1.lazy)(() => determinePackageManager(rootDir, platformDirAbs, nativeProjectDirAbs));
236
237
  const webDirAbs = (0, promise_1.lazy)(() => determineIOSWebDirAbs(nativeProjectDirAbs, nativeTargetDirAbs, nativeXcodeProjDirAbs));
237
238
  const cordovaPluginsDir = 'capacitor-cordova-ios-plugins';
238
239
  const buildOptions = {
@@ -260,6 +261,7 @@ async function loadIOSConfig(rootDir, extConfig) {
260
261
  webDir: (0, promise_1.lazy)(async () => (0, path_1.relative)(platformDirAbs, await webDirAbs)),
261
262
  webDirAbs,
262
263
  podPath,
264
+ packageManager,
263
265
  buildOptions,
264
266
  };
265
267
  }
@@ -350,10 +352,19 @@ async function determineAndroidStudioPath(os) {
350
352
  }
351
353
  return '';
352
354
  }
353
- async function determineGemfileOrCocoapodPath(rootDir, platformDir, nativeProjectDirAbs) {
355
+ async function determineCocoapodPath() {
354
356
  if (process.env.CAPACITOR_COCOAPODS_PATH) {
355
357
  return process.env.CAPACITOR_COCOAPODS_PATH;
356
358
  }
359
+ return 'pod';
360
+ }
361
+ async function determinePackageManager(rootDir, platformDir, nativeProjectDirAbs) {
362
+ if ((0, fs_extra_1.existsSync)((0, path_1.resolve)(nativeProjectDirAbs, 'CapApp-SPM'))) {
363
+ return 'SPM';
364
+ }
365
+ if (process.env.CAPACITOR_COCOAPODS_PATH) {
366
+ return 'Cocoapods';
367
+ }
357
368
  let gemfilePath = '';
358
369
  if (await (0, fs_extra_1.pathExists)((0, path_1.resolve)(rootDir, 'Gemfile'))) {
359
370
  gemfilePath = (0, path_1.resolve)(rootDir, 'Gemfile');
@@ -380,18 +391,18 @@ async function determineGemfileOrCocoapodPath(rootDir, platformDir, nativeProjec
380
391
  try {
381
392
  const gemfileText = (await (0, fs_extra_1.readFile)(gemfilePath)).toString();
382
393
  if (!gemfileText) {
383
- return 'pod';
394
+ return 'Cocoapods';
384
395
  }
385
396
  const cocoapodsInGemfile = new RegExp(/gem\s+['"]cocoapods/).test(gemfileText);
386
- if (cocoapodsInGemfile) {
387
- return 'bundle exec pod';
397
+ if (cocoapodsInGemfile && (await (0, subprocess_1.isInstalled)('bundle'))) {
398
+ return 'bundler';
388
399
  }
389
400
  else {
390
- return 'pod';
401
+ return 'Cocoapods';
391
402
  }
392
403
  }
393
404
  catch {
394
- return 'pod';
405
+ return 'Cocoapods';
395
406
  }
396
407
  }
397
408
  function formatConfigTS(extConfig) {
@@ -460,6 +460,60 @@ export interface CapacitorConfig {
460
460
  provisioningProfile?: string;
461
461
  };
462
462
  };
463
+ experimental?: {
464
+ /**
465
+ * Experimental iOS-specific configuration.
466
+ *
467
+ * These options may change or be removed in future versions.
468
+ *
469
+ * @since 8.2.0
470
+ */
471
+ ios?: {
472
+ /**
473
+ * Swift Package Manager (SPM) specific configuration.
474
+ *
475
+ * @since 8.2.0
476
+ */
477
+ spm?: {
478
+ /**
479
+ * Swift tools version to use in Package.swift header.
480
+ *
481
+ * Defines the minimum version of the Swift compiler version required to build your app.
482
+ * For more information check the [swift documentation](https://docs.swift.org/swiftpm/documentation/packagemanagerdocs/settingswifttoolsversion/)
483
+ *
484
+ * Warning: Capacitor does not officially support Swift 6 yet.
485
+ * Setting this property to 6.0 or higher may cause issues.
486
+ * If you need to set this property to 6.0 or higher, make sure to throughrouly test your iOS app.
487
+ *
488
+ * This setting may graduate to `ios.spm.swiftToolsVersion` in a future major release.
489
+ *
490
+ * @since 8.3.0
491
+ * @default '5.9'
492
+ * @example '6.1'
493
+ */
494
+ swiftToolsVersion?: string;
495
+ /**
496
+ * Define package traits for SPM plugin dependencies.
497
+ *
498
+ * This requires explicitly setting experimental.ios.spm.swiftToolsVersion
499
+ * to '6.1' or higher.
500
+ *
501
+ * The key is the plugin ID (e.g. `@capacitor-firebase/analytics`)
502
+ * and the value is an array of trait names.
503
+ *
504
+ * Packages can have default traits. If you use this property, and
505
+ * want to preserve the defaults, include ".defaults" in the array.
506
+ *
507
+ * This setting may graduate to `ios.spm.packageTraits` in a future major release.
508
+ *
509
+ * @since 8.3.0
510
+ */
511
+ packageTraits?: {
512
+ [pluginId: string]: string[];
513
+ };
514
+ };
515
+ };
516
+ };
463
517
  server?: {
464
518
  /**
465
519
  * Configure the local hostname of the device.
@@ -648,7 +702,7 @@ export interface PluginsConfig {
648
702
  *
649
703
  * `css` = Injects CSS variables (`--safe-area-inset-*`) containing correct safe area inset values into the webview.
650
704
  *
651
- * `disable` = Disable all inset handling.
705
+ * `disable` = Disable CSS variables injection.
652
706
  *
653
707
  * @default "css"
654
708
  */
package/dist/index.js CHANGED
@@ -27,6 +27,15 @@ async function run() {
27
27
  }
28
28
  }
29
29
  exports.run = run;
30
+ async function getPackageManager(config, packageManager) {
31
+ if (packageManager === 'cocoapods') {
32
+ if ((await config.ios.packageManager) === 'bundler') {
33
+ return 'bundler';
34
+ }
35
+ return 'Cocoapods';
36
+ }
37
+ return 'SPM';
38
+ }
30
39
  function runProgram(config) {
31
40
  commander_1.program.version(config.cli.package.version);
32
41
  commander_1.program
@@ -147,11 +156,12 @@ function runProgram(config) {
147
156
  .option('--target-name-sdk-version <version>', 'use a specific sdk version when using --target-name, ex: 26.0 (for iOS 26) or 35 (for Android API 35)')
148
157
  .option('--no-sync', `do not run ${colors_1.default.input('sync')}`)
149
158
  .option('--forwardPorts <port:port>', 'Automatically run "adb reverse" for better live-reloading support')
150
- .option('-l, --live-reload', 'Enable Live Reload')
151
- .option('--host <host>', 'Host used for live reload')
152
- .option('--port <port>', 'Port used for live reload')
159
+ .option('-l, --live-reload', 'Set live-reload URL via CLI (uses defaults, overrides server.url config)')
160
+ .option('--host <host>', 'Configure host for live-reload URL (used with --live-reload)')
161
+ .option('--port <port>', 'Configure port for live-reload URL (used with --live-reload)')
153
162
  .option('--configuration <name>', 'Configuration name of the iOS Scheme')
154
- .action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { scheme, flavor, list, json, target, targetName, targetNameSdkVersion, sync, forwardPorts, liveReload, host, port, configuration, }) => {
163
+ .option('--https', 'Use https:// instead of http:// for live-reload URL (used with --live-reload)')
164
+ .action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { scheme, flavor, list, json, target, targetName, targetNameSdkVersion, sync, forwardPorts, liveReload, host, port, configuration, https, }) => {
155
165
  const { runCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/run')));
156
166
  await runCommand(config, platform, {
157
167
  scheme,
@@ -167,6 +177,7 @@ function runProgram(config) {
167
177
  host,
168
178
  port,
169
179
  configuration,
180
+ https,
170
181
  });
171
182
  })));
172
183
  commander_1.program
@@ -183,6 +194,7 @@ function runProgram(config) {
183
194
  .action((0, cli_1.wrapAction)((0, telemetry_1.telemetryAction)(config, async (platform, { packagemanager }) => {
184
195
  const { addCommand } = await Promise.resolve().then(() => tslib_1.__importStar(require('./tasks/add')));
185
196
  const configWritable = config;
197
+ configWritable.ios.packageManager = getPackageManager(config, packagemanager === null || packagemanager === void 0 ? void 0 : packagemanager.toLowerCase());
186
198
  if ((packagemanager === null || packagemanager === void 0 ? void 0 : packagemanager.toLowerCase()) === 'CocoaPods'.toLowerCase()) {
187
199
  configWritable.cli.assets.ios.platformTemplateArchive = 'ios-pods-template.tar.gz';
188
200
  configWritable.cli.assets.ios.platformTemplateArchiveAbs = (0, path_1.resolve)(configWritable.cli.assetsDirAbs, configWritable.cli.assets.ios.platformTemplateArchive);
package/dist/ios/build.js CHANGED
@@ -7,15 +7,13 @@ const rimraf_1 = require("rimraf");
7
7
  const common_1 = require("../common");
8
8
  const definitions_1 = require("../definitions");
9
9
  const log_1 = require("../log");
10
- const spm_1 = require("../util/spm");
11
10
  const subprocess_1 = require("../util/subprocess");
12
11
  async function buildiOS(config, buildOptions) {
13
12
  var _a, _b, _c, _d;
14
13
  const theScheme = (_a = buildOptions.scheme) !== null && _a !== void 0 ? _a : 'App';
15
- const packageManager = await (0, spm_1.checkPackageManager)(config);
16
14
  let typeOfBuild;
17
15
  let projectName;
18
- if (packageManager == 'Cocoapods') {
16
+ if ((await config.ios.packageManager) !== 'SPM') {
19
17
  typeOfBuild = '-workspace';
20
18
  projectName = (0, path_1.basename)(await config.ios.nativeXcodeWorkspaceDirAbs);
21
19
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getMajorMinoriOSVersion = exports.getMajoriOSVersion = exports.editProjectSettingsIOS = exports.resolvePlugin = exports.getIOSPlugins = exports.checkCocoaPods = exports.checkBundler = exports.checkIOSPackage = void 0;
3
+ exports.getMajorMinoriOSVersion = exports.getMajoriOSVersion = exports.editProjectSettingsIOS = exports.resolvePlugin = exports.getIOSPlugins = exports.checkCocoaPods = exports.checkBundler = exports.getCommonChecks = exports.checkIOSPackage = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const child_process_1 = require("child_process");
6
6
  const fs_extra_1 = require("fs-extra");
@@ -10,6 +10,7 @@ const common_1 = require("../common");
10
10
  const cordova_1 = require("../cordova");
11
11
  const log_1 = require("../log");
12
12
  const plugin_1 = require("../plugin");
13
+ const spm_1 = require("../util/spm");
13
14
  const subprocess_1 = require("../util/subprocess");
14
15
  async function checkIOSPackage(config) {
15
16
  return (0, common_1.checkCapacitorPlatform)(config, 'ios');
@@ -24,6 +25,28 @@ function execBundler() {
24
25
  return -1;
25
26
  }
26
27
  }
28
+ async function getCommonChecks(config) {
29
+ var _a, _b, _c;
30
+ const checks = [];
31
+ if ((await config.ios.packageManager) === 'bundler') {
32
+ const bundlerCheck = await checkBundler(config);
33
+ if (bundlerCheck) {
34
+ checks.push(() => Promise.resolve(bundlerCheck));
35
+ }
36
+ }
37
+ else if ((await config.ios.packageManager) === 'Cocoapods') {
38
+ checks.push(() => checkCocoaPods(config));
39
+ }
40
+ else if ((await config.ios.packageManager) === 'SPM') {
41
+ const swiftToolsVersion = (_c = (_b = (_a = config.app.extConfig.experimental) === null || _a === void 0 ? void 0 : _a.ios) === null || _b === void 0 ? void 0 : _b.spm) === null || _c === void 0 ? void 0 : _c.swiftToolsVersion;
42
+ if (swiftToolsVersion) {
43
+ checks.push(() => (0, spm_1.checkSwiftToolsVersion)(config, swiftToolsVersion));
44
+ }
45
+ checks.push(() => (0, spm_1.checkPackageTraitsRequirements)(config));
46
+ }
47
+ return checks;
48
+ }
49
+ exports.getCommonChecks = getCommonChecks;
27
50
  async function checkBundler(config) {
28
51
  if (config.cli.os === "mac" /* OS.Mac */) {
29
52
  let bundlerResult = execBundler();
@@ -20,7 +20,7 @@ async function doctorIOS(config) {
20
20
  // check online datebase of common errors
21
21
  // check if www folder is empty (index.html does not exist)
22
22
  try {
23
- await (0, common_1.check)([() => (0, common_2.checkBundler)(config) || (0, common_2.checkCocoaPods)(config), () => (0, common_1.checkWebDir)(config), checkXcode]);
23
+ await (0, common_1.check)([() => (0, common_1.checkWebDir)(config), checkXcode, ...(await (0, common_2.getCommonChecks)(config))]);
24
24
  (0, log_1.logSuccess)('iOS looking great! 👌');
25
25
  }
26
26
  catch (e) {
package/dist/ios/open.js CHANGED
@@ -4,9 +4,8 @@ exports.openIOS = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const open_1 = tslib_1.__importDefault(require("open"));
6
6
  const common_1 = require("../common");
7
- const spm_1 = require("../util/spm");
8
7
  async function openIOS(config) {
9
- if ((await (0, spm_1.checkPackageManager)(config)) == 'SPM') {
8
+ if ((await config.ios.packageManager) == 'SPM') {
10
9
  await (0, open_1.default)(config.ios.nativeXcodeProjDirAbs, { wait: false });
11
10
  }
12
11
  else {
package/dist/ios/run.js CHANGED
@@ -7,7 +7,6 @@ const path_1 = require("path");
7
7
  const colors_1 = tslib_1.__importDefault(require("../colors"));
8
8
  const common_1 = require("../common");
9
9
  const native_run_1 = require("../util/native-run");
10
- const spm_1 = require("../util/spm");
11
10
  const subprocess_1 = require("../util/subprocess");
12
11
  const debug = (0, debug_1.default)('capacitor:ios:run');
13
12
  async function runIOS(config, { target: selectedTarget, targetName: selectedTargetName, targetNameSdkVersion: selectedTargetSdkVersion, scheme: selectedScheme, configuration: selectedConfiguration, }) {
@@ -15,10 +14,10 @@ async function runIOS(config, { target: selectedTarget, targetName: selectedTarg
15
14
  const runScheme = selectedScheme || config.ios.scheme;
16
15
  const configuration = selectedConfiguration || 'Debug';
17
16
  const derivedDataPath = (0, path_1.resolve)(config.ios.platformDirAbs, 'DerivedData', target.id);
18
- const packageManager = await (0, spm_1.checkPackageManager)(config);
17
+ const packageManager = await config.ios.packageManager;
19
18
  let typeOfBuild;
20
19
  let projectName;
21
- if (packageManager == 'Cocoapods') {
20
+ if (packageManager !== 'SPM') {
22
21
  typeOfBuild = '-workspace';
23
22
  projectName = (0, path_1.basename)(await config.ios.nativeXcodeWorkspaceDirAbs);
24
23
  }
@@ -11,6 +11,7 @@ const errors_1 = require("../errors");
11
11
  const log_1 = require("../log");
12
12
  const plugin_1 = require("../plugin");
13
13
  const copy_1 = require("../tasks/copy");
14
+ const migrate_1 = require("../tasks/migrate");
14
15
  const fs_1 = require("../util/fs");
15
16
  const iosplugin_1 = require("../util/iosplugin");
16
17
  const node_1 = require("../util/node");
@@ -40,7 +41,7 @@ async function updatePluginFiles(config, plugins, deployment) {
40
41
  }
41
42
  await (0, cordova_1.handleCordovaPluginsJS)(cordovaPlugins, config, platform);
42
43
  await (0, cordova_1.checkPluginDependencies)(plugins, platform, (_a = config.app.extConfig.cordova) === null || _a === void 0 ? void 0 : _a.failOnUninstalledPlugins);
43
- if ((await (0, spm_1.checkPackageManager)(config)) === 'SPM') {
44
+ if ((await config.ios.packageManager) === 'SPM') {
44
45
  await generateCordovaPackageFiles(cordovaPlugins, config);
45
46
  const validSPMPackages = await (0, spm_1.checkPluginsForPackageSwift)(config, plugins);
46
47
  await (0, spm_1.generatePackageFile)(config, validSPMPackages.concat(cordovaPlugins));
@@ -59,14 +60,132 @@ async function generateCordovaPackageFiles(cordovaPlugins, config) {
59
60
  });
60
61
  }
61
62
  async function generateCordovaPackageFile(p, config) {
63
+ var _a;
62
64
  const iosPlatformVersion = await (0, common_1.getCapacitorPackageVersion)(config, config.ios.name);
65
+ const platformTag = (0, plugin_1.getPluginPlatform)(p, platform);
66
+ if ((_a = platformTag.$) === null || _a === void 0 ? void 0 : _a.package) {
67
+ const packageSwiftPath = (0, path_1.join)(p.rootPath, 'Package.swift');
68
+ let content = await (0, fs_extra_1.readFile)(packageSwiftPath, { encoding: 'utf-8' });
69
+ content = content.replace(`apache`, `ionic-team`).replaceAll(`cordova-ios`, `capacitor-swift-pm`);
70
+ content = (0, migrate_1.setAllStringIn)(content, `url: "https://github.com/ionic-team/capacitor-swift-pm.git",`, `)`, ` from: "${iosPlatformVersion}"`);
71
+ await (0, fs_extra_1.writeFile)(packageSwiftPath, content);
72
+ }
73
+ else {
74
+ await writeGeneratedPackageSwift(p, config, iosPlatformVersion);
75
+ }
76
+ }
77
+ function buildBinaryTargetEntries(p, frameworks) {
78
+ const customXcframeworks = frameworks.filter((f) => f.$.custom === 'true' && f.$.src.endsWith('.xcframework'));
79
+ const customFrameworks = frameworks.filter((f) => f.$.custom === 'true' && f.$.src.endsWith('.framework'));
80
+ if (customFrameworks.length > 0) {
81
+ customFrameworks.forEach((f) => {
82
+ log_1.logger.warn(`${p.id}: custom .framework files are not supported as binaryTarget in SPM (${f.$.src}). Convert to .xcframework for SPM compatibility.`);
83
+ });
84
+ }
85
+ const binaryTargetsText = customXcframeworks
86
+ .map((f) => {
87
+ const name = f.$.src.split('/').pop().replace('.xcframework', '');
88
+ return `,
89
+ .binaryTarget(
90
+ name: "${name}",
91
+ path: "${f.$.src}"
92
+ )`;
93
+ })
94
+ .join('');
95
+ const binaryDepsText = customXcframeworks
96
+ .map((f) => {
97
+ const name = f.$.src.split('/').pop().replace('.xcframework', '');
98
+ return `,\n .target(name: "${name}")`;
99
+ })
100
+ .join('');
101
+ return { binaryTargetsText, binaryDepsText };
102
+ }
103
+ function buildResourcesText(resources) {
104
+ const resourceEntry = [];
105
+ for (const resource of resources) {
106
+ resourceEntry.push(`.copy("resources/${resource.$.src.split('/').pop()}")`);
107
+ }
108
+ return resources.length > 0
109
+ ? `,
110
+ resources: [
111
+ ${resourceEntry.join(',\n ')}
112
+ ]`
113
+ : '';
114
+ }
115
+ function buildCSettingsText(p, sourceFiles) {
116
+ var _a;
117
+ const pluginId = p.id;
118
+ const allFlags = new Set();
119
+ for (const sourceFile of sourceFiles) {
120
+ const flags = (_a = sourceFile.$) === null || _a === void 0 ? void 0 : _a['compiler-flags'];
121
+ if (flags) {
122
+ flags
123
+ .split(/\s+/)
124
+ .map((f) => f.trim())
125
+ .filter((f) => f.length > 0)
126
+ .forEach((f) => allFlags.add(f));
127
+ }
128
+ }
129
+ if (allFlags.size === 0) {
130
+ return '';
131
+ }
132
+ const entries = [];
133
+ const unsupportedFlags = [];
134
+ for (const flag of allFlags) {
135
+ if (flag.startsWith('-D')) {
136
+ const definition = flag.slice(2);
137
+ const eqIndex = definition.indexOf('=');
138
+ if (eqIndex !== -1) {
139
+ const name = definition.slice(0, eqIndex);
140
+ const value = definition.slice(eqIndex + 1);
141
+ entries.push(` .define("${name}", to: "${value}")`);
142
+ }
143
+ else {
144
+ entries.push(` .define("${definition}")`);
145
+ }
146
+ }
147
+ else {
148
+ unsupportedFlags.push(flag);
149
+ }
150
+ }
151
+ if (unsupportedFlags.length > 0) {
152
+ log_1.logger.warn(`${pluginId}: the following compiler flags are not supported in SPM and were ignored: ${unsupportedFlags.join(', ')}. ` +
153
+ `This might cause the plugin to fail to compile.`);
154
+ }
155
+ if (entries.length === 0) {
156
+ return '';
157
+ }
158
+ return `,
159
+ cSettings: [
160
+ ${entries.join(',\n')}
161
+ ]`;
162
+ }
163
+ async function writeGeneratedPackageSwift(p, config, iosPlatformVersion) {
63
164
  const iosVersion = (0, common_2.getMajoriOSVersion)(config);
64
165
  const headerFiles = (0, plugin_1.getPlatformElement)(p, platform, 'header-file');
65
- let headersText = '';
66
- if (headerFiles.length > 0) {
67
- headersText = `,
68
- publicHeadersPath: "."`;
166
+ const headersText = headerFiles.length > 0
167
+ ? `,
168
+ publicHeadersPath: "."`
169
+ : '';
170
+ const resources = (0, plugin_1.getPlatformElement)(p, platform, 'resource-file');
171
+ const sourceFiles = (0, plugin_1.getPlatformElement)(p, platform, 'source-file');
172
+ if (sourceFiles.length === 0 && headerFiles.length === 0 && resources.length === 0) {
173
+ return;
69
174
  }
175
+ const frameworks = (0, plugin_1.getPlatformElement)(p, platform, 'framework');
176
+ const { binaryTargetsText, binaryDepsText } = buildBinaryTargetEntries(p, frameworks);
177
+ const cSettingsText = buildCSettingsText(p, sourceFiles);
178
+ const systemFrameworks = frameworks.filter((f) => !f.$.custom && f.$.src.endsWith('.framework'));
179
+ const hasWeakFrameworks = systemFrameworks.some((f) => f.$.weak === 'true');
180
+ const requiredSystemFrameworks = systemFrameworks.filter((f) => f.$.weak !== 'true');
181
+ const resourcesText = buildResourcesText(resources);
182
+ const libraryTypeText = hasWeakFrameworks ? `\n type: .dynamic,` : '';
183
+ const linkerSettingsText = requiredSystemFrameworks.length > 0
184
+ ? `,
185
+ linkerSettings: [
186
+ ${requiredSystemFrameworks.map((f) => ` .linkedFramework("${f.$.src.replace('.framework', '')}")`).join(',\n')}
187
+ ]`
188
+ : '';
70
189
  const content = `// swift-tools-version: 5.9
71
190
 
72
191
  import PackageDescription
@@ -76,7 +195,7 @@ let package = Package(
76
195
  platforms: [.iOS(.v${iosVersion})],
77
196
  products: [
78
197
  .library(
79
- name: "${p.name}",
198
+ name: "${p.name}",${libraryTypeText}
80
199
  targets: ["${p.name}"]
81
200
  )
82
201
  ],
@@ -87,10 +206,10 @@ let package = Package(
87
206
  .target(
88
207
  name: "${p.name}",
89
208
  dependencies: [
90
- .product(name: "Cordova", package: "capacitor-swift-pm")
209
+ .product(name: "Cordova", package: "capacitor-swift-pm")${binaryDepsText}
91
210
  ],
92
- path: "."${headersText}
93
- )
211
+ path: "."${resourcesText}${headersText}${cSettingsText}${linkerSettingsText}
212
+ )${binaryTargetsText}
94
213
  ]
95
214
  )`;
96
215
  await (0, fs_extra_1.writeFile)((0, path_1.join)(config.ios.cordovaPluginsDirAbs, 'sources', p.name, 'Package.swift'), content);
@@ -110,19 +229,16 @@ async function updatePodfile(config, plugins, deployment) {
110
229
  podfileContent = podfileContent.replace(/(require_relative)[\s\S]+?(@capacitor\/ios\/scripts\/pods_helpers')/, `require_relative '${relativeCapacitoriOSPath}/scripts/pods_helpers'`);
111
230
  await (0, fs_extra_1.writeFile)(podfilePath, podfileContent, { encoding: 'utf-8' });
112
231
  const podPath = await config.ios.podPath;
113
- const useBundler = podPath.startsWith('bundle') && (await (0, subprocess_1.isInstalled)('bundle'));
114
- const podCommandExists = await (0, subprocess_1.isInstalled)('pod');
115
- if (useBundler || podCommandExists) {
116
- if (useBundler) {
117
- await (0, subprocess_1.runCommand)('bundle', ['exec', 'pod', 'install', ...(deployment ? ['--deployment'] : [])], {
118
- cwd: config.ios.nativeProjectDirAbs,
119
- });
120
- }
121
- else {
122
- await (0, subprocess_1.runCommand)(podPath, ['install', ...(deployment ? ['--deployment'] : [])], {
123
- cwd: config.ios.nativeProjectDirAbs,
124
- });
125
- }
232
+ const useBundler = (await config.ios.packageManager) === 'bundler';
233
+ if (useBundler) {
234
+ await (0, subprocess_1.runCommand)('bundle', ['exec', 'pod', 'install', ...(deployment ? ['--deployment'] : [])], {
235
+ cwd: config.ios.nativeProjectDirAbs,
236
+ });
237
+ }
238
+ else if (await (0, subprocess_1.isInstalled)('pod')) {
239
+ await (0, subprocess_1.runCommand)(podPath, ['install', ...(deployment ? ['--deployment'] : [])], {
240
+ cwd: config.ios.nativeProjectDirAbs,
241
+ });
126
242
  }
127
243
  else {
128
244
  log_1.logger.warn('Skipping pod install because CocoaPods is not installed');
@@ -361,13 +477,19 @@ function getLinkerFlags(config) {
361
477
  return '';
362
478
  }
363
479
  async function copyPluginsNativeFiles(config, cordovaPlugins) {
480
+ var _a;
481
+ const isSPM = (await config.ios.packageManager) === 'SPM';
364
482
  for (const p of cordovaPlugins) {
483
+ const platformTag = (0, plugin_1.getPluginPlatform)(p, platform);
484
+ if ((_a = platformTag.$) === null || _a === void 0 ? void 0 : _a.package) {
485
+ continue;
486
+ }
365
487
  const sourceFiles = (0, plugin_1.getPlatformElement)(p, platform, 'source-file');
366
488
  const headerFiles = (0, plugin_1.getPlatformElement)(p, platform, 'header-file');
367
489
  const codeFiles = sourceFiles.concat(headerFiles);
368
490
  const frameworks = (0, plugin_1.getPlatformElement)(p, platform, 'framework');
369
491
  let sourcesFolderName = 'sources';
370
- if ((0, cordova_1.needsStaticPod)(p)) {
492
+ if (!isSPM && (0, cordova_1.needsStaticPod)(p)) {
371
493
  sourcesFolderName += 'static';
372
494
  }
373
495
  const sourcesFolder = (0, path_1.join)(config.ios.cordovaPluginsDirAbs, sourcesFolderName, p.name);
@@ -378,7 +500,7 @@ async function copyPluginsNativeFiles(config, cordovaPlugins) {
378
500
  fileName = 'lib' + fileName;
379
501
  }
380
502
  let destFolder = sourcesFolderName;
381
- if (codeFile.$['compiler-flags'] && codeFile.$['compiler-flags'] === '-fno-objc-arc') {
503
+ if (!isSPM && codeFile.$['compiler-flags'] && codeFile.$['compiler-flags'] === '-fno-objc-arc') {
382
504
  destFolder = 'noarc';
383
505
  }
384
506
  const filePath = (0, plugin_1.getFilePath)(config, p, codeFile.$.src);
@@ -397,8 +519,13 @@ async function copyPluginsNativeFiles(config, cordovaPlugins) {
397
519
  }
398
520
  if (fileContent.includes('[NSBundle bundleForClass:[self class]]') ||
399
521
  fileContent.includes('[NSBundle bundleForClass:[CDVCapture class]]')) {
400
- fileContent = fileContent.replace('[NSBundle bundleForClass:[self class]]', '[NSBundle mainBundle]');
401
- fileContent = fileContent.replace('[NSBundle bundleForClass:[CDVCapture class]]', '[NSBundle mainBundle]');
522
+ const bundleName = isSPM ? 'SWIFTPM_MODULE_BUNDLE' : '[NSBundle mainBundle]';
523
+ fileContent = fileContent.replace('[NSBundle bundleForClass:[self class]]', bundleName);
524
+ fileContent = fileContent.replace('[NSBundle bundleForClass:[CDVCapture class]]', bundleName);
525
+ await (0, fs_extra_1.writeFile)(fileDest, fileContent, { encoding: 'utf-8' });
526
+ }
527
+ if (isSPM && fileContent.includes('[NSBundle mainBundle] URLForResource')) {
528
+ fileContent = fileContent.replace('[NSBundle mainBundle] URLForResource', 'SWIFTPM_MODULE_BUNDLE URLForResource');
402
529
  await (0, fs_extra_1.writeFile)(fileDest, fileContent, { encoding: 'utf-8' });
403
530
  }
404
531
  if (fileContent.includes('[self.webView superview]') || fileContent.includes('self.webView.superview')) {
@@ -412,7 +539,8 @@ async function copyPluginsNativeFiles(config, cordovaPlugins) {
412
539
  const resourceFiles = (0, plugin_1.getPlatformElement)(p, platform, 'resource-file');
413
540
  for (const resourceFile of resourceFiles) {
414
541
  const fileName = resourceFile.$.src.split('/').pop();
415
- await (0, fs_extra_1.copy)((0, plugin_1.getFilePath)(config, p, resourceFile.$.src), (0, path_1.join)(config.ios.cordovaPluginsDirAbs, 'resources', fileName));
542
+ const rootResFolder = isSPM ? sourcesFolder : config.ios.cordovaPluginsDirAbs;
543
+ await (0, fs_extra_1.copy)((0, plugin_1.getFilePath)(config, p, resourceFile.$.src), (0, path_1.join)(rootResFolder, 'resources', fileName));
416
544
  }
417
545
  for (const framework of frameworks) {
418
546
  if (framework.$.custom && framework.$.custom === 'true') {
package/dist/tasks/add.js CHANGED
@@ -47,7 +47,7 @@ async function addCommand(config, selectedPlatformName) {
47
47
  `${colors_1.default.strong('WARNING')}: Your native project will be completely removed.`);
48
48
  }
49
49
  try {
50
- await (0, common_2.check)([() => (0, common_2.checkPackage)(), () => (0, common_2.checkAppConfig)(config), ...addChecks(config, platformName)]);
50
+ await (0, common_2.check)([() => (0, common_2.checkPackage)(), () => (0, common_2.checkAppConfig)(config), ...(await getAddChecks(config, platformName))]);
51
51
  await doAdd(config, platformName);
52
52
  await editPlatforms(config, platformName);
53
53
  if (await (0, fs_extra_1.pathExists)(config.app.webDirAbs)) {
@@ -76,9 +76,9 @@ function printNextSteps(platformName) {
76
76
  (0, log_1.logSuccess)(`${colors_1.default.strong(platformName)} platform added!`);
77
77
  log_1.output.write(`Follow the Developer Workflow guide to get building:\n${colors_1.default.strong(`https://capacitorjs.com/docs/basics/workflow`)}\n`);
78
78
  }
79
- function addChecks(config, platformName) {
79
+ async function getAddChecks(config, platformName) {
80
80
  if (platformName === config.ios.name) {
81
- return [() => (0, common_3.checkIOSPackage)(config), () => (0, common_3.checkBundler)(config) || (0, common_3.checkCocoaPods)(config)];
81
+ return [() => (0, common_3.checkIOSPackage)(config), ...(await (0, common_3.getCommonChecks)(config))];
82
82
  }
83
83
  else if (platformName === config.android.name) {
84
84
  return [() => (0, common_1.checkAndroidPackage)(config)];
@@ -1,19 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.migrateToSPM = void 0;
4
+ const common_1 = require("../common");
4
5
  const errors_1 = require("../errors");
6
+ const common_2 = require("../ios/common");
5
7
  const log_1 = require("../log");
6
8
  const spm_1 = require("../util/spm");
7
9
  const update_1 = require("./update");
8
10
  async function migrateToSPM(config) {
9
- if ((await (0, spm_1.checkPackageManager)(config)) == 'SPM') {
11
+ if ((await config.ios.packageManager) == 'SPM') {
10
12
  (0, errors_1.fatal)('Capacitor project is already using SPM, exiting.');
11
13
  }
14
+ await (0, common_1.check)(await (0, common_2.getCommonChecks)(config));
12
15
  await (0, spm_1.extractSPMPackageDirectory)(config);
13
16
  await (0, spm_1.runCocoapodsDeintegrate)(config);
14
17
  await (0, spm_1.removeCocoapodsFiles)(config);
15
18
  await (0, spm_1.addInfoPlistDebugIfNeeded)(config);
16
- await (0, update_1.update)(config, 'ios', true);
19
+ const configWritable = config;
20
+ configWritable.ios.packageManager = Promise.resolve('SPM');
21
+ await (0, update_1.update)(configWritable, 'ios', false);
17
22
  log_1.logger.info('To complete migration follow the manual steps at https://capacitorjs.com/docs/ios/spm#using-our-migration-tool');
18
23
  }
19
24
  exports.migrateToSPM = migrateToSPM;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.migrateCommand = void 0;
3
+ 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");
@@ -12,7 +12,6 @@ const errors_1 = require("../errors");
12
12
  const common_2 = require("../ios/common");
13
13
  const log_1 = require("../log");
14
14
  const fs_1 = require("../util/fs");
15
- const spm_1 = require("../util/spm");
16
15
  const subprocess_1 = require("../util/subprocess");
17
16
  const template_1 = require("../util/template");
18
17
  // eslint-disable-next-line prefer-const
@@ -162,7 +161,7 @@ async function migrateCommand(config, noprompt, packagemanager) {
162
161
  await (0, common_1.runTask)(`Migrating deployment target to ${iOSVersion}.0.`, () => {
163
162
  return updateFile(config, (0, path_1.join)(config.ios.nativeXcodeProjDirAbs, 'project.pbxproj'), 'IPHONEOS_DEPLOYMENT_TARGET = ', ';', `${iOSVersion}.0`);
164
163
  });
165
- if ((await (0, spm_1.checkPackageManager)(config)) === 'Cocoapods') {
164
+ if ((await config.ios.packageManager) !== 'SPM') {
166
165
  // Update Podfile
167
166
  await (0, common_1.runTask)(`Migrating Podfile to ${iOSVersion}.0.`, () => {
168
167
  return updateFile(config, (0, path_1.join)(config.ios.nativeProjectDirAbs, 'Podfile'), `platform :ios, '`, `'`, `${iOSVersion}.0`);
@@ -545,6 +544,7 @@ function setAllStringIn(data, start, end, replacement) {
545
544
  }
546
545
  return result;
547
546
  }
547
+ exports.setAllStringIn = setAllStringIn;
548
548
  async function updateAndroidManifest(filename) {
549
549
  const txt = readFile(filename);
550
550
  if (!txt) {
package/dist/tasks/run.js CHANGED
@@ -14,9 +14,11 @@ const livereload_1 = require("../util/livereload");
14
14
  const native_run_1 = require("../util/native-run");
15
15
  const sync_1 = require("./sync");
16
16
  async function runCommand(config, selectedPlatformName, options) {
17
- var _a, _b, _c, _d;
17
+ var _a, _b, _c;
18
18
  options.host = (_b = (_a = options.host) !== null && _a !== void 0 ? _a : livereload_1.CapLiveReloadHelper.getIpAddress()) !== null && _b !== void 0 ? _b : 'localhost';
19
- options.port = (_c = options.port) !== null && _c !== void 0 ? _c : '3000';
19
+ if (!options.port) {
20
+ options.port = '3000';
21
+ }
20
22
  if (selectedPlatformName && !(await (0, common_1.isValidPlatform)(selectedPlatformName))) {
21
23
  const platformDir = (0, common_1.resolvePlatform)(config, selectedPlatformName);
22
24
  if (platformDir) {
@@ -78,13 +80,13 @@ async function runCommand(config, selectedPlatformName, options) {
78
80
  }
79
81
  })
80
82
  .then(() => process.exit());
81
- log_1.logger.info(`App running with live reload listing for: http://${options.host}:${options.port}. Press Ctrl+C to quit.`);
83
+ log_1.logger.info(`App running with live reload listing for: ${options.https ? 'https' : 'http'}://${options.host}${options.port ? `:${options.port}` : ''}. Press Ctrl+C to quit.`);
82
84
  await sleepForever();
83
85
  }
84
86
  }
85
87
  catch (e) {
86
88
  if (!(0, errors_1.isFatal)(e)) {
87
- (0, errors_1.fatal)((_d = e.stack) !== null && _d !== void 0 ? _d : e);
89
+ (0, errors_1.fatal)((_c = e.stack) !== null && _c !== void 0 ? _c : e);
88
90
  }
89
91
  throw e;
90
92
  }
@@ -13,7 +13,7 @@ function walkDirectory(dirPath) {
13
13
  }
14
14
  else {
15
15
  const mapFile = (0, path_1.join)(dirPath, `${file}.map`);
16
- if ((0, path_1.extname)(file) === '.js' && (0, fs_extra_1.existsSync)(mapFile)) {
16
+ if (((0, path_1.extname)(file) === '.js' || (0, path_1.extname)(file) === '.css') && (0, fs_extra_1.existsSync)(mapFile)) {
17
17
  const bufMap = (0, fs_extra_1.readFileSync)(mapFile).toString('base64');
18
18
  const bufFile = (0, fs_extra_1.readFileSync)(targetFile, 'utf8');
19
19
  const result = bufFile.replace(`sourceMappingURL=${file}.map`, 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + bufMap);
@@ -25,7 +25,7 @@ async function syncCommand(config, selectedPlatformName, deployment, inline = fa
25
25
  const then = +new Date();
26
26
  const platforms = await (0, common_1.selectPlatforms)(config, selectedPlatformName);
27
27
  try {
28
- await (0, common_1.check)([() => (0, common_1.checkPackage)(), () => (0, common_1.checkWebDir)(config), ...(0, update_1.updateChecks)(config, platforms)]);
28
+ await (0, common_1.check)([() => (0, common_1.checkPackage)(), () => (0, common_1.checkWebDir)(config), ...(await (0, update_1.addUpdateChecks)(config, platforms))]);
29
29
  await (0, promise_1.allSerial)(platforms.map((platformName) => () => sync(config, platformName, deployment, inline)));
30
30
  const now = +new Date();
31
31
  const diff = (now - then) / 1000;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.update = exports.updateChecks = exports.updateCommand = void 0;
3
+ exports.update = exports.updateChecks = exports.addUpdateChecks = exports.updateCommand = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const update_1 = require("../android/update");
6
6
  const colors_1 = tslib_1.__importDefault(require("../colors"));
@@ -25,7 +25,7 @@ async function updateCommand(config, selectedPlatformName, deployment) {
25
25
  const then = +new Date();
26
26
  const platforms = await (0, common_1.selectPlatforms)(config, selectedPlatformName);
27
27
  try {
28
- await (0, common_1.check)([() => (0, common_1.checkPackage)(), ...updateChecks(config, platforms)]);
28
+ await (0, common_1.check)([() => (0, common_1.checkPackage)(), ...(await addUpdateChecks(config, platforms))]);
29
29
  await (0, promise_1.allSerial)(platforms.map((platformName) => async () => await update(config, platformName, deployment)));
30
30
  const now = +new Date();
31
31
  const diff = (now - then) / 1000;
@@ -40,6 +40,31 @@ async function updateCommand(config, selectedPlatformName, deployment) {
40
40
  }
41
41
  }
42
42
  exports.updateCommand = updateCommand;
43
+ async function addUpdateChecks(config, platforms) {
44
+ let checks = [];
45
+ for (const platformName of platforms) {
46
+ if (platformName === config.ios.name) {
47
+ checks = await (0, common_2.getCommonChecks)(config);
48
+ }
49
+ else if (platformName === config.android.name) {
50
+ continue;
51
+ }
52
+ else if (platformName === config.web.name) {
53
+ continue;
54
+ }
55
+ else {
56
+ throw `Platform ${platformName} is not valid.`;
57
+ }
58
+ }
59
+ return checks;
60
+ }
61
+ exports.addUpdateChecks = addUpdateChecks;
62
+ /**
63
+ * @deprecated use addUpdateChecks
64
+ * @param config
65
+ * @param platforms
66
+ * @returns
67
+ */
43
68
  function updateChecks(config, platforms) {
44
69
  const checks = [];
45
70
  for (const platformName of platforms) {
@@ -129,8 +129,9 @@ class CapLiveReload {
129
129
  const configJson = (0, fs_extra_1.readJSONSync)(capConfigPath);
130
130
  this.configJsonToRevertTo.json = JSON.stringify(configJson, null, 2);
131
131
  this.configJsonToRevertTo.platformPath = capConfigPath;
132
- const url = `http://${options.host}:${options.port}`;
132
+ const url = `${options.https ? 'https' : 'http'}://${options.host}${options.port ? `:${options.port}` : ''}`;
133
133
  configJson.server = {
134
+ ...configJson.server,
134
135
  url,
135
136
  };
136
137
  (0, fs_extra_1.writeJSONSync)(capConfigPath, configJson, { spaces: '\t' });
package/dist/util/spm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.addInfoPlistDebugIfNeeded = exports.runCocoapodsDeintegrate = exports.generatePackageText = exports.removeCocoapodsFiles = exports.extractSPMPackageDirectory = exports.checkPluginsForPackageSwift = exports.generatePackageFile = exports.findPackageSwiftFile = exports.checkPackageManager = void 0;
3
+ exports.checkPackageTraitsRequirements = exports.checkSwiftToolsVersion = exports.addInfoPlistDebugIfNeeded = exports.runCocoapodsDeintegrate = exports.generatePackageText = exports.removeCocoapodsFiles = exports.extractSPMPackageDirectory = exports.checkPluginsForPackageSwift = exports.generatePackageFile = exports.findPackageSwiftFile = exports.checkPackageManager = void 0;
4
4
  const fs_extra_1 = require("fs-extra");
5
5
  const os_1 = require("os");
6
6
  const path_1 = require("path");
@@ -12,6 +12,11 @@ const common_2 = require("../ios/common");
12
12
  const log_1 = require("../log");
13
13
  const plugin_1 = require("../plugin");
14
14
  const subprocess_1 = require("../util/subprocess");
15
+ /**
16
+ * @deprecated use config.ios.packageManager
17
+ * @param config
18
+ * @returns 'Cocoapods' | 'SPM'
19
+ */
15
20
  async function checkPackageManager(config) {
16
21
  const iosDirectory = config.ios.nativeProjectDirAbs;
17
22
  if ((0, fs_extra_1.existsSync)((0, path_1.resolve)(iosDirectory, 'CapApp-SPM'))) {
@@ -40,12 +45,12 @@ exports.generatePackageFile = generatePackageFile;
40
45
  async function checkPluginsForPackageSwift(config, plugins) {
41
46
  const iOSCapacitorPlugins = plugins.filter((p) => (0, plugin_1.getPluginType)(p, 'ios') === 0 /* PluginType.Core */);
42
47
  const packageSwiftPluginList = await pluginsWithPackageSwift(iOSCapacitorPlugins);
43
- if (plugins.length == packageSwiftPluginList.length) {
44
- log_1.logger.debug(`Found ${plugins.length} iOS plugins, ${packageSwiftPluginList.length} have a Package.swift file`);
45
- log_1.logger.info('All plugins have a Package.swift file and will be included in Package.swift');
48
+ if (iOSCapacitorPlugins.length == packageSwiftPluginList.length) {
49
+ log_1.logger.debug(`Found ${iOSCapacitorPlugins.length} Capacitor iOS plugins, ${packageSwiftPluginList.length} have a Package.swift file`);
50
+ log_1.logger.info('All Capacitor plugins have a Package.swift file and will be included in Package.swift');
46
51
  }
47
52
  else {
48
- log_1.logger.warn('Some installed packages are not compatable with SPM');
53
+ log_1.logger.warn('Some installed Capacitor plugins are not compatible with SPM');
49
54
  }
50
55
  return packageSwiftPluginList;
51
56
  }
@@ -79,10 +84,12 @@ async function removeCocoapodsFiles(config) {
79
84
  }
80
85
  exports.removeCocoapodsFiles = removeCocoapodsFiles;
81
86
  async function generatePackageText(config, plugins) {
82
- var _a, _b, _c;
87
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
83
88
  const iosPlatformVersion = await (0, common_1.getCapacitorPackageVersion)(config, config.ios.name);
84
- const iosVersion = (0, common_2.getMajorMinoriOSVersion)(config);
85
- let packageSwiftText = `// swift-tools-version: 5.9
89
+ const iosVersion = (0, common_2.getMajoriOSVersion)(config);
90
+ const packageTraits = (_d = (_c = (_b = (_a = config.app.extConfig.experimental) === null || _a === void 0 ? void 0 : _a.ios) === null || _b === void 0 ? void 0 : _b.spm) === null || _c === void 0 ? void 0 : _c.packageTraits) !== null && _d !== void 0 ? _d : {};
91
+ const swiftToolsVersion = (_h = (_g = (_f = (_e = config.app.extConfig.experimental) === null || _e === void 0 ? void 0 : _e.ios) === null || _f === void 0 ? void 0 : _f.spm) === null || _g === void 0 ? void 0 : _g.swiftToolsVersion) !== null && _h !== void 0 ? _h : '5.9';
92
+ let packageSwiftText = `// swift-tools-version: ${swiftToolsVersion}
86
93
  import PackageDescription
87
94
 
88
95
  // DO NOT MODIFY THIS FILE - managed by Capacitor CLI commands
@@ -98,11 +105,32 @@ let package = Package(
98
105
  .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", exact: "${iosPlatformVersion}")`;
99
106
  for (const plugin of plugins) {
100
107
  if ((0, plugin_1.getPluginType)(plugin, config.ios.name) === 1 /* PluginType.Cordova */) {
101
- packageSwiftText += `,\n .package(name: "${plugin.name}", path: "../../capacitor-cordova-ios-plugins/sources/${plugin.name}")`;
108
+ const platformTag = (0, plugin_1.getPluginPlatform)(plugin, config.ios.name);
109
+ if ((_j = platformTag.$) === null || _j === void 0 ? void 0 : _j.package) {
110
+ const relPath = (0, path_1.relative)(config.ios.nativeXcodeProjDirAbs, plugin.rootPath);
111
+ packageSwiftText += `,\n .package(name: "${plugin.id}", path: "${relPath}")`;
112
+ }
113
+ else {
114
+ const sourceFiles = (0, plugin_1.getPlatformElement)(plugin, config.ios.name, 'source-file');
115
+ const headerFiles = (0, plugin_1.getPlatformElement)(plugin, config.ios.name, 'header-file');
116
+ if (sourceFiles.length === 0 && headerFiles.length === 0) {
117
+ continue;
118
+ }
119
+ packageSwiftText += `,\n .package(name: "${plugin.name}", path: "../../capacitor-cordova-ios-plugins/sources/${plugin.name}")`;
120
+ }
102
121
  }
103
122
  else {
104
123
  const relPath = (0, path_1.relative)(config.ios.nativeXcodeProjDirAbs, plugin.rootPath);
105
- packageSwiftText += `,\n .package(name: "${(_a = plugin.ios) === null || _a === void 0 ? void 0 : _a.name}", path: "${relPath}")`;
124
+ const traits = packageTraits[plugin.id];
125
+ const traitsSuffix = (traits === null || traits === void 0 ? void 0 : traits.length)
126
+ ? `, traits: [${traits
127
+ .map((t) => {
128
+ // Any trait is written with quotes, with the exception of .defaults
129
+ return /^\.?defaults?$/i.test(t) ? '.defaults' : `"${t}"`;
130
+ })
131
+ .join(', ')}]`
132
+ : '';
133
+ packageSwiftText += `,\n .package(name: "${(_k = plugin.ios) === null || _k === void 0 ? void 0 : _k.name}", path: "${relPath}"${traitsSuffix})`;
106
134
  }
107
135
  }
108
136
  packageSwiftText += `
@@ -114,7 +142,21 @@ let package = Package(
114
142
  .product(name: "Capacitor", package: "capacitor-swift-pm"),
115
143
  .product(name: "Cordova", package: "capacitor-swift-pm")`;
116
144
  for (const plugin of plugins) {
117
- 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}")`;
145
+ let pluginText = `,\n .product(name: "${(_l = plugin.ios) === null || _l === void 0 ? void 0 : _l.name}", package: "${(_m = plugin.ios) === null || _m === void 0 ? void 0 : _m.name}")`;
146
+ if ((0, plugin_1.getPluginType)(plugin, config.ios.name) === 1 /* PluginType.Cordova */) {
147
+ const platformTag = (0, plugin_1.getPluginPlatform)(plugin, config.ios.name);
148
+ if ((_o = platformTag.$) === null || _o === void 0 ? void 0 : _o.package) {
149
+ pluginText = `,\n .product(name: "${plugin.id}", package: "${plugin.id}")`;
150
+ }
151
+ else {
152
+ const sourceFiles = (0, plugin_1.getPlatformElement)(plugin, config.ios.name, 'source-file');
153
+ const headerFiles = (0, plugin_1.getPlatformElement)(plugin, config.ios.name, 'header-file');
154
+ if (sourceFiles.length === 0 && headerFiles.length === 0) {
155
+ pluginText = '';
156
+ }
157
+ }
158
+ }
159
+ packageSwiftText += pluginText;
118
160
  }
119
161
  packageSwiftText += `
120
162
  ]
@@ -128,25 +170,18 @@ exports.generatePackageText = generatePackageText;
128
170
  async function runCocoapodsDeintegrate(config) {
129
171
  const podPath = await config.ios.podPath;
130
172
  const projectFileName = config.ios.nativeXcodeProjDirAbs;
131
- const useBundler = podPath.startsWith('bundle') && (await (0, subprocess_1.isInstalled)('bundle'));
132
- const podCommandExists = await (0, subprocess_1.isInstalled)('pod');
133
- if (useBundler)
134
- log_1.logger.info('Found bundler, using it to run CocoaPods.');
173
+ const useBundler = (await config.ios.packageManager) === 'bundler';
135
174
  log_1.logger.info('Running pod deintegrate on project ' + projectFileName);
136
- if (useBundler || podCommandExists) {
137
- if (useBundler) {
138
- await (0, subprocess_1.runCommand)('bundle', ['exec', 'pod', 'deintegrate', projectFileName], {
139
- cwd: config.ios.nativeProjectDirAbs,
140
- });
141
- }
142
- else {
143
- await (0, subprocess_1.runCommand)(podPath, ['deintegrate', projectFileName], {
144
- cwd: config.ios.nativeProjectDirAbs,
145
- });
146
- }
175
+ if (useBundler) {
176
+ log_1.logger.info('Found bundler, using it to run CocoaPods.');
177
+ await (0, subprocess_1.runCommand)('bundle', ['exec', 'pod', 'deintegrate', projectFileName], {
178
+ cwd: config.ios.nativeProjectDirAbs,
179
+ });
147
180
  }
148
181
  else {
149
- log_1.logger.warn('Skipping pod deintegrate because CocoaPods is not installed - migration will be incomplete');
182
+ await (0, subprocess_1.runCommand)(podPath, ['deintegrate', projectFileName], {
183
+ cwd: config.ios.nativeProjectDirAbs,
184
+ });
150
185
  }
151
186
  }
152
187
  exports.runCocoapodsDeintegrate = runCocoapodsDeintegrate;
@@ -171,6 +206,40 @@ async function addInfoPlistDebugIfNeeded(config) {
171
206
  }
172
207
  }
173
208
  exports.addInfoPlistDebugIfNeeded = addInfoPlistDebugIfNeeded;
209
+ async function checkSwiftToolsVersion(config, version) {
210
+ if (!version) {
211
+ return null;
212
+ }
213
+ const swiftToolsVersionRegex = /^[0-9]+\.[0-9]+(\.[0-9]+)?$/;
214
+ if (!swiftToolsVersionRegex.test(version)) {
215
+ return (`Invalid Swift tools version: "${version}".\n` +
216
+ `The Swift tools version must be in major.minor or major.minor.patch format (e.g., "5.9", "6.0", "5.9.2").`);
217
+ }
218
+ return null;
219
+ }
220
+ exports.checkSwiftToolsVersion = checkSwiftToolsVersion;
221
+ async function checkPackageTraitsRequirements(config) {
222
+ var _a, _b, _c, _d, _e, _f;
223
+ const packageTraits = (_c = (_b = (_a = config.app.extConfig.experimental) === null || _a === void 0 ? void 0 : _a.ios) === null || _b === void 0 ? void 0 : _b.spm) === null || _c === void 0 ? void 0 : _c.packageTraits;
224
+ const swiftToolsVersion = (_f = (_e = (_d = config.app.extConfig.experimental) === null || _d === void 0 ? void 0 : _d.ios) === null || _e === void 0 ? void 0 : _e.spm) === null || _f === void 0 ? void 0 : _f.swiftToolsVersion;
225
+ const hasPackageTraits = packageTraits && Object.keys(packageTraits).some((key) => { var _a; return ((_a = packageTraits[key]) === null || _a === void 0 ? void 0 : _a.length) > 0; });
226
+ if (!hasPackageTraits) {
227
+ return null;
228
+ }
229
+ if (!swiftToolsVersion) {
230
+ return (`Package traits require an explicit Swift tools version of 6.1 or higher.\n` +
231
+ `Set experimental.ios.spm.swiftToolsVersion to '6.1' or higher in your Capacitor configuration.`);
232
+ }
233
+ const versionParts = swiftToolsVersion.split('.').map((part) => parseInt(part, 10));
234
+ const major = versionParts[0] || 0;
235
+ const minor = versionParts[1] || 0;
236
+ if (major < 6 || (major === 6 && minor < 1)) {
237
+ return (`Package traits require Swift tools version 6.1 or higher, but "${swiftToolsVersion}" was specified.\n` +
238
+ `Update experimental.ios.spm.swiftToolsVersion to '6.1' or higher in your Capacitor configuration.`);
239
+ }
240
+ return null;
241
+ }
242
+ exports.checkPackageTraitsRequirements = checkPackageTraitsRequirements;
174
243
  // Private Functions
175
244
  async function pluginsWithPackageSwift(plugins) {
176
245
  const pluginList = [];
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.extractTemplate = void 0;
4
- const tslib_1 = require("tslib");
5
4
  const fs_extra_1 = require("fs-extra");
6
- const tar_1 = tslib_1.__importDefault(require("tar"));
5
+ const tar_1 = require("tar");
7
6
  async function extractTemplate(src, dir) {
8
7
  await (0, fs_extra_1.mkdirp)(dir);
9
- await tar_1.default.extract({ file: src, cwd: dir });
8
+ await (0, tar_1.extract)({ file: src, cwd: dir });
10
9
  }
11
10
  exports.extractTemplate = extractTemplate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor-plus/cli",
3
- "version": "8.0.7",
3
+ "version": "8.3.3",
4
4
  "description": "Capacitor+: Enhanced Capacitor with automated upstream sync - Cross-platform apps with JavaScript and the web",
5
5
  "homepage": "https://capgo.app/docs/plugins/capacitor-plus/",
6
6
  "author": "Capgo Team <support@capgo.app> (https://capgo.app)",
@@ -58,7 +58,7 @@
58
58
  "prompts": "^2.4.2",
59
59
  "rimraf": "^6.0.1",
60
60
  "semver": "^7.6.3",
61
- "tar": "^6.1.11",
61
+ "tar": "^7.5.3",
62
62
  "tslib": "^2.8.1",
63
63
  "xml2js": "^0.6.2"
64
64
  },
@@ -69,7 +69,6 @@
69
69
  "@types/plist": "^3.0.5",
70
70
  "@types/prompts": "^2.4.9",
71
71
  "@types/semver": "^7.5.8",
72
- "@types/tar": "^6.1.1",
73
72
  "@types/tmp": "^0.2.6",
74
73
  "@types/xml2js": "0.4.5",
75
74
  "jest": "^29.7.0",