@forge/cli 11.0.0 → 11.1.0-next.24

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 (38) hide show
  1. package/CHANGELOG.md +255 -0
  2. package/npm-shrinkwrap.json +56 -56
  3. package/out/command-line/command.d.ts +3 -3
  4. package/out/command-line/command.d.ts.map +1 -1
  5. package/out/command-line/command.js +6 -6
  6. package/out/command-line/controller/install-controller.d.ts +6 -3
  7. package/out/command-line/controller/install-controller.d.ts.map +1 -1
  8. package/out/command-line/controller/install-controller.js +112 -40
  9. package/out/command-line/dependency-injection.d.ts.map +1 -1
  10. package/out/command-line/dependency-injection.js +2 -1
  11. package/out/command-line/index.d.ts +1 -1
  12. package/out/command-line/index.d.ts.map +1 -1
  13. package/out/command-line/index.js +4 -4
  14. package/out/command-line/register-installation-commands.d.ts +1 -4
  15. package/out/command-line/register-installation-commands.d.ts.map +1 -1
  16. package/out/command-line/register-installation-commands.js +24 -72
  17. package/out/command-line/register-webtrigger-commands.d.ts +1 -1
  18. package/out/command-line/register-webtrigger-commands.d.ts.map +1 -1
  19. package/out/command-line/register-webtrigger-commands.js +2 -3
  20. package/out/command-line/uninstall-command-helpers.d.ts +18 -0
  21. package/out/command-line/uninstall-command-helpers.d.ts.map +1 -0
  22. package/out/command-line/uninstall-command-helpers.js +106 -0
  23. package/out/command-line/version-info.js +1 -1
  24. package/out/environment/graphql-client.d.ts +1 -1
  25. package/out/environment/graphql-client.js +2 -2
  26. package/out/environment/list-environment.d.ts +1 -1
  27. package/out/environment/list-environment.d.ts.map +1 -1
  28. package/out/installations/graphql-client.js +1 -1
  29. package/out/installations/uninstall-app.d.ts +1 -0
  30. package/out/installations/uninstall-app.d.ts.map +1 -1
  31. package/out/installations/uninstall-app.js +1 -0
  32. package/out/service/installation-service.d.ts +1 -1
  33. package/out/service/installation-service.d.ts.map +1 -1
  34. package/out/service/installation-service.js +6 -6
  35. package/out/service/version-service.d.ts +3 -0
  36. package/out/service/version-service.d.ts.map +1 -1
  37. package/out/service/version-service.js +31 -1
  38. package/package.json +9 -9
@@ -43,7 +43,7 @@ class InstallController {
43
43
  }
44
44
  }
45
45
  async installOrUpgrade(upgrade, environment, environmentType, site, product, appId, text, license, overrides) {
46
- const isWorkspaceProduct = !!product && (await this.supportedProductsService.isWorkspaceProduct(product));
46
+ const isWorkspaceProduct = !!product && this.supportedProductsService.isWorkspaceProduct(product);
47
47
  return this.ui.displayProgress(async () => {
48
48
  if (upgrade) {
49
49
  const isAlreadyUpdated = await this.installationService.upgradeInstallation(site, product, environment, appId);
@@ -59,23 +59,31 @@ class InstallController {
59
59
  });
60
60
  return false;
61
61
  }
62
- }, text.cmd.start(environment, environmentType), (alreadyUpdated) => {
62
+ }, text.cmd.start(environment, environmentType, (0, cli_shared_1.productDisplayName)(product)), (alreadyUpdated) => {
63
63
  if (alreadyUpdated) {
64
64
  return isWorkspaceProduct
65
65
  ? cli_shared_1.Text.upgrade.alreadyUpdated.spinnerWorkspace
66
66
  : cli_shared_1.Text.upgrade.alreadyUpdated.spinnerSite;
67
67
  }
68
68
  else {
69
- return text.cmd.end(false);
69
+ return text.cmd.end(false, product);
70
70
  }
71
71
  });
72
72
  }
73
- async promptForProduct() {
73
+ async promptForProducts(requiredProducts) {
74
+ if (requiredProducts?.length) {
75
+ const supportedProducts = this.supportedProductsService.getSupportedSecondaryProductsForXPA(requiredProducts) ?? [];
76
+ const choices = supportedProducts.map((product) => ({ names: [product] }));
77
+ const selected = await this.ui.promptForTable(cli_shared_1.Text.installationContext.promptOptionalProducts, '', [], choices, true);
78
+ return selected.map((index) => supportedProducts[index]);
79
+ }
74
80
  this.ui.info(cli_shared_1.Text.installationContext.overviewProduct);
75
- return await this.ui.promptForList(cli_shared_1.Text.installationContext.promptProduct, await this.supportedProductsService.getSupportedProducts());
81
+ return [
82
+ await this.ui.promptForList(cli_shared_1.Text.installationContext.promptProduct, this.supportedProductsService.getSupportedProducts())
83
+ ];
76
84
  }
77
- async promptForSite(product) {
78
- const isWorkspaceBased = product && (await this.supportedProductsService.isWorkspaceProduct(product));
85
+ async promptForSite(products) {
86
+ const isWorkspaceBased = products.length > 0 && this.supportedProductsService.isWorkspaceProduct(products[0]);
79
87
  const overviewText = isWorkspaceBased
80
88
  ? cli_shared_1.Text.installationContext.overviewWorkspace
81
89
  : cli_shared_1.Text.installationContext.overviewSite;
@@ -88,7 +96,7 @@ class InstallController {
88
96
  if (!trySite) {
89
97
  throw new cli_shared_1.ValidationError(invalidText);
90
98
  }
91
- return this.supportedProductsService.validateSite(trySite, product);
99
+ return this.supportedProductsService.validateSite(trySite, products[0]);
92
100
  }
93
101
  async promptForUpgrade(siteOption, productOption, environmentOption) {
94
102
  const { installations } = await this.installationService.listNonTechnicalAppInstallations({
@@ -99,7 +107,7 @@ class InstallController {
99
107
  const { site, product, environmentKey, environmentType } = await this.installView.promptForUpgrade(installations);
100
108
  const productName = (0, cli_shared_1.productDisplayName)(product);
101
109
  return {
102
- site: await this.supportedProductsService.validateSite(site, productName),
110
+ site: this.supportedProductsService.validateSite(site, productName),
103
111
  product: productName,
104
112
  environment: environmentKey,
105
113
  environmentType
@@ -143,27 +151,36 @@ class InstallController {
143
151
  this.installView.displayUIKit1DeprecationMessage(uiKit1Modules);
144
152
  }
145
153
  };
146
- async run({ environment, site, product, upgrade, confirmScopes, license, licenseModes, usersWithAccess, nonInteractive }) {
154
+ async run({ environment, site, products, upgrade, confirmScopes, license, licenseModes, usersWithAccess, nonInteractive }) {
147
155
  const { id } = await this.appConfigProvider();
148
156
  const text = upgrade ? cli_shared_1.Text.upgrade : cli_shared_1.Text.install;
149
157
  const validLicense = this.validateLicenseOption(license, environment);
150
158
  const overrides = await this.validateEcosystemAppInstallationOverridesInput(licenseModes, usersWithAccess, environment);
151
- if (upgrade && (!site || !product)) {
152
- const upgradeResult = await this.promptForUpgrade(site, product, environment);
159
+ const environmentPermissions = await this.installationService.getAppEnvironmentPermissions(id, environment);
160
+ const requiredProducts = environmentPermissions?.requiredProducts;
161
+ if (upgrade && (!site || !products?.length)) {
162
+ const upgradeResult = await this.promptForUpgrade(site, products?.[0], environment);
153
163
  environment = upgradeResult.environment;
154
164
  site = upgradeResult.site;
155
- product = upgradeResult.product;
165
+ products = [upgradeResult.product];
166
+ }
167
+ if (!requiredProducts?.length) {
168
+ products = products?.length ? products : await this.promptForProducts();
169
+ site = site ? site : await this.promptForSite(products);
170
+ const bannerText = (await this.supportedProductsService.isWorkspaceProduct(products[0]))
171
+ ? text.bannerWorkspace
172
+ : text.bannerSite;
173
+ this.ui.info(bannerText);
174
+ }
175
+ else {
176
+ const result = await this.getXPAProductsAndSite(requiredProducts.map(cli_shared_1.productDisplayName), products, site);
177
+ site = result.site;
178
+ products = result.products;
179
+ this.ui.info(cli_shared_1.Text.install.installConfirmation(products.join(', '), site.host));
156
180
  }
157
- product = product ? product : await this.promptForProduct();
158
- site = site ? site : await this.promptForSite(product);
159
- const bannerText = product && (await this.supportedProductsService.isWorkspaceProduct(product))
160
- ? text.bannerWorkspace
161
- : text.bannerSite;
162
- this.ui.info(bannerText);
163
181
  if ((0, cli_shared_1.isSecureSite)(site)) {
164
182
  await this.securityPrompt(site);
165
183
  }
166
- const environmentPermissions = await this.installationService.getAppEnvironmentPermissions(id, environment);
167
184
  if (!environmentPermissions?.hasDeployments) {
168
185
  this.ui.error(new NoDeploymentError(environment), { pad: false });
169
186
  return;
@@ -185,30 +202,82 @@ class InstallController {
185
202
  const scopesConfirmationResult = await this.installView.promptForPermissionsConfirmation(environmentPermissions, addedScopes, [...manifestScopes], manifestEgressAddresses, environment, confirmScopes, !!nonInteractive, text);
186
203
  if (!scopesConfirmationResult)
187
204
  return;
188
- const isAlreadyUpdated = await this.installOrUpgrade(upgrade, environment, environmentType, site, product, id, text, validLicense, overrides);
189
- if (isAlreadyUpdated) {
190
- this.ui.info(cli_shared_1.Text.upgrade.alreadyUpdated.banner(environment, product, site.host));
205
+ const successfulProducts = [];
206
+ const failedProducts = [];
207
+ for (const product of products) {
208
+ try {
209
+ const isAlreadyUpdated = await this.installOrUpgrade(upgrade, environment, environmentType, site, product, id, text, validLicense, overrides);
210
+ if (isAlreadyUpdated) {
211
+ this.ui.info(cli_shared_1.Text.upgrade.alreadyUpdated.banner(environment, (0, cli_shared_1.productDisplayName)(product), site.host));
212
+ }
213
+ else {
214
+ this.ui.clearSpinner();
215
+ this.ui.emptyLine();
216
+ successfulProducts.push(product);
217
+ }
218
+ }
219
+ catch (error) {
220
+ this.ui.clearSpinner();
221
+ this.ui.error(error);
222
+ failedProducts.push(product);
223
+ }
224
+ await this.checkForMultiProductScopes(environmentScopes, site, environment);
225
+ }
226
+ if (successfulProducts.length) {
227
+ this.ui.info(text.success.banner(environment, environmentType, (0, cli_shared_1.productDisplayName)(successfulProducts.join(', ')), site.host));
191
228
  }
192
229
  else {
193
- this.ui.emptyLine();
194
- this.ui.info(text.success.banner(environment, environmentType, product, site.host));
195
- const uniqueProductsFromScopes = this.getUniqueInstallationProductsFromScopes(environmentScopes);
196
- if (!uniqueProductsFromScopes || uniqueProductsFromScopes.length <= 1)
197
- return;
198
- const { installations } = await this.installationService.listNonTechnicalAppInstallations({
199
- site,
200
- environment
201
- });
202
- const productsToUpgrade = installations
203
- .filter((installation) => !installation.version.isLatest)
204
- .map((installation) => installation.product);
205
- const installedProducts = installations.map((installation) => installation.product);
206
- const productsToInstall = uniqueProductsFromScopes.filter((product) => !installedProducts.includes(product));
207
- if (productsToInstall.length === 0 && productsToUpgrade.length === 0)
208
- return;
209
- this.ui.warn(cli_shared_1.Text.install.multiProductScopesDetected(productsToInstall, productsToUpgrade, site.host, environment));
230
+ this.ui.info(cli_shared_1.Text.install.failedAll(site, environment));
231
+ }
232
+ if (failedProducts.length) {
233
+ throw new cli_shared_1.PartialInstallationError(cli_shared_1.Text.error.partialInstallation(failedProducts));
210
234
  }
211
235
  }
236
+ getXPAProductsAndSite = async (requiredProducts, products, site) => {
237
+ const { installations } = (await this.installationService.listAppInstallations()) ?? [];
238
+ site = site ? site : await this.promptForSite([]);
239
+ if (!products?.length) {
240
+ const hasRequiredInstallations = this.checkRequiredInstallationExists(installations, site.host, requiredProducts);
241
+ if (hasRequiredInstallations) {
242
+ this.ui.info(cli_shared_1.Text.install.alreadyInstalledInRequiredProduct(requiredProducts[0]));
243
+ products = products?.length ? products : await this.promptForProducts(requiredProducts);
244
+ }
245
+ else {
246
+ this.ui.info(cli_shared_1.Text.install.installingToRequiredProduct(requiredProducts[0]));
247
+ products = requiredProducts;
248
+ }
249
+ }
250
+ else {
251
+ const allowedProducts = this.supportedProductsService.getSupportedSecondaryProductsForXPA([]);
252
+ if (products.some((product) => !allowedProducts.includes(product))) {
253
+ throw new cli_shared_1.ValidationError(cli_shared_1.Text.error.invalidProduct);
254
+ }
255
+ if (requiredProducts.includes(products[0])) {
256
+ this.ui.info(cli_shared_1.Text.install.installingToRequiredProduct(products[0]));
257
+ }
258
+ else {
259
+ this.ui.info(cli_shared_1.Text.install.installingToOptionalProduct(products[0]));
260
+ }
261
+ }
262
+ return { site, products };
263
+ };
264
+ checkForMultiProductScopes = async (environmentScopes, site, environment) => {
265
+ const uniqueProductsFromScopes = this.getUniqueInstallationProductsFromScopes(environmentScopes);
266
+ if (!uniqueProductsFromScopes || uniqueProductsFromScopes.length <= 1)
267
+ return;
268
+ const { installations: nonTechnicalInstallations } = await this.installationService.listNonTechnicalAppInstallations({
269
+ site,
270
+ environment
271
+ });
272
+ const productsToUpgrade = nonTechnicalInstallations
273
+ .filter((installation) => !installation.version.isLatest)
274
+ .map((installation) => installation.product);
275
+ const installedProducts = nonTechnicalInstallations.map((installation) => installation.product);
276
+ const productsToInstall = uniqueProductsFromScopes.filter((product) => !installedProducts.includes(product));
277
+ if (productsToInstall.length === 0 && productsToUpgrade.length === 0)
278
+ return;
279
+ this.ui.warn(cli_shared_1.Text.install.multiProductScopesDetected(productsToInstall, productsToUpgrade, site.host, environment));
280
+ };
212
281
  async extractAddedScopes({ addedScopes }) {
213
282
  const scopesWithInteractiveConsent = (0, manifest_1.getScopesWithInteractiveConsent)();
214
283
  return addedScopes.map((scope) => ({
@@ -265,5 +334,8 @@ class InstallController {
265
334
  ? { licenseModes: ecosystemLicenseModes, usersWithAccess }
266
335
  : undefined;
267
336
  }
337
+ checkRequiredInstallationExists = (installations, site, requiredProducts) => {
338
+ return requiredProducts.every((requiredProduct) => installations.some((installation) => installation.site.includes(site) && installation.product.toLowerCase() === requiredProduct.toLowerCase()));
339
+ };
268
340
  }
269
341
  exports.InstallController = InstallController;
@@ -1 +1 @@
1
- {"version":3,"file":"dependency-injection.d.ts","sourceRoot":"","sources":["../../src/command-line/dependency-injection.ts"],"names":[],"mappings":"AAIA,OAAO,EASL,UAAU,EACV,aAAa,EAEb,UAAU,EAGV,gBAAgB,EAGhB,kBAAkB,EAGlB,gBAAgB,EAQhB,YAAY,EACZ,aAAa,EAOb,kBAAkB,EAIlB,kBAAkB,EAElB,kBAAkB,EAKlB,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAc3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,OAAO,EAML,0BAA0B,EAG3B,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAC;AAExG,OAAO,EAAE,+BAA+B,EAAE,MAAM,qDAAqD,CAAC;AACtG,OAAO,EAAE,6BAA6B,EAAE,MAAM,mDAAmD,CAAC;AAIlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAG3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAEtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAM7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAIrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAQtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAI3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAG3E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAUlE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAGhF,OAAO,EAAE,4BAA4B,EAAE,MAAM,6CAA6C,CAAC;AAG3F,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAKpE,eAAO,MAAM,eAAe,eAAsB,UAAU,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8XvE,CAAC;AAGF,aAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAC7D,oBAAY,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"dependency-injection.d.ts","sourceRoot":"","sources":["../../src/command-line/dependency-injection.ts"],"names":[],"mappings":"AAIA,OAAO,EASL,UAAU,EACV,aAAa,EAEb,UAAU,EAGV,gBAAgB,EAGhB,kBAAkB,EAGlB,gBAAgB,EAQhB,YAAY,EACZ,aAAa,EAOb,kBAAkB,EAIlB,kBAAkB,EAElB,kBAAkB,EAKlB,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAc3B,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,OAAO,EAML,0BAA0B,EAG3B,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAC;AAExG,OAAO,EAAE,+BAA+B,EAAE,MAAM,qDAAqD,CAAC;AACtG,OAAO,EAAE,6BAA6B,EAAE,MAAM,mDAAmD,CAAC;AAIlG,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAG3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAEtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAM7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAIrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAQtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAI3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAG3E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAUlE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAGhF,OAAO,EAAE,4BAA4B,EAAE,MAAM,6CAA6C,CAAC;AAG3F,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAKpE,eAAO,MAAM,eAAe,eAAsB,UAAU,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoYvE,CAAC;AAGF,aAAK,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAC7D,oBAAY,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC"}
@@ -97,7 +97,7 @@ const getDependencies = async (cliDetails) => {
97
97
  const credentialStore = (0, cli_shared_1.getCredentialStore)(ui, userRepository);
98
98
  const featureFlagService = new cli_shared_1.FeatureFlagService(ui, cliDetails, credentialStore, appConfigReader);
99
99
  const statsigService = new cli_shared_1.StatsigService(ui, cliDetails, credentialStore, appConfigReader);
100
- const supportedProductsService = new cli_shared_1.SupportedProductsService(statsigService);
100
+ const supportedProductsService = new cli_shared_1.SupportedProductsService();
101
101
  const settingsView = new settings_view_1.SettingsView(ui);
102
102
  const settingsController = new settings_controller_1.SettingsController(settingsView, cachedConfigService, assertiveAppConfigReader);
103
103
  const liteLintView = new lite_lint_view_1.LiteLintView(ui);
@@ -199,6 +199,7 @@ const getDependencies = async (cliDetails) => {
199
199
  const prerequisitesController = new prerequisites_controller_1.PrerequisitesController(ui, cliDetails);
200
200
  const defaultEnvironmentController = new default_environment_controller_1.DefaultEnvironmentController(ui, credentialStore, cachedConfigService, assertiveAppConfigReader, userRepository, createEnvironmentCommand, listEnvironmentCommand, getAppOwnerQuery);
201
201
  cmd = command_1.Command.program(ui, analyticsClientReporter, preCommandController, cliDetails, credentialStore, defaultEnvironmentController, featureFlagService, supportedProductsService);
202
+ await supportedProductsService.initializeWithSupportedProducts(statsigService);
202
203
  return {
203
204
  ui,
204
205
  cmd,
@@ -1,4 +1,4 @@
1
1
  import { Dependencies } from './dependency-injection';
2
- export declare function registerCommands(deps: Dependencies): Promise<void>;
2
+ export declare function registerCommands(deps: Dependencies): void;
3
3
  export declare const main: () => Promise<void>;
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/command-line/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAqBvE,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,YAAY,iBAkBxD;AAQD,eAAO,MAAM,IAAI,QAAa,QAAQ,IAAI,CAUzC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/command-line/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAqBvE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,QAkBlD;AAQD,eAAO,MAAM,IAAI,QAAa,QAAQ,IAAI,CAUzC,CAAC"}
@@ -21,18 +21,18 @@ const register_environments_commands_1 = require("./register-environments-comman
21
21
  const register_storage_commands_1 = require("./register-storage-commands");
22
22
  const register_eligibility_commands_1 = require("./register-eligibility-commands");
23
23
  const register_version_commands_1 = require("./register-version-commands");
24
- async function registerCommands(deps) {
24
+ function registerCommands(deps) {
25
25
  (0, register_autocomplete_commands_1.registerCommands)(deps);
26
26
  (0, register_authentication_command_1.registerCommands)(deps);
27
27
  (0, register_app_commands_1.registerCommands)(deps);
28
28
  (0, register_deployment_commands_1.registerCommands)(deps);
29
- await (0, register_installation_commands_1.registerCommands)(deps);
29
+ (0, register_installation_commands_1.registerCommands)(deps);
30
30
  (0, register_environments_commands_1.registerCommands)(deps);
31
31
  (0, register_environment_variables_commands_1.registerCommands)(deps);
32
32
  (0, register_lint_command_1.registerCommands)(deps);
33
33
  (0, register_log_commands_1.registerCommands)(deps);
34
34
  (0, register_tunnel_commands_1.registerCommands)(deps);
35
- await (0, register_webtrigger_commands_1.registerCommands)(deps);
35
+ (0, register_webtrigger_commands_1.registerCommands)(deps);
36
36
  (0, register_feedback_commands_1.registerCommands)(deps);
37
37
  (0, register_settings_commands_1.registerCommands)(deps);
38
38
  (0, register_providers_commands_1.registerCommands)(deps);
@@ -50,7 +50,7 @@ const main = async () => {
50
50
  const cliDetails = (0, version_info_1.getCLIDetails)();
51
51
  const deps = await (0, dependency_injection_1.getDependencies)(cliDetails);
52
52
  registerEvents(deps);
53
- await registerCommands(deps);
53
+ registerCommands(deps);
54
54
  await deps.controllers.prerequisitesController.check();
55
55
  await deps.cmd.parse(process.argv);
56
56
  };
@@ -1,7 +1,4 @@
1
1
  import { Dependencies } from './dependency-injection';
2
- import { Installation } from '../service/installation-service';
3
2
  export declare const registerListInstallationsCommand: ({ cmd, ui, services: { installationsService } }: Dependencies) => void;
4
- export declare const performSingleUninstall: (installId: string, { ui, commands: { uninstallAppCommand } }: Dependencies) => Promise<void>;
5
- export declare const performMultipleUninstalls: (appsToUninstall: Installation[], { ui, commands: { uninstallAppCommand } }: Dependencies) => Promise<void>;
6
- export declare const registerCommands: ({ cmd, ...deps }: Dependencies) => Promise<void>;
3
+ export declare const registerCommands: ({ cmd, ...deps }: Dependencies) => void;
7
4
  //# sourceMappingURL=register-installation-commands.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"register-installation-commands.d.ts","sourceRoot":"","sources":["../../src/command-line/register-installation-commands.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAqD/D,eAAO,MAAM,gCAAgC,oDAAqD,YAAY,SAmC7G,CAAC;AAEF,eAAO,MAAM,sBAAsB,cACtB,MAAM,6CAC0B,YAAY,kBAuBxD,CAAC;AAEF,eAAO,MAAM,yBAAyB,oBACnB,YAAY,EAAE,6CACY,YAAY,kBA8CxD,CAAC;AAsEF,eAAO,MAAM,gBAAgB,qBAA4B,YAAY,KAAG,QAAQ,IAAI,CAenF,CAAC"}
1
+ {"version":3,"file":"register-installation-commands.d.ts","sourceRoot":"","sources":["../../src/command-line/register-installation-commands.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAqDtD,eAAO,MAAM,gCAAgC,oDAAqD,YAAY,SAmC7G,CAAC;AA2EF,eAAO,MAAM,gBAAgB,qBAAsB,YAAY,KAAG,IAejE,CAAC"}
@@ -1,17 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerCommands = exports.performMultipleUninstalls = exports.performSingleUninstall = exports.registerListInstallationsCommand = void 0;
3
+ exports.registerCommands = exports.registerListInstallationsCommand = void 0;
4
4
  const cli_shared_1 = require("@forge/cli-shared");
5
5
  const shared_1 = require("../installations/shared");
6
- const errors_1 = require("./errors");
6
+ const uninstall_command_helpers_1 = require("./uninstall-command-helpers");
7
7
  const semver_1 = require("semver");
8
8
  const COMMAND_NAME = 'install';
9
- const registerInstallAppCommand = async ({ cmd, controllers: { installController }, services: { supportedProductsService } }) => {
10
- const supportedProducts = await supportedProductsService.getSupportedProducts();
9
+ const registerInstallAppCommand = ({ cmd, controllers: { installController } }) => {
11
10
  cmd
12
11
  .requireAppId()
13
12
  .environmentOption()
14
- .contextOption(supportedProducts)
13
+ .contextOption()
15
14
  .option('--upgrade', cli_shared_1.Text.install.optionUpgrade, false)
16
15
  .option('--confirm-scopes', cli_shared_1.Text.install.optionConfirmScopes, false)
17
16
  .option('-l, --license [license]', cli_shared_1.Text.install.optionLicense)
@@ -23,7 +22,7 @@ const registerInstallAppCommand = async ({ cmd, controllers: { installController
23
22
  await installController.run({
24
23
  environment,
25
24
  site,
26
- product,
25
+ products: product ? [product] : [],
27
26
  upgrade,
28
27
  confirmScopes,
29
28
  license,
@@ -65,58 +64,11 @@ const registerListInstallationsCommand = ({ cmd, ui, services: { installationsSe
65
64
  });
66
65
  };
67
66
  exports.registerListInstallationsCommand = registerListInstallationsCommand;
68
- const performSingleUninstall = async (installId, { ui, commands: { uninstallAppCommand } }) => {
69
- const installation = await ui.displayProgress(() => uninstallAppCommand.execute(installId), cli_shared_1.Text.uninstall.cmd.start, (result) => ({
70
- successful: !!result.successful,
71
- message: cli_shared_1.Text.uninstall.cmd.success(false)
72
- }));
73
- const uninstallMessageFormat = installation.successful ? cli_shared_1.Text.uninstall.done : cli_shared_1.Text.uninstall.failed;
74
- const uninstallMessage = uninstallMessageFormat((0, cli_shared_1.productDisplayName)(installation.product), installation.site, installation.environmentKey, false);
75
- if (installation.successful) {
76
- ui.info(uninstallMessage);
77
- }
78
- else {
79
- ui.error(new shared_1.UninstallAppError(uninstallMessage));
80
- }
81
- };
82
- exports.performSingleUninstall = performSingleUninstall;
83
- const performMultipleUninstalls = async (appsToUninstall, { ui, commands: { uninstallAppCommand } }) => {
84
- const filteredInstallations = appsToUninstall.filter(({ product }) => product !== 'identity');
85
- const hasMultipleNonIdentityApps = filteredInstallations.length > 1;
86
- const uninstalledApps = await ui.displayProgress(() => uninstallAppCommand.batchExecute([], appsToUninstall), cli_shared_1.Text.uninstall.cmd.start, (result) => {
87
- const isSuccessful = !result.some(({ successful }) => successful === false);
88
- return {
89
- successful: isSuccessful,
90
- message: cli_shared_1.Text.uninstall.cmd.success(hasMultipleNonIdentityApps)
91
- };
92
- });
93
- const deferredErrors = [];
94
- uninstalledApps.forEach((uninstall) => {
95
- const uninstallMessageFormat = uninstall.successful ? cli_shared_1.Text.uninstall.done : cli_shared_1.Text.uninstall.failed;
96
- const formattedMessage = uninstallMessageFormat((0, cli_shared_1.productDisplayName)(uninstall.product), uninstall.site, uninstall.environmentKey, hasMultipleNonIdentityApps);
97
- if (uninstall.successful && uninstall.product !== 'identity') {
98
- ui.info(formattedMessage);
99
- }
100
- else if (!uninstall.successful) {
101
- const uninstallError = new shared_1.UninstallAppError(formattedMessage);
102
- ui.error(uninstallError);
103
- deferredErrors.push(uninstallError);
104
- }
105
- });
106
- if (uninstalledApps.some(({ successful }) => successful === false)) {
107
- throw new errors_1.DeferredErrors(deferredErrors);
108
- }
109
- if (hasMultipleNonIdentityApps) {
110
- ui.info(cli_shared_1.Text.uninstall.interactive.done);
111
- }
112
- };
113
- exports.performMultipleUninstalls = performMultipleUninstalls;
114
- const registerUninstallCommand = async (deps) => {
115
- const { cmd, ui, services: { installationsService, supportedProductsService } } = deps;
116
- const supportedProducts = await supportedProductsService.getSupportedProducts();
67
+ const registerUninstallCommand = (deps) => {
68
+ const { cmd, ui, services: { installationsService } } = deps;
117
69
  cmd
118
70
  .command('uninstall')
119
- .contextOption(supportedProducts)
71
+ .contextOption()
120
72
  .environmentOption()
121
73
  .requireAppId()
122
74
  .description(cli_shared_1.Text.uninstall.cmd.desc)
@@ -135,33 +87,33 @@ const registerUninstallCommand = async (deps) => {
135
87
  ui.info(cli_shared_1.Text.uninstall.info);
136
88
  ui.info(cli_shared_1.Text.ctrlC);
137
89
  ui.emptyLine();
138
- await (0, exports.performSingleUninstall)(installation.id, deps);
90
+ await (0, uninstall_command_helpers_1.performSingleUninstall)(installation.id, deps);
139
91
  }
140
92
  else {
141
93
  const filteredInstallations = installations.filter((install) => install.product !== 'identity' && install.product !== 'jira-servicedesk');
142
- const selectedSitesIndexes = await ui.promptForTable(cli_shared_1.Text.uninstall.interactive.desc, cli_shared_1.Text.uninstall.interactive.progressInfo, ['Environment', 'Site', 'Product'], filteredInstallations.map(({ id, environmentKey, product, site }) => ({
143
- names: [(0, cli_shared_1.environmentToOption)(environmentKey), site, (0, cli_shared_1.productDisplayName)(product)],
144
- value: id
145
- })));
146
- const appsToUninstall = filteredInstallations.filter((_, index) => selectedSitesIndexes.includes(index));
147
- const selectedSites = new Set(appsToUninstall.map(({ site }) => site));
148
- const remainingApps = filteredInstallations.filter((_, index) => !selectedSitesIndexes.includes(index));
149
- appsToUninstall.push(...(0, shared_1.getHangingIdentityInstallationsFromSite)(installations, remainingApps, selectedSites));
150
- if (appsToUninstall.length > 1) {
151
- await (0, exports.performMultipleUninstalls)(appsToUninstall, deps);
94
+ const options = (0, uninstall_command_helpers_1.getMultiChoiceOptionsForUninstall)(filteredInstallations);
95
+ const selectedSitesIndexes = await ui.promptForTable(cli_shared_1.Text.uninstall.interactive.desc, cli_shared_1.Text.uninstall.interactive.progressInfo, ['Environment', 'Site', 'Product'], options);
96
+ const [firstUninstall, secondUninstall] = (0, uninstall_command_helpers_1.getInstallationsFromSelection)(options, selectedSitesIndexes, filteredInstallations);
97
+ const selectedSites = new Set(firstUninstall.map(({ site }) => site).concat(secondUninstall.map(({ site }) => site)));
98
+ const remainingApps = options
99
+ .filter((_, index) => !selectedSitesIndexes.includes(index))
100
+ .map(({ extra }) => filteredInstallations[extra.installationIdx]);
101
+ firstUninstall.push(...(0, shared_1.getHangingIdentityInstallationsFromSite)(installations, remainingApps, selectedSites));
102
+ if (firstUninstall.length > 1 || secondUninstall.length > 0) {
103
+ await (0, uninstall_command_helpers_1.performMultipleUninstalls)(firstUninstall, secondUninstall, deps);
152
104
  }
153
- else {
154
- await (0, exports.performSingleUninstall)(appsToUninstall[0].id, deps);
105
+ else if (firstUninstall.length === 1) {
106
+ await (0, uninstall_command_helpers_1.performSingleUninstall)(firstUninstall[0].id, deps);
155
107
  }
156
108
  }
157
109
  });
158
110
  };
159
111
  const DEPRECATED_LIST_COMMAND = 'install:list';
160
- const registerCommands = async ({ cmd, ...deps }) => {
112
+ const registerCommands = ({ cmd, ...deps }) => {
161
113
  const install = cmd.command(COMMAND_NAME).description(cli_shared_1.Text.variables.description);
162
- await registerUninstallCommand({ cmd, ...deps });
114
+ registerUninstallCommand({ cmd, ...deps });
163
115
  cmd.deprecatedCommand(DEPRECATED_LIST_COMMAND, `${COMMAND_NAME} ${LIST_COMMAND_NAME}`, deps.controllers.stubController);
164
- await registerInstallAppCommand({ cmd: install, ...deps });
116
+ registerInstallAppCommand({ cmd: install, ...deps });
165
117
  (0, exports.registerListInstallationsCommand)({ cmd: install, ...deps });
166
118
  };
167
119
  exports.registerCommands = registerCommands;
@@ -1,3 +1,3 @@
1
1
  import { Dependencies } from './dependency-injection';
2
- export declare const registerCommands: ({ cmd, ui, configFile, services: { installationsService, supportedProductsService }, commands: { getWebTriggerURLCommand } }: Dependencies) => Promise<void>;
2
+ export declare const registerCommands: ({ cmd, ui, configFile, services: { installationsService }, commands: { getWebTriggerURLCommand } }: Dependencies) => void;
3
3
  //# sourceMappingURL=register-webtrigger-commands.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"register-webtrigger-commands.d.ts","sourceRoot":"","sources":["../../src/command-line/register-webtrigger-commands.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAgCtD,eAAO,MAAM,gBAAgB,iIAM1B,YAAY,kBAyDd,CAAC"}
1
+ {"version":3,"file":"register-webtrigger-commands.d.ts","sourceRoot":"","sources":["../../src/command-line/register-webtrigger-commands.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAgCtD,eAAO,MAAM,gBAAgB,uGAM1B,YAAY,SAsDd,CAAC"}
@@ -26,7 +26,7 @@ function manifestDefinesTriggers(configFile) {
26
26
  await getValidWebtriggers(configFile);
27
27
  };
28
28
  }
29
- const registerCommands = async ({ cmd, ui, configFile, services: { installationsService, supportedProductsService }, commands: { getWebTriggerURLCommand } }) => {
29
+ const registerCommands = ({ cmd, ui, configFile, services: { installationsService }, commands: { getWebTriggerURLCommand } }) => {
30
30
  const validateWebtriggerKey = async (functionKey) => {
31
31
  const availableWebTriggers = await getValidWebtriggers(configFile);
32
32
  if (functionKey) {
@@ -40,13 +40,12 @@ const registerCommands = async ({ cmd, ui, configFile, services: { installations
40
40
  return await ui.promptForList(cli_shared_1.Text.webtrigger.promptFuncKey, options);
41
41
  }
42
42
  };
43
- const supportedProducts = await supportedProductsService.getSupportedProducts();
44
43
  cmd
45
44
  .command('webtrigger')
46
45
  .requireAppId()
47
46
  .description(cli_shared_1.Text.webtrigger.cmd)
48
47
  .option('-f, --functionKey [function]', cli_shared_1.Text.webtrigger.optionFuncKey)
49
- .contextOption(supportedProducts)
48
+ .contextOption()
50
49
  .environmentOption()
51
50
  .precondition(manifestDefinesTriggers(configFile))
52
51
  .action(async ({ functionKey, site, environment, product }) => {
@@ -0,0 +1,18 @@
1
+ import { Installation } from '../service/installation-service';
2
+ import { Dependencies } from './dependency-injection';
3
+ export interface Option {
4
+ names: string[];
5
+ value: string;
6
+ extra: {
7
+ primary?: boolean;
8
+ secondary?: boolean;
9
+ contextAri?: string;
10
+ installationIdx: number;
11
+ product: string;
12
+ };
13
+ }
14
+ export declare const getMultiChoiceOptionsForUninstall: (filteredInstallations: Installation[]) => Option[];
15
+ export declare const getInstallationsFromSelection: (options: Option[], selectedSitesIndexes: number[], filteredInstallations: Installation[]) => [Installation[], Installation[]];
16
+ export declare const performSingleUninstall: (installId: string, { ui, commands: { uninstallAppCommand } }: Dependencies) => Promise<void>;
17
+ export declare const performMultipleUninstalls: (appsToUninstallFirst: Installation[], appsToUninstallSecond: Installation[], { ui, commands: { uninstallAppCommand } }: Dependencies) => Promise<void>;
18
+ //# sourceMappingURL=uninstall-command-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall-command-helpers.d.ts","sourceRoot":"","sources":["../../src/command-line/uninstall-command-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAItD,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAClH;AAMD,eAAO,MAAM,iCAAiC,0BAA2B,YAAY,EAAE,KAAG,MAAM,EA8B/F,CAAC;AAEF,eAAO,MAAM,6BAA6B,YAC/B,MAAM,EAAE,wBACK,MAAM,EAAE,yBACP,YAAY,EAAE,KACpC,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,CAiBjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,cACtB,MAAM,6CAC0B,YAAY,kBAuBxD,CAAC;AAEF,eAAO,MAAM,yBAAyB,yBACd,YAAY,EAAE,yBACb,YAAY,EAAE,6CACM,YAAY,kBAsDxD,CAAC"}
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.performMultipleUninstalls = exports.performSingleUninstall = exports.getInstallationsFromSelection = exports.getMultiChoiceOptionsForUninstall = void 0;
4
+ const cli_shared_1 = require("@forge/cli-shared");
5
+ const shared_1 = require("../installations/shared");
6
+ const errors_1 = require("./errors");
7
+ function addPrimarySuffix(productDisplayName, secondaryCount) {
8
+ return secondaryCount ? `${productDisplayName} (Primary)` : productDisplayName;
9
+ }
10
+ const getMultiChoiceOptionsForUninstall = (filteredInstallations) => {
11
+ return filteredInstallations.reduce((acc, { id, environmentKey, site, product, secondaryProducts, secondaryContexts }, idx) => {
12
+ acc.push({
13
+ names: [
14
+ (0, cli_shared_1.environmentToOption)(environmentKey),
15
+ site,
16
+ addPrimarySuffix((0, cli_shared_1.productDisplayName)(product), secondaryProducts?.length)
17
+ ],
18
+ value: id,
19
+ extra: {
20
+ installationIdx: idx,
21
+ product: product,
22
+ primary: !!secondaryProducts?.length
23
+ }
24
+ });
25
+ if (secondaryProducts) {
26
+ secondaryProducts.forEach((secondaryProduct, secondaryIdx) => {
27
+ const contextAri = secondaryContexts?.[secondaryIdx];
28
+ acc.push({
29
+ names: [(0, cli_shared_1.environmentToOption)(environmentKey), site, (0, cli_shared_1.productDisplayName)(secondaryProduct)],
30
+ value: id,
31
+ extra: { secondary: true, contextAri, installationIdx: idx, product: secondaryProduct }
32
+ });
33
+ });
34
+ }
35
+ return acc;
36
+ }, []);
37
+ };
38
+ exports.getMultiChoiceOptionsForUninstall = getMultiChoiceOptionsForUninstall;
39
+ const getInstallationsFromSelection = (options, selectedSitesIndexes, filteredInstallations) => {
40
+ const firstUninstall = options
41
+ .filter((_, idx) => selectedSitesIndexes.includes(idx))
42
+ .filter(({ extra }) => !extra?.primary)
43
+ .map(({ extra }) => ({
44
+ ...filteredInstallations[extra.installationIdx],
45
+ ...(extra.secondary && { context: extra.contextAri, product: extra.product })
46
+ }));
47
+ const secondUninstall = options
48
+ .filter((_, idx) => selectedSitesIndexes.includes(idx))
49
+ .filter(({ extra }) => extra?.primary)
50
+ .map(({ extra }) => filteredInstallations[extra.installationIdx]);
51
+ return [firstUninstall, secondUninstall];
52
+ };
53
+ exports.getInstallationsFromSelection = getInstallationsFromSelection;
54
+ const performSingleUninstall = async (installId, { ui, commands: { uninstallAppCommand } }) => {
55
+ const installation = await ui.displayProgress(() => uninstallAppCommand.execute(installId), cli_shared_1.Text.uninstall.cmd.start, (result) => ({
56
+ successful: !!result.successful,
57
+ message: cli_shared_1.Text.uninstall.cmd.success(false)
58
+ }));
59
+ const uninstallMessageFormat = installation.successful ? cli_shared_1.Text.uninstall.done : cli_shared_1.Text.uninstall.failed;
60
+ const uninstallMessage = uninstallMessageFormat((0, cli_shared_1.productDisplayName)(installation.product), installation.site, installation.environmentKey, false);
61
+ if (installation.successful) {
62
+ ui.info(uninstallMessage);
63
+ }
64
+ else {
65
+ ui.error(new shared_1.UninstallAppError(uninstallMessage));
66
+ }
67
+ };
68
+ exports.performSingleUninstall = performSingleUninstall;
69
+ const performMultipleUninstalls = async (appsToUninstallFirst, appsToUninstallSecond, { ui, commands: { uninstallAppCommand } }) => {
70
+ const filteredInstallations = appsToUninstallFirst.filter(({ product }) => product !== 'identity');
71
+ const hasMultipleNonIdentityApps = filteredInstallations.length > 1;
72
+ const uninstalledApps = await ui.displayProgress(async () => {
73
+ const result1 = await uninstallAppCommand.batchExecute([], appsToUninstallFirst);
74
+ if (result1.some(({ successful }) => successful === false)) {
75
+ return result1;
76
+ }
77
+ const result2 = await uninstallAppCommand.batchExecute([], appsToUninstallSecond);
78
+ return result1.concat(result2);
79
+ }, cli_shared_1.Text.uninstall.cmd.start, (result) => {
80
+ const isSuccessful = !result.some(({ successful }) => successful === false);
81
+ return {
82
+ successful: isSuccessful,
83
+ message: cli_shared_1.Text.uninstall.cmd.success(hasMultipleNonIdentityApps)
84
+ };
85
+ });
86
+ const deferredErrors = [];
87
+ uninstalledApps.forEach((uninstall) => {
88
+ const uninstallMessageFormat = uninstall.successful ? cli_shared_1.Text.uninstall.done : cli_shared_1.Text.uninstall.failed;
89
+ const formattedMessage = uninstallMessageFormat((0, cli_shared_1.productDisplayName)(uninstall.product), uninstall.site, uninstall.environmentKey, hasMultipleNonIdentityApps);
90
+ if (uninstall.successful && uninstall.product !== 'identity') {
91
+ ui.info(formattedMessage);
92
+ }
93
+ else if (!uninstall.successful) {
94
+ const uninstallError = new shared_1.UninstallAppError(formattedMessage);
95
+ ui.error(uninstallError);
96
+ deferredErrors.push(uninstallError);
97
+ }
98
+ });
99
+ if (uninstalledApps.some(({ successful }) => successful === false)) {
100
+ throw new errors_1.DeferredErrors(deferredErrors);
101
+ }
102
+ if (hasMultipleNonIdentityApps) {
103
+ ui.info(cli_shared_1.Text.uninstall.interactive.done);
104
+ }
105
+ };
106
+ exports.performMultipleUninstalls = performMultipleUninstalls;
@@ -21,7 +21,7 @@ const getCLIDetails = () => {
21
21
  }
22
22
  };
23
23
  exports.getCLIDetails = getCLIDetails;
24
- const supportedNodeMajorVersions = [18, 20];
24
+ const supportedNodeMajorVersions = [18, 20, 22];
25
25
  exports.semverSupportedNodeVersion = supportedNodeMajorVersions.map((v) => `${v}.x`).join(' || ');
26
26
  exports.humanReadableSupportedNodeVersion = supportedNodeMajorVersions
27
27
  .map((v) => `${v}.x`)