@salesforce/packaging
Version:
Packaging library for the Salesforce packaging platform
279 lines • 14.9 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.PackageBundleVersionCreate = 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 fs = __importStar(require("node:fs"));
const core_1 = require("@salesforce/core");
const bundleUtils_1 = require("../utils/bundleUtils");
core_1.Messages.importMessagesDirectory(__dirname);
const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'bundle_version_create');
class PackageBundleVersionCreate {
static async getCreateStatus(createPackageVersionRequestId, connection) {
try {
const query = 'SELECT Id, RequestStatus, PackageBundle.Id, PackageBundle.BundleName, PackageBundleVersion.Id, ' +
'VersionName, MajorVersion, MinorVersion, Ancestor.Id, BundleVersionComponents, ' +
'CreatedDate, CreatedById, ValidationError ' +
`FROM PkgBundleVersionCreateReq WHERE Id = '${createPackageVersionRequestId}'`;
const queryResult = await connection.autoFetchQuery(query, {
tooling: true,
});
if (!queryResult.records || queryResult.records.length === 0) {
throw new Error(messages.getMessage('failedToGetPackageBundleVersionCreateStatus'));
}
const record = queryResult.records[0];
return {
Id: record.Id,
RequestStatus: record.RequestStatus,
PackageBundleId: record.PackageBundle?.Id ?? '',
PackageBundleVersionId: record.PackageBundleVersion?.Id ?? '',
VersionName: record.VersionName ?? '',
MajorVersion: record.MajorVersion ?? '',
MinorVersion: record.MinorVersion ?? '',
Ancestor: record.Ancestor?.Id ?? '',
BundleVersionComponents: record.BundleVersionComponents ?? '',
CreatedDate: record.CreatedDate ?? '',
CreatedById: record.CreatedById ?? '',
ValidationError: record.ValidationError ?? '',
};
}
catch (error) {
throw (0, bundleUtils_1.massageErrorMessage)(error);
}
}
static async getCreateStatuses(connection, status, createdLastDays) {
let query = 'SELECT Id, RequestStatus, PackageBundle.Id, PackageBundle.BundleName, PackageBundleVersion.Id, ' +
'VersionName, MajorVersion, MinorVersion, Ancestor.Id, BundleVersionComponents, ' +
'CreatedDate, CreatedById, ValidationError ' +
'FROM PkgBundleVersionCreateReq';
if (status && createdLastDays) {
query += ` WHERE RequestStatus = '${status}' AND CreatedDate = LAST_N_DAYS: ${createdLastDays}`;
}
else if (status) {
query += ` WHERE RequestStatus = '${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,
RequestStatus: record.RequestStatus,
PackageBundleId: record.PackageBundle?.Id ?? '',
PackageBundleVersionId: record.PackageBundleVersion?.Id ?? '',
VersionName: record.VersionName ?? '',
MajorVersion: record.MajorVersion ?? '',
MinorVersion: record.MinorVersion ?? '',
Ancestor: record.Ancestor?.Id ?? '',
BundleVersionComponents: record.BundleVersionComponents ?? '',
CreatedDate: record.CreatedDate ?? '',
CreatedById: record.CreatedById ?? '',
ValidationError: record.ValidationError ?? '',
}));
}
static async createBundleVersion(connection, project, options) {
const bundleVersionComponents = PackageBundleVersionCreate.readBundleVersionComponents(options.BundleVersionComponentsPath, project);
const packageBundleId = PackageBundleVersionCreate.parsePackageBundleId(options.PackageBundle, project);
// Use provided MajorVersion and MinorVersion if they are not empty strings, otherwise get from bundle configuration
const version = options.MajorVersion && options.MinorVersion
? { MajorVersion: options.MajorVersion, MinorVersion: options.MinorVersion }
: await PackageBundleVersionCreate.getPackageVersion(options, project, connection);
// Get the versionName from the bundle configuration
const versionName = await PackageBundleVersionCreate.getVersionNameFromBundle(options.PackageBundle, project, connection);
const request = {
PackageBundleId: packageBundleId,
VersionName: versionName,
MajorVersion: version.MajorVersion,
MinorVersion: version.MinorVersion,
BundleVersionComponents: JSON.stringify(bundleVersionComponents),
...(options.Ancestor ? { Ancestor: options.Ancestor } : {}),
};
let createResult;
try {
createResult = await connection.tooling.sobject('PkgBundleVersionCreateReq').create(request);
}
catch (err) {
const error = err instanceof Error
? err
: new Error(typeof err === 'string' ? err : messages.getMessage('failedToCreatePackageBundleVersion'));
throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(error));
}
if (!createResult?.success) {
let errorMessage = messages.getMessage('failedToCreatePackageBundleVersion');
if (createResult.errors?.length) {
errorMessage = createResult.errors.join(', ');
}
else if (createResult.errors && createResult.errors.length === 0) {
errorMessage = 'No specific error details available from Salesforce API';
}
throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(new Error(errorMessage)));
}
// Return the request result with the ID - polling will be handled by the caller if needed
// Query the actual status from the server to get accurate information including the request ID
return PackageBundleVersionCreate.getCreateStatus(createResult.id, connection);
}
static readBundleVersionComponents(filePath, project) {
try {
const fileContent = fs.readFileSync(filePath, 'utf8');
const bundleVersionComponents = JSON.parse(fileContent);
if (!Array.isArray(bundleVersionComponents)) {
throw new core_1.SfError(messages.getMessage('bundleVersionComponentsMustBeArray'));
}
// Validate that each item has the required packageVersion property
for (const component of bundleVersionComponents) {
if (!component || typeof component !== 'object' || !component.packageVersion) {
throw new core_1.SfError(messages.getMessage('bundleVersionComponentMustBeObject'));
}
}
// Process each component to get the package version ID
return bundleVersionComponents.map((component) => {
const packageVersion = component.packageVersion;
// Check if it's already an ID (04t followed by 15 characters)
if (/^04t[a-zA-Z0-9]{15}$/.test(packageVersion)) {
return packageVersion;
}
// Otherwise, treat it as an alias and resolve it from sfdx-project.json
const packageVersionId = project.getPackageIdFromAlias(packageVersion);
if (!packageVersionId) {
throw new core_1.SfError(messages.getMessage('noPackageVersionFoundWithAlias', [packageVersion]));
}
return packageVersionId;
});
}
catch (err) {
const error = err instanceof Error ? err : new Error(messages.getMessage('failedToReadBundleVersionComponentsFile'));
throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(error));
}
}
static async getVersionNameFromBundle(packageBundle, project, connection) {
const packageBundleId = PackageBundleVersionCreate.parsePackageBundleId(packageBundle, project);
const query = `SELECT BundleName FROM PackageBundle WHERE Id = '${packageBundleId}'`;
const result = await connection.tooling.query(query);
if (!result.records || result.records.length === 0) {
throw new core_1.SfError(messages.getMessage('noBundleFoundWithId', [packageBundleId]));
}
const bundleName = result.records[0].BundleName;
const bundles = project.getSfProjectJson().getPackageBundles();
const bundle = bundles.find((b) => b.name === bundleName);
if (!bundle) {
throw new core_1.SfError(messages.getMessage('noBundleFoundWithName', [bundleName]));
}
if (!bundle.versionName) {
throw new core_1.SfError(`Bundle '${bundleName}' is missing versionName in sfdx-project.json. Please add a versionName field to the bundle configuration.`);
}
return bundle.versionName;
}
static parsePackageBundleId(packageBundle, project) {
if (/^1Fl.{15}$/.test(packageBundle)) {
return packageBundle;
}
const bundleId = project.getPackageBundleIdFromAlias(packageBundle);
if (!bundleId) {
throw new core_1.SfError(messages.getMessage('noPackageBundleFoundWithAlias', [packageBundle]));
}
return bundleId;
}
static async getPackageVersion(options, project, connection) {
const packageBundleId = PackageBundleVersionCreate.parsePackageBundleId(options.PackageBundle, project);
const query = `SELECT BundleName FROM PackageBundle WHERE Id = '${packageBundleId}'`;
const result = await connection.tooling.query(query);
if (!result.records || result.records.length === 0) {
throw new core_1.SfError(messages.getMessage('noBundleFoundWithId', [packageBundleId]));
}
const bundleName = result.records[0].BundleName;
const bundles = project.getSfProjectJson().getPackageBundles();
const bundle = bundles.find((b) => b.name === bundleName);
if (!bundle) {
throw new core_1.SfError(messages.getMessage('noBundleFoundWithName', [bundleName]));
}
const [major, minor] = bundle.versionNumber.split('.');
if (!major || !minor) {
throw new core_1.SfError(messages.getMessage('invalidVersionNumberFormat', [bundle.versionNumber]));
}
// Check if major is an integer
const majorInt = parseInt(major, 10);
if (isNaN(majorInt) || majorInt.toString() !== major) {
throw new core_1.SfError(messages.getMessage('invalidVersionNumberFormat', [bundle.versionNumber]));
}
// Check if minor is either an integer or "next"
if (minor === 'NEXT') {
// Query existing bundle versions to find the highest minor version for this major version
const bundleVersionQuery = 'SELECT Id, PackageBundle.Id, PackageBundle.BundleName, VersionName, MajorVersion, MinorVersion, IsReleased ' +
'FROM PackageBundleVersion ' +
`WHERE PackageBundle.BundleName = '${bundleName}' AND MajorVersion = ${major} ` +
'ORDER BY MinorVersion DESC LIMIT 1';
const queryResult = await connection.tooling.query(bundleVersionQuery);
if (queryResult.records && queryResult.records.length > 0) {
const highestRecord = queryResult.records[0];
// Get the highest minor version and add 1
const highestMinorVersion = parseInt(highestRecord.MinorVersion, 10);
if (isNaN(highestMinorVersion)) {
throw new core_1.SfError(messages.getMessage('invalidMinorVersionInExisting', [highestRecord.MinorVersion]));
}
const nextMinorVersion = (highestMinorVersion + 1).toString();
return { MajorVersion: major, MinorVersion: nextMinorVersion };
}
else {
// No existing versions found for this major version, start with .0
return { MajorVersion: major, MinorVersion: '0' };
}
}
else {
const minorInt = parseInt(minor, 10);
if (isNaN(minorInt) || minorInt.toString() !== minor) {
throw new core_1.SfError(messages.getMessage('invalidVersionNumberFormat', [bundle.versionNumber]));
}
}
return { MajorVersion: major, MinorVersion: minor };
}
}
exports.PackageBundleVersionCreate = PackageBundleVersionCreate;
//# sourceMappingURL=packageBundleVersionCreate.js.map