@salesforce/packaging
Version:
Packaging library for the Salesforce packaging platform
168 lines • 8.61 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PackageBundleInstall = void 0;
/*
* 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.
*/
const core_1 = require("@salesforce/core");
const kit_1 = require("@salesforce/kit");
const interfaces_1 = require("../interfaces");
const bundleUtils_1 = require("../utils/bundleUtils");
core_1.Messages.importMessagesDirectory(__dirname);
const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'bundle_install');
class PackageBundleInstall {
static async getInstallStatus(installRequestId, connection) {
try {
const query = 'SELECT Id, InstallStatus, PackageBundleVersionId, DevelopmentOrganization, ValidationError, ' +
'CreatedDate, CreatedById ' +
`FROM PkgBundleVersionInstallReq WHERE Id = '${installRequestId}'`;
const queryResult = await connection.autoFetchQuery(query, {
tooling: true,
});
if (!queryResult.records || queryResult.records.length === 0) {
throw new Error(messages.getMessage('failedToGetPackageBundleInstallStatus'));
}
const record = queryResult.records[0];
return {
Id: record.Id,
InstallStatus: record.InstallStatus,
PackageBundleVersionId: record.PackageBundleVersionId ?? '',
DevelopmentOrganization: record.DevelopmentOrganization ?? '',
ValidationError: record.ValidationError ?? '',
CreatedDate: record.CreatedDate ?? '',
CreatedById: record.CreatedById ?? '',
Error: record.Error,
};
}
catch (err) {
const error = err instanceof Error ? err : new Error(messages.getMessage('failedToGetPackageBundleInstallStatus'));
throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(error));
}
}
static async getInstallStatuses(connection, status, createdLastDays) {
let query = 'SELECT Id, InstallStatus, PackageBundleVersionId, DevelopmentOrganization, ValidationError, ' +
'CreatedDate, CreatedById ' +
'FROM PkgBundleVersionInstallReq';
if (status && createdLastDays) {
query += ` WHERE InstallStatus = '${status}' AND CreatedDate = LAST_N_DAYS: ${createdLastDays}`;
}
else if (status) {
query += ` WHERE InstallStatus = '${status}'`;
}
else if (createdLastDays) {
query += ` WHERE CreatedDate = LAST_N_DAYS: ${createdLastDays}`;
}
const queryResult = await connection.autoFetchQuery(query, {
tooling: true,
});
return queryResult.records.map((record) => ({
Id: record.Id,
InstallStatus: record.InstallStatus,
PackageBundleVersionId: record.PackageBundleVersionId ?? '',
DevelopmentOrganization: record.DevelopmentOrganization ?? '',
ValidationError: record.ValidationError ?? '',
CreatedDate: record.CreatedDate ?? '',
CreatedById: record.CreatedById ?? '',
Error: record.Error,
}));
}
static async installBundle(connection, project, options) {
const packageBundleVersionId = PackageBundleInstall.parsePackageBundleVersionId(options.PackageBundleVersion, project);
const request = {
PackageBundleVersionId: packageBundleVersionId,
DevelopmentOrganization: options.DevelopmentOrganization,
};
let installResult;
try {
installResult = await connection.tooling.sobject('PkgBundleVersionInstallReq').create(request);
}
catch (err) {
const error = err instanceof Error
? err
: new Error(typeof err === 'string' ? err : messages.getMessage('failedToInstallPackageBundle'));
throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(error));
}
if (!installResult?.success) {
throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(new Error(messages.getMessage('failedToInstallPackageBundle'))));
}
if (options.polling) {
return PackageBundleInstall.pollInstallStatus(installResult.id, connection, options.polling);
}
// When not polling, query the actual status from the server to get accurate information
return PackageBundleInstall.getInstallStatus(installResult.id, connection);
}
static parsePackageBundleVersionId(packageBundleVersion, project) {
// Check if it's already an ID (starts with appropriate prefix)
if (/^1Q8.{15}$/.test(packageBundleVersion)) {
return packageBundleVersion;
}
// Otherwise, treat it as an alias and resolve it from sfdx-project.json
const packageBundleVersionId = project.getPackageBundleIdFromAlias(packageBundleVersion);
if (!packageBundleVersionId) {
throw new core_1.SfError(messages.getMessage('noPackageBundleVersionFoundWithAlias', [packageBundleVersion]));
}
return packageBundleVersionId;
}
static async pollInstallStatus(installRequestId, connection, polling) {
if (polling.timeout?.milliseconds <= 0) {
return PackageBundleInstall.getInstallStatus(installRequestId, connection);
}
let remainingWaitTime = polling.timeout;
const pollingClient = await core_1.PollingClient.create({
poll: async () => {
const report = await PackageBundleInstall.getInstallStatus(installRequestId, connection);
switch (report.InstallStatus) {
case interfaces_1.BundleSObjects.PkgBundleVersionInstallReqStatus.queued:
case interfaces_1.BundleSObjects.PkgBundleVersionInstallReqStatus.inProgress:
// Emit progress event for UI updates
await core_1.Lifecycle.getInstance().emit('bundle-install-progress', { ...report, remainingWaitTime });
remainingWaitTime = kit_1.Duration.seconds(remainingWaitTime.seconds - polling.frequency.seconds);
return {
completed: false,
payload: report,
};
case interfaces_1.BundleSObjects.PkgBundleVersionInstallReqStatus.success:
return { completed: true, payload: report };
case interfaces_1.BundleSObjects.PkgBundleVersionInstallReqStatus.error:
return { completed: true, payload: report };
default:
// Handle any unexpected status by continuing to poll
await core_1.Lifecycle.getInstance().emit('bundle-install-progress', { ...report, remainingWaitTime });
remainingWaitTime = kit_1.Duration.seconds(remainingWaitTime.seconds - polling.frequency.seconds);
return {
completed: false,
payload: report,
};
}
},
frequency: polling.frequency,
timeout: polling.timeout,
});
try {
return await pollingClient.subscribe();
}
catch (err) {
const report = await PackageBundleInstall.getInstallStatus(installRequestId, connection);
if (err instanceof Error) {
const timeoutError = new core_1.SfError(`Install request timed out. Run 'sf package bundle install report -i ${installRequestId} -o <target-org>' to check the status.`);
timeoutError.setData({ InstallRequestId: installRequestId, ...report });
throw timeoutError;
}
throw err;
}
}
}
exports.PackageBundleInstall = PackageBundleInstall;
//# sourceMappingURL=packageBundleInstall.js.map