@forge/cli
14.1.0-next.1-experimental-13c2f8d14.1.0-next.21-experimental-554d417
out/installations/graphql-client.js~
out/installations/graphql-client.jsModified+122−34
Index: package/out/installations/graphql-client.js
===================================================================
--- package/out/installations/graphql-client.js
+++ package/out/installations/graphql-client.js
@@ -4,8 +4,9 @@
const exponential_backoff_1 = require("exponential-backoff");
const ari_1 = require("@forge/util/packages/ari");
const cli_shared_1 = require("@forge/cli-shared");
const egress_1 = require("@forge/egress");
+const installation_helper_1 = require("./installation-helper");
const harmonized_app_installation_errors_1 = require("./harmonized-apps/harmonized-app-installation-errors");
exports.UNINSTALLATION_EVENT_POLL_INTERVAL = 500;
const DECOUPLED_STATE_NOT_ENABLED_CODE = 'DECOUPLED_STATE_NOT_ENABLED';
const APP_INSTALLATION_LIMIT_WARNING = 'APP_INSTALLATION_LIMIT_WARNING';
@@ -136,16 +137,24 @@
pause;
logger;
SITE_RESOURCE_TYPE = 'site';
WORKSPACE_RESOURCE_TYPE = 'workspace';
+ UNIT_RESOURCE_TYPE = 'unit';
static buildInstallationContext(product, resourceId, resourceType) {
const ari = ari_1.AnyAri.create({
resourceOwner: (0, cli_shared_1.ariResourceOwner)(product),
resourceType: resourceType,
resourceId: resourceId
});
return ari.toString();
}
+ static buildUnitInstallationContext(unitId) {
+ return ari_1.AnyAri.create({
+ resourceOwner: 'platform',
+ resourceType: 'unit',
+ resourceId: unitId
+ }).toString();
+ }
constructor(graphqlClient, sitedProductTranslator, bitbucketTranslator, pause, logger = cli_shared_1.NullLogger) {
this.graphqlClient = graphqlClient;
this.sitedProductTranslator = sitedProductTranslator;
this.bitbucketTranslator = bitbucketTranslator;
@@ -184,15 +193,15 @@
}
}
return undefined;
}
- async installAppIntoSite({ environmentKey, site, product, appId, licenseOverride, overrides, majorVersionId, environmentType }) {
- const workspaceAri = await this.buildInstallationContext(product, site);
+ async submitInstallMutation({ installationContext, appId, environmentKey, licenseOverride, overrides, majorVersionId, environmentType }) {
const query = `
mutation forge_cli_installApplication($input: AppInstallationInput!) {
installApp(input: $input) {
success
taskId
+ installationId
errors {
message
extensions {
errorType
@@ -203,9 +212,9 @@
}
`;
const variables = {
input: {
- installationContext: workspaceAri,
+ installationContext,
appId,
environmentKey,
async: true,
licenseOverride,
@@ -213,9 +222,9 @@
...(majorVersionId ? { versionId: majorVersionId } : {})
}
};
const mutationResult = await this.graphqlClient.mutate(query, variables);
- const { response: { installApp: { success, taskId, errors } }, requestId, extensions } = mutationResult;
+ const { response: { installApp: { success, taskId, installationId, errors } }, requestId, extensions } = mutationResult;
const error = (0, cli_shared_1.getError)(errors);
if (!success) {
if (error.code === PERMISSION_DENIED) {
throw new PermissionDeniedError(requestId, ari_1.AnyAri.parse(appId).resourceId, error.statusCode);
@@ -229,13 +238,111 @@
if (!taskId) {
throw new MissingTaskIdError(error.message);
}
await this.monitorAppInstallOrUpgrade(taskId, !!majorVersionId, environmentKey, environmentType);
- const warnings = this.extractInstallWarnings(extensions);
- return {
- warnings
- };
+ return { installationId: installationId ?? undefined, warnings: this.extractInstallWarnings(extensions) };
}
+ async installAppIntoSite({ environmentKey, site, product, appId, licenseOverride, overrides, majorVersionId, environmentType }) {
+ const { warnings } = await this.submitInstallMutation({
+ installationContext: await this.buildInstallationContext(product, site),
+ appId,
+ environmentKey,
+ licenseOverride,
+ overrides,
+ majorVersionId,
+ environmentType
+ });
+ return { warnings };
+ }
+ async installAppIntoUnit({ environmentKey, unitId, appId, licenseOverride, overrides, majorVersionId, environmentType }) {
+ const { installationId, warnings } = await this.submitInstallMutation({
+ installationContext: InstallationsGraphqlClient.buildUnitInstallationContext(unitId),
+ appId,
+ environmentKey,
+ licenseOverride,
+ overrides,
+ majorVersionId,
+ environmentType
+ });
+ const resolvedInstallationId = installationId ?? (await this.getUnitInstallationId(appId, environmentKey, unitId));
+ return { installationId: resolvedInstallationId, warnings };
+ }
+ async upgradeAppInUnit({ appId, environmentKey, unitId, majorVersionId, isCodeUpgrade }) {
+ const { success, errors, taskId, requestId } = await this.submitUpgradeMutation({
+ installationContext: InstallationsGraphqlClient.buildUnitInstallationContext(unitId),
+ appId,
+ environmentKey,
+ majorVersionId,
+ isCodeUpgrade
+ });
+ const error = (0, cli_shared_1.getError)(errors);
+ if (!success) {
+ throw new UpgradeError(`${error.message} (requestId: ${requestId || 'unknown'})`, {
+ requestId,
+ code: error.code,
+ statusCode: error.statusCode
+ });
+ }
+ if (!taskId) {
+ throw new MissingTaskIdError(error.message);
+ }
+ await this.monitorAppInstallOrUpgrade(taskId, !!majorVersionId, environmentKey);
+ }
+ async submitUpgradeMutation({ installationContext, appId, environmentKey, majorVersionId, isCodeUpgrade }) {
+ const query = `
+ mutation forge_cli_upgradeApplication($input: AppInstallationUpgradeInput!) {
+ upgradeApp(input: $input) {
+ success
+ taskId
+ errors {
+ message
+ extensions {
+ errorType
+ statusCode
+ }
+ }
+ }
+ }
+ `;
+ const { response: { upgradeApp: { success, errors, taskId } }, requestId } = await this.graphqlClient.mutate(query, {
+ input: {
+ installationContext,
+ appId,
+ environmentKey,
+ ...(majorVersionId ? { versionId: majorVersionId } : {}),
+ ...(isCodeUpgrade ? { computeOnly: isCodeUpgrade } : {}),
+ async: true
+ }
+ });
+ return { success, errors, taskId, requestId };
+ }
+ async getUnitInstallationId(appId, environmentKey, unitId) {
+ const installations = await this.listInstallations(appId, { environment: environmentKey });
+ return installations.find((installation) => installation.installedInUnit && installation.unitId === unitId)?.id;
+ }
+ async getUnitInstallations(appId, environmentKey) {
+ const installations = await this.listInstallations(appId, { environment: environmentKey });
+ return installations
+ .filter((installation) => Boolean(installation.installedInUnit && installation.unitId))
+ .map((installation) => ({
+ unitId: installation.unitId,
+ environmentKey: installation.environmentKey,
+ connections: (installation.connections ?? []).map((connection) => connection.product),
+ version: installation.version.version,
+ isLatest: installation.version.isLatest
+ }));
+ }
+ async getLinkedConnectionProducts(appId, installationId) {
+ const installation = await this.getInstallation(appId, installationId);
+ return (installation.connections ?? []).map((connection) => connection.product);
+ }
+ async linkOptionalConnection(installationId, product, site) {
+ const context = await this.buildInstallationContext(product, site);
+ await this.provisionInstallationLink({
+ installationAri: (0, installation_helper_1.buildInstallationContextFromId)(installationId),
+ context
+ });
+ }
async getEntitlementOffering(site, product) {
try {
const productKeys = this.getHamsProductKeys(product);
const results = await Promise.allSettled(productKeys.map((productKey) => this.graphqlClient.query(`query getEntitlementOffering($hostNames: [String!], $product: String!) {
@@ -297,34 +404,15 @@
}
}
async upgradeInstallation({ site, product, environmentKey, appId, currentVersion, majorVersionId, isCodeUpgrade, targetVersion, isLatest }) {
const workspaceAri = await this.buildInstallationContext(product, site);
- const query = `
- mutation forge_cli_upgradeApplication($input: AppInstallationUpgradeInput!) {
- upgradeApp(input: $input) {
- success
- taskId
- errors {
- message
- extensions {
- errorType
- statusCode
- }
- }
- }
- }
- `;
- const variables = {
- input: {
- installationContext: workspaceAri,
- appId,
- environmentKey,
- ...(majorVersionId ? { versionId: majorVersionId } : {}),
- ...(isCodeUpgrade ? { computeOnly: isCodeUpgrade } : {}),
- async: true
- }
- };
- const { response: { upgradeApp: { success, errors, taskId } }, requestId } = await this.graphqlClient.mutate(query, variables);
+ const { success, errors, taskId, requestId } = await this.submitUpgradeMutation({
+ installationContext: workspaceAri,
+ appId,
+ environmentKey,
+ majorVersionId,
+ isCodeUpgrade
+ });
const error = (0, cli_shared_1.getError)(errors);
if (!success) {
const { VERSION_DECREASES_ROLLING_RELEASE_CODE, MISSING_APP_MANAGED_PERMISSIONS_ROLLING_RELEASE_CODE } = RollingReleaseValidationErrorCodes;
switch (error.code) {