@capacitor/cli 9.0.0-alpha.7 → 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.
- package/assets/android-template.tar.gz +0 -0
- package/assets/capacitor-cordova-android-plugins.tar.gz +0 -0
- package/assets/capacitor-cordova-ios-plugins.tar.gz +0 -0
- package/assets/ios-pods-template.tar.gz +0 -0
- package/assets/ios-spm-template.tar.gz +0 -0
- package/dist/android/network-security-config.js +230 -0
- package/dist/android/update.js +5 -1
- package/dist/common.js +1 -1
- package/dist/config.js +4 -3
- package/dist/cordova.js +8 -17
- package/dist/declarations.d.ts +8 -41
- package/dist/index.js +4 -14
- package/dist/ios/common.js +1 -1
- package/dist/ios/update.js +9 -17
- package/dist/ipc.js +51 -11
- package/dist/plugin.js +1 -1
- package/dist/run-context/declared.js +54 -0
- package/dist/run-context/index.js +111 -0
- package/dist/run-context/registry.js +45 -0
- package/dist/run-context/signals.js +115 -0
- package/dist/run-context/types.js +2 -0
- package/dist/run-context/unknown.js +46 -0
- package/dist/run-context/version.js +74 -0
- package/dist/tasks/copy.js +3 -1
- package/dist/tasks/doctor.js +4 -1
- package/dist/tasks/list.js +1 -1
- package/dist/tasks/migrate-debug-xcconfig.js +60 -0
- package/dist/tasks/migrate-spm.js +0 -1
- package/dist/tasks/migrate-swiftui.js +344 -54
- package/dist/tasks/migrate-to-modern-project.js +27 -0
- package/dist/tasks/migrate.js +41 -4
- package/dist/tasks/run.js +8 -3
- package/dist/tasks/telemetry.js +8 -1
- package/dist/telemetry.js +303 -57
- package/dist/util/capacitor-package.js +95 -146
- package/dist/util/cordova-ios.js +13 -8
- package/dist/util/js.js +1 -1
- package/dist/util/monorepotools.js +2 -2
- package/dist/util/node.js +3 -3
- package/dist/util/npm.js +120 -0
- package/dist/util/spm.js +35 -25
- package/dist/util/subprocess.js +2 -2
- package/dist/util/xcode.js +193 -2
- package/dist/util/xml.js +1 -1
- package/package.json +3 -2
|
@@ -1,68 +1,77 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.findCapacitorDependencyVersion = exports.rewriteCapacitorDependency = exports.renderCapacitorPackage = exports.
|
|
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
|
-
|
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
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
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return undefined;
|
|
64
67
|
}
|
|
65
|
-
|
|
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,
|
|
77
|
-
|
|
78
|
-
|
|
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. */
|
|
@@ -95,8 +101,40 @@ function findCapacitorDependencyVersion(content) {
|
|
|
95
101
|
return undefined;
|
|
96
102
|
}
|
|
97
103
|
exports.findCapacitorDependencyVersion = findCapacitorDependencyVersion;
|
|
104
|
+
const IOS_PLATFORM_VERSION_REGEX = /\.iOS\(\s*(?:\.v(\d+)|"([\d.]+)")\s*\)/;
|
|
105
|
+
/**
|
|
106
|
+
* Bumps a Package.swift's declared iOS deployment target (e.g. `.iOS(.v13)` or `.iOS("14.0")`) up to
|
|
107
|
+
* `requiredIosVersion` if it's lower.
|
|
108
|
+
*
|
|
109
|
+
* Only relevant for the source package: it declares `platforms: [.iOS(.v16)]` on its own manifest,
|
|
110
|
+
* and SwiftPM enforces that across the whole graph, so a plugin still declaring an older, lower
|
|
111
|
+
* target fails to resolve with "requires minimum platform version X ... but this target supports Y" —
|
|
112
|
+
* even though the very same plugin links fine against the prebuilt `capacitor-swift-pm`, which never
|
|
113
|
+
* declared a `platforms:` entry for SwiftPM to check against.
|
|
114
|
+
*/
|
|
115
|
+
function patchPackageSwiftDeploymentTarget(content, requiredIosVersion) {
|
|
116
|
+
const match = content.match(IOS_PLATFORM_VERSION_REGEX);
|
|
117
|
+
if (!match) {
|
|
118
|
+
return { content, changed: false, previousVersion: null };
|
|
119
|
+
}
|
|
120
|
+
const isSymbolic = match[1] !== undefined;
|
|
121
|
+
const previousVersion = isSymbolic ? match[1] : match[2];
|
|
122
|
+
const requiredMajor = Math.trunc(parseFloat(requiredIosVersion));
|
|
123
|
+
if (parseFloat(previousVersion) >= requiredMajor) {
|
|
124
|
+
return { content, changed: false, previousVersion };
|
|
125
|
+
}
|
|
126
|
+
const replacement = isSymbolic ? `.iOS(.v${requiredMajor})` : `.iOS("${requiredMajor}.0")`;
|
|
127
|
+
const patchedContent = content.replace(IOS_PLATFORM_VERSION_REGEX, replacement);
|
|
128
|
+
return { content: patchedContent, changed: true, previousVersion };
|
|
129
|
+
}
|
|
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
|
+
*/
|
|
98
136
|
function referencesCapacitor(call) {
|
|
99
|
-
return call.includes(BINARY_PACKAGE_IDENTITY) || call.includes(
|
|
137
|
+
return call.includes(BINARY_PACKAGE_IDENTITY) || call.includes(SOURCE_PACKAGE_URL) || SOURCE_PACKAGE_NAME.test(call);
|
|
100
138
|
}
|
|
101
139
|
/**
|
|
102
140
|
* Locates `.package(...)` calls in code, skipping any inside a comment or string literal.
|
|
@@ -206,92 +244,3 @@ function startOfEntry(content, start) {
|
|
|
206
244
|
}
|
|
207
245
|
return content[cursor] === ',' ? cursor : start;
|
|
208
246
|
}
|
|
209
|
-
function renderRequirement(requirement) {
|
|
210
|
-
switch (requirement.kind) {
|
|
211
|
-
case 'branch':
|
|
212
|
-
return `branch: "${requirement.branch}"`;
|
|
213
|
-
case 'revision':
|
|
214
|
-
return `revision: "${requirement.revision}"`;
|
|
215
|
-
case 'exact':
|
|
216
|
-
return `exact: "${requirement.version}"`;
|
|
217
|
-
case 'from':
|
|
218
|
-
return `from: "${requirement.version}"`;
|
|
219
|
-
case 'path':
|
|
220
|
-
throw new Error('path requirements are rendered by renderCapacitorPackage');
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
function resolveOverride(config) {
|
|
224
|
-
var _a, _b, _c, _d;
|
|
225
|
-
const baseDir = config.app.rootDir;
|
|
226
|
-
const fromEnv = (_a = process.env[ENV_OVERRIDE]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
227
|
-
if (fromEnv) {
|
|
228
|
-
return { requirement: parseRequirementSpec(fromEnv, baseDir) };
|
|
229
|
-
}
|
|
230
|
-
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;
|
|
231
|
-
if (!fromConfig) {
|
|
232
|
-
return undefined;
|
|
233
|
-
}
|
|
234
|
-
const provided = REQUIREMENT_KEYS.filter((key) => fromConfig[key] !== undefined);
|
|
235
|
-
if (provided.length === 0) {
|
|
236
|
-
(0, errors_1.fatal)(`experimental.ios.spm.capacitorPackage must set one of: ${REQUIREMENT_KEYS.join(', ')}.\n` +
|
|
237
|
-
`Remove the entry to use the version matching the installed @capacitor/ios.`);
|
|
238
|
-
}
|
|
239
|
-
if (provided.length > 1) {
|
|
240
|
-
(0, errors_1.fatal)(`experimental.ios.spm.capacitorPackage sets more than one of: ${provided.join(', ')}.\n` + `Only one may be set.`);
|
|
241
|
-
}
|
|
242
|
-
const key = provided[0];
|
|
243
|
-
const value = String(fromConfig[key]);
|
|
244
|
-
if (key === 'path') {
|
|
245
|
-
if (fromConfig.url !== undefined) {
|
|
246
|
-
(0, errors_1.fatal)(`experimental.ios.spm.capacitorPackage cannot set both "url" and "path".`);
|
|
247
|
-
}
|
|
248
|
-
return { requirement: pathRequirement(value, baseDir) };
|
|
249
|
-
}
|
|
250
|
-
return { url: fromConfig.url, requirement: { kind: key, ...requirementValue(key, value) } };
|
|
251
|
-
}
|
|
252
|
-
function requirementValue(key, value) {
|
|
253
|
-
switch (key) {
|
|
254
|
-
case 'branch':
|
|
255
|
-
return { branch: value };
|
|
256
|
-
case 'revision':
|
|
257
|
-
return { revision: value };
|
|
258
|
-
default:
|
|
259
|
-
return { version: value };
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Parses a `CAPACITOR_IOS_PACKAGE` value. Accepts an explicit `kind:value` form, or infers `path`
|
|
264
|
-
* for anything path-shaped and `exact` for a bare version.
|
|
265
|
-
*/
|
|
266
|
-
function parseRequirementSpec(spec, baseDir) {
|
|
267
|
-
const separator = spec.indexOf(':');
|
|
268
|
-
if (separator > 0) {
|
|
269
|
-
const key = spec.slice(0, separator);
|
|
270
|
-
const value = spec.slice(separator + 1);
|
|
271
|
-
if (REQUIREMENT_KEYS.includes(key)) {
|
|
272
|
-
if (key === 'path') {
|
|
273
|
-
return pathRequirement(value, baseDir);
|
|
274
|
-
}
|
|
275
|
-
return {
|
|
276
|
-
kind: key,
|
|
277
|
-
...requirementValue(key, value),
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
if (spec.startsWith('.') || (0, path_1.isAbsolute)(spec)) {
|
|
282
|
-
return pathRequirement(spec, baseDir);
|
|
283
|
-
}
|
|
284
|
-
if ((0, semver_1.valid)(spec)) {
|
|
285
|
-
return { kind: 'exact', version: spec };
|
|
286
|
-
}
|
|
287
|
-
return (0, errors_1.fatal)(`Could not understand ${ENV_OVERRIDE}="${spec}".\n` +
|
|
288
|
-
`Expected one of ${REQUIREMENT_KEYS.map((k) => `${k}:<value>`).join(', ')}, a path, or a version.`);
|
|
289
|
-
}
|
|
290
|
-
function pathRequirement(value, baseDir) {
|
|
291
|
-
const absolutePath = (0, path_1.resolve)(baseDir, value);
|
|
292
|
-
if (!(0, fs_extra_1.existsSync)((0, path_1.resolve)(absolutePath, 'Package.swift'))) {
|
|
293
|
-
(0, errors_1.fatal)(`No Package.swift found at ${absolutePath}.\n` +
|
|
294
|
-
`A local Capacitor package must point at the repository root, not the ios directory.`);
|
|
295
|
-
}
|
|
296
|
-
return { kind: 'path', absolutePath };
|
|
297
|
-
}
|
package/dist/util/cordova-ios.js
CHANGED
|
@@ -218,6 +218,10 @@ async function copyPluginsNativeFiles(config, cordovaPlugins) {
|
|
|
218
218
|
fileContent = fileContent.replace(/self.webView.superview/g, 'self.viewController.view');
|
|
219
219
|
await (0, fs_extra_1.writeFile)(fileDest, fileContent, { encoding: 'utf-8' });
|
|
220
220
|
}
|
|
221
|
+
if (isSPM && fileContent.includes(`#import "AppDelegate.h"`)) {
|
|
222
|
+
fileContent = fileContent.replace(`#import "AppDelegate.h"`, `#import <Cordova/AppDelegate.h>`);
|
|
223
|
+
await (0, fs_extra_1.writeFile)(fileDest, fileContent, { encoding: 'utf-8' });
|
|
224
|
+
}
|
|
221
225
|
}
|
|
222
226
|
}
|
|
223
227
|
}
|
|
@@ -316,9 +320,9 @@ function filterResources(plugin) {
|
|
|
316
320
|
return resources.length > 0;
|
|
317
321
|
}
|
|
318
322
|
async function generateCordovaPackageFiles(cordovaPlugins, config) {
|
|
319
|
-
cordovaPlugins.map((plugin) => {
|
|
320
|
-
generateCordovaPackageFile(plugin, config);
|
|
321
|
-
});
|
|
323
|
+
await Promise.all(cordovaPlugins.map(async (plugin) => {
|
|
324
|
+
await generateCordovaPackageFile(plugin, config);
|
|
325
|
+
}));
|
|
322
326
|
}
|
|
323
327
|
exports.generateCordovaPackageFiles = generateCordovaPackageFiles;
|
|
324
328
|
function buildBinaryTargetEntries(p, frameworks) {
|
|
@@ -435,7 +439,7 @@ ${entries.join(',\n')}
|
|
|
435
439
|
}
|
|
436
440
|
async function generateCordovaPackageFile(p, config) {
|
|
437
441
|
var _a;
|
|
438
|
-
const
|
|
442
|
+
const capacitorPackagePath = await (0, capacitor_package_1.resolveCapacitorPackagePath)(config);
|
|
439
443
|
const iosVersion = (0, common_1.getMajoriOSVersion)(config);
|
|
440
444
|
const headerFiles = (0, plugin_1.getPlatformElement)(p, platform, 'header-file');
|
|
441
445
|
let headersText = '';
|
|
@@ -447,8 +451,9 @@ async function generateCordovaPackageFile(p, config) {
|
|
|
447
451
|
if ((_a = platformTag.$) === null || _a === void 0 ? void 0 : _a.package) {
|
|
448
452
|
const packageSwiftPath = (0, path_1.join)(p.rootPath, 'Package.swift');
|
|
449
453
|
let content = await (0, fs_extra_1.readFile)(packageSwiftPath, { encoding: 'utf-8' });
|
|
450
|
-
content = content.replace(`apache`, `ionic-team`).replaceAll(`cordova-ios`,
|
|
451
|
-
content = (0, capacitor_package_1.rewriteCapacitorDependency)(content,
|
|
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;
|
|
452
457
|
await (0, fs_extra_1.writeFile)(packageSwiftPath, content);
|
|
453
458
|
}
|
|
454
459
|
else {
|
|
@@ -486,13 +491,13 @@ let package = Package(
|
|
|
486
491
|
)
|
|
487
492
|
],
|
|
488
493
|
dependencies: [
|
|
489
|
-
${(0, capacitor_package_1.renderCapacitorPackage)(
|
|
494
|
+
${(0, capacitor_package_1.renderCapacitorPackage)(capacitorPackagePath, (0, path_1.join)(config.ios.cordovaPluginsDirAbs, 'sources', p.name))}${packageText}
|
|
490
495
|
],
|
|
491
496
|
targets: [
|
|
492
497
|
.target(
|
|
493
498
|
name: "${p.name}",
|
|
494
499
|
dependencies: [
|
|
495
|
-
.product(name: "Cordova", package: "${
|
|
500
|
+
.product(name: "Cordova", package: "${capacitor_package_1.SOURCE_PACKAGE_IDENTITY}")${binaryDepsText}${productText}
|
|
496
501
|
],
|
|
497
502
|
path: "."${resourcesText}${headersText}${cSettingsText}${linkerSettingsText}
|
|
498
503
|
)${binaryTargetsText}
|
package/dist/util/js.js
CHANGED
|
@@ -8,7 +8,7 @@ function formatJSObject(o) {
|
|
|
8
8
|
o = JSON.parse(JSON.stringify(o));
|
|
9
9
|
}
|
|
10
10
|
catch (e) {
|
|
11
|
-
throw new Error(`Cannot parse object as JSON: ${e.stack ? e.stack : e}
|
|
11
|
+
throw new Error(`Cannot parse object as JSON: ${e.stack ? e.stack : e}`, { cause: e });
|
|
12
12
|
}
|
|
13
13
|
return util_1.default.inspect(o, {
|
|
14
14
|
compact: false,
|
|
@@ -87,7 +87,7 @@ function isMonorepo(currentPath) {
|
|
|
87
87
|
findMonorepoRoot(currentPath);
|
|
88
88
|
return true;
|
|
89
89
|
}
|
|
90
|
-
catch
|
|
90
|
+
catch {
|
|
91
91
|
return false;
|
|
92
92
|
}
|
|
93
93
|
}
|
|
@@ -102,7 +102,7 @@ function isNXMonorepo(currentPath) {
|
|
|
102
102
|
findNXMonorepoRoot(currentPath);
|
|
103
103
|
return true;
|
|
104
104
|
}
|
|
105
|
-
catch
|
|
105
|
+
catch {
|
|
106
106
|
return false;
|
|
107
107
|
}
|
|
108
108
|
}
|
package/dist/util/node.js
CHANGED
|
@@ -38,7 +38,7 @@ const requireTS = async (ts, p) => {
|
|
|
38
38
|
if ((e === null || e === void 0 ? void 0 : e.code) === 'ERR_UNKNOWN_FILE_EXTENSION') {
|
|
39
39
|
throw new Error(`Your installed version of TypeScript (${ts.version}) no longer provides the compiler API Capacitor previously used to load .ts config files, ` +
|
|
40
40
|
`and your Node.js runtime (${process.version}) doesn't support loading them natively either.\n` +
|
|
41
|
-
'Upgrade to Node.js 22.6+ (running with --experimental-strip-types), or Node.js 23.6+, to continue using capacitor.config.ts.');
|
|
41
|
+
'Upgrade to Node.js 22.6+ (running with --experimental-strip-types), or Node.js 23.6+, to continue using capacitor.config.ts.', { cause: e });
|
|
42
42
|
}
|
|
43
43
|
throw e;
|
|
44
44
|
}
|
|
@@ -68,7 +68,7 @@ const requireTS = async (ts, p) => {
|
|
|
68
68
|
}
|
|
69
69
|
(_a = module._compile) === null || _a === void 0 ? void 0 : _a.call(module, sourceText, fileName);
|
|
70
70
|
};
|
|
71
|
-
const m = require(id); // eslint-disable-line @typescript-eslint/no-
|
|
71
|
+
const m = require(id); // eslint-disable-line @typescript-eslint/no-require-imports
|
|
72
72
|
delete require.extensions['.ts'];
|
|
73
73
|
return m;
|
|
74
74
|
};
|
|
@@ -77,7 +77,7 @@ function resolveNode(root, ...pathSegments) {
|
|
|
77
77
|
try {
|
|
78
78
|
return require.resolve(pathSegments.join('/'), { paths: [root] });
|
|
79
79
|
}
|
|
80
|
-
catch
|
|
80
|
+
catch {
|
|
81
81
|
const path = [root, 'node_modules', ...pathSegments].join('/');
|
|
82
82
|
if ((0, fs_1.existsSync)(path)) {
|
|
83
83
|
return path;
|
package/dist/util/npm.js
ADDED
|
@@ -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.
|
|
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
|
|
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)(
|
|
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: "${
|
|
153
|
+
.product(name: "Capacitor", package: "${capacitor_package_1.SOURCE_PACKAGE_IDENTITY}")`;
|
|
157
154
|
if (enableCordova) {
|
|
158
|
-
packageSwiftText += `,\n .product(name: "${
|
|
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
|
-
|
|
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
|
-
|
|
215
|
-
|
|
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
|
-
|
|
229
|
-
|
|
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.
|
|
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;
|
package/dist/util/subprocess.js
CHANGED
|
@@ -20,7 +20,7 @@ async function getCommandOutput(command, args, options = {}) {
|
|
|
20
20
|
try {
|
|
21
21
|
return (await runCommand(command, args, options)).trim();
|
|
22
22
|
}
|
|
23
|
-
catch
|
|
23
|
+
catch {
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -29,7 +29,7 @@ async function isInstalled(command) {
|
|
|
29
29
|
try {
|
|
30
30
|
await (0, utils_subprocess_1.which)(command);
|
|
31
31
|
}
|
|
32
|
-
catch
|
|
32
|
+
catch {
|
|
33
33
|
return false;
|
|
34
34
|
}
|
|
35
35
|
return true;
|