@salesforce/packaging 5.0.7 → 5.0.9-spi-dev.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.
@@ -38,6 +38,27 @@ export type PackageUpdateOptions = {
38
38
  AppAnalyticsEnabled?: boolean;
39
39
  RecommendedVersionId?: string;
40
40
  };
41
+ export type PackageAuthorizationOptions = {
42
+ connection: Connection;
43
+ subscriberPackageId?: string;
44
+ };
45
+ export type PackageAuthorizationRecord = {
46
+ Id: string;
47
+ SubscriberOrg: string;
48
+ SubscriberPackageId: string | null;
49
+ Status: 'Active' | 'Revoked';
50
+ CreatedDate: string;
51
+ CreatedById: string;
52
+ CreatedByUsername: string;
53
+ };
54
+ export type PackageAuthorizationAddResult = {
55
+ Id: string;
56
+ SubscriberOrg: string;
57
+ };
58
+ export type PackageAuthorizationRemoveResult = {
59
+ SubscriberOrg: string;
60
+ removed: boolean;
61
+ };
41
62
  export type PackageIdType = 'PackageId' | 'SubscriberPackageVersionId' | 'PackageInstallRequestId' | 'PackageUninstallRequestId';
42
63
  export type PackageVersionOptions1GP = Record<string, unknown>;
43
64
  export type PackageVersionCreateRequestResult = {
@@ -141,6 +162,14 @@ export type PackagePushScheduleResult = {
141
162
  ScheduledStartTime: string | undefined;
142
163
  Status: string;
143
164
  };
165
+ export type PackageTrustLinkRequestOptions = {
166
+ verifiedOrgId: string;
167
+ };
168
+ export type PackageTrustLinkRequestResult = {
169
+ LinkRequestId: string;
170
+ VerifiedOrgId: string;
171
+ Status: string;
172
+ };
144
173
  export type PackagePushRequestReportQueryOptions = {
145
174
  packagePushRequestId: string;
146
175
  };
@@ -1,7 +1,9 @@
1
1
  export * from './package';
2
+ export * from './packageAuthorization';
2
3
  export * from './packageVersion';
3
4
  export * from './subscriberPackageVersion';
4
5
  export * from './packagePushUpgrade';
6
+ export * from './packageTrustLink';
5
7
  export { VersionNumber } from './versionNumber';
6
8
  export * from './packageBundle';
7
9
  export * from './packageBundleVersion';
@@ -31,9 +31,11 @@ exports.VersionNumber = void 0;
31
31
  * limitations under the License.
32
32
  */
33
33
  __exportStar(require("./package"), exports);
34
+ __exportStar(require("./packageAuthorization"), exports);
34
35
  __exportStar(require("./packageVersion"), exports);
35
36
  __exportStar(require("./subscriberPackageVersion"), exports);
36
37
  __exportStar(require("./packagePushUpgrade"), exports);
38
+ __exportStar(require("./packageTrustLink"), exports);
37
39
  var versionNumber_1 = require("./versionNumber");
38
40
  Object.defineProperty(exports, "VersionNumber", { enumerable: true, get: function () { return versionNumber_1.VersionNumber; } });
39
41
  __exportStar(require("./packageBundle"), exports);
@@ -100,6 +100,12 @@ export declare class Package {
100
100
  * @returns {string} package ID (0Ho)
101
101
  */
102
102
  getId(): string;
103
+ /**
104
+ * Returns the subscriber package ID associated with this package.
105
+ *
106
+ * @returns the subscriber package ID
107
+ */
108
+ getSubscriberPackageId(): Promise<string>;
103
109
  /**
104
110
  * Returns the package type of the package.
105
111
  *
@@ -194,6 +194,18 @@ class Package {
194
194
  getId() {
195
195
  return this.packageId;
196
196
  }
197
+ /**
198
+ * Returns the subscriber package ID associated with this package.
199
+ *
200
+ * @returns the subscriber package ID
201
+ */
202
+ async getSubscriberPackageId() {
203
+ const packageData = await this.getPackageData();
204
+ if (!packageData?.SubscriberPackageId) {
205
+ throw messages.createError('subscriberPackageIdNotFound', [this.packageId]);
206
+ }
207
+ return packageData.SubscriberPackageId;
208
+ }
197
209
  /**
198
210
  * Returns the package type of the package.
199
211
  *
@@ -317,7 +317,6 @@ class PackageAncestry extends kit_1.AsyncCreatable {
317
317
  async buildAncestryTreeFromRoots(roots) {
318
318
  while (roots.length > 0) {
319
319
  const subscriberPackageVersion = roots.shift();
320
- // eslint-disable-next-line no-await-in-loop
321
320
  if (subscriberPackageVersion) {
322
321
  // eslint-disable-next-line no-await-in-loop
323
322
  const descendants = await this.addDescendantsFromPackageVersion(subscriberPackageVersion);
@@ -0,0 +1,10 @@
1
+ import { PackageAuthorizationAddResult, PackageAuthorizationOptions, PackageAuthorizationRecord, PackageAuthorizationRemoveResult } from '../interfaces';
2
+ export declare class PackageAuthorization {
3
+ private readonly connection;
4
+ private readonly subscriberPackageId?;
5
+ constructor(options: PackageAuthorizationOptions);
6
+ add(subscriberOrgs: string[]): Promise<PackageAuthorizationAddResult[]>;
7
+ remove(subscriberOrg: string): Promise<PackageAuthorizationRemoveResult>;
8
+ list(): Promise<PackageAuthorizationRecord[]>;
9
+ private query;
10
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PackageAuthorization = void 0;
4
+ const core_1 = require("@salesforce/core");
5
+ const packageUtils_1 = require("../utils/packageUtils");
6
+ const PACKAGE_AUTHORIZATION_SOBJECT = 'PkgAuthOrgSbscrbTrustRela';
7
+ const MINIMUM_API_VERSION = '68.0';
8
+ core_1.Messages.importMessagesDirectory(__dirname);
9
+ const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'package_authorize');
10
+ const normalizeSubscriberOrg = (subscriberOrg) => {
11
+ if (!subscriberOrg.startsWith('00D') || !(0, core_1.validateSalesforceId)(subscriberOrg)) {
12
+ throw messages.createError('invalidSubscriberOrg', [subscriberOrg]);
13
+ }
14
+ return (0, core_1.trimTo15)(subscriberOrg);
15
+ };
16
+ class PackageAuthorization {
17
+ connection;
18
+ subscriberPackageId;
19
+ constructor(options) {
20
+ if (Number(options.connection.getApiVersion()) < Number(MINIMUM_API_VERSION)) {
21
+ throw messages.createError('apiVersionTooLow', [MINIMUM_API_VERSION]);
22
+ }
23
+ if (options.subscriberPackageId &&
24
+ (!options.subscriberPackageId.startsWith('033') || !(0, core_1.validateSalesforceId)(options.subscriberPackageId))) {
25
+ throw messages.createError('invalidSubscriberPackage', [options.subscriberPackageId]);
26
+ }
27
+ this.connection = options.connection;
28
+ this.subscriberPackageId = options.subscriberPackageId;
29
+ }
30
+ async add(subscriberOrgs) {
31
+ if (subscriberOrgs.length === 0) {
32
+ throw messages.createError('noSubscriberOrgs');
33
+ }
34
+ const normalizedSubscriberOrgs = subscriberOrgs.map(normalizeSubscriberOrg);
35
+ return normalizedSubscriberOrgs.reduce(async (resultsPromise, subscriberOrg) => {
36
+ const results = await resultsPromise;
37
+ const result = await this.connection.tooling.create(PACKAGE_AUTHORIZATION_SOBJECT, {
38
+ SubscriberOrg: subscriberOrg,
39
+ ...(this.subscriberPackageId ? { SubscriberPackageId: this.subscriberPackageId } : {}),
40
+ Status: 'Active',
41
+ });
42
+ if (!result.success || !result.id) {
43
+ throw (0, packageUtils_1.combineSaveErrors)(PACKAGE_AUTHORIZATION_SOBJECT, 'create', result.errors);
44
+ }
45
+ results.push({ Id: result.id, SubscriberOrg: subscriberOrg });
46
+ return results;
47
+ }, Promise.resolve([]));
48
+ }
49
+ async remove(subscriberOrg) {
50
+ const normalizedSubscriberOrg = normalizeSubscriberOrg(subscriberOrg);
51
+ const subscriberPackageFilter = this.subscriberPackageId
52
+ ? `SubscriberPackageId = '${this.subscriberPackageId}'`
53
+ : 'SubscriberPackageId = NULL';
54
+ const records = await this.query(`WHERE SubscriberOrg = '${normalizedSubscriberOrg}' AND ${subscriberPackageFilter} LIMIT 1`);
55
+ const record = records[0];
56
+ if (!record) {
57
+ return { SubscriberOrg: normalizedSubscriberOrg, removed: false };
58
+ }
59
+ const result = await this.connection.tooling.sobject(PACKAGE_AUTHORIZATION_SOBJECT).destroy(record.Id);
60
+ if (!result.success) {
61
+ throw (0, packageUtils_1.combineSaveErrors)(PACKAGE_AUTHORIZATION_SOBJECT, 'delete', result.errors);
62
+ }
63
+ return { SubscriberOrg: normalizedSubscriberOrg, removed: true };
64
+ }
65
+ async list() {
66
+ const packageFilter = this.subscriberPackageId ? `WHERE SubscriberPackageId = '${this.subscriberPackageId}' ` : '';
67
+ return this.query(`${packageFilter}ORDER BY SubscriberOrg`);
68
+ }
69
+ async query(whereClause) {
70
+ const query = 'SELECT Id, SubscriberOrg, SubscriberPackageId, Status, CreatedDate, CreatedById, CreatedBy.Username FROM ' +
71
+ `${PACKAGE_AUTHORIZATION_SOBJECT} ${whereClause}`;
72
+ const result = await this.connection.autoFetchQuery(query, { tooling: true });
73
+ return (result.records ?? []).map(({ Id, SubscriberOrg, SubscriberPackageId, Status, CreatedDate, CreatedById, CreatedBy }) => ({
74
+ Id,
75
+ SubscriberOrg,
76
+ SubscriberPackageId,
77
+ Status,
78
+ CreatedDate,
79
+ CreatedById,
80
+ CreatedByUsername: CreatedBy?.Username ?? CreatedById,
81
+ }));
82
+ }
83
+ }
84
+ exports.PackageAuthorization = PackageAuthorization;
85
+ //# sourceMappingURL=packageAuthorization.js.map
@@ -66,7 +66,6 @@ class PackageBundle {
66
66
  if (!project) {
67
67
  throw new core_1.SfError('Project instance is required when deleting package bundle by alias');
68
68
  }
69
- // eslint-disable-next-line no-param-reassign
70
69
  idOrAlias = project.getPackageBundleIdFromAlias(idOrAlias) ?? idOrAlias;
71
70
  return connection.tooling.sobject('PackageBundle').delete(idOrAlias);
72
71
  }
@@ -305,7 +305,6 @@ async function pollForStatusWithInterval(id, retries, packageId, branch, project
305
305
  // for multiple errors, display one per line prefixed with (x)
306
306
  if (results[0].Error.length > 1) {
307
307
  results[0].Error.forEach((error) => {
308
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
309
308
  errors.push(`(${errors.length + 1}) ${error}`);
310
309
  });
311
310
  errors.unshift(messages.getMessage('versionCreateFailedWithMultipleErrors'));
@@ -41,7 +41,7 @@ class PackageProfileApi extends kit_1.AsyncCreatable {
41
41
  this.project = options.project;
42
42
  this.includeUserLicenses = options.includeUserLicenses ?? false;
43
43
  }
44
- // eslint-disable-next-line class-methods-use-this,@typescript-eslint/no-empty-function
44
+ // eslint-disable-next-line class-methods-use-this
45
45
  async init() { }
46
46
  /**
47
47
  * For any profile present in the project package directories, this function generates a subset of data that only
@@ -0,0 +1,17 @@
1
+ import { Connection } from '@salesforce/core';
2
+ import { PackageTrustLinkRequestOptions, PackageTrustLinkRequestResult } from '../interfaces';
3
+ export declare class PackageTrustLink {
4
+ constructor();
5
+ /**
6
+ * Request a Public Secure (VerifiedDev) trust link from the connected authoring org to a Verified PBO.
7
+ *
8
+ * Establishes the developer/authoring-org side of the two-way trust handshake by creating a
9
+ * `Pending` trust relationship. A PBO admin approves it separately. This does not change any
10
+ * package's distribution type — trust and enforcement are decoupled.
11
+ *
12
+ * @param connection - Connection to the authoring org (the 1GP namespace org or 2GP Dev Hub).
13
+ * @param options - the verified org (PBO) ID to request a trust link to.
14
+ * @returns the created trust relationship Id, verified org ID, and status.
15
+ */
16
+ static request(connection: Connection, options: PackageTrustLinkRequestOptions): Promise<PackageTrustLinkRequestResult>;
17
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PackageTrustLink = void 0;
4
+ const core_1 = require("@salesforce/core");
5
+ const packageUtils_1 = require("../utils/packageUtils");
6
+ core_1.Messages.importMessagesDirectory(__dirname);
7
+ const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'package_trust_link');
8
+ // Tooling API SObject backing the VerifiedDev (Public Secure) org-level trust relationship
9
+ // between the connected authoring org and a Verified PBO. See W-23970567 / SPI CLI design doc.
10
+ const TRUST_LINK_SOBJECT = 'PkgVrfyAuthOrgTrustRela';
11
+ class PackageTrustLink {
12
+ constructor() { }
13
+ /**
14
+ * Request a Public Secure (VerifiedDev) trust link from the connected authoring org to a Verified PBO.
15
+ *
16
+ * Establishes the developer/authoring-org side of the two-way trust handshake by creating a
17
+ * `Pending` trust relationship. A PBO admin approves it separately. This does not change any
18
+ * package's distribution type — trust and enforcement are decoupled.
19
+ *
20
+ * @param connection - Connection to the authoring org (the 1GP namespace org or 2GP Dev Hub).
21
+ * @param options - the verified org (PBO) ID to request a trust link to.
22
+ * @returns the created trust relationship Id, verified org ID, and status.
23
+ */
24
+ static async request(connection, options) {
25
+ if (!options.verifiedOrgId.startsWith('00D') || !(0, core_1.validateSalesforceId)(options.verifiedOrgId)) {
26
+ throw messages.createError('invalidVerifiedOrgId', [options.verifiedOrgId]);
27
+ }
28
+ // VerifiedOrg is a TEXT field that core stores as a 15-char ID, so normalize before
29
+ // insert to avoid 18-char mismatches.
30
+ const verifiedOrgId = (0, core_1.trimTo15)(options.verifiedOrgId);
31
+ // An authoring org can hold at most one trust relationship at a time. The Tooling API
32
+ // query below runs against the connected authoring org and only returns that org's own
33
+ // rows (AuthoringOrg is server-set), so any existing row (in any status, to any verified
34
+ // org) blocks a new request until it's deleted (unlinked).
35
+ const existing = await queryExistingTrustLink(connection);
36
+ if (existing) {
37
+ throw messages.createError('trustLinkAlreadyExists', [existing.VerifiedOrg, existing.Status]);
38
+ }
39
+ // Create the trust relationship via the Tooling API. Status is required and must be
40
+ // 'Pending' on create; the PBO admin advances it during the approval handshake.
41
+ const createResult = await connection.tooling.create(TRUST_LINK_SOBJECT, {
42
+ VerifiedOrg: verifiedOrgId,
43
+ Status: 'Pending',
44
+ });
45
+ if (!createResult.success || !createResult.id) {
46
+ throw (0, packageUtils_1.combineSaveErrors)(TRUST_LINK_SOBJECT, 'create', createResult.errors);
47
+ }
48
+ return {
49
+ LinkRequestId: createResult.id,
50
+ VerifiedOrgId: verifiedOrgId,
51
+ Status: 'Pending',
52
+ };
53
+ }
54
+ }
55
+ exports.PackageTrustLink = PackageTrustLink;
56
+ async function queryExistingTrustLink(connection) {
57
+ const query = `SELECT Id, VerifiedOrg, Status FROM ${TRUST_LINK_SOBJECT} LIMIT 1`;
58
+ const result = await connection.autoFetchQuery(query, { tooling: true });
59
+ return result.records?.[0];
60
+ }
61
+ //# sourceMappingURL=packageTrustLink.js.map
@@ -285,7 +285,6 @@ class PackageVersion {
285
285
  case Package2VersionStatus.success:
286
286
  await core_1.Lifecycle.getInstance().emit(interfaces_1.PackageVersionEvents.create.success, report);
287
287
  await new PackageVersion({
288
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
289
288
  idOrAlias: report.SubscriberPackageVersionId,
290
289
  project,
291
290
  connection,
@@ -255,7 +255,6 @@ class PackageVersionCreate {
255
255
  throw messages.createError('noReleaseVersionFoundForBranch', [packageId, branch, versionNumber.toString()]);
256
256
  }
257
257
  }
258
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
259
258
  return `${results.records[0].expr0}`;
260
259
  }
261
260
  async createRequestObject(preserveFiles, packageVersTmpRoot, packageVersBlobZipFile) {
@@ -851,7 +850,6 @@ const packageXmlStringToPackageXmlJson = (rawXml) => {
851
850
  // make sure types and members is always an array
852
851
  isArray: (name) => ['types', 'members'].includes(name),
853
852
  });
854
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
855
853
  return parser.parse(rawXml).Package;
856
854
  };
857
855
  exports.packageXmlStringToPackageXmlJson = packageXmlStringToPackageXmlJson;
@@ -83,7 +83,6 @@ const profileStringToProfile = (profileString) => {
83
83
  },
84
84
  isArray: (name) => rewriteProps.includes(name),
85
85
  });
86
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
87
86
  return parser.parse(profileString).Profile;
88
87
  };
89
88
  exports.profileStringToProfile = profileStringToProfile;
@@ -36,7 +36,7 @@ export declare class SubscriberPackageVersion {
36
36
  * @param installationKey
37
37
  * @param options
38
38
  */
39
- static installStatus(connection: Connection, packageInstallRequestOrId: string | PackagingSObjects.PackageInstallRequest, installationKey?: string | undefined | Nullable<string>, options?: PackageInstallOptions): Promise<PackagingSObjects.PackageInstallRequest>;
39
+ static installStatus(connection: Connection, packageInstallRequestOrId: string | PackagingSObjects.PackageInstallRequest, installationKey?: string | Nullable<string>, options?: PackageInstallOptions): Promise<PackagingSObjects.PackageInstallRequest>;
40
40
  /**
41
41
  * list the packages installed in the org
42
42
  *
@@ -244,7 +244,6 @@ function escapeInstallationKey(key) {
244
244
  * @param packageIds The list of package IDs
245
245
  * @param connection For tooling query
246
246
  */
247
- // eslint-disable-next-line @typescript-eslint/require-await
248
247
  async function getContainerOptions(packageIds, connection) {
249
248
  const ids = (0, kit_1.ensureArray)(packageIds).filter(ts_types_1.isString);
250
249
  if (ids.length === 0) {
@@ -264,7 +263,6 @@ async function getContainerOptions(packageIds, connection) {
264
263
  * @param subscriberPackageVersionIds
265
264
  * @param connection For tooling query
266
265
  */
267
- // eslint-disable-next-line @typescript-eslint/require-await
268
266
  async function getPackageVersionStrings(subscriberPackageVersionIds, connection) {
269
267
  let results = new Map();
270
268
  if (!subscriberPackageVersionIds || subscriberPackageVersionIds.length === 0) {
@@ -22,6 +22,10 @@ Package alias %s not found in project.
22
22
 
23
23
  A package with id %s was not found.
24
24
 
25
+ # subscriberPackageIdNotFound
26
+
27
+ The subscriber package ID for package %s was not found.
28
+
25
29
  # appAnalyticsEnabledApiPriorTo59Error
26
30
 
27
31
  Enabling App Analytics is only possible with API version 59.0 or higher.
@@ -0,0 +1,15 @@
1
+ # invalidSubscriberOrg
2
+
3
+ The subscriber org ID %s is invalid. It must be a 15- or 18-character ID that starts with "00D".
4
+
5
+ # invalidSubscriberPackage
6
+
7
+ The subscriber package ID %s is invalid. It must be a 15- or 18-character ID that starts with "033".
8
+
9
+ # noSubscriberOrgs
10
+
11
+ Provide at least one subscriber org ID.
12
+
13
+ # apiVersionTooLow
14
+
15
+ Package authorization requires API version %s or later.
@@ -0,0 +1,7 @@
1
+ # invalidVerifiedOrgId
2
+
3
+ The Verified Org ID %s isn't valid. Specify a valid organization ID (starts with 00D and is 15 or 18 characters) for the Verified Partner Business Org and retry the command.
4
+
5
+ # trustLinkAlreadyExists
6
+
7
+ This org already has a trust link to Verified Org %s with status '%s'. An org can have only one trust link at a time; delete the existing trust link before requesting a new one.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/packaging",
3
- "version": "5.0.7",
3
+ "version": "5.0.9-spi-dev.0",
4
4
  "description": "Packaging library for the Salesforce packaging platform",
5
5
  "main": "lib/exported",
6
6
  "types": "lib/exported.d.ts",
@@ -59,10 +59,16 @@
59
59
  },
60
60
  "devDependencies": {
61
61
  "@salesforce/cli-plugins-testkit": "^5.3.64",
62
- "@salesforce/dev-scripts": "^11.0.4",
62
+ "@salesforce/dev-scripts": "^13.0.2",
63
+ "@types/chai": "^4.3.17",
63
64
  "@types/globby": "^9.1.0",
64
65
  "@types/jszip": "^3.4.1",
65
- "eslint-plugin-sf-plugin": "^1.20.33",
66
+ "@types/mocha": "^10.0.10",
67
+ "@types/node": "^18",
68
+ "@types/sinon": "^10.0.20",
69
+ "eslint": "^10.4.0",
70
+ "eslint-config-salesforce-typescript": "^6.0.0",
71
+ "eslint-plugin-sf-plugin": "^3.0.0",
66
72
  "ts-node": "^10.9.2",
67
73
  "typescript": "^5.9.3"
68
74
  },
@@ -110,6 +116,7 @@
110
116
  "src/**/*.ts",
111
117
  "test/**/*.ts",
112
118
  "messages/**",
119
+ "**/eslint.config.*",
113
120
  "**/.eslint*",
114
121
  "**/tsconfig.json"
115
122
  ],