UNPKG

salesforce-alm

Version:

This package contains tools, and APIs, for an improved salesforce.com developer experience.

165 lines (163 loc) 7.33 kB
"use strict"; /* * Copyright (c) 2020, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ Object.defineProperty(exports, "__esModule", { value: true }); exports.SourceDeployApiBase = void 0; const BBPromise = require("bluebird"); const replace = BBPromise.promisify(require('replace')); const kit_1 = require("@salesforce/kit"); const core_1 = require("@salesforce/core"); const consts = require("../core/constants"); const StashApi = require("../core/stash"); const srcDevUtil = require("../core/srcDevUtil"); const MdapiDeployApi = require("../mdapi/mdapiDeployApi"); const MdapiPollIntervalStrategy = require("../mdapi/mdapiPollIntervalStrategy"); const parseManifestEntriesArray_1 = require("./parseManifestEntriesArray"); const workspaceFileState_1 = require("./workspaceFileState"); const SourceConvertApi = require("./sourceConvertApi"); const { INSTANCE_URL_TOKEN } = consts; const { sequentialExecute } = srcDevUtil; class SourceDeployApiBase extends kit_1.AsyncCreatable { constructor(options) { super(options); this.orgApi = options.org; this.force = options.org.force; this.isAsync = !!options.isAsync; } async init() { this.logger = await core_1.Logger.child(this.constructor.name); } /** * Set additional required MDAPI options config and deploy * * @param options The flags on the context passed to the command. * @param {any} pollIntervalStrategy The strategy for how often to poll when doing a MD deploy * @returns {any} */ mdapiDeploy(options, pollIntervalStrategy) { // Default to disable mdapi logging. Only when checkonly is explicitly true, // or testlevel is set, use the mdapi logging. options.disableLogging = !(options.checkonly === true || options.testlevel); options.autoUpdatePackage = false; options.testlevel = options.testlevel || 'NoTestRun'; options.source = true; return new MdapiDeployApi(this.orgApi, pollIntervalStrategy, StashApi.Commands.SOURCE_DEPLOY).deploy(options); } /** * Set the state of the source elements that were deployed * * @param aggregateSourceElements The map of source elements to deploy * @returns {any} */ getOutboundFiles(aggregateSourceElements, isDelete = false) { let deployedSourceElements = []; aggregateSourceElements.getAllSourceElements().forEach((aggregateSourceElement) => { deployedSourceElements = deployedSourceElements.concat(isDelete ? aggregateSourceElement.getWorkspaceElements().filter((el) => el.getState() === workspaceFileState_1.WorkspaceFileState.DELETED) : aggregateSourceElement.getWorkspaceElements()); }); return deployedSourceElements.map((workspaceElement) => workspaceElement.toObject()); } /** * Convert the SDFX-formatted source to MD-format and then deploy it to the org * * @param options The flags on the context passed to the command. * @param sourceWorkspaceAdapter * @param aggregateSourceElements The map of source elements to deploy * @param {boolean} createDestructiveChanges Whether destructiveChanges.xml needs to be created for this deployment * @returns {any} */ async convertAndDeploy(options, sourceWorkspaceAdapter, aggregateSourceElements, createDestructiveChanges) { const sourceConvertApi = new SourceConvertApi(this.orgApi, sourceWorkspaceAdapter); let result; try { const [sourceElementsToUpsert, deletedTypeNamePairs] = await sourceConvertApi.convertSourceToMdapi(options.deploydir, null, aggregateSourceElements, createDestructiveChanges, options.unsupportedMimeTypes, options.delete); // replace tokens embedded in source if (options.replacetokens) { await this.replaceTokens(options.deploydir); } let pollIntervalStrategy; // If checkonly or testlevel is set don't provide a poller or it will display // a status message from the mdapiDeploy logging on every poll. if (!(options.checkonly || options.testlevel || this.isAsync)) { pollIntervalStrategy = new MdapiPollIntervalStrategy(sourceElementsToUpsert, deletedTypeNamePairs); } result = await this.mdapiDeploy(options, pollIntervalStrategy); return result; } catch (err) { if (err.name === 'mdapiDeployFailed') { result = err.result; return result; } throw err; } finally { // Emit post deploy event upon success or failure. If result is undefined // most likely there was an error during conversion. if (result) { core_1.Lifecycle.getInstance().emit('postdeploy', result); } } } /** * Remove source elements that failed to deploy * * @param componentFailures * @param aggregateSourceElements */ removeFailedAggregates(componentFailures, deployedSourceElements) { let failedSourcePaths = []; const failures = parseManifestEntriesArray_1.toArray(componentFailures); failures.forEach((failure) => { const key = `${failure.componentType}__${failure.fullName}`; const packageName = core_1.SfdxProject.getInstance().getPackageNameFromPath(failure.fileName); const element = deployedSourceElements.getSourceElement(packageName, key); if (element) { // eslint-disable-next-line @typescript-eslint/no-shadow element.getWorkspaceElements().forEach((element) => { failedSourcePaths = failedSourcePaths.concat(element.getSourcePath()); }); deployedSourceElements.deleteSourceElement(packageName, key); } }); } /** * Some metadata types, such as RemoteSiteSetting, contain values specific to an org and need to be replaced * when the source is deployed to a new org * * @param dir The directory where the metadata resides */ // eslint-disable-next-line @typescript-eslint/require-await async replaceTokens(dir) { const replaceConfigs = [ { regex: INSTANCE_URL_TOKEN, replacement: this.orgApi.authConfig.instanceUrl, paths: [dir], recursive: true, includes: ['*.remoteSite-meta.xml'], silent: true, }, ]; const replaceFns = []; replaceConfigs.forEach((replaceConfig) => { replaceFns.push(() => new BBPromise((resolve, reject) => { try { replace(replaceConfig); return resolve(); } catch (err) { return reject(err); } })); }); return sequentialExecute(replaceFns); } } exports.SourceDeployApiBase = SourceDeployApiBase; //# sourceMappingURL=sourceDeployApiBase.js.map