npm package diff

Package: @forge/cli

Versions: 10.13.6 - 11.0.0-next.18

File: package/out/service/installation-service.js

Index: package/out/service/installation-service.js
===================================================================
--- package/out/service/installation-service.js
+++ package/out/service/installation-service.js
@@ -1,44 +1,75 @@
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.InstallationService = void 0;
+exports.InstallationService = exports.MultipleMatchingInstallationsError = void 0;
 const cli_shared_1 = require("@forge/cli-shared");
 const egress_1 = require("@forge/egress");
 const lodash_1 = require("lodash");
 const graphql_client_1 = require("../installations/graphql-client");
 const IDENTITY_PRODUCT_NAME = 'identity';
+const BITBUCKET_PRODUCT_NAME = 'bitbucket';
 const JIRA_SERVICE_DESK_PRODUCT_NAME = 'jira-servicedesk';
+class MultipleMatchingInstallationsError extends cli_shared_1.BaseError {
+    constructor() {
+        super(cli_shared_1.Text.error.multipleMatchingInstallations);
+    }
+}
+exports.MultipleMatchingInstallationsError = MultipleMatchingInstallationsError;
 class InstallationService {
     getAppConfig;
     listInstallationsClient;
     upgradeAppInstallationsClient;
-    constructor(getAppConfig, listInstallationsClient, upgradeAppInstallationsClient) {
+    hasNoAppInstallationsForEnvClient;
+    constructor(getAppConfig, listInstallationsClient, upgradeAppInstallationsClient, hasNoAppInstallationsForEnvClient) {
         this.getAppConfig = getAppConfig;
         this.listInstallationsClient = listInstallationsClient;
         this.upgradeAppInstallationsClient = upgradeAppInstallationsClient;
+        this.hasNoAppInstallationsForEnvClient = hasNoAppInstallationsForEnvClient;
     }
+    comparePossibleInstallations(url1, url2) {
+        const trimmedUrl1 = url1.replace(/\/+$/, '');
+        const trimmedUrl2 = url2.replace(/\/+$/, '');
+        return trimmedUrl1 === trimmedUrl2;
+    }
+    matchSiteForProduct(filterSite, installationSite, installationProduct) {
+        if (installationProduct === BITBUCKET_PRODUCT_NAME) {
+            return this.comparePossibleInstallations(filterSite.href, installationSite);
+        }
+        return this.comparePossibleInstallations(filterSite.host, installationSite);
+    }
     filterInstallations(installations, { site: filterSite, product: filterProduct, environment: filterEnvironment }) {
-        const isDefaultEnvironment = (env) => env === (0, cli_shared_1.optionToEnvironment)(cli_shared_1.DEFAULT_ENVIRONMENT_OPTION);
         return installations.filter(({ product, site, environmentKey }) => {
             const matchProduct = !filterProduct || filterProduct === (0, cli_shared_1.productDisplayName)(product);
-            const matchSite = !filterSite || filterSite === site;
-            const matchEnvironment = filterEnvironment
-                ? isDefaultEnvironment(filterEnvironment) || filterEnvironment === (0, cli_shared_1.environmentToOption)(environmentKey)
-                : true;
+            const matchSite = !filterSite || this.matchSiteForProduct(filterSite, site, product);
+            const matchEnvironment = !filterEnvironment || filterEnvironment === (0, cli_shared_1.optionToEnvironment)(environmentKey);
             return matchProduct && matchSite && matchEnvironment;
         });
     }
     async listAppInstallations(filter) {
         const { id: appId } = await this.getAppConfig();
         const installations = await this.listInstallationsClient.listInstallations(appId);
         return { installations: this.filterInstallations(installations, { ...filter }) };
     }
+    async hasNoAppInstallationsForEnv(appEnv) {
+        const { id: appId } = await this.getAppConfig();
+        return this.hasNoAppInstallationsForEnvClient.hasNoAppInstallationsForEnv(appId, appEnv);
+    }
     async listNonTechnicalAppInstallations(filter) {
         const { installations } = await this.listAppInstallations(filter);
         return {
             installations: installations.filter(({ product }) => product !== IDENTITY_PRODUCT_NAME && product !== JIRA_SERVICE_DESK_PRODUCT_NAME)
         };
     }
+    async findOnlyMatchingInstallation(filter) {
+        const filterInstalls = await this.listNonTechnicalAppInstallations(filter);
+        if (!filterInstalls.installations.length) {
+            throw new cli_shared_1.UserError(cli_shared_1.Text.error.invalidInstallationContext);
+        }
+        if (filterInstalls.installations.length !== 1) {
+            throw new MultipleMatchingInstallationsError();
+        }
+        return filterInstalls.installations[0];
+    }
     async hasOutdatedProductInstallation(environment) {
         const { installations } = await this.listNonTechnicalAppInstallations({
             environment
         });
@@ -64,25 +95,27 @@
         }
     }
     getPermissionsFromAppEnvironmentVersion(appEnvironmentVersion) {
         const permissions = appEnvironmentVersion?.permissions[0];
+        const primaryProduct = appEnvironmentVersion?.primaryProduct ?? undefined;
         if (!permissions) {
-            return { scopes: [], egressAddresses: [] };
+            return { scopes: [], egressAddresses: [], primaryProduct };
         }
         const scopes = permissions.scopes.map((s) => s.key);
         const egressAddresses = permissions?.egress ? (0, cli_shared_1.flatMap)(permissions.egress, ({ addresses }) => addresses ?? []) : [];
-        return { scopes, egressAddresses };
+        return { scopes, egressAddresses, primaryProduct };
     }
     async getAppEnvironmentPermissions(appId, environmentKey) {
         const versionDetails = await this.listInstallationsClient.getVersions(appId, environmentKey, 2);
         const versions = versionDetails?.nodes;
         if (!versions || versions.length === 0)
             return;
-        const [{ scopes, egressAddresses }, oldVersion] = versions.map((appEnvironmentVersion) => this.getPermissionsFromAppEnvironmentVersion(appEnvironmentVersion));
+        const [{ scopes, egressAddresses, primaryProduct }, oldVersion] = versions.map((appEnvironmentVersion) => this.getPermissionsFromAppEnvironmentVersion(appEnvironmentVersion));
         const groupedEgressAddresses = (0, egress_1.sortAndGroupEgressPermissionsByDomain)(egressAddresses);
         if (!oldVersion) {
             return {
                 scopes,
+                primaryProduct,
                 hasDeployments: false,
                 egressAddresses: groupedEgressAddresses,
                 addedScopes: scopes,
                 environmentType: versionDetails.environmentType
@@ -91,8 +124,9 @@
         const { scopes: oldScopes } = oldVersion;
         const addedScopes = (0, lodash_1.difference)(scopes, oldScopes);
         return {
             scopes,
+            primaryProduct,
             hasDeployments: true,
             egressAddresses: groupedEgressAddresses,
             addedScopes,
             environmentType: versionDetails.environmentType