@salesforce/packaging 4.11.0 → 4.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2025, salesforce.com, inc.
4
+ * All rights reserved.
5
+ * Licensed under the BSD 3-Clause license.
6
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.PackageBundleVersion = void 0;
10
+ const core_1 = require("@salesforce/core");
11
+ const kit_1 = require("@salesforce/kit");
12
+ const interfaces_1 = require("../interfaces");
13
+ const bundleUtils_1 = require("../utils/bundleUtils");
14
+ const packageUtils_1 = require("../utils/packageUtils");
15
+ const packageBundleVersionCreate_1 = require("./packageBundleVersionCreate");
16
+ core_1.Messages.importMessagesDirectory(__dirname);
17
+ const bundleVersionMessages = core_1.Messages.loadMessages('@salesforce/packaging', 'bundle_version');
18
+ class PackageBundleVersion {
19
+ static async create(options, polling) {
20
+ const createResult = await packageBundleVersionCreate_1.PackageBundleVersionCreate.createBundleVersion(options.connection, options.project, options);
21
+ if (polling) {
22
+ return PackageBundleVersion.pollCreateStatus(createResult.Id, options.connection, options.project, polling).catch((error) => {
23
+ if (error.name === 'PollingClientTimeout') {
24
+ const modifiedError = new core_1.SfError(error.message);
25
+ modifiedError.setData({ VersionCreateRequestId: createResult.Id });
26
+ modifiedError.message += ` Run 'sf package bundle version create report -i ${createResult.Id}' to check the status.`;
27
+ throw (0, packageUtils_1.applyErrorAction)((0, bundleUtils_1.massageErrorMessage)(modifiedError));
28
+ }
29
+ throw (0, packageUtils_1.applyErrorAction)((0, bundleUtils_1.massageErrorMessage)(error));
30
+ });
31
+ }
32
+ return createResult;
33
+ }
34
+ static async pollCreateStatus(createPackageVersionRequestId, connection, project, polling) {
35
+ if (polling.timeout?.milliseconds <= 0) {
36
+ return packageBundleVersionCreate_1.PackageBundleVersionCreate.getCreateStatus(createPackageVersionRequestId, connection);
37
+ }
38
+ let remainingWaitTime = polling.timeout;
39
+ const pollingClient = await core_1.PollingClient.create({
40
+ poll: async () => {
41
+ const report = await packageBundleVersionCreate_1.PackageBundleVersionCreate.getCreateStatus(createPackageVersionRequestId, connection);
42
+ switch (report.RequestStatus) {
43
+ case interfaces_1.BundleSObjects.PkgBundleVersionCreateReqStatus.queued:
44
+ await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageVersionEvents.create.enqueued, { ...report, remainingWaitTime });
45
+ remainingWaitTime = kit_1.Duration.seconds(remainingWaitTime.seconds - polling.frequency.seconds);
46
+ return {
47
+ completed: false,
48
+ payload: report,
49
+ };
50
+ case interfaces_1.BundleSObjects.PkgBundleVersionCreateReqStatus.success: {
51
+ await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageVersionEvents.create.success, report);
52
+ return { completed: true, payload: report };
53
+ }
54
+ case interfaces_1.BundleSObjects.PkgBundleVersionCreateReqStatus.error:
55
+ await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageVersionEvents.create.error, report);
56
+ return { completed: true, payload: report };
57
+ }
58
+ },
59
+ frequency: polling.frequency,
60
+ timeout: polling.timeout,
61
+ });
62
+ try {
63
+ return await pollingClient.subscribe();
64
+ }
65
+ catch (err) {
66
+ const report = await packageBundleVersionCreate_1.PackageBundleVersionCreate.getCreateStatus(createPackageVersionRequestId, connection);
67
+ await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageVersionEvents.create['timed-out'], report);
68
+ if (err instanceof Error) {
69
+ throw (0, packageUtils_1.applyErrorAction)(err);
70
+ }
71
+ throw err;
72
+ }
73
+ }
74
+ static async report(connection, id) {
75
+ const query = `SELECT Id, PackageBundle.Id, PackageBundle.BundleName, VersionName, MajorVersion, MinorVersion, IsReleased, PackageBundle.Description, PackageBundle.IsDeleted, PackageBundle.CreatedDate, PackageBundle.CreatedById, PackageBundle.LastModifiedDate, PackageBundle.LastModifiedById, PackageBundle.SystemModstamp, Ancestor.Id, Ancestor.PackageBundle.Id, Ancestor.PackageBundle.BundleName, Ancestor.VersionName, Ancestor.MajorVersion, Ancestor.MinorVersion, Ancestor.IsReleased, Ancestor.PackageBundle.Description, Ancestor.PackageBundle.IsDeleted, Ancestor.PackageBundle.CreatedDate, Ancestor.PackageBundle.CreatedById, Ancestor.PackageBundle.LastModifiedDate, Ancestor.PackageBundle.LastModifiedById, Ancestor.PackageBundle.SystemModstamp FROM PackageBundleVersion WHERE Id = '${id}'`;
76
+ const queryResult = await connection.autoFetchQuery(query, { tooling: true });
77
+ return queryResult.records.length > 0
78
+ ? PackageBundleVersion.mapRecordToBundleVersion(queryResult.records[0])
79
+ : null;
80
+ }
81
+ static async list(connection) {
82
+ const query = 'SELECT Id, PackageBundle.Id, PackageBundle.BundleName, VersionName, MajorVersion, MinorVersion, IsReleased, PackageBundle.Description, PackageBundle.IsDeleted, PackageBundle.CreatedDate, PackageBundle.CreatedById, PackageBundle.LastModifiedDate, PackageBundle.LastModifiedById, PackageBundle.SystemModstamp, Ancestor.Id, Ancestor.PackageBundle.Id, Ancestor.PackageBundle.BundleName, Ancestor.VersionName, Ancestor.MajorVersion, Ancestor.MinorVersion, Ancestor.IsReleased, Ancestor.PackageBundle.Description, Ancestor.PackageBundle.IsDeleted, Ancestor.PackageBundle.CreatedDate, Ancestor.PackageBundle.CreatedById, Ancestor.PackageBundle.LastModifiedDate, Ancestor.PackageBundle.LastModifiedById, Ancestor.PackageBundle.SystemModstamp FROM PackageBundleVersion';
83
+ const queryResult = await connection.autoFetchQuery(query, { tooling: true });
84
+ return queryResult.records.map((record) => PackageBundleVersion.mapRecordToBundleVersion(record));
85
+ }
86
+ static async getComponentPackages(connection, id) {
87
+ const query = `SELECT Component.Id, Component.Description, Component.PublisherName, Component.MajorVersion, Component.MinorVersion, Component.PatchVersion, Component.BuildNumber, Component.ReleaseState, Component.IsManaged, Component.IsDeprecated, Component.IsPasswordProtected, Component.IsBeta, Component.Package2ContainerOptions, Component.IsSecurityReviewed, Component.IsOrgDependent, Component.AppExchangePackageName, Component.AppExchangeDescription, Component.AppExchangePublisherName, Component.AppExchangeLogoUrl, Component.ReleaseNotesUrl, Component.PostInstallUrl, Component.RemoteSiteSettings, Component.CspTrustedSites, Component.Profiles, Component.Dependencies, Component.InstallValidationStatus, Component.SubscriberPackageId FROM PkgBundleVersionComponent WHERE PackageBundleVersion.Id = '${id}' ORDER BY CreatedDate`;
88
+ const queryResult = await connection.autoFetchQuery(query, { tooling: true });
89
+ // Get unique SubscriberPackageIds to query for Names
90
+ const subscriberPackageIds = [
91
+ ...new Set(queryResult.records
92
+ .map((record) => record.Component?.SubscriberPackageId)
93
+ .filter((packageId) => !!packageId)),
94
+ ];
95
+ // Query SubscriberPackage to get Names (one by one due to implementation restriction)
96
+ const subscriberPackageNames = new Map();
97
+ const packageQueries = subscriberPackageIds.map(async (packageId) => {
98
+ try {
99
+ const packageQuery = `SELECT Id, Name FROM SubscriberPackage WHERE Id='${packageId}'`;
100
+ const packageQueryResult = await connection.autoFetchQuery(packageQuery, { tooling: true });
101
+ return {
102
+ packageId,
103
+ name: packageQueryResult.records.length > 0 ? packageQueryResult.records[0].Name : '',
104
+ };
105
+ }
106
+ catch (error) {
107
+ // If individual query fails, return empty name for this package
108
+ return {
109
+ packageId,
110
+ name: '',
111
+ };
112
+ }
113
+ });
114
+ const packageResults = await Promise.allSettled(packageQueries);
115
+ packageResults.forEach((result) => {
116
+ if (result.status === 'fulfilled') {
117
+ subscriberPackageNames.set(result.value.packageId, result.value.name);
118
+ }
119
+ });
120
+ return queryResult.records.map((record) => {
121
+ const component = record.Component;
122
+ if (!component) {
123
+ throw new core_1.SfError(bundleVersionMessages.getMessage('componentRecordMissing'));
124
+ }
125
+ const packageName = subscriberPackageNames.get(component.SubscriberPackageId) ?? '';
126
+ return {
127
+ Id: component.Id,
128
+ SubscriberPackageId: component.SubscriberPackageId,
129
+ Name: packageName,
130
+ Description: component.Description,
131
+ PublisherName: component.PublisherName,
132
+ MajorVersion: component.MajorVersion,
133
+ MinorVersion: component.MinorVersion,
134
+ PatchVersion: component.PatchVersion,
135
+ BuildNumber: component.BuildNumber,
136
+ ReleaseState: component.ReleaseState,
137
+ IsManaged: component.IsManaged,
138
+ IsDeprecated: component.IsDeprecated,
139
+ IsPasswordProtected: component.IsPasswordProtected,
140
+ IsBeta: component.IsBeta,
141
+ Package2ContainerOptions: component.Package2ContainerOptions,
142
+ IsSecurityReviewed: component.IsSecurityReviewed,
143
+ IsOrgDependent: component.IsOrgDependent,
144
+ AppExchangePackageName: component.AppExchangePackageName,
145
+ AppExchangeDescription: component.AppExchangeDescription,
146
+ AppExchangePublisherName: component.AppExchangePublisherName,
147
+ AppExchangeLogoUrl: component.AppExchangeLogoUrl,
148
+ ReleaseNotesUrl: component.ReleaseNotesUrl,
149
+ PostInstallUrl: component.PostInstallUrl,
150
+ RemoteSiteSettings: component.RemoteSiteSettings,
151
+ CspTrustedSites: component.CspTrustedSites,
152
+ Profiles: component.Profiles,
153
+ Dependencies: component.Dependencies,
154
+ InstallValidationStatus: component.InstallValidationStatus,
155
+ };
156
+ });
157
+ }
158
+ static mapRecordToBundleVersion(record) {
159
+ return {
160
+ Id: record.Id,
161
+ PackageBundle: PackageBundleVersion.mapPackageBundle(record.PackageBundle),
162
+ VersionName: record.VersionName ?? '',
163
+ MajorVersion: record.MajorVersion ?? '',
164
+ MinorVersion: record.MinorVersion ?? '',
165
+ CreatedDate: record.PackageBundle?.CreatedDate ?? '',
166
+ CreatedById: record.PackageBundle?.CreatedById ?? '',
167
+ LastModifiedDate: record.PackageBundle?.LastModifiedDate ?? '',
168
+ LastModifiedById: record.PackageBundle?.LastModifiedById ?? '',
169
+ Ancestor: record.Ancestor?.Id ? PackageBundleVersion.mapAncestor(record.Ancestor) : null,
170
+ IsReleased: record.IsReleased ?? false,
171
+ };
172
+ }
173
+ static mapPackageBundle(packageBundle) {
174
+ return {
175
+ Id: packageBundle?.Id ?? '',
176
+ BundleName: packageBundle?.BundleName ?? '',
177
+ Description: packageBundle?.Description,
178
+ IsDeleted: packageBundle?.IsDeleted ?? false,
179
+ CreatedDate: packageBundle?.CreatedDate ?? '',
180
+ CreatedById: packageBundle?.CreatedById ?? '',
181
+ LastModifiedDate: packageBundle?.LastModifiedDate ?? '',
182
+ LastModifiedById: packageBundle?.LastModifiedById ?? '',
183
+ SystemModstamp: packageBundle?.SystemModstamp ?? '',
184
+ };
185
+ }
186
+ static mapAncestor(ancestor) {
187
+ return {
188
+ Id: ancestor.Id,
189
+ PackageBundle: PackageBundleVersion.mapAncestorPackageBundle(ancestor.PackageBundle),
190
+ VersionName: ancestor?.VersionName ?? '',
191
+ MajorVersion: ancestor?.MajorVersion ?? '',
192
+ MinorVersion: ancestor?.MinorVersion ?? '',
193
+ CreatedDate: ancestor.PackageBundle?.CreatedDate ?? '',
194
+ CreatedById: ancestor.PackageBundle?.CreatedById ?? '',
195
+ LastModifiedDate: ancestor.PackageBundle?.LastModifiedDate ?? '',
196
+ LastModifiedById: ancestor.PackageBundle?.LastModifiedById ?? '',
197
+ Ancestor: null,
198
+ IsReleased: ancestor.IsReleased ?? false,
199
+ };
200
+ }
201
+ static mapAncestorPackageBundle(packageBundle) {
202
+ return {
203
+ Id: packageBundle?.Id ?? '',
204
+ BundleName: packageBundle?.BundleName ?? '',
205
+ Description: packageBundle?.Description,
206
+ IsDeleted: packageBundle?.IsDeleted ?? false,
207
+ CreatedDate: packageBundle?.CreatedDate ?? '',
208
+ CreatedById: packageBundle?.CreatedById ?? '',
209
+ LastModifiedDate: packageBundle?.LastModifiedDate ?? '',
210
+ LastModifiedById: packageBundle?.LastModifiedById ?? '',
211
+ SystemModstamp: packageBundle?.SystemModstamp ?? '',
212
+ };
213
+ }
214
+ }
215
+ exports.PackageBundleVersion = PackageBundleVersion;
216
+ //# sourceMappingURL=packageBundleVersion.js.map
@@ -0,0 +1,11 @@
1
+ import { Connection, SfProject } from '@salesforce/core';
2
+ import { BundleSObjects, BundleVersionCreateOptions } from '../interfaces';
3
+ export declare class PackageBundleVersionCreate {
4
+ static getCreateStatus(createPackageVersionRequestId: string, connection: Connection): Promise<BundleSObjects.PackageBundleVersionCreateRequestResult>;
5
+ static getCreateStatuses(connection: Connection, status?: BundleSObjects.PkgBundleVersionCreateReqStatus, createdLastDays?: number): Promise<BundleSObjects.PackageBundleVersionCreateRequestResult[]>;
6
+ static createBundleVersion(connection: Connection, project: SfProject, options: BundleVersionCreateOptions): Promise<BundleSObjects.PackageBundleVersionCreateRequestResult>;
7
+ private static readBundleVersionComponents;
8
+ private static getVersionName;
9
+ private static parsePackageBundleId;
10
+ private static getPackageVersion;
11
+ }
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PackageBundleVersionCreate = void 0;
37
+ /*
38
+ * Copyright (c) 2025, salesforce.com, inc.
39
+ * All rights reserved.
40
+ * Licensed under the BSD 3-Clause license.
41
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
42
+ */
43
+ const fs = __importStar(require("node:fs"));
44
+ const core_1 = require("@salesforce/core");
45
+ const interfaces_1 = require("../interfaces");
46
+ const bundleUtils_1 = require("../utils/bundleUtils");
47
+ const packageBundleVersion_1 = require("./packageBundleVersion");
48
+ core_1.Messages.importMessagesDirectory(__dirname);
49
+ const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'bundle_version_create');
50
+ class PackageBundleVersionCreate {
51
+ static async getCreateStatus(createPackageVersionRequestId, connection) {
52
+ try {
53
+ const result = await connection.tooling
54
+ .sobject('PkgBundleVersionCreateReq')
55
+ .retrieve(createPackageVersionRequestId);
56
+ return result;
57
+ }
58
+ catch (err) {
59
+ const error = err instanceof Error ? err : new Error(messages.getMessage('failedToGetPackageBundleVersionCreateStatus'));
60
+ throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(error));
61
+ }
62
+ }
63
+ static async getCreateStatuses(connection, status, createdLastDays) {
64
+ let query = 'SELECT Id, RequestStatus, PackageBundle.Id, PackageBundle.BundleName, PackageBundleVersion.Id, ' +
65
+ 'VersionName, MajorVersion, MinorVersion, Ancestor.Id, BundleVersionComponents, ' +
66
+ 'CreatedDate, CreatedById ' +
67
+ 'FROM PkgBundleVersionCreateReq';
68
+ if (status && createdLastDays) {
69
+ query += ` WHERE RequestStatus = '${status}' AND CreatedDate = LAST_N_DAYS: ${createdLastDays}`;
70
+ }
71
+ else if (status) {
72
+ query += ` WHERE RequestStatus = '${status}'`;
73
+ }
74
+ else if (createdLastDays) {
75
+ query += ` WHERE CreatedDate = LAST_N_DAYS: ${createdLastDays}`;
76
+ }
77
+ const queryResult = await connection.autoFetchQuery(query, {
78
+ tooling: true,
79
+ });
80
+ return queryResult.records.map((record) => ({
81
+ Id: record.Id,
82
+ RequestStatus: record.RequestStatus,
83
+ PackageBundleId: record.PackageBundle?.Id ?? '',
84
+ PackageBundleVersionId: record.PackageBundleVersion?.Id ?? '',
85
+ VersionName: record.VersionName ?? '',
86
+ MajorVersion: record.MajorVersion ?? '',
87
+ MinorVersion: record.MinorVersion ?? '',
88
+ Ancestor: record.Ancestor?.Id ?? '',
89
+ BundleVersionComponents: record.BundleVersionComponents ?? '',
90
+ CreatedDate: record.CreatedDate ?? '',
91
+ CreatedById: record.CreatedById ?? '',
92
+ }));
93
+ }
94
+ static async createBundleVersion(connection, project, options) {
95
+ const bundleVersionComponents = PackageBundleVersionCreate.readBundleVersionComponents(options.BundleVersionComponentsPath, project);
96
+ const packageBundleId = PackageBundleVersionCreate.parsePackageBundleId(options.PackageBundle, project);
97
+ // Use provided MajorVersion and MinorVersion if they are not empty strings, otherwise get from bundle configuration
98
+ const version = options.MajorVersion && options.MinorVersion
99
+ ? { MajorVersion: options.MajorVersion, MinorVersion: options.MinorVersion }
100
+ : await PackageBundleVersionCreate.getPackageVersion(options, project, connection);
101
+ const request = {
102
+ PackageBundleId: packageBundleId,
103
+ VersionName: PackageBundleVersionCreate.getVersionName(options.PackageBundle, version.MajorVersion, version.MinorVersion),
104
+ MajorVersion: version.MajorVersion,
105
+ MinorVersion: version.MinorVersion,
106
+ BundleVersionComponents: JSON.stringify(bundleVersionComponents),
107
+ ...(options.Ancestor ? { Ancestor: options.Ancestor } : {}),
108
+ };
109
+ let createResult;
110
+ try {
111
+ createResult = await connection.tooling.sobject('PkgBundleVersionCreateReq').create(request);
112
+ }
113
+ catch (err) {
114
+ const error = err instanceof Error
115
+ ? err
116
+ : new Error(typeof err === 'string' ? err : messages.getMessage('failedToCreatePackageBundleVersion'));
117
+ throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(error));
118
+ }
119
+ if (!createResult?.success) {
120
+ throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(new Error(messages.getMessage('failedToCreatePackageBundleVersion'))));
121
+ }
122
+ if (options.polling) {
123
+ return packageBundleVersion_1.PackageBundleVersion.pollCreateStatus(createResult.id, connection, project, options.polling);
124
+ }
125
+ return {
126
+ Id: createResult.id,
127
+ PackageBundleVersionId: createResult.id,
128
+ PackageBundleId: packageBundleId,
129
+ VersionName: PackageBundleVersionCreate.getVersionName(options.PackageBundle, version.MajorVersion, version.MinorVersion),
130
+ MajorVersion: version.MajorVersion,
131
+ MinorVersion: version.MinorVersion,
132
+ BundleVersionComponents: JSON.stringify(bundleVersionComponents),
133
+ RequestStatus: interfaces_1.BundleSObjects.PkgBundleVersionCreateReqStatus.success,
134
+ CreatedDate: new Date().toISOString(),
135
+ CreatedById: connection.getUsername() ?? 'unknown',
136
+ };
137
+ }
138
+ static readBundleVersionComponents(filePath, project) {
139
+ try {
140
+ const fileContent = fs.readFileSync(filePath, 'utf8');
141
+ const bundleVersionComponents = JSON.parse(fileContent);
142
+ if (!Array.isArray(bundleVersionComponents)) {
143
+ throw new core_1.SfError(messages.getMessage('bundleVersionComponentsMustBeArray'));
144
+ }
145
+ // Validate that each item has the required packageVersion property
146
+ for (const component of bundleVersionComponents) {
147
+ if (!component || typeof component !== 'object' || !component.packageVersion) {
148
+ throw new core_1.SfError(messages.getMessage('bundleVersionComponentMustBeObject'));
149
+ }
150
+ }
151
+ // Process each component to get the package version ID
152
+ return bundleVersionComponents.map((component) => {
153
+ const packageVersion = component.packageVersion;
154
+ // Check if it's already an ID (04t followed by 15 characters)
155
+ if (/^04t[a-zA-Z0-9]{15}$/.test(packageVersion)) {
156
+ return packageVersion;
157
+ }
158
+ // Otherwise, treat it as an alias and resolve it from sfdx-project.json
159
+ const packageVersionId = project.getPackageIdFromAlias(packageVersion);
160
+ if (!packageVersionId) {
161
+ throw new core_1.SfError(messages.getMessage('noPackageVersionFoundWithAlias', [packageVersion]));
162
+ }
163
+ return packageVersionId;
164
+ });
165
+ }
166
+ catch (err) {
167
+ const error = err instanceof Error ? err : new Error(messages.getMessage('failedToReadBundleVersionComponentsFile'));
168
+ throw core_1.SfError.wrap((0, bundleUtils_1.massageErrorMessage)(error));
169
+ }
170
+ }
171
+ static getVersionName(packageBundle, majorVersion, minorVersion) {
172
+ return `${packageBundle}@${majorVersion}.${minorVersion}`;
173
+ }
174
+ static parsePackageBundleId(packageBundle, project) {
175
+ if (/^1Fl.{15}$/.test(packageBundle)) {
176
+ return packageBundle;
177
+ }
178
+ const bundleId = project.getPackageBundleIdFromAlias(packageBundle);
179
+ if (!bundleId) {
180
+ throw new core_1.SfError(messages.getMessage('noPackageBundleFoundWithAlias', [packageBundle]));
181
+ }
182
+ return bundleId;
183
+ }
184
+ static async getPackageVersion(options, project, connection) {
185
+ const packageBundleId = PackageBundleVersionCreate.parsePackageBundleId(options.PackageBundle, project);
186
+ const query = `SELECT BundleName FROM PackageBundle WHERE Id = '${packageBundleId}'`;
187
+ const result = await connection.tooling.query(query);
188
+ if (!result.records || result.records.length === 0) {
189
+ throw new core_1.SfError(messages.getMessage('noBundleFoundWithId', [packageBundleId]));
190
+ }
191
+ const bundleName = result.records[0].BundleName;
192
+ const bundles = project.getSfProjectJson().getPackageBundles();
193
+ const bundle = bundles.find((b) => b.name === bundleName);
194
+ if (!bundle) {
195
+ throw new core_1.SfError(messages.getMessage('noBundleFoundWithName', [bundleName]));
196
+ }
197
+ const [major, minor] = bundle.versionNumber.split('.');
198
+ if (!major || !minor) {
199
+ throw new core_1.SfError(messages.getMessage('invalidVersionNumberFormat', [bundle.versionNumber]));
200
+ }
201
+ // Check if major is an integer
202
+ const majorInt = parseInt(major, 10);
203
+ if (isNaN(majorInt) || majorInt.toString() !== major) {
204
+ throw new core_1.SfError(messages.getMessage('invalidVersionNumberFormat', [bundle.versionNumber]));
205
+ }
206
+ // Check if minor is either an integer or "next"
207
+ if (minor === 'NEXT') {
208
+ // Query existing bundle versions to find the highest minor version for this major version
209
+ const bundleVersionQuery = 'SELECT Id, PackageBundle.Id, PackageBundle.BundleName, VersionName, MajorVersion, MinorVersion, IsReleased ' +
210
+ 'FROM PackageBundleVersion ' +
211
+ `WHERE PackageBundle.BundleName = '${bundleName}' AND MajorVersion = ${major} ` +
212
+ 'ORDER BY MinorVersion DESC LIMIT 1';
213
+ const queryResult = await connection.tooling.query(bundleVersionQuery);
214
+ if (queryResult.records && queryResult.records.length > 0) {
215
+ const highestRecord = queryResult.records[0];
216
+ // Get the highest minor version and add 1
217
+ const highestMinorVersion = parseInt(highestRecord.MinorVersion, 10);
218
+ if (isNaN(highestMinorVersion)) {
219
+ throw new core_1.SfError(messages.getMessage('invalidMinorVersionInExisting', [highestRecord.MinorVersion]));
220
+ }
221
+ const nextMinorVersion = (highestMinorVersion + 1).toString();
222
+ return { MajorVersion: major, MinorVersion: nextMinorVersion };
223
+ }
224
+ else {
225
+ // No existing versions found for this major version, start with .0
226
+ return { MajorVersion: major, MinorVersion: '0' };
227
+ }
228
+ }
229
+ else {
230
+ const minorInt = parseInt(minor, 10);
231
+ if (isNaN(minorInt) || minorInt.toString() !== minor) {
232
+ throw new core_1.SfError(messages.getMessage('invalidVersionNumberFormat', [bundle.versionNumber]));
233
+ }
234
+ }
235
+ return { MajorVersion: major, MinorVersion: minor };
236
+ }
237
+ }
238
+ exports.PackageBundleVersionCreate = PackageBundleVersionCreate;
239
+ //# sourceMappingURL=packageBundleVersionCreate.js.map
@@ -39,10 +39,12 @@ export declare class DependencyDotProducer {
39
39
  private subscriberPackageVersionId;
40
40
  private connection;
41
41
  private dependencyGraphData;
42
+ private selectedNodeIds;
42
43
  constructor(connection: Connection, dependencyGraphString: string, verbose: boolean, edgeDirection: 'root-first' | 'root-last', resolvedPackageVersionId: string);
43
44
  private static throwErrorOnInvalidRecord;
44
45
  init(): Promise<void>;
45
46
  produce(): string;
47
+ private addSelectedNodeIds;
46
48
  private createDependencyGraphNodes;
47
49
  /**
48
50
  * Creates a single dependency graph node.
@@ -58,6 +60,7 @@ export declare class DependencyDotProducer {
58
60
  * @param node the node id and label
59
61
  */
60
62
  private buildDotNode;
63
+ private addColorToSelectedNode;
61
64
  /**
62
65
  * Builds a DOT edge line of the form fromNode -> toNode
63
66
  *
@@ -141,6 +141,7 @@ class DependencyDotProducer {
141
141
  subscriberPackageVersionId;
142
142
  connection;
143
143
  dependencyGraphData;
144
+ selectedNodeIds = [];
144
145
  constructor(connection, dependencyGraphString, verbose, edgeDirection, resolvedPackageVersionId) {
145
146
  this.verbose = verbose;
146
147
  this.edgeDirection = edgeDirection;
@@ -161,6 +162,7 @@ class DependencyDotProducer {
161
162
  nodes: await this.createDependencyGraphNodes(dependencyGraphJson.nodes),
162
163
  edges: this.createDependencyGraphEdges(dependencyGraphJson.edges),
163
164
  };
165
+ this.selectedNodeIds = await this.addSelectedNodeIds();
164
166
  }
165
167
  produce() {
166
168
  const dotLines = [];
@@ -172,6 +174,36 @@ class DependencyDotProducer {
172
174
  }
173
175
  return `strict digraph G {${node_os_1.EOL}${dotLines.join(node_os_1.EOL)}${node_os_1.EOL}}`;
174
176
  }
177
+ async addSelectedNodeIds() {
178
+ const selectedNodes = [];
179
+ if (this.subscriberPackageVersionId === exports.VERSION_BEING_BUILT) {
180
+ selectedNodes.push(this.subscriberPackageVersionId);
181
+ }
182
+ else if (this.subscriberPackageVersionId.startsWith('04t')) {
183
+ selectedNodes.push(this.subscriberPackageVersionId);
184
+ const query = `SELECT Dependencies FROM SubscriberPackageVersion WHERE Id = '${this.subscriberPackageVersionId}'`;
185
+ try {
186
+ const result = await this.connection.tooling.query(query);
187
+ if (result.records?.length !== 1) {
188
+ return selectedNodes;
189
+ }
190
+ const dependencies = result.records[0].Dependencies;
191
+ if (!dependencies) {
192
+ return selectedNodes;
193
+ }
194
+ if (dependencies.ids && Array.isArray(dependencies.ids)) {
195
+ const dependencyIds = dependencies.ids
196
+ .map((dep) => dep.subscriberPackageVersionId)
197
+ .filter((id) => id && typeof id === 'string' && id.startsWith('04t'));
198
+ selectedNodes.push(...dependencyIds);
199
+ }
200
+ }
201
+ catch (error) {
202
+ throw messages.createError('invalidPackageVersionIdError', [this.subscriberPackageVersionId]);
203
+ }
204
+ }
205
+ return selectedNodes;
206
+ }
175
207
  async createDependencyGraphNodes(jsonNodes) {
176
208
  const nodePromises = jsonNodes.map(async (node) => this.createSingleDependencyGraphNode(node.id));
177
209
  const resolvedNodes = await Promise.all(nodePromises);
@@ -279,7 +311,14 @@ class DependencyDotProducer {
279
311
  if (this.verbose) {
280
312
  label += ` (${node.subscriberPackageVersionId})`;
281
313
  }
282
- return `\t node_${nodeId} [label="${label}"]`;
314
+ const color = this.addColorToSelectedNode(node);
315
+ return `\t node_${nodeId} [label="${label}"${color}]`;
316
+ }
317
+ addColorToSelectedNode(node) {
318
+ if (this.selectedNodeIds.includes(node.subscriberPackageVersionId)) {
319
+ return ' color="green"';
320
+ }
321
+ return '';
283
322
  }
284
323
  /**
285
324
  * Builds a DOT edge line of the form fromNode -> toNode
@@ -0,0 +1 @@
1
+ export declare function massageErrorMessage(err: Error): Error;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2025, salesforce.com, inc.
4
+ * All rights reserved.
5
+ * Licensed under the BSD 3-Clause license.
6
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.massageErrorMessage = massageErrorMessage;
10
+ const core_1 = require("@salesforce/core");
11
+ core_1.Messages.importMessagesDirectory(__dirname);
12
+ const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'bundle_utils');
13
+ function massageErrorMessage(err) {
14
+ if (err.name === 'STRING_TOO_LONG') {
15
+ err['message'] = messages.getMessage('STRING_TOO_LONG');
16
+ }
17
+ return err;
18
+ }
19
+ //# sourceMappingURL=bundleUtils.js.map
@@ -1 +1,2 @@
1
1
  export { INSTALL_URL_BASE, getContainerOptions, getPackageVersionStrings, getPackageVersionNumber, } from './packageUtils';
2
+ export { massageErrorMessage } from './bundleUtils';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPackageVersionNumber = exports.getPackageVersionStrings = exports.getContainerOptions = exports.INSTALL_URL_BASE = void 0;
3
+ exports.massageErrorMessage = exports.getPackageVersionNumber = exports.getPackageVersionStrings = exports.getContainerOptions = exports.INSTALL_URL_BASE = void 0;
4
4
  /*
5
5
  * Copyright (c) 2022, salesforce.com, inc.
6
6
  * All rights reserved.
@@ -12,4 +12,6 @@ Object.defineProperty(exports, "INSTALL_URL_BASE", { enumerable: true, get: func
12
12
  Object.defineProperty(exports, "getContainerOptions", { enumerable: true, get: function () { return packageUtils_1.getContainerOptions; } });
13
13
  Object.defineProperty(exports, "getPackageVersionStrings", { enumerable: true, get: function () { return packageUtils_1.getPackageVersionStrings; } });
14
14
  Object.defineProperty(exports, "getPackageVersionNumber", { enumerable: true, get: function () { return packageUtils_1.getPackageVersionNumber; } });
15
+ var bundleUtils_1 = require("./bundleUtils");
16
+ Object.defineProperty(exports, "massageErrorMessage", { enumerable: true, get: function () { return bundleUtils_1.massageErrorMessage; } });
15
17
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,3 @@
1
+ # failedToCreatePackageBundle
2
+
3
+ Failed to create package bundle
@@ -0,0 +1,11 @@
1
+ # failedToGetPackageBundleInstallStatus
2
+
3
+ Failed to get package bundle install status
4
+
5
+ # failedToInstallPackageBundle
6
+
7
+ Failed to install package bundle
8
+
9
+ # noPackageBundleVersionFoundWithAlias
10
+
11
+ No package bundle version found with alias: %s
@@ -0,0 +1,7 @@
1
+ # STRING_TOO_LONG
2
+
3
+ Either name or description has exceeded the 255 charector limit.
4
+
5
+ # invalidIdOrAlias
6
+
7
+ The %s : %s isn't defined in the sfdx-project.json. Add it to the packageBundles section and add the alias to packageBundleAliases with its %s ID.
@@ -0,0 +1,3 @@
1
+ # componentRecordMissing
2
+
3
+ Component record is missing