@capacitor/cli 9.0.0-alpha.8 → 9.0.0-beta.0

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,68 +1,77 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.patchPackageSwiftDeploymentTarget = exports.findCapacitorDependencyVersion = exports.rewriteCapacitorDependency = exports.renderCapacitorPackage = exports.resolveCapacitorPackage = void 0;
3
+ exports.patchPackageSwiftDeploymentTarget = exports.findCapacitorDependencyVersion = exports.rewriteCapacitorDependency = exports.renderCapacitorPackage = exports.resolveCapacitorPackagePath = exports.CORDOVA_PRODUCT = exports.SOURCE_PACKAGE_IDENTITY = void 0;
4
4
  const fs_extra_1 = require("fs-extra");
5
5
  const path_1 = require("path");
6
- const semver_1 = require("semver");
7
- const common_1 = require("../common");
8
6
  const errors_1 = require("../errors");
9
7
  const fs_1 = require("./fs");
10
- /** Capacitor 9 and up builds the iOS platform from source out of the main repo. */
11
- const SOURCE_PACKAGE_MAJOR = 9;
8
+ const node_1 = require("./node");
12
9
  const SOURCE_PACKAGE_URL = 'https://github.com/ionic-team/capacitor';
13
- const SOURCE_PACKAGE_IDENTITY = 'capacitor';
14
- /** Before Capacitor 9 the platform was consumed as a prebuilt xcframework from a separate repo. */
15
- const BINARY_PACKAGE_URL = 'https://github.com/ionic-team/capacitor-swift-pm.git';
10
+ exports.SOURCE_PACKAGE_IDENTITY = 'capacitor';
11
+ const SOURCE_PACKAGE_NAME = new RegExp(`name:\\s*"${exports.SOURCE_PACKAGE_IDENTITY}"`);
12
+ /** Product providing the Cordova compatibility layer. */
13
+ exports.CORDOVA_PRODUCT = 'CapacitorCordova';
14
+ /** The npm package the Swift package ships inside. */
15
+ const PLATFORM_PACKAGE = '@capacitor/ios';
16
+ /** Plugins published before Capacitor 9 depend on the platform as a prebuilt xcframework. */
16
17
  const BINARY_PACKAGE_IDENTITY = 'capacitor-swift-pm';
17
- const ENV_OVERRIDE = 'CAPACITOR_IOS_PACKAGE';
18
- const REQUIREMENT_KEYS = ['path', 'branch', 'revision', 'exact', 'from'];
19
18
  /**
20
- * Resolves which Capacitor Swift package generated `Package.swift` files should depend on.
19
+ * Resolves the Capacitor Swift package generated `Package.swift` files should depend on: the
20
+ * `@capacitor/ios` npm already installed in the app, which ships the package alongside the sources.
21
21
  *
22
- * Precedence, most specific first:
23
- * 1. the `CAPACITOR_IOS_PACKAGE` environment variable
24
- * 2. `experimental.ios.spm.capacitorPackage` in the Capacitor config
25
- * 3. the git tag matching the installed `@capacitor/ios` version
26
- *
27
- * The environment variable deliberately outranks the config file so a checkout can be pointed at a
28
- * local or branch build without editing (and risking committing) the app's configuration.
22
+ * Resolving from `node_modules` keeps the native runtime and the `@capacitor/core` bridge it is
23
+ * versioned against on the same release, with no git tag to line up against the npm version. It
24
+ * also carries no version for the app package and any generated plugin packages to disagree about.
25
+ */
26
+ async function resolveCapacitorPackagePath(config) {
27
+ const packageJsonPath = (0, node_1.resolveNode)(config.app.rootDir, PLATFORM_PACKAGE, 'package.json');
28
+ if (!packageJsonPath) {
29
+ (0, errors_1.fatal)(`Unable to find node_modules/${PLATFORM_PACKAGE}.\nAre you sure ${PLATFORM_PACKAGE} is installed?`);
30
+ }
31
+ const absolutePath = installDirectory((0, path_1.dirname)(packageJsonPath), config.app.rootDir);
32
+ if (!(0, fs_extra_1.existsSync)((0, path_1.resolve)(absolutePath, 'Package.swift'))) {
33
+ (0, errors_1.fatal)(`The installed ${PLATFORM_PACKAGE} has no Package.swift (looked in ${absolutePath}).\n` +
34
+ `Early 9.0.0 alphas did not ship one; update ${PLATFORM_PACKAGE} to build with SPM.`);
35
+ }
36
+ return absolutePath;
37
+ }
38
+ exports.resolveCapacitorPackagePath = resolveCapacitorPackagePath;
39
+ /**
40
+ * Trades the resolved location for the `node_modules` entry that leads to it, when there is one.
29
41
  *
30
- * `legacyRequirement` only applies to pre-9 projects, where it preserves each caller's existing
31
- * requirement style. Source-based projects always pin `exact`, because the app package and any
32
- * generated plugin packages must agree: a prerelease such as `9.0.0-alpha.6` does not satisfy a
33
- * `from:` range, so mixing the two styles fails to resolve.
42
+ * Node resolves symlinks away, so a linked or `file:`-installed package resolves to wherever it
43
+ * actually lives — an absolute path outside the app, which the generated `Package.swift` is
44
+ * committed with. The entry inside the project stays valid on every machine.
34
45
  */
35
- async function resolveCapacitorPackage(config, legacyRequirement = 'exact') {
36
- var _a, _b;
37
- const version = await (0, common_1.getCapacitorPackageVersion)(config, config.ios.name);
38
- if ((0, semver_1.major)(version) < SOURCE_PACKAGE_MAJOR) {
39
- return {
40
- identity: BINARY_PACKAGE_IDENTITY,
41
- cordovaProduct: 'Cordova',
42
- sourceBased: false,
43
- url: BINARY_PACKAGE_URL,
44
- requirement: { kind: legacyRequirement, version },
45
- };
46
+ function installDirectory(resolved, rootDir) {
47
+ const real = realPath(resolved);
48
+ if (!real) {
49
+ return resolved;
50
+ }
51
+ for (let dir = (0, path_1.resolve)(rootDir);; dir = (0, path_1.dirname)(dir)) {
52
+ const candidate = (0, path_1.resolve)(dir, 'node_modules', PLATFORM_PACKAGE);
53
+ if (realPath(candidate) === real) {
54
+ return candidate;
55
+ }
56
+ if ((0, path_1.dirname)(dir) === dir) {
57
+ return resolved;
58
+ }
46
59
  }
47
- const override = resolveOverride(config);
48
- return {
49
- identity: SOURCE_PACKAGE_IDENTITY,
50
- cordovaProduct: 'CapacitorCordova',
51
- sourceBased: true,
52
- url: (_a = override === null || override === void 0 ? void 0 : override.url) !== null && _a !== void 0 ? _a : SOURCE_PACKAGE_URL,
53
- requirement: (_b = override === null || override === void 0 ? void 0 : override.requirement) !== null && _b !== void 0 ? _b : { kind: 'exact', version },
54
- };
55
60
  }
56
- exports.resolveCapacitorPackage = resolveCapacitorPackage;
57
- /** Renders the `.package(...)` entry, with any path made relative to the file being written. */
58
- function renderCapacitorPackage(pkg, fromDir) {
59
- if (pkg.requirement.kind === 'path') {
60
- const relPath = (0, fs_1.convertToUnixPath)((0, path_1.relative)(fromDir, pkg.requirement.absolutePath));
61
- // Pin the identity: for a path dependency SPM would otherwise derive it from the directory
62
- // name, which breaks `.product(package:)` when the checkout is not named "capacitor".
63
- return `.package(name: "${pkg.identity}", path: "${relPath}")`;
61
+ function realPath(path) {
62
+ try {
63
+ return (0, fs_extra_1.realpathSync)(path);
64
64
  }
65
- return `.package(url: "${pkg.url}", ${renderRequirement(pkg.requirement)})`;
65
+ catch {
66
+ return undefined;
67
+ }
68
+ }
69
+ /** Renders the `.package(...)` entry, with the path made relative to the file being written. */
70
+ function renderCapacitorPackage(absolutePath, fromDir) {
71
+ const relPath = (0, fs_1.convertToUnixPath)((0, path_1.relative)(fromDir, absolutePath));
72
+ // Pin the identity: for a path dependency SPM would otherwise derive it from the directory
73
+ // name, which breaks `.product(package:)` when the checkout is not named "capacitor".
74
+ return `.package(name: "${exports.SOURCE_PACKAGE_IDENTITY}", path: "${relPath}")`;
66
75
  }
67
76
  exports.renderCapacitorPackage = renderCapacitorPackage;
68
77
  /**
@@ -73,12 +82,9 @@ exports.renderCapacitorPackage = renderCapacitorPackage;
73
82
  * `Capacitor` product — so a plugin left untouched would either fail to resolve or link a second
74
83
  * copy of the framework. Rewriting keeps the whole graph on one identity.
75
84
  */
76
- function rewriteCapacitorDependency(content, pkg, fromDir) {
77
- let rewritten = replacePackageCalls(content, renderCapacitorPackage(pkg, fromDir));
78
- for (const identity of [BINARY_PACKAGE_IDENTITY, SOURCE_PACKAGE_IDENTITY]) {
79
- rewritten = rewritten.split(`package: "${identity}"`).join(`package: "${pkg.identity}"`);
80
- }
81
- return rewritten;
85
+ function rewriteCapacitorDependency(content, absolutePath, fromDir) {
86
+ const rewritten = replacePackageCalls(content, renderCapacitorPackage(absolutePath, fromDir));
87
+ return rewritten.split(`package: "${BINARY_PACKAGE_IDENTITY}"`).join(`package: "${exports.SOURCE_PACKAGE_IDENTITY}"`);
82
88
  }
83
89
  exports.rewriteCapacitorDependency = rewriteCapacitorDependency;
84
90
  /** Reads the version an existing `Package.swift` pins Capacitor to, if it pins one. */
@@ -122,8 +128,13 @@ function patchPackageSwiftDeploymentTarget(content, requiredIosVersion) {
122
128
  return { content: patchedContent, changed: true, previousVersion };
123
129
  }
124
130
  exports.patchPackageSwiftDeploymentTarget = patchPackageSwiftDeploymentTarget;
131
+ /**
132
+ * A path dependency carries no URL to match on, so it is matched on its pinned identity — without
133
+ * that, a manifest rewritten by an earlier sync keeps a relative path that no longer resolves once
134
+ * the app, or the package it points at, has moved.
135
+ */
125
136
  function referencesCapacitor(call) {
126
- return call.includes(BINARY_PACKAGE_IDENTITY) || call.includes(`${SOURCE_PACKAGE_URL}`);
137
+ return call.includes(BINARY_PACKAGE_IDENTITY) || call.includes(SOURCE_PACKAGE_URL) || SOURCE_PACKAGE_NAME.test(call);
127
138
  }
128
139
  /**
129
140
  * Locates `.package(...)` calls in code, skipping any inside a comment or string literal.
@@ -233,92 +244,3 @@ function startOfEntry(content, start) {
233
244
  }
234
245
  return content[cursor] === ',' ? cursor : start;
235
246
  }
236
- function renderRequirement(requirement) {
237
- switch (requirement.kind) {
238
- case 'branch':
239
- return `branch: "${requirement.branch}"`;
240
- case 'revision':
241
- return `revision: "${requirement.revision}"`;
242
- case 'exact':
243
- return `exact: "${requirement.version}"`;
244
- case 'from':
245
- return `from: "${requirement.version}"`;
246
- case 'path':
247
- throw new Error('path requirements are rendered by renderCapacitorPackage');
248
- }
249
- }
250
- function resolveOverride(config) {
251
- var _a, _b, _c, _d;
252
- const baseDir = config.app.rootDir;
253
- const fromEnv = (_a = process.env[ENV_OVERRIDE]) === null || _a === void 0 ? void 0 : _a.trim();
254
- if (fromEnv) {
255
- return { requirement: parseRequirementSpec(fromEnv, baseDir) };
256
- }
257
- const fromConfig = (_d = (_c = (_b = config.app.extConfig.experimental) === null || _b === void 0 ? void 0 : _b.ios) === null || _c === void 0 ? void 0 : _c.spm) === null || _d === void 0 ? void 0 : _d.capacitorPackage;
258
- if (!fromConfig) {
259
- return undefined;
260
- }
261
- const provided = REQUIREMENT_KEYS.filter((key) => fromConfig[key] !== undefined);
262
- if (provided.length === 0) {
263
- (0, errors_1.fatal)(`experimental.ios.spm.capacitorPackage must set one of: ${REQUIREMENT_KEYS.join(', ')}.\n` +
264
- `Remove the entry to use the version matching the installed @capacitor/ios.`);
265
- }
266
- if (provided.length > 1) {
267
- (0, errors_1.fatal)(`experimental.ios.spm.capacitorPackage sets more than one of: ${provided.join(', ')}.\n` + `Only one may be set.`);
268
- }
269
- const key = provided[0];
270
- const value = String(fromConfig[key]);
271
- if (key === 'path') {
272
- if (fromConfig.url !== undefined) {
273
- (0, errors_1.fatal)(`experimental.ios.spm.capacitorPackage cannot set both "url" and "path".`);
274
- }
275
- return { requirement: pathRequirement(value, baseDir) };
276
- }
277
- return { url: fromConfig.url, requirement: { kind: key, ...requirementValue(key, value) } };
278
- }
279
- function requirementValue(key, value) {
280
- switch (key) {
281
- case 'branch':
282
- return { branch: value };
283
- case 'revision':
284
- return { revision: value };
285
- default:
286
- return { version: value };
287
- }
288
- }
289
- /**
290
- * Parses a `CAPACITOR_IOS_PACKAGE` value. Accepts an explicit `kind:value` form, or infers `path`
291
- * for anything path-shaped and `exact` for a bare version.
292
- */
293
- function parseRequirementSpec(spec, baseDir) {
294
- const separator = spec.indexOf(':');
295
- if (separator > 0) {
296
- const key = spec.slice(0, separator);
297
- const value = spec.slice(separator + 1);
298
- if (REQUIREMENT_KEYS.includes(key)) {
299
- if (key === 'path') {
300
- return pathRequirement(value, baseDir);
301
- }
302
- return {
303
- kind: key,
304
- ...requirementValue(key, value),
305
- };
306
- }
307
- }
308
- if (spec.startsWith('.') || (0, path_1.isAbsolute)(spec)) {
309
- return pathRequirement(spec, baseDir);
310
- }
311
- if ((0, semver_1.valid)(spec)) {
312
- return { kind: 'exact', version: spec };
313
- }
314
- return (0, errors_1.fatal)(`Could not understand ${ENV_OVERRIDE}="${spec}".\n` +
315
- `Expected one of ${REQUIREMENT_KEYS.map((k) => `${k}:<value>`).join(', ')}, a path, or a version.`);
316
- }
317
- function pathRequirement(value, baseDir) {
318
- const absolutePath = (0, path_1.resolve)(baseDir, value);
319
- if (!(0, fs_extra_1.existsSync)((0, path_1.resolve)(absolutePath, 'Package.swift'))) {
320
- (0, errors_1.fatal)(`No Package.swift found at ${absolutePath}.\n` +
321
- `A local Capacitor package must point at the repository root, not the ios directory.`);
322
- }
323
- return { kind: 'path', absolutePath };
324
- }
@@ -320,9 +320,9 @@ function filterResources(plugin) {
320
320
  return resources.length > 0;
321
321
  }
322
322
  async function generateCordovaPackageFiles(cordovaPlugins, config) {
323
- cordovaPlugins.map((plugin) => {
324
- generateCordovaPackageFile(plugin, config);
325
- });
323
+ await Promise.all(cordovaPlugins.map(async (plugin) => {
324
+ await generateCordovaPackageFile(plugin, config);
325
+ }));
326
326
  }
327
327
  exports.generateCordovaPackageFiles = generateCordovaPackageFiles;
328
328
  function buildBinaryTargetEntries(p, frameworks) {
@@ -439,7 +439,7 @@ ${entries.join(',\n')}
439
439
  }
440
440
  async function generateCordovaPackageFile(p, config) {
441
441
  var _a;
442
- const capacitorPackage = await (0, capacitor_package_1.resolveCapacitorPackage)(config, 'from');
442
+ const capacitorPackagePath = await (0, capacitor_package_1.resolveCapacitorPackagePath)(config);
443
443
  const iosVersion = (0, common_1.getMajoriOSVersion)(config);
444
444
  const headerFiles = (0, plugin_1.getPlatformElement)(p, platform, 'header-file');
445
445
  let headersText = '';
@@ -451,11 +451,9 @@ async function generateCordovaPackageFile(p, config) {
451
451
  if ((_a = platformTag.$) === null || _a === void 0 ? void 0 : _a.package) {
452
452
  const packageSwiftPath = (0, path_1.join)(p.rootPath, 'Package.swift');
453
453
  let content = await (0, fs_extra_1.readFile)(packageSwiftPath, { encoding: 'utf-8' });
454
- content = content.replace(`apache`, `ionic-team`).replaceAll(`cordova-ios`, capacitorPackage.identity);
455
- content = (0, capacitor_package_1.rewriteCapacitorDependency)(content, capacitorPackage, p.rootPath);
456
- if (capacitorPackage.sourceBased) {
457
- content = (0, capacitor_package_1.patchPackageSwiftDeploymentTarget)(content, iosVersion).content;
458
- }
454
+ content = content.replace(`apache`, `ionic-team`).replaceAll(`cordova-ios`, capacitor_package_1.SOURCE_PACKAGE_IDENTITY);
455
+ content = (0, capacitor_package_1.rewriteCapacitorDependency)(content, capacitorPackagePath, p.rootPath);
456
+ content = (0, capacitor_package_1.patchPackageSwiftDeploymentTarget)(content, iosVersion).content;
459
457
  await (0, fs_extra_1.writeFile)(packageSwiftPath, content);
460
458
  }
461
459
  else {
@@ -493,13 +491,13 @@ let package = Package(
493
491
  )
494
492
  ],
495
493
  dependencies: [
496
- ${(0, capacitor_package_1.renderCapacitorPackage)(capacitorPackage, (0, path_1.join)(config.ios.cordovaPluginsDirAbs, 'sources', p.name))}${packageText}
494
+ ${(0, capacitor_package_1.renderCapacitorPackage)(capacitorPackagePath, (0, path_1.join)(config.ios.cordovaPluginsDirAbs, 'sources', p.name))}${packageText}
497
495
  ],
498
496
  targets: [
499
497
  .target(
500
498
  name: "${p.name}",
501
499
  dependencies: [
502
- .product(name: "Cordova", package: "${capacitorPackage.identity}")${binaryDepsText}${productText}
500
+ .product(name: "Cordova", package: "${capacitor_package_1.SOURCE_PACKAGE_IDENTITY}")${binaryDepsText}${productText}
503
501
  ],
504
502
  path: "."${resourcesText}${headersText}${cSettingsText}${linkerSettingsText}
505
503
  )${binaryTargetsText}
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logBlockedInstallScripts = exports.hasBlockedCapacitorScripts = exports.parseBlockedInstallScripts = exports.getBlockedInstallScripts = exports.isNpmProject = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const fs_extra_1 = require("fs-extra");
6
+ const path_1 = require("path");
7
+ const colors_1 = tslib_1.__importDefault(require("../colors"));
8
+ const log_1 = require("../log");
9
+ const subprocess_1 = require("./subprocess");
10
+ const LOCKFILE_MANAGERS = [
11
+ ['package-lock.json', 'npm'],
12
+ ['npm-shrinkwrap.json', 'npm'],
13
+ ['pnpm-lock.yaml', 'pnpm'],
14
+ ['yarn.lock', 'yarn'],
15
+ ['bun.lock', 'bun'],
16
+ ['bun.lockb', 'bun'],
17
+ ];
18
+ /**
19
+ * `npm install-scripts ls` compares the tree against npm's own `allowScripts` map, which yarn and
20
+ * pnpm never write. It therefore reports every install script in a yarn or pnpm project as
21
+ * blocked, even when that package manager ran it, so the check has to know who did the install.
22
+ *
23
+ * Only a positive signal counts. `rootDir` is the app package, which in a workspace holds neither
24
+ * a lockfile nor a `packageManager` field, and guessing npm there reports blocked scripts for an
25
+ * install npm never performed.
26
+ */
27
+ async function isNpmProject(rootDir) {
28
+ try {
29
+ const { packageManager } = await (0, fs_extra_1.readJSON)((0, path_1.join)(rootDir, 'package.json'));
30
+ if (typeof packageManager === 'string') {
31
+ return packageManager.split('@')[0] === 'npm';
32
+ }
33
+ }
34
+ catch {
35
+ // no package.json, or an unreadable one: fall through to the lockfiles
36
+ }
37
+ for (const [lockfile, manager] of LOCKFILE_MANAGERS) {
38
+ if ((0, fs_extra_1.existsSync)((0, path_1.join)(rootDir, lockfile))) {
39
+ return manager === 'npm';
40
+ }
41
+ }
42
+ return false;
43
+ }
44
+ exports.isNpmProject = isNpmProject;
45
+ /**
46
+ * npm 12 blocks dependency install scripts by default and still exits 0, so the only reliable
47
+ * signal is to ask npm directly. `npm install-scripts ls` lists every package whose scripts are
48
+ * still awaiting a decision, and does not exist before npm 12, where the command exits non-zero
49
+ * and `getCommandOutput` hands back null.
50
+ *
51
+ * Pass `packageManager` when the caller already knows which one ran the install; otherwise it is
52
+ * inferred from the project.
53
+ */
54
+ async function getBlockedInstallScripts(rootDir, packageManager) {
55
+ const isNpm = packageManager === undefined ? await isNpmProject(rootDir) : packageManager.toLowerCase() === 'npm';
56
+ if (!isNpm) {
57
+ return [];
58
+ }
59
+ return parseBlockedInstallScripts(await (0, subprocess_1.getCommandOutput)('npm', ['install-scripts', 'ls', '--json'], { cwd: rootDir }));
60
+ }
61
+ exports.getBlockedInstallScripts = getBlockedInstallScripts;
62
+ function parseBlockedInstallScripts(commandOutput) {
63
+ if (!commandOutput) {
64
+ return [];
65
+ }
66
+ let parsed;
67
+ try {
68
+ parsed = JSON.parse(commandOutput);
69
+ }
70
+ catch {
71
+ return [];
72
+ }
73
+ if (!Array.isArray(parsed === null || parsed === void 0 ? void 0 : parsed.allowScripts)) {
74
+ return [];
75
+ }
76
+ const blocked = [];
77
+ for (const entry of parsed.allowScripts) {
78
+ const name = entry === null || entry === void 0 ? void 0 : entry.name;
79
+ if (typeof name !== 'string' || !Array.isArray(entry.changes)) {
80
+ continue;
81
+ }
82
+ for (const change of entry.changes) {
83
+ if ((change === null || change === void 0 ? void 0 : change.change) !== 'pending' || typeof change.key !== 'string') {
84
+ continue;
85
+ }
86
+ blocked.push({
87
+ name,
88
+ version: change.key.startsWith(`${name}@`) ? change.key.slice(name.length + 1) : change.key,
89
+ });
90
+ }
91
+ }
92
+ return blocked;
93
+ }
94
+ exports.parseBlockedInstallScripts = parseBlockedInstallScripts;
95
+ /**
96
+ * npm 12 denies install scripts by default, so a typical project has pending entries for packages
97
+ * like esbuild or sharp that a Capacitor migration has no bearing on. Only Capacitor's own blocked
98
+ * scripts say anything about whether the migration finished.
99
+ */
100
+ function hasBlockedCapacitorScripts(blocked) {
101
+ return blocked.some(({ name }) => name.startsWith('@capacitor/'));
102
+ }
103
+ exports.hasBlockedCapacitorScripts = hasBlockedCapacitorScripts;
104
+ function logBlockedInstallScripts(blocked) {
105
+ if (blocked.length === 0) {
106
+ return;
107
+ }
108
+ const names = [...new Set(blocked.map(({ name }) => name))];
109
+ const packages = blocked.map(({ name, version }) => ` ${colors_1.default.strong(`${name}@${version}`)}\n`).join('');
110
+ const approvals = names.map((name) => ` ${colors_1.default.input(`npm install-scripts approve ${name}`)}\n`).join('');
111
+ log_1.output.write(`${colors_1.default.strong('Blocked Install Scripts:')}\n\n` +
112
+ ` npm blocked install scripts for ${names.length === 1 ? '1 package' : `${names.length} packages`}. ` +
113
+ `Features that rely on them may not work.\n\n` +
114
+ packages +
115
+ `\n To allow them, run:\n\n` +
116
+ approvals +
117
+ ` ${colors_1.default.input('npm rebuild')}\n\n` +
118
+ ` ${colors_1.default.weak('Approvals are pinned to an exact version, so repeat this after upgrading the package.')}\n\n`);
119
+ }
120
+ exports.logBlockedInstallScripts = logBlockedInstallScripts;
package/dist/util/spm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkPackageTraitsRequirements = exports.checkSwiftToolsVersion = exports.setSwiftUISceneManifest = exports.hasSwiftUISceneManifest = exports.hasSceneManifest = 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.ensureSPMGitignoreEntry = exports.setSwiftUISceneManifest = exports.hasSwiftUISceneManifest = exports.hasSceneManifest = exports.removeInfoPlistDebug = 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");
@@ -60,15 +60,12 @@ exports.checkPluginsForPackageSwift = checkPluginsForPackageSwift;
60
60
  async function extractSPMPackageDirectory(config) {
61
61
  const spmDirectory = (0, path_1.join)(config.ios.nativeProjectDirAbs, 'CapApp-SPM');
62
62
  const spmTemplate = (0, path_1.join)(config.cli.assetsDirAbs, 'ios-spm-template.tar.gz');
63
- const debugConfig = (0, path_1.join)(config.ios.platformDirAbs, 'debug.xcconfig');
64
63
  log_1.logger.info('Extracting ' + spmTemplate + ' to ' + spmDirectory);
65
64
  try {
66
65
  const tempCapDir = await (0, fs_extra_1.mkdtemp)((0, path_1.join)((0, os_1.tmpdir)(), 'cap-'));
67
66
  const tempCapSPM = (0, path_1.join)(tempCapDir, 'App', 'CapApp-SPM');
68
- const tempDebugXCConfig = (0, path_1.join)(tempCapDir, 'debug.xcconfig');
69
67
  await (0, tar_1.extract)({ file: spmTemplate, cwd: tempCapDir });
70
68
  await (0, fs_extra_1.move)(tempCapSPM, spmDirectory);
71
- await (0, fs_extra_1.move)(tempDebugXCConfig, debugConfig);
72
69
  }
73
70
  catch (err) {
74
71
  (0, errors_1.fatal)('Failed to create ' + spmDirectory + ' with error: ' + err);
@@ -92,7 +89,7 @@ async function generatePackageText(config, plugins) {
92
89
  const enableCordova = cordovaPlugins.length > 0 || config.app.forceCordova;
93
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 : {};
94
91
  const packageOptions = (_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.packageOptions) !== null && _h !== void 0 ? _h : {};
95
- const capacitorPackage = await (0, capacitor_package_1.resolveCapacitorPackage)(config);
92
+ const capacitorPackagePath = await (0, capacitor_package_1.resolveCapacitorPackagePath)(config);
96
93
  const spmDirectory = (0, path_1.join)(config.ios.nativeProjectDirAbs, 'CapApp-SPM');
97
94
  const swiftToolsVersion = (_m = (_l = (_k = (_j = config.app.extConfig.experimental) === null || _j === void 0 ? void 0 : _j.ios) === null || _k === void 0 ? void 0 : _k.spm) === null || _l === void 0 ? void 0 : _l.swiftToolsVersion) !== null && _m !== void 0 ? _m : '5.9';
98
95
  let packageSwiftText = `// swift-tools-version: ${swiftToolsVersion}
@@ -108,7 +105,7 @@ let package = Package(
108
105
  targets: ["CapApp-SPM"])
109
106
  ],
110
107
  dependencies: [
111
- ${(0, capacitor_package_1.renderCapacitorPackage)(capacitorPackage, spmDirectory)}`;
108
+ ${(0, capacitor_package_1.renderCapacitorPackage)(capacitorPackagePath, spmDirectory)}`;
112
109
  for (const plugin of plugins) {
113
110
  if ((0, plugin_1.getPluginType)(plugin, config.ios.name) === 1 /* PluginType.Cordova */) {
114
111
  const platformTag = (0, plugin_1.getPluginPlatform)(plugin, config.ios.name);
@@ -153,9 +150,9 @@ let package = Package(
153
150
  .target(
154
151
  name: "CapApp-SPM",
155
152
  dependencies: [
156
- .product(name: "Capacitor", package: "${capacitorPackage.identity}")`;
153
+ .product(name: "Capacitor", package: "${capacitor_package_1.SOURCE_PACKAGE_IDENTITY}")`;
157
154
  if (enableCordova) {
158
- packageSwiftText += `,\n .product(name: "${capacitorPackage.cordovaProduct}", package: "${capacitorPackage.identity}")`;
155
+ packageSwiftText += `,\n .product(name: "${capacitor_package_1.CORDOVA_PRODUCT}", package: "${capacitor_package_1.SOURCE_PACKAGE_IDENTITY}")`;
159
156
  }
160
157
  for (const plugin of plugins) {
161
158
  const aliases = Object.entries((_r = (_q = packageOptions[plugin.id]) === null || _q === void 0 ? void 0 : _q.moduleAliases) !== null && _r !== void 0 ? _r : {});
@@ -209,27 +206,24 @@ async function runCocoapodsDeintegrate(config) {
209
206
  }
210
207
  }
211
208
  exports.runCocoapodsDeintegrate = runCocoapodsDeintegrate;
212
- async function addInfoPlistDebugIfNeeded(config) {
209
+ /**
210
+ * Drop the CAPACITOR_DEBUG key from Info.plist. Capacitor 9 no longer reads it, and the
211
+ * debug.xcconfig that supplied its $(CAPACITOR_DEBUG) value is gone from the template.
212
+ */
213
+ function removeInfoPlistDebug(config) {
213
214
  const infoPlist = (0, path_1.resolve)(config.ios.nativeTargetDirAbs, 'Info.plist');
214
- log_1.logger.info('Checking ' + infoPlist + ' for CAPACITOR_DEBUG');
215
- if ((0, fs_extra_1.existsSync)(infoPlist)) {
216
- const infoPlistContents = (0, fs_extra_1.readFileSync)(infoPlist, 'utf-8');
217
- const plistEntries = (0, plist_1.parse)(infoPlistContents);
218
- if (plistEntries['CAPACITOR_DEBUG'] === undefined) {
219
- log_1.logger.info('Writing CAPACITOR_DEBUG to ' + infoPlist);
220
- plistEntries['CAPACITOR_DEBUG'] = '$(CAPACITOR_DEBUG)';
221
- const plistToWrite = (0, plist_1.build)(plistEntries);
222
- (0, fs_extra_1.writeFileSync)(infoPlist, plistToWrite);
223
- }
224
- else {
225
- log_1.logger.warn('Found CAPACITOR_DEBUG set to ' + plistEntries['CAPACITOR_DEBUG'] + ', skipping.');
226
- }
215
+ if (!(0, fs_extra_1.existsSync)(infoPlist)) {
216
+ return { status: 'skipped', reason: `${infoPlist} not found.` };
227
217
  }
228
- else {
229
- log_1.logger.warn(infoPlist + ' not found.');
218
+ const entries = (0, plist_1.parse)((0, fs_extra_1.readFileSync)(infoPlist, 'utf-8'));
219
+ if (entries['CAPACITOR_DEBUG'] === undefined) {
220
+ return { status: 'unchanged' };
230
221
  }
222
+ delete entries['CAPACITOR_DEBUG'];
223
+ (0, fs_extra_1.writeFileSync)(infoPlist, (0, plist_1.build)(entries));
224
+ return { status: 'removed' };
231
225
  }
232
- exports.addInfoPlistDebugIfNeeded = addInfoPlistDebugIfNeeded;
226
+ exports.removeInfoPlistDebug = removeInfoPlistDebug;
233
227
  function hasSceneManifest(config) {
234
228
  const infoPlist = (0, path_1.resolve)(config.ios.nativeTargetDirAbs, 'Info.plist');
235
229
  if (!(0, fs_extra_1.existsSync)(infoPlist)) {
@@ -297,6 +291,22 @@ function customSceneDelegateClassNames(manifest) {
297
291
  .filter((className) => typeof className === 'string')
298
292
  .filter((className) => className.split('.').pop() !== 'SceneDelegate');
299
293
  }
294
+ async function ensureSPMGitignoreEntry(config) {
295
+ const gitignorePath = (0, path_1.join)(config.ios.nativeProjectDirAbs, 'CapApp-SPM', '.gitignore');
296
+ const entry = '/Package.resolved';
297
+ if (!(0, fs_extra_1.existsSync)(gitignorePath)) {
298
+ log_1.logger.warn(gitignorePath + ' not found, skipping.');
299
+ return;
300
+ }
301
+ const contents = (0, fs_extra_1.readFileSync)(gitignorePath, 'utf-8');
302
+ if (contents.split('\n').some((line) => line.trim() === entry)) {
303
+ log_1.logger.warn('Found ' + entry + ' in ' + gitignorePath + ', skipping.');
304
+ return;
305
+ }
306
+ const updated = contents.endsWith('\n') ? contents + entry + '\n' : contents + '\n' + entry + '\n';
307
+ (0, fs_extra_1.writeFileSync)(gitignorePath, updated);
308
+ }
309
+ exports.ensureSPMGitignoreEntry = ensureSPMGitignoreEntry;
300
310
  async function checkSwiftToolsVersion(config, version) {
301
311
  if (!version) {
302
312
  return null;