UNPKG

@salesforce/packaging

Version:

Packaging library for the Salesforce packaging platform

211 lines 10.1 kB
"use strict"; /* * Copyright 2026, Salesforce, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.createPackageInstallRequest = createPackageInstallRequest; exports.getStatus = getStatus; exports.isErrorFromSPVQueryRestriction = isErrorFromSPVQueryRestriction; exports.isErrorPackageNotAvailable = isErrorPackageNotAvailable; exports.getInstallationStatus = getInstallationStatus; exports.waitForPublish = waitForPublish; exports.pollStatus = pollStatus; const core_1 = require("@salesforce/core"); const ts_types_1 = require("@salesforce/ts-types"); const packageUtils_1 = require("../utils/packageUtils"); const interfaces_1 = require("../interfaces"); core_1.Messages.importMessagesDirectory(__dirname); const installMsgs = core_1.Messages.loadMessages('@salesforce/packaging', 'package_install'); let logger; const getLogger = () => { if (!logger) { logger = core_1.Logger.childFromRoot('installPackage'); } return logger; }; async function createPackageInstallRequest(connection, pkgInstallCreateRequest, packageType) { const defaults = { ApexCompileType: 'all', EnableRss: false, NameConflictResolution: 'Block', PackageInstallSource: 'U', SecurityType: 'None', UpgradeType: 'mixed-mode', }; const request = Object.assign({}, defaults, pkgInstallCreateRequest); if (request.Password) { request.Password = (0, packageUtils_1.escapeInstallationKey)(request.Password); } // Only unlocked packages can change the UpgradeType and ApexCompile options from the defaults. if (packageType !== 'Unlocked') { if (request.UpgradeType !== defaults.UpgradeType) { const msg = installMsgs.getMessage('upgradeTypeOnlyForUnlockedWarning'); await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageEvents.install.warning, msg); delete request.UpgradeType; } if (request.ApexCompileType !== defaults.ApexCompileType) { const msg = installMsgs.getMessage('apexCompileOnlyForUnlockedWarning'); await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageEvents.install.warning, msg); delete request.ApexCompileType; } } await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageEvents.install.presend, request); const result = await connection.tooling.create('PackageInstallRequest', request); await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageEvents.install.postsend, result); const packageInstallRequestId = result.id; if (!packageInstallRequestId) { throw installMsgs.createError('packageInstallRequestError', [ request.SubscriberPackageVersionKey, result.errors.toString(), ]); } return getStatus(connection, packageInstallRequestId); } async function getStatus(connection, packageInstallRequestId) { const results = (await connection.tooling.retrieve('PackageInstallRequest', packageInstallRequestId)); return results; } // determines if error is from malformed SubscriberPackageVersion query // this is in place to allow cli to run against app version 214, where SPV queries // do not require installation key function isErrorFromSPVQueryRestriction(err) { return (err.name === 'MALFORMED_QUERY' && err.message.includes('Implementation restriction: You can only perform queries of the form Id')); } function isErrorPackageNotAvailable(err) { return ['UNKNOWN_EXCEPTION', 'PACKAGE_UNAVAILABLE', 'PACKAGE_UNAVAILABLE_CRC', 'PACKAGE_UNAVAILABLE_ZIP'].includes(err.name); } async function getInstallationStatus(subscriberPackageVersionId, installationKey, connection) { let query = `SELECT Id, SubscriberPackageId, InstallValidationStatus FROM SubscriberPackageVersion WHERE Id ='${subscriberPackageVersionId}'`; if (installationKey) { query += ` AND InstallationKey ='${(0, packageUtils_1.escapeInstallationKey)(installationKey)}'`; } try { return await connection.tooling.query(query); } catch (e) { if (e instanceof Error && isErrorPackageNotAvailable(e)) { getLogger().debug('getInstallationStatus:', e.name); } else { throw e; } } } async function waitForPublish(connection, subscriberPackageVersionId, frequency, timeout, installationKey) { const pollingTimeout = (0, packageUtils_1.numberToDuration)(timeout); if (pollingTimeout.milliseconds <= 0) { return; } let queryResult; let installValidationStatus = 'PACKAGE_UNAVAILABLE'; const pollingOptions = { frequency: (0, packageUtils_1.numberToDuration)(frequency), timeout: pollingTimeout, poll: async () => { queryResult = await getInstallationStatus(subscriberPackageVersionId, installationKey, connection); // Continue retrying if there is no record // or for an InstallValidationStatus of PACKAGE_UNAVAILABLE (replication to the subscriber's instance has not completed) // or for an InstallValidationStatus of UNINSTALL_IN_PROGRESS // or PACKAGE_UNAVAILABLE_ZIP or PACKAGE_UNAVAILABLE_CRC if (queryResult?.records?.length) { installValidationStatus = queryResult.records[0].InstallValidationStatus; } getLogger().debug(installMsgs.getMessage('publishWaitProgress', [` Status = ${installValidationStatus}`])); await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageEvents.install['subscriber-status'], installValidationStatus); if (![ 'PACKAGE_UNAVAILABLE', 'PACKAGE_UNAVAILABLE_CRC', 'PACKAGE_UNAVAILABLE_ZIP', 'UNINSTALL_IN_PROGRESS', ].includes(installValidationStatus)) { return { completed: true, payload: installValidationStatus }; } return { completed: false, payload: installValidationStatus }; }, }; const pollingClient = await core_1.PollingClient.create(pollingOptions); try { getLogger().debug(`Polling for package availability in org. Package ID = ${subscriberPackageVersionId}`); getLogger().debug(`Polling frequency (ms): ${pollingOptions.frequency.milliseconds}`); getLogger().debug(`Polling timeout (min): ${pollingOptions.timeout.minutes}`); await pollingClient.subscribe(); } catch (e) { // For installation key problems throw that error. if (e instanceof Error && e.name.includes('INSTALL_KEY')) { throw core_1.SfError.create({ name: e.name, message: e.message, cause: e, }); } // if polling timed out const error = installMsgs.createError('subscriberPackageVersionNotPublished'); if (queryResult?.records[0]) { error.setData(queryResult?.records[0]); } if (error.stack && e instanceof Error && e.stack) { getLogger().debug(`Error during waitForPublish polling:\n${e.stack}`); // append the original stack to this new error error.stack += `\nDUE TO:\n${e.stack}`; if (e.message) { error.actions = (error.actions ?? []).concat([e.message]); } } throw error; } } async function pollStatus(connection, installRequestId, options = { pollingFrequency: 5000, pollingTimeout: 300_000 }) { let packageInstallRequest = await getStatus(connection, installRequestId); const { pollingFrequency, pollingTimeout } = options; const frequency = (0, packageUtils_1.numberToDuration)(pollingFrequency ?? 5000); const timeout = (0, packageUtils_1.numberToDuration)(pollingTimeout ?? 300_000); const pollingOptions = { frequency, timeout, poll: async () => { packageInstallRequest = await getStatus(connection, installRequestId); getLogger().debug(installMsgs.getMessage('packageInstallPolling', [packageInstallRequest?.Status])); await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageEvents.install.status, packageInstallRequest); if (['SUCCESS', 'ERROR'].includes(packageInstallRequest?.Status)) { return { completed: true, payload: packageInstallRequest }; } return { completed: false }; }, }; const pollingClient = await core_1.PollingClient.create(pollingOptions); try { getLogger().debug(`Polling for PackageInstallRequest status. Package ID = ${installRequestId}`); getLogger().debug(`Polling frequency (ms): ${pollingOptions.frequency.milliseconds}`); getLogger().debug(`Polling timeout (min): ${pollingOptions.timeout.minutes}`); await pollingClient.subscribe(); return packageInstallRequest; } catch (e) { const errMsg = e instanceof Error ? e.message : (0, ts_types_1.isString)(e) ? e : 'polling timed out'; const error = new core_1.SfError(errMsg, 'PackageInstallTimeout'); error.setData(packageInstallRequest); if (error.stack && e instanceof Error && e.stack) { // add the original stack to this new error error.stack += `\nDUE TO:\n${e.stack}`; if (e.message) { error.actions = (error.actions ?? []).concat([e.message]); } } throw error; } } //# sourceMappingURL=packageInstall.js.map