@forge/cli
14.1.0-next.19-experimental-fd0ebbc14.1.0-next.32
out/installations/graphql-client.js~
out/installations/graphql-client.jsModified+138−49
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';
@@ -23,8 +24,39 @@
exports.ALREADY_UPGRADED_CODE = 'INSTALLATION_ALREADY_UPGRADED';
const ALREADY_INSTALLED_CODE = 'APP_ALREADY_INSTALLED';
const INSTALLATION_LIMIT_REACHED_CODE = 'INSTALLATION_LIMIT_REACHED';
const PERMISSION_DENIED = 'PERMISSION_DENIED';
+const INSTALL_APPLICATION_MUTATION = (0, cli_shared_1.graphql)(`
+ mutation forge_cli_installApplication($input: AppInstallationInput!) {
+ installApp(input: $input) {
+ success
+ taskId
+ installationId
+ errors {
+ message
+ extensions {
+ errorType
+ statusCode
+ }
+ }
+ }
+ }
+`);
+const UPGRADE_APPLICATION_MUTATION = (0, cli_shared_1.graphql)(`
+ mutation forge_cli_upgradeApplication($input: AppInstallationUpgradeInput!) {
+ upgradeApp(input: $input) {
+ success
+ taskId
+ errors {
+ message
+ extensions {
+ errorType
+ statusCode
+ }
+ }
+ }
+ }
+`);
class PermissionDeniedError extends cli_shared_1.GraphQlMutationError {
constructor(requestId = 'unknown', appId = 'unknown', statusCode) {
super(cli_shared_1.Text.install.error.permissionsDeniedInstructions(requestId, appId), {
requestId,
@@ -136,16 +168,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,38 +224,22 @@
}
}
return undefined;
}
- async installAppIntoSite({ environmentKey, site, product, appId, licenseOverride, overrides, majorVersionId, environmentType }) {
- const workspaceAri = await this.buildInstallationContext(product, site);
- const query = (0, cli_shared_1.graphql)(`
- mutation forge_cli_installApplication($input: AppInstallationInput!) {
- installApp(input: $input) {
- success
- taskId
- errors {
- message
- extensions {
- errorType
- statusCode
- }
- }
- }
- }
- `);
+ async submitInstallMutation({ installationContext, appId, environmentKey, licenseOverride, overrides, majorVersionId, environmentType }) {
const variables = {
input: {
- installationContext: workspaceAri,
+ installationContext,
appId,
environmentKey,
async: true,
licenseOverride,
overrides,
...(majorVersionId ? { versionId: majorVersionId } : {})
}
};
- const { response, requestId, extensions } = await this.graphqlClient.mutate(query, variables);
- const { success, taskId, errors } = (0, cli_shared_1.requireMutationPayload)(response.installApp, requestId);
+ const { response, requestId, extensions } = await this.graphqlClient.mutate(INSTALL_APPLICATION_MUTATION, variables);
+ const { success, taskId, installationId, errors } = (0, cli_shared_1.requireMutationPayload)(response.installApp, requestId);
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 +253,96 @@
if (!taskId) {
throw new MissingTaskIdError(error.message);
}
await this.monitorAppInstallOrUpgrade(taskId, !!majorVersionId, environmentKey, environmentType);
- const warnings = this.extractInstallWarnings(extensions);
return {
- warnings
+ 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 { response, requestId } = await this.graphqlClient.mutate(UPGRADE_APPLICATION_MUTATION, {
+ input: {
+ installationContext,
+ appId,
+ environmentKey,
+ ...(majorVersionId ? { versionId: majorVersionId } : {}),
+ ...(isCodeUpgrade ? { computeOnly: isCodeUpgrade } : {}),
+ async: true
+ }
+ });
+ const { success, errors, taskId } = (0, cli_shared_1.requireMutationPayload)(response.upgradeApp, requestId);
+ 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 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((0, cli_shared_1.graphql)(`
@@ -299,35 +406,15 @@
}
}
async upgradeInstallation({ site, product, environmentKey, appId, currentVersion, majorVersionId, isCodeUpgrade, targetVersion, isLatest }) {
const workspaceAri = await this.buildInstallationContext(product, site);
- const query = (0, cli_shared_1.graphql)(`
- 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, requestId } = await this.graphqlClient.mutate(query, variables);
- const { success, errors, taskId } = (0, cli_shared_1.requireMutationPayload)(response.upgradeApp, requestId);
+ 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) {
@@ -773,8 +860,9 @@
versions(first: $firstN) {
nodes {
version
isLatest
+ installationTarget
requiredProducts
permissions {
egress {
addresses
@@ -825,8 +913,9 @@
nodes {
id
version
isLatest
+ installationTarget
requiredProducts
permissions {
egress {
addresses