@salesforce/packaging 0.0.30 → 0.0.33

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.0.33](https://github.com/forcedotcom/packaging/compare/v0.0.32...v0.0.33) (2022-09-08)
6
+
7
+ ### Bug Fixes
8
+
9
+ - add PackageVersion.listCreated, NUT ([31280aa](https://github.com/forcedotcom/packaging/commit/31280aaa79967e1bd9a2c039f028b7d7fe6d658b))
10
+
11
+ ### [0.0.32](https://github.com/forcedotcom/packaging/compare/v0.0.31...v0.0.32) (2022-09-07)
12
+
13
+ ### Bug Fixes
14
+
15
+ - add Package.uninstallReport method, NUT ([9269c9b](https://github.com/forcedotcom/packaging/commit/9269c9b999dcac25ac52c4ee64bf261ffebfb0e0))
16
+
17
+ ### [0.0.31](https://github.com/forcedotcom/packaging/compare/v0.0.30...v0.0.31) (2022-09-07)
18
+
19
+ ### Bug Fixes
20
+
21
+ - add Package2.IsOrgDependent to select query ([8f013ef](https://github.com/forcedotcom/packaging/commit/8f013ef602c76990fa8649b585214991c8afe2c0))
22
+
5
23
  ### [0.0.30](https://github.com/forcedotcom/packaging/compare/v0.0.29...v0.0.30) (2022-08-29)
6
24
 
7
25
  ### Bug Fixes
@@ -1,7 +1,9 @@
1
1
  import { Duration } from '@salesforce/kit';
2
2
  import { Connection, NamedPackageDir, SfProject } from '@salesforce/core';
3
3
  import { QueryResult, SaveResult } from 'jsforce';
4
+ import { Attributes } from 'graphology-types';
4
5
  import { PackageProfileApi } from '../package/packageProfileApi';
6
+ import { PackageAncestryNode } from '../package/packageAncestry';
5
7
  import { PackagingSObjects } from './packagingSObjects';
6
8
  import Package2VersionStatus = PackagingSObjects.Package2VersionStatus;
7
9
  import PackageInstallRequest = PackagingSObjects.PackageInstallRequest;
@@ -232,7 +234,7 @@ export declare type PackageVersionCreateOptions = Partial<PackageVersionOptions
232
234
  export declare type PackageVersionCreateRequestQueryOptions = {
233
235
  createdlastdays?: number;
234
236
  connection?: Connection;
235
- status?: string;
237
+ status?: 'Queued' | 'InProgress' | 'Success' | 'Error';
236
238
  };
237
239
  export declare type ProfileApiOptions = {
238
240
  project: SfProject;
@@ -269,3 +271,34 @@ export declare type CodeCoveragePercentages = null | {
269
271
  }
270
272
  ];
271
273
  };
274
+ export declare type PackageAncestryNodeOptions = Attributes & {
275
+ AncestorId?: string;
276
+ SubscriberPackageVersionId?: string;
277
+ MajorVersion?: string | number;
278
+ MinorVersion?: string | number;
279
+ PatchVersion?: string | number;
280
+ BuildNumber?: string | number;
281
+ depthCounter?: number;
282
+ };
283
+ export declare type PackageAncestryData = Omit<PackageAncestryNodeOptions, 'AncestorId'>;
284
+ export declare type PackageAncestryNodeData = {
285
+ data: PackageAncestryNodeOptions;
286
+ children: PackageAncestryNodeData[];
287
+ };
288
+ export declare type PackageAncestryOptions = {
289
+ packageId: string;
290
+ project: SfProject;
291
+ connection: Connection;
292
+ };
293
+ export declare type AncestryRepresentationProducerOptions = {
294
+ [key: string]: unknown;
295
+ node: PackageAncestryNode;
296
+ depth?: number;
297
+ verbose?: boolean;
298
+ };
299
+ export interface AncestryRepresentationProducer {
300
+ label: string;
301
+ options: AncestryRepresentationProducerOptions;
302
+ addNode(node: AncestryRepresentationProducer): void;
303
+ produce<T>(): T | string | void;
304
+ }
@@ -175,7 +175,7 @@ export declare namespace PackagingSObjects {
175
175
  LastModifiedById: string;
176
176
  SystemModstamp: number;
177
177
  SubscriberPackageVersionId: string;
178
- Status: string;
178
+ Status: 'Error' | 'InProgress' | 'Queued' | 'Success';
179
179
  };
180
180
  type PackageVersionUninstallRequestError = {
181
181
  Id: string;
@@ -9,3 +9,4 @@ export { deletePackage } from './packageDelete';
9
9
  export { uninstallPackage } from './packageUninstall';
10
10
  export * from './packageInstalledList';
11
11
  export * from './packageVersionCreateRequestReport';
12
+ export * from './packageAncestry';
@@ -36,4 +36,5 @@ var packageUninstall_1 = require("./packageUninstall");
36
36
  Object.defineProperty(exports, "uninstallPackage", { enumerable: true, get: function () { return packageUninstall_1.uninstallPackage; } });
37
37
  __exportStar(require("./packageInstalledList"), exports);
38
38
  __exportStar(require("./packageVersionCreateRequestReport"), exports);
39
+ __exportStar(require("./packageAncestry"), exports);
39
40
  //# sourceMappingURL=index.js.map
@@ -32,6 +32,12 @@ export declare class Package extends AsyncCreatable<PackageOptions> implements I
32
32
  getInstallStatus(installRequestId: string): Promise<PackageInstallRequest>;
33
33
  list(): Promise<QueryResult<PackagingSObjects.Package2>>;
34
34
  uninstall(): Promise<void>;
35
+ /**
36
+ * Reports on the uninstall progress of a package.
37
+ *
38
+ * @param id the 06y package uninstall request id
39
+ */
40
+ uninstallReport(id: string): Promise<PackagingSObjects.SubscriberPackageVersionUninstallRequest>;
35
41
  update(options: PackageUpdateOptions): Promise<PackageSaveResult>;
36
42
  getPackage(packageId: string): Promise<PackagingSObjects.Package2>;
37
43
  getExternalSites(subscriberPackageVersionId: string, installationKey?: string): Promise<Optional<string[]>>;
@@ -72,6 +72,25 @@ class Package extends kit_1.AsyncCreatable {
72
72
  uninstall() {
73
73
  return Promise.resolve(undefined);
74
74
  }
75
+ /**
76
+ * Reports on the uninstall progress of a package.
77
+ *
78
+ * @param id the 06y package uninstall request id
79
+ */
80
+ async uninstallReport(id) {
81
+ const result = (await this.options.connection.tooling.retrieve('SubscriberPackageVersionUninstallRequest', id));
82
+ if (result.Status === 'Error') {
83
+ const errorDetails = await this.options.connection.tooling.query(`SELECT Message FROM PackageVersionUninstallRequestError WHERE ParentRequest.Id = '${id}' ORDER BY Message`);
84
+ const errors = [];
85
+ errorDetails.records.forEach((record) => {
86
+ errors.push(`(${errors.length + 1}) ${record.Message}`);
87
+ });
88
+ const errHeader = errors.length > 0 ? `\n=== Errors\n${errors.join('\n')}` : '';
89
+ const err = messages.getMessage('defaultErrorMessage', [id, result.Id]);
90
+ throw new core_1.SfError(`${err}${errHeader}`, 'UNINSTALL_ERROR', [messages.getMessage('action')]);
91
+ }
92
+ return result;
93
+ }
75
94
  async update(options) {
76
95
  // filter out any undefined values and their keys
77
96
  Object.keys(options).forEach((key) => options[key] === undefined && delete options[key]);
@@ -0,0 +1,111 @@
1
+ import { DirectedGraph } from 'graphology';
2
+ import { AsyncCreatable } from '@salesforce/kit';
3
+ import { Tree } from '@oclif/core/lib/cli-ux/styled/tree';
4
+ import { Attributes } from 'graphology-types';
5
+ import { AncestryRepresentationProducer, AncestryRepresentationProducerOptions, PackageAncestryNodeOptions, PackageAncestryOptions } from '../interfaces';
6
+ import { VersionNumber } from '../utils/versionNumber';
7
+ /**
8
+ * A class that represents the package ancestry graph.
9
+ */
10
+ export declare class PackageAncestry extends AsyncCreatable<PackageAncestryOptions> {
11
+ private options;
12
+ private _requestedPackageId;
13
+ private graph;
14
+ private roots;
15
+ constructor(options: PackageAncestryOptions);
16
+ get requestedPackageId(): string;
17
+ init(): Promise<void>;
18
+ /**
19
+ * Returns the internal representation of the requested package ancestry graph.
20
+ */
21
+ getAncestryGraph(): DirectedGraph<Attributes, Attributes, Attributes>;
22
+ /**
23
+ * Convenience method to get the json representation of the package ancestry graph.
24
+ */
25
+ getJsonProducer(): Promise<AncestryRepresentationProducer>;
26
+ /**
27
+ * Convenience method to get the CliUx.Tree representation of the package ancestry graph.
28
+ */
29
+ getTreeProducer(verbose: boolean): Promise<AncestryRepresentationProducer>;
30
+ /**
31
+ * Convenience method to get the dot representation of the package ancestry graph.
32
+ */
33
+ getDotProducer(): Promise<AncestryRepresentationProducer>;
34
+ /**
35
+ * Returns the producer representation of the package ancestry graph.
36
+ *
37
+ * @param producerCtor - function that returns a new instance of the producer
38
+ * @param root - the subscriber package version id of the root node
39
+ */
40
+ getRepresentationProducer(producerCtor: (options?: AncestryRepresentationProducerOptions) => AncestryRepresentationProducer, root: string | undefined): Promise<AncestryRepresentationProducer>;
41
+ /**
42
+ * Returns a list of ancestry nodes that represent the path from subscriber package version id to the root of the
43
+ * package ancestry tree.
44
+ *
45
+ * @param subscriberPackageVersionId
46
+ */
47
+ getLeafPathToRoot(subscriberPackageVersionId?: string): Promise<PackageAncestryNode[][]>;
48
+ private buildAncestryTree;
49
+ private getRoots;
50
+ private findRootsForPackageVersion;
51
+ private getPackageVersion;
52
+ private findRootsForPackage;
53
+ private buildAncestryTreeFromRoots;
54
+ private addDescendantsFromPackageVersion;
55
+ private addToGraph;
56
+ private getDescendants;
57
+ }
58
+ export declare class AncestryTreeProducer extends Tree implements AncestryRepresentationProducer {
59
+ label: string;
60
+ options: AncestryRepresentationProducerOptions;
61
+ private verbose;
62
+ constructor(options?: AncestryRepresentationProducerOptions);
63
+ addNode(node: AncestryTreeProducer): void;
64
+ produce(): void;
65
+ private createLabel;
66
+ }
67
+ export declare class AncestryJsonProducer implements AncestryRepresentationProducer {
68
+ label: string;
69
+ options: AncestryRepresentationProducerOptions;
70
+ private children;
71
+ private readonly data;
72
+ constructor(options?: AncestryRepresentationProducerOptions);
73
+ addNode(node: AncestryJsonProducer): void;
74
+ produce<PackageAncestryNodeData>(): PackageAncestryNodeData;
75
+ }
76
+ export declare class AncestryDotProducer implements AncestryRepresentationProducer {
77
+ label: string;
78
+ options: AncestryRepresentationProducerOptions;
79
+ private children;
80
+ constructor(options?: AncestryRepresentationProducerOptions);
81
+ /**
82
+ * Builds a node line in DOT, of the form nodeID [label="MAJOR.MINOR.PATCH"]
83
+ *
84
+ * @param currentNode
85
+ */
86
+ static buildDotNode(currentNode: AncestryDotProducer): string;
87
+ /**
88
+ * Builds an edge line in DOT, of the form fromNode -- toNode
89
+ *
90
+ * @param fromNode
91
+ * @param toNode
92
+ */
93
+ static buildDotEdge(fromNode: AncestryDotProducer, toNode: AncestryDotProducer): string;
94
+ addNode(node: AncestryDotProducer): void;
95
+ produce(): string;
96
+ }
97
+ export declare class PackageAncestryNode extends AsyncCreatable<PackageAncestryNodeOptions> implements Attributes {
98
+ #private;
99
+ options: PackageAncestryNodeOptions;
100
+ constructor(options: PackageAncestryNodeOptions);
101
+ get AncestorId(): string;
102
+ get SubscriberPackageVersionId(): string;
103
+ get version(): VersionNumber;
104
+ get MinorVersion(): number;
105
+ get PatchVersion(): number;
106
+ get BuildNumber(): number | string;
107
+ get MajorVersion(): number;
108
+ get depthCounter(): number;
109
+ getVersion(): string;
110
+ protected init(): Promise<void>;
111
+ }
@@ -0,0 +1,432 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _PackageAncestryNode_version, _PackageAncestryNode_MajorVersion, _PackageAncestryNode_MinorVersion, _PackageAncestryNode_PatchVersion, _PackageAncestryNode_BuildNumber, _PackageAncestryNode_AncestorId, _PackageAncestryNode_SubscriberPackageVersionId, _PackageAncestryNode_depthCounter;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.PackageAncestryNode = exports.AncestryDotProducer = exports.AncestryJsonProducer = exports.AncestryTreeProducer = exports.PackageAncestry = void 0;
16
+ /*
17
+ * Copyright (c) 2022, salesforce.com, inc.
18
+ * All rights reserved.
19
+ * Licensed under the BSD 3-Clause license.
20
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
21
+ */
22
+ const os_1 = require("os");
23
+ const core_1 = require("@salesforce/core");
24
+ const graphology_1 = require("graphology");
25
+ const kit_1 = require("@salesforce/kit");
26
+ const tree_1 = require("@oclif/core/lib/cli-ux/styled/tree");
27
+ const graphology_traversal_1 = require("graphology-traversal");
28
+ const pkgUtils = require("../utils/packageUtils");
29
+ const versionNumber_1 = require("../utils/versionNumber");
30
+ core_1.Messages.importMessagesDirectory(__dirname);
31
+ const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'messages');
32
+ const SELECT_PACKAGE_VERSION = 'SELECT AncestorId, SubscriberPackageVersionId, MajorVersion, MinorVersion, PatchVersion, BuildNumber FROM Package2Version';
33
+ const SELECT_PACKAGE_CONTAINER_OPTIONS = 'SELECT ContainerOptions FROM Package2 ';
34
+ const SELECT_PACKAGE_VERSION_CONTAINER_OPTIONS = 'SELECT Package2ContainerOptions FROM SubscriberPackageVersion';
35
+ // Add this to query calls to only show released package versions in the output
36
+ const releasedOnlyFilter = ' AND IsReleased = true';
37
+ /**
38
+ * A class that represents the package ancestry graph.
39
+ */
40
+ class PackageAncestry extends kit_1.AsyncCreatable {
41
+ constructor(options) {
42
+ super(options);
43
+ this.options = options;
44
+ this.graph = new graphology_1.DirectedGraph();
45
+ }
46
+ get requestedPackageId() {
47
+ return this._requestedPackageId;
48
+ }
49
+ async init() {
50
+ await this.buildAncestryTree();
51
+ }
52
+ /**
53
+ * Returns the internal representation of the requested package ancestry graph.
54
+ */
55
+ getAncestryGraph() {
56
+ return this.graph;
57
+ }
58
+ /**
59
+ * Convenience method to get the json representation of the package ancestry graph.
60
+ */
61
+ async getJsonProducer() {
62
+ return this.getRepresentationProducer((opts) => new AncestryJsonProducer(opts), this.requestedPackageId);
63
+ }
64
+ /**
65
+ * Convenience method to get the CliUx.Tree representation of the package ancestry graph.
66
+ */
67
+ async getTreeProducer(verbose) {
68
+ return this.getRepresentationProducer((opts) => new AncestryTreeProducer({ ...opts, verbose: !!verbose }), this.requestedPackageId);
69
+ }
70
+ /**
71
+ * Convenience method to get the dot representation of the package ancestry graph.
72
+ */
73
+ async getDotProducer() {
74
+ return this.getRepresentationProducer((opts) => new AncestryDotProducer(opts), this.requestedPackageId);
75
+ }
76
+ /**
77
+ * Returns the producer representation of the package ancestry graph.
78
+ *
79
+ * @param producerCtor - function that returns a new instance of the producer
80
+ * @param root - the subscriber package version id of the root node
81
+ */
82
+ async getRepresentationProducer(producerCtor, root) {
83
+ const treeRoot = root
84
+ ? this.graph.findNode((node, attributes) => attributes.node.SubscriberPackageVersionId === root)
85
+ : undefined;
86
+ const tree = producerCtor();
87
+ const treeStack = [];
88
+ function handleNode(node, attr, depth) {
89
+ if (treeStack.length > depth) {
90
+ treeStack.splice(depth);
91
+ }
92
+ let t = treeStack[depth];
93
+ if (!t) {
94
+ t = producerCtor({ node: attr.node, depth });
95
+ treeStack.push(t);
96
+ }
97
+ if (depth === 0) {
98
+ tree.addNode(t);
99
+ }
100
+ else {
101
+ treeStack[depth - 1].addNode(t);
102
+ }
103
+ }
104
+ if (treeRoot) {
105
+ (0, graphology_traversal_1.dfsFromNode)(this.graph, treeRoot, handleNode);
106
+ }
107
+ else {
108
+ (0, graphology_traversal_1.dfs)(this.graph, handleNode);
109
+ }
110
+ return tree;
111
+ }
112
+ /**
113
+ * Returns a list of ancestry nodes that represent the path from subscriber package version id to the root of the
114
+ * package ancestry tree.
115
+ *
116
+ * @param subscriberPackageVersionId
117
+ */
118
+ async getLeafPathToRoot(subscriberPackageVersionId) {
119
+ const root = this.graph.findNode((node, attributes) => attributes.node.AncestorId === null);
120
+ const paths = [];
121
+ let path = [];
122
+ let previousDepth = 0;
123
+ (0, graphology_traversal_1.dfsFromNode)(this.graph, root, function (node, attr, depth) {
124
+ if (depth === 0) {
125
+ paths.push(path);
126
+ path = [];
127
+ }
128
+ else if (depth <= previousDepth) {
129
+ paths.push(path);
130
+ path = path.slice(0, depth);
131
+ }
132
+ previousDepth = depth;
133
+ path.push(attr.node);
134
+ });
135
+ // push remaining path
136
+ paths.push(path);
137
+ return paths
138
+ .filter((path) => path.length > 0 && // don't care about zero length paths
139
+ (!subscriberPackageVersionId ||
140
+ path.some((node) => node.SubscriberPackageVersionId === subscriberPackageVersionId)))
141
+ .map((path) => path.reverse())
142
+ .map((path) => {
143
+ const subscriberPackageVersionIdIndex = path.findIndex((node) => node.SubscriberPackageVersionId === subscriberPackageVersionId);
144
+ return path.slice(subscriberPackageVersionIdIndex === -1 ? 0 : subscriberPackageVersionIdIndex);
145
+ });
146
+ }
147
+ async buildAncestryTree() {
148
+ this.roots = await this.getRoots();
149
+ await this.buildAncestryTreeFromRoots(this.roots);
150
+ }
151
+ async getRoots() {
152
+ let roots = [];
153
+ this._requestedPackageId = pkgUtils.getPackageIdFromAlias(this.options.packageId, this.options.project);
154
+ switch (this.requestedPackageId.slice(0, 3)) {
155
+ case '0Ho':
156
+ pkgUtils.validateId(pkgUtils.BY_LABEL.PACKAGE_ID, this.requestedPackageId);
157
+ roots = await this.findRootsForPackage();
158
+ break;
159
+ case '04t':
160
+ pkgUtils.validateId(pkgUtils.BY_LABEL.SUBSCRIBER_PACKAGE_VERSION_ID, this.requestedPackageId);
161
+ roots = await this.findRootsForPackageVersion();
162
+ break;
163
+ default:
164
+ throw messages.createError('idOrAliasNotFound', [this.requestedPackageId]);
165
+ }
166
+ return roots;
167
+ }
168
+ async findRootsForPackageVersion() {
169
+ // Check to see if the package version is part of an unlocked package
170
+ // if so, throw an error since ancestry only applies to managed packages
171
+ const versionQuery = `${SELECT_PACKAGE_VERSION_CONTAINER_OPTIONS} WHERE Id = '${this.requestedPackageId}'`;
172
+ const packageVersionTypeResults = await this.options.connection.singleRecordQuery(versionQuery, { tooling: true });
173
+ if (packageVersionTypeResults.Package2ContainerOptions !== 'Managed') {
174
+ throw messages.createError('unlockedPackageError');
175
+ }
176
+ // Start with the node, and shoot up
177
+ let node = await this.getPackageVersion(this.requestedPackageId);
178
+ while (node.AncestorId !== null) {
179
+ const ancestor = await this.getPackageVersion(node.AncestorId);
180
+ this.addToGraph(ancestor, node);
181
+ node = ancestor;
182
+ }
183
+ return [node];
184
+ }
185
+ async getPackageVersion(nodeId) {
186
+ const query = `${SELECT_PACKAGE_VERSION} WHERE SubscriberPackageVersionId = '${nodeId}'`;
187
+ try {
188
+ const results = await this.options.connection.singleRecordQuery(query, {
189
+ tooling: true,
190
+ });
191
+ return new PackageAncestryNode(results);
192
+ }
193
+ catch (e) {
194
+ if (e.message.includes('No record found for')) {
195
+ throw messages.createError('versionNotFound', [nodeId]);
196
+ }
197
+ throw e;
198
+ }
199
+ }
200
+ async findRootsForPackage() {
201
+ // Check to see if the package is an unlocked package
202
+ // if so, throw and error since ancestry only applies to managed packages
203
+ const query = `${SELECT_PACKAGE_CONTAINER_OPTIONS} WHERE Id = '${this.requestedPackageId}'`;
204
+ const packageTypeResults = await this.options.connection.tooling.query(query);
205
+ if (packageTypeResults?.records?.length === 0) {
206
+ throw messages.createError('invalidId', [this.requestedPackageId]);
207
+ }
208
+ else if (packageTypeResults?.records?.length && packageTypeResults?.records[0].ContainerOptions !== 'Managed') {
209
+ throw messages.createError('unlockedPackageError');
210
+ }
211
+ const normalQuery = `${SELECT_PACKAGE_VERSION} WHERE AncestorId = NULL AND Package2Id = '${this.requestedPackageId}' ${releasedOnlyFilter}`;
212
+ const subscriberPackageVersions = (await this.options.connection.tooling.query(normalQuery)).records?.map((record) => new PackageAncestryNode(record));
213
+ // The package exists, but there are no versions for the provided package
214
+ if (subscriberPackageVersions.length === 0) {
215
+ throw messages.createError('noVersionsError');
216
+ }
217
+ return subscriberPackageVersions;
218
+ }
219
+ async buildAncestryTreeFromRoots(roots) {
220
+ while (roots.length > 0) {
221
+ const subscriberPackageVersion = roots.shift();
222
+ const descendants = await this.addDescendantsFromPackageVersion(subscriberPackageVersion);
223
+ roots.push(...descendants);
224
+ }
225
+ }
226
+ async addDescendantsFromPackageVersion(subscriberPackageVersion) {
227
+ const descendants = await this.getDescendants(subscriberPackageVersion);
228
+ descendants.forEach((descendant) => this.addToGraph(subscriberPackageVersion, descendant));
229
+ return descendants;
230
+ }
231
+ addToGraph(ancestor, descendant) {
232
+ if (!this.graph.hasNode(ancestor.getVersion())) {
233
+ this.graph.addNode(ancestor.getVersion(), { node: ancestor });
234
+ }
235
+ if (!this.graph.hasNode(descendant.getVersion())) {
236
+ this.graph.addNode(descendant.getVersion(), { node: descendant });
237
+ }
238
+ if (!this.graph.hasEdge(ancestor.getVersion(), descendant.getVersion())) {
239
+ this.graph.addDirectedEdgeWithKey(`${ancestor.getVersion()}->${descendant.getVersion()}`, ancestor.getVersion(), descendant.getVersion(), {
240
+ from: ancestor.getVersion(),
241
+ to: descendant.getVersion(),
242
+ });
243
+ }
244
+ }
245
+ async getDescendants(ancestor) {
246
+ const query = `${SELECT_PACKAGE_VERSION} WHERE AncestorId = '${ancestor.SubscriberPackageVersionId}' ${releasedOnlyFilter}`;
247
+ const results = await this.options.connection.tooling.query(query);
248
+ return results.records.map((result) => new PackageAncestryNode(result));
249
+ }
250
+ }
251
+ exports.PackageAncestry = PackageAncestry;
252
+ class AncestryTreeProducer extends tree_1.Tree {
253
+ constructor(options) {
254
+ super();
255
+ this.verbose = false;
256
+ this.options = options;
257
+ this.label = this.options?.node?.getVersion() || 'root';
258
+ this.verbose = this.options?.verbose || false;
259
+ }
260
+ addNode(node) {
261
+ const label = this.createLabel(node);
262
+ this.insert(label, node);
263
+ }
264
+ produce() {
265
+ const producers = [];
266
+ producers.push(this);
267
+ while (producers.length > 0) {
268
+ const producer = producers.shift();
269
+ Object.values(producer.nodes)
270
+ .sort((a, b) => a.options.node.version.compareTo(b.options.node.version))
271
+ .forEach((child) => {
272
+ delete producer.nodes[this.createLabel(child)];
273
+ producer.addNode(child);
274
+ producers.push(child);
275
+ });
276
+ }
277
+ this.display(this.options ? this.options['logger'] : undefined);
278
+ }
279
+ createLabel(node) {
280
+ const subscriberId = this.verbose && node?.options?.node?.SubscriberPackageVersionId
281
+ ? ` (${node.options.node.SubscriberPackageVersionId})`
282
+ : '';
283
+ return node?.label ? `${node.label}${subscriberId}` : 'root';
284
+ }
285
+ }
286
+ exports.AncestryTreeProducer = AncestryTreeProducer;
287
+ class AncestryJsonProducer {
288
+ constructor(options) {
289
+ this.children = [];
290
+ this.options = options;
291
+ this.label = this.options?.node?.getVersion() || 'root';
292
+ this.data = {
293
+ children: [],
294
+ data: {
295
+ SubscriberPackageVersionId: this.options?.node?.SubscriberPackageVersionId,
296
+ MajorVersion: this.options?.node?.MajorVersion,
297
+ MinorVersion: this.options?.node?.MinorVersion,
298
+ PatchVersion: this.options?.node?.PatchVersion,
299
+ BuildNumber: this.options?.node?.BuildNumber,
300
+ depthCounter: this.options?.depth,
301
+ },
302
+ };
303
+ }
304
+ addNode(node) {
305
+ this.data.children.push(node.data);
306
+ this.children.push(node);
307
+ }
308
+ produce() {
309
+ const producers = [];
310
+ producers.push(this);
311
+ while (producers.length > 0) {
312
+ const producer = producers.shift();
313
+ producer.data.children.sort((a, b) => {
314
+ const aVersion = new versionNumber_1.VersionNumber(a.data.MajorVersion, a.data.MinorVersion, a.data.PatchVersion, a.data.BuildNumber);
315
+ const bVersion = new versionNumber_1.VersionNumber(b.data.MajorVersion, b.data.MinorVersion, b.data.PatchVersion, b.data.BuildNumber);
316
+ return aVersion.compareTo(bVersion);
317
+ });
318
+ producers.push(...producer.children);
319
+ }
320
+ return this.data.children[0];
321
+ }
322
+ }
323
+ exports.AncestryJsonProducer = AncestryJsonProducer;
324
+ class AncestryDotProducer {
325
+ constructor(options) {
326
+ this.children = [];
327
+ this.options = options;
328
+ this.label = this.options?.node?.getVersion() || 'root';
329
+ }
330
+ /**
331
+ * Builds a node line in DOT, of the form nodeID [label="MAJOR.MINOR.PATCH"]
332
+ *
333
+ * @param currentNode
334
+ */
335
+ static buildDotNode(currentNode) {
336
+ return `\t node${currentNode.options.node.SubscriberPackageVersionId} [label="${currentNode.label}"]`;
337
+ }
338
+ /**
339
+ * Builds an edge line in DOT, of the form fromNode -- toNode
340
+ *
341
+ * @param fromNode
342
+ * @param toNode
343
+ */
344
+ static buildDotEdge(fromNode, toNode) {
345
+ return `\t node${fromNode.options.node.SubscriberPackageVersionId} -- node${toNode.options.node.SubscriberPackageVersionId}`;
346
+ }
347
+ addNode(node) {
348
+ this.children.push(node);
349
+ }
350
+ produce() {
351
+ const producers = [];
352
+ producers.push(this);
353
+ const dotLines = [];
354
+ while (producers.length > 0) {
355
+ const producer = producers.shift();
356
+ if (producer.options) {
357
+ dotLines.push(AncestryDotProducer.buildDotNode(producer));
358
+ }
359
+ producers.push(...producer.children);
360
+ }
361
+ producers.push(this);
362
+ while (producers.length > 0) {
363
+ const producer = producers.shift();
364
+ if (producer.options) {
365
+ producer.children.forEach((child) => dotLines.push(AncestryDotProducer.buildDotEdge(producer, child)));
366
+ }
367
+ producers.push(...producer.children);
368
+ }
369
+ return `strict graph G {${os_1.EOL}${dotLines.join(os_1.EOL)}${os_1.EOL}}`;
370
+ }
371
+ }
372
+ exports.AncestryDotProducer = AncestryDotProducer;
373
+ class PackageAncestryNode extends kit_1.AsyncCreatable {
374
+ constructor(options) {
375
+ super(options);
376
+ this.options = options;
377
+ _PackageAncestryNode_version.set(this, void 0);
378
+ _PackageAncestryNode_MajorVersion.set(this, void 0);
379
+ _PackageAncestryNode_MinorVersion.set(this, void 0);
380
+ _PackageAncestryNode_PatchVersion.set(this, void 0);
381
+ _PackageAncestryNode_BuildNumber.set(this, void 0);
382
+ _PackageAncestryNode_AncestorId.set(this, void 0);
383
+ _PackageAncestryNode_SubscriberPackageVersionId.set(this, void 0);
384
+ _PackageAncestryNode_depthCounter.set(this, void 0);
385
+ __classPrivateFieldSet(this, _PackageAncestryNode_version, new versionNumber_1.VersionNumber(this.options.MajorVersion, this.options.MinorVersion, this.options.PatchVersion, this.options.BuildNumber), "f");
386
+ __classPrivateFieldSet(this, _PackageAncestryNode_AncestorId, this.options.AncestorId, "f");
387
+ __classPrivateFieldSet(this, _PackageAncestryNode_SubscriberPackageVersionId, this.options.SubscriberPackageVersionId, "f");
388
+ __classPrivateFieldSet(this, _PackageAncestryNode_MajorVersion, typeof this.options.MajorVersion === 'number'
389
+ ? this.options.MajorVersion
390
+ : parseInt(this.options.MajorVersion, 10), "f");
391
+ __classPrivateFieldSet(this, _PackageAncestryNode_MinorVersion, typeof this.options.MinorVersion === 'number'
392
+ ? this.options.MinorVersion
393
+ : parseInt(this.options.MinorVersion, 10), "f");
394
+ __classPrivateFieldSet(this, _PackageAncestryNode_PatchVersion, typeof this.options.PatchVersion === 'number'
395
+ ? this.options.PatchVersion
396
+ : parseInt(this.options.PatchVersion, 10), "f");
397
+ __classPrivateFieldSet(this, _PackageAncestryNode_BuildNumber, this.options.BuildNumber, "f");
398
+ }
399
+ get AncestorId() {
400
+ return __classPrivateFieldGet(this, _PackageAncestryNode_AncestorId, "f");
401
+ }
402
+ get SubscriberPackageVersionId() {
403
+ return __classPrivateFieldGet(this, _PackageAncestryNode_SubscriberPackageVersionId, "f");
404
+ }
405
+ get version() {
406
+ return __classPrivateFieldGet(this, _PackageAncestryNode_version, "f");
407
+ }
408
+ get MinorVersion() {
409
+ return __classPrivateFieldGet(this, _PackageAncestryNode_MinorVersion, "f");
410
+ }
411
+ get PatchVersion() {
412
+ return __classPrivateFieldGet(this, _PackageAncestryNode_PatchVersion, "f");
413
+ }
414
+ get BuildNumber() {
415
+ return __classPrivateFieldGet(this, _PackageAncestryNode_BuildNumber, "f");
416
+ }
417
+ get MajorVersion() {
418
+ return __classPrivateFieldGet(this, _PackageAncestryNode_MajorVersion, "f");
419
+ }
420
+ get depthCounter() {
421
+ return __classPrivateFieldGet(this, _PackageAncestryNode_depthCounter, "f");
422
+ }
423
+ getVersion() {
424
+ return __classPrivateFieldGet(this, _PackageAncestryNode_version, "f").toString();
425
+ }
426
+ init() {
427
+ return Promise.resolve();
428
+ }
429
+ }
430
+ exports.PackageAncestryNode = PackageAncestryNode;
431
+ _PackageAncestryNode_version = new WeakMap(), _PackageAncestryNode_MajorVersion = new WeakMap(), _PackageAncestryNode_MinorVersion = new WeakMap(), _PackageAncestryNode_PatchVersion = new WeakMap(), _PackageAncestryNode_BuildNumber = new WeakMap(), _PackageAncestryNode_AncestorId = new WeakMap(), _PackageAncestryNode_SubscriberPackageVersionId = new WeakMap(), _PackageAncestryNode_depthCounter = new WeakMap();
432
+ //# sourceMappingURL=packageAncestry.js.map
@@ -105,8 +105,7 @@ async function getExternalSites(connection, subscriberPackageVersionId, installa
105
105
  }
106
106
  exports.getExternalSites = getExternalSites;
107
107
  async function getStatus(connection, installRequestId) {
108
- const result = await connection.tooling.retrieve('PackageInstallRequest', installRequestId);
109
- return result;
108
+ return (await connection.tooling.retrieve('PackageInstallRequest', installRequestId));
110
109
  }
111
110
  exports.getStatus = getStatus;
112
111
  // internal
@@ -1,5 +1,5 @@
1
1
  import { Duration } from '@salesforce/kit';
2
- import { PackageSaveResult, PackageVersionCreateOptions, PackageVersionCreateRequestResult, PackageVersionListOptions, PackageVersionListResult, PackageVersionOptions, PackageVersionReportResult, PackageVersionUpdateOptions } from '../interfaces';
2
+ import { PackageSaveResult, PackageVersionCreateOptions, PackageVersionCreateRequestQueryOptions, PackageVersionCreateRequestResult, PackageVersionListOptions, PackageVersionListResult, PackageVersionOptions, PackageVersionReportResult, PackageVersionUpdateOptions } from '../interfaces';
3
3
  export declare class PackageVersion {
4
4
  private options;
5
5
  private readonly project;
@@ -40,6 +40,7 @@ export declare class PackageVersion {
40
40
  * @param createPackageRequestId
41
41
  */
42
42
  getCreateVersionReport(createPackageRequestId: string): Promise<PackageVersionCreateRequestResult>;
43
+ createdList(options?: Omit<PackageVersionCreateRequestQueryOptions, 'connection'>): Promise<PackageVersionCreateRequestResult[]>;
43
44
  /**
44
45
  * Convenience function that will wait for a package version to be created.
45
46
  *
@@ -14,6 +14,7 @@ const packageVersionCreate_1 = require("./packageVersionCreate");
14
14
  const packageVersionReport_1 = require("./packageVersionReport");
15
15
  const packageVersionCreateRequestReport_1 = require("./packageVersionCreateRequestReport");
16
16
  const packageVersionList_1 = require("./packageVersionList");
17
+ const packageVersionCreateRequest_1 = require("./packageVersionCreateRequest");
17
18
  core_1.Messages.importMessagesDirectory(__dirname);
18
19
  class PackageVersion {
19
20
  constructor(options) {
@@ -89,6 +90,9 @@ class PackageVersion {
89
90
  throw (0, utils_1.applyErrorAction)(err);
90
91
  });
91
92
  }
93
+ async createdList(options) {
94
+ return await (0, packageVersionCreateRequest_1.list)({ ...options, connection: this.connection });
95
+ }
92
96
  /**
93
97
  * Convenience function that will wait for a package version to be created.
94
98
  *
@@ -167,7 +167,7 @@ class PackageVersionCreate {
167
167
  async resolveBuildNumber(versionNumber, packageId, branch) {
168
168
  if (!versionNumber.isbuildKeyword()) {
169
169
  // The build number is already specified so just return it using the tooling query result obj structure
170
- return versionNumber.build;
170
+ return `${versionNumber.build}`;
171
171
  }
172
172
  // query for the LATEST or RELEASED build number (excluding deleted versions)
173
173
  let branchCondition = '';
@@ -19,9 +19,8 @@ const QUERY = 'SELECT Id, Status, Package2Id, Package2VersionId, Package2Version
19
19
  '%s' + // WHERE, if applicable
20
20
  'ORDER BY CreatedDate';
21
21
  const ERROR_QUERY = "SELECT Message FROM Package2VersionCreateRequestError WHERE ParentRequest.Id = '%s'";
22
- const STATUSES = ['Queued', 'InProgress', 'Success', 'Error'];
23
- async function list(options = {}) {
24
- const whereClause = _constructWhere();
22
+ async function list(options) {
23
+ const whereClause = _constructWhere(options);
25
24
  return _query(util.format(QUERY, whereClause), options.connection);
26
25
  }
27
26
  exports.list = list;
@@ -62,23 +61,15 @@ async function _queryErrors(packageVersionCreateRequestId, connection) {
62
61
  function _constructWhere(options) {
63
62
  const where = [];
64
63
  // filter on created date, days ago: 0 for today, etc
65
- if (!util.isNullOrUndefined(this.options.createdlastdays)) {
64
+ if (options?.createdlastdays) {
66
65
  if (options.createdlastdays < 0) {
67
66
  throw messages.createError('invalidDaysNumber', ['createdlastdays', options.createdlastdays]);
68
67
  }
69
- where.push(`CreatedDate = LAST_N_DAYS:${this.options.createdlastdays}`);
68
+ where.push(`CreatedDate = LAST_N_DAYS:${options.createdlastdays}`);
70
69
  }
71
70
  // filter on errors
72
- if (options.status) {
73
- const foundStatus = STATUSES.find((status) => status.toLowerCase() === this.options.status.toLowerCase());
74
- if (!foundStatus) {
75
- const args = [options.status];
76
- STATUSES.forEach((status) => {
77
- args.push(status);
78
- });
79
- throw messages.createError('invalidStatus', args);
80
- }
81
- where.push(`Status = '${foundStatus}'`);
71
+ if (options?.status) {
72
+ where.push(`Status = '${options.status.toLowerCase()}'`);
82
73
  }
83
74
  return where.length > 0 ? `WHERE ${where.join(' AND ')}` : '';
84
75
  }
@@ -13,7 +13,7 @@ const utils_1 = require("../utils");
13
13
  core_1.Messages.importMessagesDirectory(__dirname);
14
14
  const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'messages');
15
15
  // Stripping CodeCoverage, HasPassedCodeCoverageCheck as they are causing a perf issue in 47.0+ W-6997762
16
- const DEFAULT_SELECT = 'SELECT Id, Package2Id, SubscriberPackageVersionId, Name, Package2.Name, Package2.NamespacePrefix, ' +
16
+ const DEFAULT_SELECT = 'SELECT Id, Package2Id, SubscriberPackageVersionId, Name, Package2.Name, Package2.NamespacePrefix, Package2.IsOrgDependent, ' +
17
17
  'Description, Tag, Branch, MajorVersion, MinorVersion, PatchVersion, BuildNumber, IsReleased, ' +
18
18
  'CreatedDate, LastModifiedDate, IsPasswordProtected, AncestorId, ValidationSkipped, CreatedById ' +
19
19
  'FROM Package2Version';
@@ -1,2 +1,3 @@
1
1
  export * from './packageUtils';
2
2
  export * from './srcDevUtils';
3
+ export * from './versionNumber';
@@ -22,4 +22,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
22
22
  */
23
23
  __exportStar(require("./packageUtils"), exports);
24
24
  __exportStar(require("./srcDevUtils"), exports);
25
+ __exportStar(require("./versionNumber"), exports);
25
26
  //# sourceMappingURL=index.js.map
@@ -74,7 +74,7 @@ exports.validateIdNoThrow = validateIdNoThrow;
74
74
  function validateVersionNumber(versionNumberString, supportedBuildNumberToken, supportedBuildNumberToken2) {
75
75
  const versionNumber = versionNumber_1.VersionNumber.from(versionNumberString);
76
76
  // build number can be a number or valid token
77
- if (Number.isNaN(parseInt(versionNumber.build, 10)) &&
77
+ if (Number.isNaN(parseInt(`${versionNumber.build}`, 10)) &&
78
78
  versionNumber.build !== supportedBuildNumberToken &&
79
79
  versionNumber.build !== supportedBuildNumberToken2) {
80
80
  if (supportedBuildNumberToken2) {
@@ -6,12 +6,13 @@ export declare enum BuildNumberToken {
6
6
  NONE_VERSION_NUMBER_TOKEN = "NONE"
7
7
  }
8
8
  export declare class VersionNumber {
9
- major: string;
10
- minor: string;
11
- patch: string;
12
- build: string;
13
- private constructor();
9
+ major: string | number;
10
+ minor: string | number;
11
+ patch: string | number;
12
+ build: string | number;
13
+ constructor(major: string | number, minor: string | number, patch: string | number, build: string | number);
14
14
  static from(versionString: string): VersionNumber;
15
15
  toString(): string;
16
16
  isbuildKeyword(): boolean;
17
+ compareTo(other: VersionNumber): number;
17
18
  }
@@ -54,7 +54,33 @@ class VersionNumber {
54
54
  isbuildKeyword() {
55
55
  return Object.values(BuildNumberToken)
56
56
  .map((v) => v.toString())
57
- .includes(this.build.toLowerCase());
57
+ .includes(typeof this.build === 'string' && this.build.toUpperCase());
58
+ }
59
+ compareTo(other) {
60
+ const [aMajor, aMinor, aPatch, aBuild] = [this.major, this.minor, this.patch, this.build].map((v) => typeof v === 'number' ? v : parseInt(v, 10));
61
+ const [oMajor, oMinor, oPatch, oBuild] = [other.major, other.minor, other.patch, other.build].map((v) => typeof v === 'number' ? v : parseInt(v, 10));
62
+ if (aMajor !== oMajor) {
63
+ return aMajor - oMajor;
64
+ }
65
+ if (aMinor !== oMinor) {
66
+ return aMinor - oMinor;
67
+ }
68
+ if (aPatch !== oPatch) {
69
+ return aPatch - oPatch;
70
+ }
71
+ if (isNaN(aBuild) && isNaN(oBuild)) {
72
+ return 0;
73
+ }
74
+ if (isNaN(aBuild)) {
75
+ return 1;
76
+ }
77
+ if (isNaN(oBuild)) {
78
+ return -1;
79
+ }
80
+ if (aBuild !== oBuild) {
81
+ return aBuild - oBuild;
82
+ }
83
+ return 0;
58
84
  }
59
85
  }
60
86
  exports.VersionNumber = VersionNumber;
@@ -177,6 +177,14 @@ Only one package in a Dev Hub is allowed per converted from first-generation pac
177
177
 
178
178
  Multiple errors occurred:
179
179
 
180
+ # errorScriptsNotApplicableToUnlockedPackage
181
+
182
+ We can’t create the package version. This parameter is available only for second-generation managed packages. Create the package version without the postinstallscript or uninstallscript parameters.,
183
+
184
+ # errorAncestorNotApplicableToUnlockedPackage
185
+
186
+ Can’t create package version. Specifying an ancestor is available only for second-generation managed packages. Remove the ancestorId or ancestorVersion from your sfdx-project.json file, and then create the package version again.,
187
+
180
188
  # itemDoesNotFitWithinMaxLength
181
189
 
182
190
  When calculating the number of items to be included in query "%s", when formatted, was too long.
@@ -203,10 +211,34 @@ The %s value, [%s], and %s value, [%s], were both found in sfdx-project.json but
203
211
 
204
212
  The provided package ID '%s' is invalid.
205
213
 
214
+ # tempFileLocation
215
+
216
+ The temp files are located at: %s.
217
+
218
+ # failedToCreatePVCRequest
219
+
220
+ Failed to create request %s: %s
221
+
222
+ # versionNumberNotFoundInDevHub
223
+
224
+ No version number was found in Dev Hub for package id %s and branch %s and version number %s that resolved to build number %s.
225
+
226
+ # noReleaseVersionFound
227
+
228
+ No released version was found in Dev Hub for package id %s and version number %s.
229
+
230
+ # noReleaseVersionFoundForBranch
231
+
232
+ No version number was found in Dev Hub for package id $s and branch %s and version number %s.
233
+
206
234
  # packagingDirNotFoundInConfigFile
207
235
 
208
236
  Config file %s does not contain a packaging directory for %s.
209
237
 
238
+ # unpackagedMDDirectoryDoesNotExist
239
+
240
+ Un-packaged metadata directory %s was specified but does not exist.
241
+
210
242
  # directoryDoesNotExist
211
243
 
212
244
  Directory %s does not exist.
@@ -231,3 +263,7 @@ Verify installed package ID and resolve errors, then try again.
231
263
  # errorNoSubscriberPackageRecord
232
264
 
233
265
  No subscriber package was found for seed id: %s'
266
+
267
+ # idOrAliasNotFound
268
+
269
+ Can't find package with id or alias: %s
@@ -5,3 +5,11 @@ The %s: [%s] is invalid. It must start with "%s".
5
5
  # invalidIdLength
6
6
 
7
7
  The %s: [%s] is invalid. It must be either 15 or 18 characters.
8
+
9
+ # defaultErrorMessage
10
+
11
+ Can't uninstall the package %s during uninstall request %s.
12
+
13
+ # action
14
+
15
+ Verify installed package ID and resolve errors, then try again.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/packaging",
3
- "version": "0.0.30",
3
+ "version": "0.0.33",
4
4
  "description": "packing libraries to Salesforce packaging platform",
5
5
  "main": "lib/exported",
6
6
  "types": "lib/exported.d.ts",
@@ -35,6 +35,7 @@
35
35
  "!lib/**/*.map"
36
36
  ],
37
37
  "dependencies": {
38
+ "@oclif/core": "^1.14.2",
38
39
  "@salesforce/core": "^3.26.2",
39
40
  "@salesforce/kit": "^1.6.0",
40
41
  "@salesforce/schemas": "^1.2.0",
@@ -43,6 +44,9 @@
43
44
  "@xmldom/xmldom": "^0.8.2",
44
45
  "debug": "^4.3.4",
45
46
  "globby": "^11",
47
+ "graphology": "^0.24.1",
48
+ "graphology-traversal": "^0.3.1",
49
+ "graphology-types": "^0.24.4",
46
50
  "js2xmlparser": "^4.0.2",
47
51
  "jsforce": "beta",
48
52
  "jszip": "^3.10.0",