@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.
Files changed (51) hide show
  1. package/config/test-deps-versions-generated.json +16 -0
  2. package/docs/man_pages/project/configuration/widget-ios.md +24 -0
  3. package/docs/man_pages/project/configuration/widget.md +24 -0
  4. package/docs/man_pages/start.md +1 -1
  5. package/lib/.d.ts +2 -0
  6. package/lib/bootstrap.js +1 -0
  7. package/lib/bun-package-manager.js +1 -1
  8. package/lib/commands/appstore-upload.js +3 -6
  9. package/lib/commands/create-project.js +6 -1
  10. package/lib/commands/generate.js +2 -41
  11. package/lib/commands/widget.js +799 -0
  12. package/lib/common/file-system.js +1 -2
  13. package/lib/common/logger/logger.js +4 -4
  14. package/lib/common/mobile/android/android-emulator-services.js +1 -1
  15. package/lib/common/mobile/android/android-ini-file-parser.js +8 -6
  16. package/lib/common/mobile/android/logcat-helper.js +1 -1
  17. package/lib/common/mobile/emulator-helper.js +1 -0
  18. package/lib/common/mobile/mobile-core/devices-service.js +2 -1
  19. package/lib/common/opener.js +2 -2
  20. package/lib/common/services/hooks-service.js +23 -6
  21. package/lib/constants.js +2 -1
  22. package/lib/controllers/migrate-controller.js +8 -8
  23. package/lib/controllers/prepare-controller.js +7 -6
  24. package/lib/data/prepare-data.js +1 -0
  25. package/lib/declarations.d.ts +1 -1
  26. package/lib/definitions/ios.d.ts +11 -1
  27. package/lib/definitions/prepare.d.ts +2 -0
  28. package/lib/definitions/project.d.ts +50 -24
  29. package/lib/key-commands/index.js +28 -21
  30. package/lib/node-package-manager.js +1 -1
  31. package/lib/options.js +1 -0
  32. package/lib/services/analytics/analytics-service.js +2 -1
  33. package/lib/services/android/gradle-build-args-service.js +1 -1
  34. package/lib/services/android-plugin-build-service.js +1 -1
  35. package/lib/services/apple-portal/apple-portal-application-service.js +1 -1
  36. package/lib/services/apple-portal/apple-portal-session-service.js +36 -9
  37. package/lib/services/apple-portal/srp/srp-wrapper.js +61 -0
  38. package/lib/services/assets-generation/assets-generation-service.js +33 -15
  39. package/lib/services/ios/export-options-plist-service.js +4 -2
  40. package/lib/services/ios/ios-signing-service.js +45 -23
  41. package/lib/services/ios/spm-service.js +10 -1
  42. package/lib/services/ios/xcodebuild-service.js +2 -0
  43. package/lib/services/ios-debugger-port-service.js +1 -1
  44. package/lib/services/ios-project-service.js +45 -14
  45. package/lib/services/livesync/android-livesync-tool.js +1 -1
  46. package/lib/services/project-config-service.js +12 -3
  47. package/lib/services/webpack/webpack-compiler-service.js +10 -3
  48. package/lib/tools/config-manipulation/config-transformer.js +9 -0
  49. package/package.json +51 -56
  50. package/vendor/gradle-app/app/build.gradle +347 -119
  51. 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
- const os = (0, os_1.platform)();
50
- if (os === "darwin") {
51
- const possibleStudioPaths = [
52
- "/Applications/Android Studio.app",
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
- if (!fs.existsSync(`/usr/local/android-studio/bin/studio.sh`)) {
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", "--legacy-peer-deps"];
33
+ let params = ["install"];
34
34
  const isInstallingAllDependencies = packageName === pathToSave;
35
35
  if (!isInstallingAllDependencies) {
36
36
  params.push(packageName);
package/lib/options.js CHANGED
@@ -227,6 +227,7 @@ class Options {
227
227
  default: true,
228
228
  },
229
229
  dryRun: { type: "boolean", hasSensitiveValue: false },
230
+ uniqueBundle: { type: "boolean", hasSensitiveValue: false },
230
231
  };
231
232
  }
232
233
  get optionNames() {
@@ -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"] = projectData.isShared.toString();
170
+ customDimensions["cd9"] =
171
+ projectData.isShared.toString();
171
172
  }
172
173
  return customDimensions;
173
174
  }
@@ -56,7 +56,7 @@ class GradleBuildArgsService {
56
56
  args.push("--debug");
57
57
  }
58
58
  else if (logLevel === "INFO") {
59
- args.push("--quiet");
59
+ args.push("--info");
60
60
  }
61
61
  return args;
62
62
  }
@@ -454,7 +454,7 @@ class AndroidPluginBuildService {
454
454
  localArgs.push(...additionalArgs);
455
455
  }
456
456
  if (this.$logger.getLevel() === "INFO") {
457
- localArgs.push("--quiet");
457
+ localArgs.push("--info");
458
458
  }
459
459
  const opts = {
460
460
  cwd: pluginBuildSettings.pluginDir,
@@ -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,prices", summaries);
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 body = {
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
- this.$applePortalCookieService.updateUserSessionCookie(loginResponse.headers["set-cookie"]);
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 Jimp = require("jimp");
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 = Jimp.cssColorToHex(color);
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, outputPath, image);
115
+ image = this.generateImage(background, width, height, image);
116
116
  break;
117
117
  case "blank":
118
- image = this.generateImage(background, width, height, outputPath);
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, outputPath, image);
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.colorType(2);
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(width, height);
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, outputPath, overlayImage) {
141
- const J = Jimp;
148
+ generateImage(background, width, height, overlayImage) {
142
149
  const backgroundColor = this.getRgbaNumber(background);
143
- let image = new J(width, height, backgroundColor);
150
+ let image = new JimpModule.Jimp({
151
+ width,
152
+ height,
153
+ color: backgroundColor,
154
+ });
144
155
  if (overlayImage) {
145
- const centeredWidth = (width - overlayImage.bitmap.width) / 2;
146
- const centeredHeight = (height - overlayImage.bitmap.height) / 2;
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 Jimp.rgbaToInt(colorRgb.red(), colorRgb.green(), colorRgb.blue(), alpha);
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 += ` <key>provisioningProfiles</key>
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 choices = [];
200
- for (const team of teams) {
201
- choices.push(team.name + " (" + team.id + ")");
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
- const choice = await this.$prompter.promptForChoice("Found multiple development teams, select one:", choices);
204
- teamId = teams[choices.indexOf(choice)].id;
205
- const choicesPersist = [
206
- "Yes, set the DEVELOPMENT_TEAM setting in build.xcconfig file.",
207
- "Yes, persist the team id in platforms folder.",
208
- "No, don't persist this setting.",
209
- ];
210
- const choicePersist = await this.$prompter.promptForChoice("Do you want to make teamId: " +
211
- teamId +
212
- " a persistent choice for your app?", choicesPersist);
213
- switch (choicesPersist.indexOf(choicePersist)) {
214
- case 0:
215
- const xcconfigFile = path.join(projectData.appResourcesDirectoryPath, "iOS", constants_1.BUILD_XCCONFIG_FILE_NAME);
216
- this.$fs.appendFile(xcconfigFile, "\nDEVELOPMENT_TEAM = " + teamId + "\n");
217
- break;
218
- case 1:
219
- this.$fs.writeFile(path.join(projectRoot, "teamid"), teamId);
220
- break;
221
- default:
222
- break;
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
  }