npm package diff

Package: @forge/cli

Versions: 11.3.0-next.17-experimental-beb5acf - 11.3.0-next.22

File: package/out/command-line/controller/install-controller.js

Index: package/out/command-line/controller/install-controller.js
===================================================================
--- package/out/command-line/controller/install-controller.js
+++ package/out/command-line/controller/install-controller.js
@@ -82,9 +82,10 @@
             await this.ui.promptForList(cli_shared_1.Text.installationContext.promptProduct, this.supportedProductsService.getSupportedProducts())
         ];
     }
     async promptForSite(products) {
-        const isWorkspaceBased = products.length > 0 && this.supportedProductsService.isWorkspaceProduct(products[0]);
+        const displayName = (0, cli_shared_1.productDisplayName)(products[0]);
+        const isWorkspaceBased = products.length > 0 && this.supportedProductsService.isWorkspaceProduct(displayName);
         const overviewText = isWorkspaceBased
             ? cli_shared_1.Text.installationContext.overviewWorkspace
             : cli_shared_1.Text.installationContext.overviewSite;
         this.ui.info(overviewText);
@@ -95,23 +96,38 @@
         const invalidText = isWorkspaceBased ? cli_shared_1.Text.error.invalidWorkspace : cli_shared_1.Text.error.invalidSite;
         if (!trySite) {
             throw new cli_shared_1.ValidationError(invalidText);
         }
-        return this.supportedProductsService.validateSite(trySite, products[0]);
+        return this.supportedProductsService.validateSite(trySite, displayName);
     }
-    async promptForUpgrade(siteOption, productOption, environmentOption) {
+    async getAppInstallations(siteOption, productOption, environmentOption) {
         const { installations } = await this.installationService.listNonTechnicalAppInstallations({
             site: siteOption,
             product: productOption,
             environment: environmentOption
         });
-        const { site, product, environmentKey, environmentType } = await this.installView.promptForUpgrade(installations);
+        return installations;
+    }
+    async getInstallationToUpgrade(siteOption, productOption, environmentOption) {
+        const matchingInstallations = await this.getAppInstallations(siteOption, productOption, environmentOption);
+        let selectedInstallationToUpgrade;
+        if (siteOption && productOption?.length) {
+            if (!matchingInstallations.length) {
+                throw new cli_shared_1.ValidationError(cli_shared_1.Text.error.invalidInstallationContext);
+            }
+            selectedInstallationToUpgrade = matchingInstallations[0];
+        }
+        else {
+            selectedInstallationToUpgrade = await this.installView.promptForUpgrade(matchingInstallations);
+        }
+        const { site, product, environmentKey, environmentType, version } = selectedInstallationToUpgrade;
         const productName = (0, cli_shared_1.productDisplayName)(product);
         return {
             site: this.supportedProductsService.validateSite(site, productName),
-            product: productName,
+            product: this.supportedProductsService.validateSupportedProduct(productName),
             environment: environmentKey,
-            environmentType
+            environmentType,
+            scopes: version.scopes
         };
     }
     getUniqueInstallationProductsFromScopes(scopes) {
         if (!scopes || scopes.length === 0)
@@ -145,8 +161,10 @@
         }
         return upperCaseLicense;
     }
     checkForUIKit1Modules = (modules) => {
+        if (!modules)
+            return;
         const uiKit1Modules = (0, cli_shared_1.findUIKit1Modules)(modules);
         if (uiKit1Modules.length > 0) {
             this.installView.displayUIKit1DeprecationMessage(uiKit1Modules);
         }
@@ -157,21 +175,21 @@
         const validLicense = this.validateLicenseOption(license, environment);
         const overrides = await this.validateEcosystemAppInstallationOverridesInput(licenseModes, usersWithAccess, environment);
         const environmentPermissions = await this.installationService.getAppEnvironmentPermissions(id, environment);
         const requiredProducts = environmentPermissions?.requiredProducts;
-        if (upgrade && (!site || !products?.length)) {
-            const upgradeResult = await this.promptForUpgrade(site, products?.[0], environment);
+        let scopesFromLastInstallation = new Set();
+        if (upgrade) {
+            const upgradeResult = await this.getInstallationToUpgrade(site, products?.[0], environment);
             environment = upgradeResult.environment;
             site = upgradeResult.site;
             products = [upgradeResult.product];
+            scopesFromLastInstallation = new Set(upgradeResult.scopes);
+            this.ui.info(this.supportedProductsService.isWorkspaceProduct(products[0]) ? text.bannerWorkspace : text.bannerSite);
         }
-        if (!requiredProducts?.length) {
+        else if (!requiredProducts?.length) {
             products = products?.length ? products : await this.promptForProducts();
             site = site ? site : await this.promptForSite(products);
-            const bannerText = (await this.supportedProductsService.isWorkspaceProduct(products[0]))
-                ? text.bannerWorkspace
-                : text.bannerSite;
-            this.ui.info(bannerText);
+            this.ui.info(this.supportedProductsService.isWorkspaceProduct(products[0]) ? text.bannerWorkspace : text.bannerSite);
         }
         else {
             const result = await this.getXPAProductsAndSite(requiredProducts.map(cli_shared_1.productDisplayName), products, site);
             site = result.site;
@@ -184,23 +202,18 @@
         if (!environmentPermissions?.hasDeployments) {
             this.ui.error(new NoDeploymentError(environment), { pad: false });
             return;
         }
-        if (environmentPermissions.scopes === undefined) {
-            environmentPermissions.scopes = [];
-        }
+        environmentPermissions.scopes = environmentPermissions.scopes ?? [];
         const { scopes: environmentScopes, environmentType } = environmentPermissions;
         const [{ permissions, modules }, manifestEgressEntries] = await Promise.all([
             this.configFile.readConfig(),
             this.configFile.getEgressPermissions()
         ]);
-        if (modules) {
-            this.checkForUIKit1Modules(modules);
-        }
-        const manifestEgressAddresses = (0, cli_shared_1.flatMap)(manifestEgressEntries, ({ domains }) => domains ?? []);
-        const manifestScopes = new Set(permissions?.scopes ?? []);
-        const listScopesString = upgrade ? environmentPermissions.addedScopes : environmentPermissions.scopes;
-        const listScopes = await this.convertListScope(listScopesString);
+        this.checkForUIKit1Modules(modules);
+        const { manifestEgressAddresses, manifestScopes } = this.extractManifestData(manifestEgressEntries, permissions);
+        const differenceInScopes = environmentScopes.filter((x) => !scopesFromLastInstallation.has(x));
+        const listScopes = await this.convertListScope(differenceInScopes);
         const scopesConfirmationResult = await this.installView.promptForPermissionsConfirmation(environmentPermissions, listScopes, [...manifestScopes], manifestEgressAddresses, environment, confirmScopes, !!nonInteractive, text);
         if (!scopesConfirmationResult)
             return;
         const successfulProducts = [];
@@ -226,15 +239,20 @@
         }
         if (successfulProducts.length) {
             this.ui.info(text.success.banner(environment, environmentType, (0, cli_shared_1.productDisplayName)(successfulProducts.join(', ')), site.host));
         }
-        else {
+        else if (!upgrade) {
             this.ui.info(cli_shared_1.Text.install.failedAll(site, environment));
         }
         if (failedProducts.length) {
             throw new cli_shared_1.PartialInstallationError(cli_shared_1.Text.error.partialInstallation(failedProducts));
         }
     }
+    extractManifestData = (manifestEgressEntries, permissions) => {
+        const manifestEgressAddresses = (0, cli_shared_1.flatMap)(manifestEgressEntries, ({ domains }) => domains ?? []);
+        const manifestScopes = new Set(permissions?.scopes ?? []);
+        return { manifestEgressAddresses, manifestScopes };
+    };
     getXPAProductsAndSite = async (requiredProducts, products, site) => {
         const { installations } = (await this.installationService.listAppInstallations()) ?? [];
         site = site ? site : await this.promptForSite([]);
         if (!products?.length) {
@@ -244,9 +262,9 @@
                 products = products?.length ? products : await this.promptForProducts(requiredProducts);
             }
             else {
                 this.ui.info(cli_shared_1.Text.install.installingToRequiredProduct(requiredProducts[0]));
-                products = requiredProducts;
+                products = requiredProducts.map((product) => (0, cli_shared_1.productDisplayName)(product));
             }
         }
         else {
             const allowedProducts = this.supportedProductsService.getSupportedSecondaryProductsForXPA([]);