@akylas/nativescript-cli 8.8.6 → 8.9.4
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/config/test-deps-versions-generated.json +16 -0
- package/docs/man_pages/project/configuration/widget-ios.md +24 -0
- package/docs/man_pages/project/configuration/widget.md +24 -0
- package/docs/man_pages/start.md +1 -1
- package/lib/.d.ts +2 -0
- package/lib/bootstrap.js +1 -0
- package/lib/bun-package-manager.js +1 -1
- package/lib/commands/appstore-upload.js +3 -6
- package/lib/commands/create-project.js +6 -1
- package/lib/commands/generate.js +2 -41
- package/lib/commands/widget.js +799 -0
- package/lib/common/file-system.js +1 -2
- package/lib/common/logger/logger.js +4 -4
- package/lib/common/mobile/android/android-emulator-services.js +1 -1
- package/lib/common/mobile/android/android-ini-file-parser.js +8 -6
- package/lib/common/mobile/android/logcat-helper.js +1 -1
- package/lib/common/mobile/emulator-helper.js +1 -0
- package/lib/common/mobile/mobile-core/devices-service.js +2 -1
- package/lib/common/opener.js +2 -2
- package/lib/common/services/hooks-service.js +23 -6
- package/lib/constants.js +2 -1
- package/lib/controllers/migrate-controller.js +8 -8
- package/lib/controllers/prepare-controller.js +7 -6
- package/lib/data/prepare-data.js +1 -0
- package/lib/declarations.d.ts +1 -1
- package/lib/definitions/ios.d.ts +11 -1
- package/lib/definitions/prepare.d.ts +2 -0
- package/lib/definitions/project.d.ts +50 -24
- package/lib/key-commands/index.js +28 -21
- package/lib/node-package-manager.js +1 -1
- package/lib/options.js +1 -0
- package/lib/services/analytics/analytics-service.js +2 -1
- package/lib/services/android/gradle-build-args-service.js +1 -1
- package/lib/services/android-plugin-build-service.js +1 -1
- package/lib/services/apple-portal/apple-portal-application-service.js +1 -1
- package/lib/services/apple-portal/apple-portal-session-service.js +36 -9
- package/lib/services/apple-portal/srp/srp-wrapper.js +61 -0
- package/lib/services/assets-generation/assets-generation-service.js +33 -15
- package/lib/services/ios/export-options-plist-service.js +4 -2
- package/lib/services/ios/ios-signing-service.js +45 -23
- package/lib/services/ios/spm-service.js +10 -1
- package/lib/services/ios/xcodebuild-service.js +2 -0
- package/lib/services/ios-debugger-port-service.js +1 -1
- package/lib/services/ios-project-service.js +45 -14
- package/lib/services/livesync/android-livesync-tool.js +1 -1
- package/lib/services/project-config-service.js +12 -3
- package/lib/services/webpack/webpack-compiler-service.js +10 -3
- package/lib/tools/config-manipulation/config-transformer.js +9 -0
- package/package.json +51 -56
- package/vendor/gradle-app/app/build.gradle +347 -119
- package/vendor/gradle-app/build.gradle +7 -7
|
@@ -35,6 +35,25 @@ class ShiftA {
|
|
|
35
35
|
this.willBlockKeyCommandExecution = true;
|
|
36
36
|
this.isInteractive = true;
|
|
37
37
|
}
|
|
38
|
+
getAndroidStudioPath() {
|
|
39
|
+
const os = (0, os_1.platform)();
|
|
40
|
+
if (os === "darwin") {
|
|
41
|
+
const possibleStudioPaths = [
|
|
42
|
+
"/Applications/Android Studio.app",
|
|
43
|
+
`${process.env.HOME}/Applications/Android Studio.app`,
|
|
44
|
+
];
|
|
45
|
+
return possibleStudioPaths.find((p) => fs.existsSync(p)) || null;
|
|
46
|
+
}
|
|
47
|
+
else if (os === "win32") {
|
|
48
|
+
const studioPath = path.join("C:", "Program Files", "Android", "Android Studio", "bin", "studio64.exe");
|
|
49
|
+
return fs.existsSync(studioPath) ? studioPath : null;
|
|
50
|
+
}
|
|
51
|
+
else if (os === "linux") {
|
|
52
|
+
const studioPath = "/usr/local/android-studio/bin/studio.sh";
|
|
53
|
+
return fs.existsSync(studioPath) ? studioPath : null;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
38
57
|
async execute() {
|
|
39
58
|
this.$liveSyncCommandHelper.validatePlatform(this.platform);
|
|
40
59
|
this.$projectData.initializeProjectData();
|
|
@@ -46,28 +65,20 @@ class ShiftA {
|
|
|
46
65
|
process.stdin.resume();
|
|
47
66
|
}
|
|
48
67
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
`${process.env.HOME}/Applications/Android Studio.app`,
|
|
54
|
-
];
|
|
55
|
-
const studioPath = possibleStudioPaths.find((p) => {
|
|
56
|
-
this.$logger.trace(`Checking for Android Studio at ${p}`);
|
|
57
|
-
return fs.existsSync(p);
|
|
58
|
-
});
|
|
68
|
+
let studioPath = null;
|
|
69
|
+
studioPath = process.env.NATIVESCRIPT_ANDROID_STUDIO_PATH;
|
|
70
|
+
if (!studioPath) {
|
|
71
|
+
studioPath = this.getAndroidStudioPath();
|
|
59
72
|
if (!studioPath) {
|
|
60
|
-
this.$logger.error("Android Studio is not installed, or not in a standard location.");
|
|
73
|
+
this.$logger.error("Android Studio is not installed, or is not in a standard location. Use NATIVESCRIPT_ANDROID_STUDIO_PATH.");
|
|
61
74
|
return;
|
|
62
75
|
}
|
|
76
|
+
}
|
|
77
|
+
const os = (0, os_1.platform)();
|
|
78
|
+
if (os === "darwin") {
|
|
63
79
|
this.$childProcess.exec(`open -a "${studioPath}" ${androidDir}`);
|
|
64
80
|
}
|
|
65
81
|
else if (os === "win32") {
|
|
66
|
-
const studioPath = path.join("C:", "Program Files", "Android", "Android Studio", "bin", "studio64.exe");
|
|
67
|
-
if (!fs.existsSync(studioPath)) {
|
|
68
|
-
this.$logger.error("Android Studio is not installed");
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
82
|
const child = this.$childProcess.spawn(studioPath, [androidDir], {
|
|
72
83
|
detached: true,
|
|
73
84
|
stdio: "ignore",
|
|
@@ -75,11 +86,7 @@ class ShiftA {
|
|
|
75
86
|
child.unref();
|
|
76
87
|
}
|
|
77
88
|
else if (os === "linux") {
|
|
78
|
-
|
|
79
|
-
this.$logger.error("Android Studio is not installed");
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
this.$childProcess.exec(`/usr/local/android-studio/bin/studio.sh ${androidDir}`);
|
|
89
|
+
this.$childProcess.exec(`${studioPath} ${androidDir}`);
|
|
83
90
|
}
|
|
84
91
|
}
|
|
85
92
|
}
|
|
@@ -30,7 +30,7 @@ class NodePackageManager extends base_package_manager_1.BasePackageManager {
|
|
|
30
30
|
const packageJsonPath = (0, path_1.join)(pathToSave, "package.json");
|
|
31
31
|
const jsonContentBefore = this.$fs.readJson(packageJsonPath);
|
|
32
32
|
const flags = this.getFlagsString(config, true);
|
|
33
|
-
let params = ["install"
|
|
33
|
+
let params = ["install"];
|
|
34
34
|
const isInstallingAllDependencies = packageName === pathToSave;
|
|
35
35
|
if (!isInstallingAllDependencies) {
|
|
36
36
|
params.push(packageName);
|
package/lib/options.js
CHANGED
|
@@ -167,7 +167,8 @@ class AnalyticsService {
|
|
|
167
167
|
const projectData = this.$projectDataService.getProjectData(projectDir);
|
|
168
168
|
customDimensions["cd2"] =
|
|
169
169
|
projectData.projectType;
|
|
170
|
-
customDimensions["cd9"] =
|
|
170
|
+
customDimensions["cd9"] =
|
|
171
|
+
projectData.isShared.toString();
|
|
171
172
|
}
|
|
172
173
|
return customDimensions;
|
|
173
174
|
}
|
|
@@ -21,7 +21,7 @@ class ApplePortalApplicationService {
|
|
|
21
21
|
async getApplicationsByProvider(contentProviderId) {
|
|
22
22
|
const webSessionCookie = await this.$applePortalSessionService.createWebSession(contentProviderId);
|
|
23
23
|
const summaries = [];
|
|
24
|
-
await this.getApplicationsByUrl(webSessionCookie, "https://appstoreconnect.apple.com/iris/v1/apps?include=appStoreVersions
|
|
24
|
+
await this.getApplicationsByUrl(webSessionCookie, "https://appstoreconnect.apple.com/iris/v1/apps?include=appStoreVersions", summaries);
|
|
25
25
|
return { summaries: summaries };
|
|
26
26
|
}
|
|
27
27
|
async getApplicationsByUrl(webSessionCookie, url, summaries) {
|
|
@@ -4,6 +4,7 @@ exports.ApplePortalSessionService = void 0;
|
|
|
4
4
|
const helpers_1 = require("../../common/helpers");
|
|
5
5
|
const yok_1 = require("../../common/yok");
|
|
6
6
|
const crypto = require("crypto");
|
|
7
|
+
const srp_wrapper_1 = require("./srp/srp-wrapper");
|
|
7
8
|
class ApplePortalSessionService {
|
|
8
9
|
constructor($applePortalCookieService, $errors, $httpClient, $logger, $prompter) {
|
|
9
10
|
this.$applePortalCookieService = $applePortalCookieService;
|
|
@@ -123,26 +124,41 @@ For more details how to set up your environment, please execute "ns publish ios
|
|
|
123
124
|
return result;
|
|
124
125
|
}
|
|
125
126
|
async loginCore(credentials) {
|
|
127
|
+
const wrapper = new srp_wrapper_1.GSASRPAuthenticator(credentials.username);
|
|
128
|
+
const initData = await wrapper.getInit();
|
|
126
129
|
const loginConfig = await this.getLoginConfig();
|
|
127
|
-
const loginUrl = `${loginConfig.authServiceUrl}/auth/signin`;
|
|
130
|
+
const loginUrl = `${loginConfig.authServiceUrl}/auth/signin/init`;
|
|
128
131
|
const headers = {
|
|
129
132
|
"Content-Type": "application/json",
|
|
130
133
|
"X-Requested-With": "XMLHttpRequest",
|
|
131
134
|
"X-Apple-Widget-Key": loginConfig.authServiceKey,
|
|
132
135
|
Accept: "application/json, text/javascript",
|
|
133
136
|
};
|
|
134
|
-
const
|
|
135
|
-
accountName: credentials.username,
|
|
136
|
-
password: credentials.password,
|
|
137
|
-
rememberMe: true,
|
|
138
|
-
};
|
|
139
|
-
const loginResponse = await this.$httpClient.httpRequest({
|
|
137
|
+
const initResponse = await this.$httpClient.httpRequest({
|
|
140
138
|
url: loginUrl,
|
|
141
139
|
method: "POST",
|
|
142
|
-
body,
|
|
140
|
+
body: initData,
|
|
143
141
|
headers,
|
|
144
142
|
});
|
|
145
|
-
|
|
143
|
+
const body = JSON.parse(initResponse.response.body);
|
|
144
|
+
const completeData = await wrapper.getComplete(credentials.password, body);
|
|
145
|
+
const hashcash = await this.fetchHashcash(loginConfig.authServiceUrl, loginConfig.authServiceKey);
|
|
146
|
+
const completeUrl = `${loginConfig.authServiceUrl}/auth/signin/complete?isRememberMeEnabled=false`;
|
|
147
|
+
const completeHeaders = {
|
|
148
|
+
"Content-Type": "application/json",
|
|
149
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
150
|
+
"X-Apple-Widget-Key": loginConfig.authServiceKey,
|
|
151
|
+
Accept: "application/json, text/javascript",
|
|
152
|
+
"X-Apple-HC": hashcash || "",
|
|
153
|
+
};
|
|
154
|
+
const completeResponse = await this.$httpClient.httpRequest({
|
|
155
|
+
url: completeUrl,
|
|
156
|
+
method: "POST",
|
|
157
|
+
completeHeaders,
|
|
158
|
+
body: completeData,
|
|
159
|
+
headers: completeHeaders,
|
|
160
|
+
});
|
|
161
|
+
this.$applePortalCookieService.updateUserSessionCookie(completeResponse.headers["set-cookie"]);
|
|
146
162
|
}
|
|
147
163
|
async getLoginConfig() {
|
|
148
164
|
let config = null;
|
|
@@ -158,6 +174,17 @@ For more details how to set up your environment, please execute "ns publish ios
|
|
|
158
174
|
}
|
|
159
175
|
return config || this.defaultLoginConfig;
|
|
160
176
|
}
|
|
177
|
+
async fetchHashcash(authServiceUrl, authServiceKey) {
|
|
178
|
+
const loginUrl = `${authServiceUrl}/auth/signin?widgetKey=${authServiceKey}`;
|
|
179
|
+
const response = await this.$httpClient.httpRequest({
|
|
180
|
+
url: loginUrl,
|
|
181
|
+
method: "GET",
|
|
182
|
+
});
|
|
183
|
+
const headers = response.headers;
|
|
184
|
+
const bits = headers["X-Apple-HC-Bits"];
|
|
185
|
+
const challenge = headers["X-Apple-HC-Challenge"];
|
|
186
|
+
return makeHashCash(bits, challenge);
|
|
187
|
+
}
|
|
161
188
|
async handleTwoFactorAuthentication(scnt, xAppleIdSessionId, authServiceKey, hashcash) {
|
|
162
189
|
const headers = {
|
|
163
190
|
scnt: scnt,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GSASRPAuthenticator = void 0;
|
|
4
|
+
const js_srp_1 = require("@foxt/js-srp");
|
|
5
|
+
const crypto = require("crypto");
|
|
6
|
+
let srp = new js_srp_1.Srp(js_srp_1.Mode.GSA, js_srp_1.Hash.SHA256, 2048);
|
|
7
|
+
const stringToU8Array = (str) => new TextEncoder().encode(str);
|
|
8
|
+
const base64ToU8Array = (str) => Uint8Array.from(Buffer.from(str, "base64"));
|
|
9
|
+
class GSASRPAuthenticator {
|
|
10
|
+
constructor(username) {
|
|
11
|
+
this.username = username;
|
|
12
|
+
this.srpClient = undefined;
|
|
13
|
+
}
|
|
14
|
+
async derivePassword(protocol, password, salt, iterations) {
|
|
15
|
+
let passHash = new Uint8Array(await js_srp_1.util.hash(srp.h, stringToU8Array(password)));
|
|
16
|
+
if (protocol == "s2k_fo") {
|
|
17
|
+
passHash = stringToU8Array(js_srp_1.util.toHex(passHash));
|
|
18
|
+
}
|
|
19
|
+
let imported = await crypto.subtle.importKey("raw", passHash, { name: "PBKDF2" }, false, ["deriveBits"]);
|
|
20
|
+
let derived = await crypto.subtle.deriveBits({
|
|
21
|
+
name: "PBKDF2",
|
|
22
|
+
hash: { name: "SHA-256" },
|
|
23
|
+
iterations,
|
|
24
|
+
salt,
|
|
25
|
+
}, imported, 256);
|
|
26
|
+
return new Uint8Array(derived);
|
|
27
|
+
}
|
|
28
|
+
async getInit() {
|
|
29
|
+
if (this.srpClient)
|
|
30
|
+
throw new Error("Already initialized");
|
|
31
|
+
this.srpClient = await srp.newClient(stringToU8Array(this.username), new Uint8Array());
|
|
32
|
+
let a = Buffer.from(js_srp_1.util.bytesFromBigint(this.srpClient.A)).toString("base64");
|
|
33
|
+
return {
|
|
34
|
+
a,
|
|
35
|
+
protocols: ["s2k", "s2k_fo"],
|
|
36
|
+
accountName: this.username,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
async getComplete(password, serverData) {
|
|
40
|
+
if (!this.srpClient)
|
|
41
|
+
throw new Error("Not initialized");
|
|
42
|
+
if (serverData.protocol != "s2k" && serverData.protocol != "s2k_fo")
|
|
43
|
+
throw new Error("Unsupported protocol " + serverData.protocol);
|
|
44
|
+
let salt = base64ToU8Array(serverData.salt);
|
|
45
|
+
let serverPub = base64ToU8Array(serverData.b);
|
|
46
|
+
let iterations = serverData.iteration;
|
|
47
|
+
let derived = await this.derivePassword(serverData.protocol, password, salt, iterations);
|
|
48
|
+
this.srpClient.p = derived;
|
|
49
|
+
await this.srpClient.generate(salt, serverPub);
|
|
50
|
+
let m1 = Buffer.from(this.srpClient._M).toString("base64");
|
|
51
|
+
let M2 = await this.srpClient.generateM2();
|
|
52
|
+
let m2 = Buffer.from(M2).toString("base64");
|
|
53
|
+
return {
|
|
54
|
+
accountName: this.username,
|
|
55
|
+
m1,
|
|
56
|
+
m2,
|
|
57
|
+
c: serverData.c,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.GSASRPAuthenticator = GSASRPAuthenticator;
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
};
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.AssetsGenerationService = void 0;
|
|
10
|
-
const
|
|
10
|
+
const JimpModule = require("jimp");
|
|
11
11
|
const Color = require("color");
|
|
12
12
|
const decorators_1 = require("../../common/decorators");
|
|
13
13
|
const constants_1 = require("../../constants");
|
|
@@ -67,7 +67,7 @@ class AssetsGenerationService {
|
|
|
67
67
|
}
|
|
68
68
|
try {
|
|
69
69
|
const color = (_e = (_c = generationData[(_b = assetItem.data) === null || _b === void 0 ? void 0 : _b.fromKey]) !== null && _c !== void 0 ? _c : (_d = assetItem.data) === null || _d === void 0 ? void 0 : _d.default) !== null && _e !== void 0 ? _e : "white";
|
|
70
|
-
const colorHEX =
|
|
70
|
+
const colorHEX = JimpModule.cssColorToHex(color);
|
|
71
71
|
const hex = (_f = colorHEX === null || colorHEX === void 0 ? void 0 : colorHEX.toString(16).substring(0, 6)) !== null && _f !== void 0 ? _f : "FFFFFF";
|
|
72
72
|
this.$fs.writeFile(assetItem.path, [
|
|
73
73
|
`<?xml version="1.0" encoding="utf-8"?>`,
|
|
@@ -112,38 +112,49 @@ class AssetsGenerationService {
|
|
|
112
112
|
constants_1.AssetConstants.defaultOverlayImageScale;
|
|
113
113
|
const imageResize = Math.round(Math.min(width, height) * overlayImageScale);
|
|
114
114
|
image = await this.resize(generationData.imagePath, imageResize, imageResize);
|
|
115
|
-
image = this.generateImage(background, width, height,
|
|
115
|
+
image = this.generateImage(background, width, height, image);
|
|
116
116
|
break;
|
|
117
117
|
case "blank":
|
|
118
|
-
image = this.generateImage(background, width, height
|
|
118
|
+
image = this.generateImage(background, width, height);
|
|
119
119
|
break;
|
|
120
120
|
case "resize":
|
|
121
121
|
image = await this.resize(generationData.imagePath, width, height);
|
|
122
122
|
break;
|
|
123
123
|
case "outerScale":
|
|
124
124
|
image = await this.resize(generationData.imagePath, assetItem.width, assetItem.height);
|
|
125
|
-
image = this.generateImage("#00000000", width, height,
|
|
125
|
+
image = this.generateImage("#00000000", width, height, image);
|
|
126
126
|
break;
|
|
127
127
|
default:
|
|
128
128
|
throw new Error(`Invalid image generation operation: ${operation}`);
|
|
129
129
|
}
|
|
130
130
|
if (assetItem.rgba === false) {
|
|
131
|
-
image = image.
|
|
131
|
+
image = this.generateImage("#FFFFFF", image.width, image.height, image);
|
|
132
|
+
}
|
|
133
|
+
if (this.isAssetFilePath(outputPath)) {
|
|
134
|
+
image.write(outputPath);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
this.$logger.warn(`Incorrect destination path ${outputPath} for image ${assetItem.filename}`);
|
|
132
138
|
}
|
|
133
|
-
image.write(outputPath);
|
|
134
139
|
}
|
|
135
140
|
}
|
|
136
141
|
async resize(imagePath, width, height) {
|
|
137
|
-
const image = await Jimp.read(imagePath);
|
|
138
|
-
return image.scaleToFit(
|
|
142
|
+
const image = await JimpModule.Jimp.read(imagePath);
|
|
143
|
+
return image.scaleToFit({
|
|
144
|
+
w: width,
|
|
145
|
+
h: height,
|
|
146
|
+
});
|
|
139
147
|
}
|
|
140
|
-
generateImage(background, width, height,
|
|
141
|
-
const J = Jimp;
|
|
148
|
+
generateImage(background, width, height, overlayImage) {
|
|
142
149
|
const backgroundColor = this.getRgbaNumber(background);
|
|
143
|
-
let image = new
|
|
150
|
+
let image = new JimpModule.Jimp({
|
|
151
|
+
width,
|
|
152
|
+
height,
|
|
153
|
+
color: backgroundColor,
|
|
154
|
+
});
|
|
144
155
|
if (overlayImage) {
|
|
145
|
-
const centeredWidth = (width - overlayImage.
|
|
146
|
-
const centeredHeight = (height - overlayImage.
|
|
156
|
+
const centeredWidth = (width - overlayImage.width) / 2;
|
|
157
|
+
const centeredHeight = (height - overlayImage.height) / 2;
|
|
147
158
|
image = image.composite(overlayImage, centeredWidth, centeredHeight);
|
|
148
159
|
}
|
|
149
160
|
return image;
|
|
@@ -152,7 +163,14 @@ class AssetsGenerationService {
|
|
|
152
163
|
const color = new Color(colorString);
|
|
153
164
|
const colorRgb = color.rgb();
|
|
154
165
|
const alpha = Math.round(colorRgb.alpha() * 255);
|
|
155
|
-
return
|
|
166
|
+
return JimpModule.rgbaToInt(colorRgb.red(), colorRgb.green(), colorRgb.blue(), alpha);
|
|
167
|
+
}
|
|
168
|
+
isAssetFilePath(path) {
|
|
169
|
+
if (!path) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
const index = path.lastIndexOf(".");
|
|
173
|
+
return index > -1 && index < path.length - 1;
|
|
156
174
|
}
|
|
157
175
|
}
|
|
158
176
|
exports.AssetsGenerationService = AssetsGenerationService;
|
|
@@ -77,7 +77,9 @@ class ExportOptionsPlistService {
|
|
|
77
77
|
`;
|
|
78
78
|
}
|
|
79
79
|
if (provision) {
|
|
80
|
-
plistTemplate += `
|
|
80
|
+
plistTemplate += ` <key>signingStyle</key>
|
|
81
|
+
<string>manual</string>
|
|
82
|
+
<key>provisioningProfiles</key>
|
|
81
83
|
<dict>
|
|
82
84
|
<key>${projectData.projectIdentifiers.ios}</key>
|
|
83
85
|
<string>${provision}</string>
|
|
@@ -85,7 +87,7 @@ class ExportOptionsPlistService {
|
|
|
85
87
|
</dict>`;
|
|
86
88
|
}
|
|
87
89
|
plistTemplate += ` <key>method</key>
|
|
88
|
-
<string>app-store</string>
|
|
90
|
+
<string>app-store-connect</string>
|
|
89
91
|
<key>uploadBitcode</key>
|
|
90
92
|
<false/>
|
|
91
93
|
<key>compileBitcode</key>
|
|
@@ -178,6 +178,18 @@ class IOSSigningService {
|
|
|
178
178
|
getPbxProjPath(projectData, projectRoot) {
|
|
179
179
|
return path.join(this.$xcprojService.getXcodeprojPath(projectData, projectRoot), "project.pbxproj");
|
|
180
180
|
}
|
|
181
|
+
readTeamIdFromFile(projectRoot) {
|
|
182
|
+
try {
|
|
183
|
+
const filePath = path.join(projectRoot, "teamid");
|
|
184
|
+
if (this.$fs.exists(filePath)) {
|
|
185
|
+
return this.$fs.readText(filePath);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
this.$logger.trace("Unable to read file: teamid. Error is: ", e);
|
|
190
|
+
}
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
181
193
|
async getDevelopmentTeam(projectData, projectRoot, teamId) {
|
|
182
194
|
teamId = teamId || this.readXCConfigDevelopmentTeam(projectData);
|
|
183
195
|
if (!teamId) {
|
|
@@ -196,30 +208,40 @@ class IOSSigningService {
|
|
|
196
208
|
if (!helpers.isInteractive()) {
|
|
197
209
|
this.$errors.fail(`Unable to determine default development team. Available development teams are: ${_.map(teams, (team) => team.id)}. Specify team in app/App_Resources/iOS/build.xcconfig file in the following way: DEVELOPMENT_TEAM = <team id>`);
|
|
198
210
|
}
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
211
|
+
const fromFile = this.readTeamIdFromFile(projectRoot);
|
|
212
|
+
if (fromFile) {
|
|
213
|
+
const idFromFile = teams.find((value) => value.id === fromFile);
|
|
214
|
+
if (idFromFile) {
|
|
215
|
+
teamId = idFromFile.id;
|
|
216
|
+
this.$logger.info(`Team Id resolved from file: '${teamId}'.`);
|
|
217
|
+
}
|
|
202
218
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
219
|
+
if (!teamId) {
|
|
220
|
+
const choices = [];
|
|
221
|
+
for (const team of teams) {
|
|
222
|
+
choices.push(team.name + " (" + team.id + ")");
|
|
223
|
+
}
|
|
224
|
+
const choice = await this.$prompter.promptForChoice("Found multiple development teams, select one:", choices);
|
|
225
|
+
teamId = teams[choices.indexOf(choice)].id;
|
|
226
|
+
const choicesPersist = [
|
|
227
|
+
"Yes, set the DEVELOPMENT_TEAM setting in build.xcconfig file.",
|
|
228
|
+
"Yes, persist the team id in platforms folder.",
|
|
229
|
+
"No, don't persist this setting.",
|
|
230
|
+
];
|
|
231
|
+
const choicePersist = await this.$prompter.promptForChoice("Do you want to make teamId: " +
|
|
232
|
+
teamId +
|
|
233
|
+
" a persistent choice for your app?", choicesPersist);
|
|
234
|
+
switch (choicesPersist.indexOf(choicePersist)) {
|
|
235
|
+
case 0:
|
|
236
|
+
const xcconfigFile = path.join(projectData.appResourcesDirectoryPath, "iOS", constants_1.BUILD_XCCONFIG_FILE_NAME);
|
|
237
|
+
this.$fs.appendFile(xcconfigFile, "\nDEVELOPMENT_TEAM = " + teamId + "\n");
|
|
238
|
+
break;
|
|
239
|
+
case 1:
|
|
240
|
+
this.$fs.writeFile(path.join(projectRoot, "teamid"), teamId);
|
|
241
|
+
break;
|
|
242
|
+
default:
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
223
245
|
}
|
|
224
246
|
}
|
|
225
247
|
}
|
|
@@ -15,9 +15,13 @@ class SPMService {
|
|
|
15
15
|
const spmPackages = this.$projectConfigService.getValue(`${platform}.SPMPackages`, []);
|
|
16
16
|
return spmPackages;
|
|
17
17
|
}
|
|
18
|
-
async applySPMPackages(platformData, projectData) {
|
|
18
|
+
async applySPMPackages(platformData, projectData, pluginSpmPackages) {
|
|
19
|
+
var _a;
|
|
19
20
|
try {
|
|
20
21
|
const spmPackages = this.getSPMPackages(projectData, platformData.platformNameLowerCase);
|
|
22
|
+
if (pluginSpmPackages === null || pluginSpmPackages === void 0 ? void 0 : pluginSpmPackages.length) {
|
|
23
|
+
spmPackages.push(...pluginSpmPackages);
|
|
24
|
+
}
|
|
21
25
|
if (!spmPackages.length) {
|
|
22
26
|
this.$logger.trace("SPM: no SPM packages to apply.");
|
|
23
27
|
return;
|
|
@@ -40,6 +44,11 @@ class SPMService {
|
|
|
40
44
|
}
|
|
41
45
|
this.$logger.trace(`SPM: adding package ${pkg.name} to project.`, pkg);
|
|
42
46
|
await project.ios.addSPMPackage(projectData.projectName, pkg);
|
|
47
|
+
if ((_a = pkg.targets) === null || _a === void 0 ? void 0 : _a.length) {
|
|
48
|
+
for (const target of pkg.targets) {
|
|
49
|
+
await project.ios.addSPMPackage(target, pkg);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
43
52
|
}
|
|
44
53
|
await project.commit();
|
|
45
54
|
await this.resolveSPMDependencies(platformData, projectData);
|
|
@@ -55,6 +55,7 @@ class XcodebuildService {
|
|
|
55
55
|
async createDistributionArchive(platformData, projectData, buildConfig) {
|
|
56
56
|
const archivePath = path.join(platformData.getBuildOutputPath(buildConfig), projectData.projectName + ".xcarchive");
|
|
57
57
|
const output = await this.$exportOptionsPlistService.createDistributionExportOptionsPlist(archivePath, projectData, buildConfig);
|
|
58
|
+
const provision = buildConfig.provision || buildConfig.mobileProvisionIdentifier;
|
|
58
59
|
const args = [
|
|
59
60
|
"-exportArchive",
|
|
60
61
|
"-archivePath",
|
|
@@ -63,6 +64,7 @@ class XcodebuildService {
|
|
|
63
64
|
output.exportFileDir,
|
|
64
65
|
"-exportOptionsPlist",
|
|
65
66
|
output.exportOptionsPlistFilePath,
|
|
67
|
+
provision ? "" : "-allowProvisioningUpdates",
|
|
66
68
|
];
|
|
67
69
|
await this.$xcodebuildCommandService.executeCommand(args, {
|
|
68
70
|
cwd: platformData.projectRoot,
|
|
@@ -111,7 +111,7 @@ class IOSDebuggerPortService {
|
|
|
111
111
|
}
|
|
112
112
|
clearTimeout(data) {
|
|
113
113
|
const storedData = this.mapDebuggerPortData[`${data.deviceId}${data.appId}`];
|
|
114
|
-
if (storedData && storedData.timer) {
|
|
114
|
+
if (storedData && typeof storedData.timer === "number") {
|
|
115
115
|
clearTimeout(storedData.timer);
|
|
116
116
|
}
|
|
117
117
|
}
|