@simplysf/simply-package 2.1.0 → 2.3.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.
- package/README.md +62 -2
- package/lib/commands/simply/package/dependencies/manage.d.ts +20 -0
- package/lib/commands/simply/package/dependencies/manage.js +196 -0
- package/lib/commands/simply/package/dependencies/manage.js.map +1 -0
- package/lib/common/packageVersionService.d.ts +26 -0
- package/lib/common/packageVersionService.js +314 -0
- package/lib/common/packageVersionService.js.map +1 -0
- package/lib/common/sfdxProjectService.d.ts +12 -0
- package/lib/common/sfdxProjectService.js +129 -0
- package/lib/common/sfdxProjectService.js.map +1 -0
- package/lib/schemas/manage/dependencyChange.d.ts +18 -0
- package/lib/schemas/manage/dependencyChange.js +17 -0
- package/lib/schemas/manage/dependencyChange.js.map +1 -0
- package/lib/schemas/manage/parsedDependency.d.ts +12 -0
- package/lib/schemas/manage/parsedDependency.js +39 -0
- package/lib/schemas/manage/parsedDependency.js.map +1 -0
- package/messages/simply.package.dependencies.manage.md +86 -0
- package/npm-shrinkwrap.json +32 -137
- package/oclif.manifest.json +229 -109
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -57,6 +57,7 @@ sf plugins
|
|
|
57
57
|
|
|
58
58
|
<!-- commands -->
|
|
59
59
|
* [`sf simply package dependencies install`](#sf-simply-package-dependencies-install)
|
|
60
|
+
* [`sf simply package dependencies manage`](#sf-simply-package-dependencies-manage)
|
|
60
61
|
* [`sf simply package version cleanup`](#sf-simply-package-version-cleanup)
|
|
61
62
|
|
|
62
63
|
## `sf simply package dependencies install`
|
|
@@ -153,7 +154,66 @@ FLAG DESCRIPTIONS
|
|
|
153
154
|
from by entering the branch build name. If not specified, the builds from NULL branch will be considered.
|
|
154
155
|
```
|
|
155
156
|
|
|
156
|
-
_See code: [lib/commands/simply/package/dependencies/install.js](https://github.com/SimplySF/simply-package/blob/
|
|
157
|
+
_See code: [lib/commands/simply/package/dependencies/install.js](https://github.com/SimplySF/simply-package/blob/2.3.0/lib/commands/simply/package/dependencies/install.js)_
|
|
158
|
+
|
|
159
|
+
## `sf simply package dependencies manage`
|
|
160
|
+
|
|
161
|
+
Manage package dependency versions for a Salesforce project.
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
USAGE
|
|
165
|
+
$ sf simply package dependencies manage -v <value> [--json] [--flags-dir <value>] [-b <value>] [--update-to-released |
|
|
166
|
+
--update-to-latest] [--api-version <value>]
|
|
167
|
+
|
|
168
|
+
FLAGS
|
|
169
|
+
-b, --branch=<value> Package branch to consider when evaluating version options.
|
|
170
|
+
-v, --target-dev-hub=<value> (required) Username or alias of the Dev Hub org. Not required if the `target-dev-hub`
|
|
171
|
+
configuration variable is already set.
|
|
172
|
+
--api-version=<value> Override the api version used for api requests made by this command
|
|
173
|
+
--update-to-latest Automatically set all dependencies to the latest non-pinned build.
|
|
174
|
+
--update-to-released Automatically update all dependencies to the latest released version.
|
|
175
|
+
|
|
176
|
+
GLOBAL FLAGS
|
|
177
|
+
--flags-dir=<value> Import flag values from a directory.
|
|
178
|
+
--json Format output as json.
|
|
179
|
+
|
|
180
|
+
DESCRIPTION
|
|
181
|
+
Manage package dependency versions for a Salesforce project.
|
|
182
|
+
|
|
183
|
+
Interactively updates package dependency versions in sfdx-project.json by querying the Dev Hub for available versions.
|
|
184
|
+
Supports interactive selection or automatic update to the latest released or latest build version.
|
|
185
|
+
|
|
186
|
+
Project-level configuration (in sfdx-project.json) is read from the following keys:
|
|
187
|
+
|
|
188
|
+
- plugins.simply.dependencies.ignore — array of Package2Ids or aliases to leave unchanged
|
|
189
|
+
- plugins.simply.package.brancheswithreleasedversions — array of branch names that contain released versions
|
|
190
|
+
|
|
191
|
+
EXAMPLES
|
|
192
|
+
$ sf simply package dependencies manage --target-dev-hub myDevHub
|
|
193
|
+
|
|
194
|
+
$ sf simply package dependencies manage --target-dev-hub myDevHub --branch my-feature-branch
|
|
195
|
+
|
|
196
|
+
$ sf simply package dependencies manage --target-dev-hub myDevHub --update-to-released
|
|
197
|
+
|
|
198
|
+
$ sf simply package dependencies manage --target-dev-hub myDevHub --update-to-latest
|
|
199
|
+
|
|
200
|
+
FLAG DESCRIPTIONS
|
|
201
|
+
-b, --branch=<value> Package branch to consider when evaluating version options.
|
|
202
|
+
|
|
203
|
+
When specified, the command will include the latest build on this branch as a selectable option for each dependency.
|
|
204
|
+
|
|
205
|
+
--update-to-latest Automatically set all dependencies to the latest non-pinned build.
|
|
206
|
+
|
|
207
|
+
When specified, all dependencies managed by the Dev Hub are automatically set to a non-pinned X.Y.Z.LATEST version
|
|
208
|
+
number without interactive prompts. Mutually exclusive with --update-to-released.
|
|
209
|
+
|
|
210
|
+
--update-to-released Automatically update all dependencies to the latest released version.
|
|
211
|
+
|
|
212
|
+
When specified, all dependencies managed by the Dev Hub are automatically updated to the latest released package
|
|
213
|
+
version without interactive prompts. Mutually exclusive with --update-to-latest.
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
_See code: [lib/commands/simply/package/dependencies/manage.js](https://github.com/SimplySF/simply-package/blob/2.3.0/lib/commands/simply/package/dependencies/manage.js)_
|
|
157
217
|
|
|
158
218
|
## `sf simply package version cleanup`
|
|
159
219
|
|
|
@@ -194,5 +254,5 @@ FLAG DESCRIPTIONS
|
|
|
194
254
|
The MAJOR.MINOR.PATCH matcher that should be used to find package versions to delete.
|
|
195
255
|
```
|
|
196
256
|
|
|
197
|
-
_See code: [lib/commands/simply/package/version/cleanup.js](https://github.com/SimplySF/simply-package/blob/
|
|
257
|
+
_See code: [lib/commands/simply/package/version/cleanup.js](https://github.com/SimplySF/simply-package/blob/2.3.0/lib/commands/simply/package/version/cleanup.js)_
|
|
198
258
|
<!-- commandsstop -->
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { PackageDependenciesManageResult } from '../../../../schemas/manage/dependencyChange.js';
|
|
3
|
+
import { VersionChoice } from '../../../../common/packageVersionService.js';
|
|
4
|
+
export type { PackageDependenciesManageResult };
|
|
5
|
+
export default class PackageDependenciesManage extends SfCommand<PackageDependenciesManageResult[]> {
|
|
6
|
+
static readonly summary: string;
|
|
7
|
+
static readonly description: string;
|
|
8
|
+
static readonly examples: string[];
|
|
9
|
+
static readonly requiresProject = true;
|
|
10
|
+
static readonly flags: {
|
|
11
|
+
branch: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
'update-to-released': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
'update-to-latest': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
'api-version': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
'target-dev-hub': import("@oclif/core/interfaces").OptionFlag<import("@salesforce/core").Org, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
'flags-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
};
|
|
18
|
+
run(): Promise<PackageDependenciesManageResult[]>;
|
|
19
|
+
protected promptForVersion(message: string, choices: VersionChoice[]): Promise<string>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/* eslint-disable no-await-in-loop */
|
|
17
|
+
import { select } from '@inquirer/prompts';
|
|
18
|
+
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
19
|
+
import { Messages } from '@salesforce/core';
|
|
20
|
+
import { buildVersionService, } from '../../../../common/packageVersionService.js';
|
|
21
|
+
import { buildProjectService } from '../../../../common/sfdxProjectService.js';
|
|
22
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
23
|
+
const messages = Messages.loadMessages('@simplysf/simply-package', 'simply.package.dependencies.manage');
|
|
24
|
+
export default class PackageDependenciesManage extends SfCommand {
|
|
25
|
+
static summary = messages.getMessage('summary');
|
|
26
|
+
static description = messages.getMessage('description');
|
|
27
|
+
static examples = messages.getMessages('examples');
|
|
28
|
+
static requiresProject = true;
|
|
29
|
+
static flags = {
|
|
30
|
+
...SfCommand.baseFlags,
|
|
31
|
+
branch: Flags.string({
|
|
32
|
+
summary: messages.getMessage('flags.branch.summary'),
|
|
33
|
+
description: messages.getMessage('flags.branch.description'),
|
|
34
|
+
char: 'b',
|
|
35
|
+
}),
|
|
36
|
+
'update-to-released': Flags.boolean({
|
|
37
|
+
summary: messages.getMessage('flags.update-to-released.summary'),
|
|
38
|
+
description: messages.getMessage('flags.update-to-released.description'),
|
|
39
|
+
default: false,
|
|
40
|
+
exclusive: ['update-to-latest'],
|
|
41
|
+
}),
|
|
42
|
+
'update-to-latest': Flags.boolean({
|
|
43
|
+
summary: messages.getMessage('flags.update-to-latest.summary'),
|
|
44
|
+
description: messages.getMessage('flags.update-to-latest.description'),
|
|
45
|
+
default: false,
|
|
46
|
+
exclusive: ['update-to-released'],
|
|
47
|
+
}),
|
|
48
|
+
'api-version': Flags.orgApiVersion(),
|
|
49
|
+
'target-dev-hub': Flags.requiredHub(),
|
|
50
|
+
};
|
|
51
|
+
// eslint-disable-next-line complexity
|
|
52
|
+
async run() {
|
|
53
|
+
const { flags } = await this.parse(PackageDependenciesManage);
|
|
54
|
+
const isInteractive = !flags['update-to-released'] && !flags['update-to-latest'];
|
|
55
|
+
const connection = flags['target-dev-hub'].getConnection(flags['api-version']);
|
|
56
|
+
this.spinner.start(messages.getMessage('info.analyzingDependencies'));
|
|
57
|
+
const projectService = await buildProjectService(this.project);
|
|
58
|
+
const dependenciesByDirectory = projectService.getDependenciesByDirectory();
|
|
59
|
+
const dependenciesToIgnore = projectService.getDependenciesToIgnore();
|
|
60
|
+
const branchesWithReleased = projectService.getBranchesWithReleasedVersions();
|
|
61
|
+
this.spinner.stop();
|
|
62
|
+
const allDependencies = [...dependenciesByDirectory.values()].flat();
|
|
63
|
+
const filterIds = {
|
|
64
|
+
package2Ids: allDependencies.flatMap((d) => (d.package2Id ? [d.package2Id] : [])),
|
|
65
|
+
subscriberVersionIds: allDependencies.flatMap((d) => d.subscriberPackageVersionId ? [d.subscriberPackageVersionId] : []),
|
|
66
|
+
};
|
|
67
|
+
this.spinner.start(messages.getMessage('info.loadingDevHubData'));
|
|
68
|
+
const versionService = await buildVersionService(connection, this.project, filterIds);
|
|
69
|
+
this.spinner.stop();
|
|
70
|
+
const changesByDirectory = new Map();
|
|
71
|
+
const results = [];
|
|
72
|
+
for (const [dirPath, dependencies] of dependenciesByDirectory) {
|
|
73
|
+
changesByDirectory.set(dirPath, []);
|
|
74
|
+
const dirResults = { packageDirectory: dirPath, changes: [] };
|
|
75
|
+
for (const rawDependency of dependencies) {
|
|
76
|
+
const dependency = versionService.enrichDependency(rawDependency);
|
|
77
|
+
const package2Id = dependency.package2Id;
|
|
78
|
+
const dependencyDisplayName = buildDisplayName(dependency, projectService.findAlias.bind(projectService));
|
|
79
|
+
this.info('');
|
|
80
|
+
if (!package2Id ||
|
|
81
|
+
(!versionService.knowsAboutPackage(package2Id) &&
|
|
82
|
+
!versionService.knowsAboutVersion(dependency.subscriberPackageVersionId ?? ''))) {
|
|
83
|
+
this.info(messages.getMessage('info.dependencyNotManagedByDevHub', [dependencyDisplayName]));
|
|
84
|
+
const oldAlias = projectService.findAlias(dependency.subscriberPackageVersionId ?? dependency.package2Id ?? '') ??
|
|
85
|
+
dependencyDisplayName;
|
|
86
|
+
changesByDirectory.get(dirPath).push({
|
|
87
|
+
oldAlias,
|
|
88
|
+
oldDependency: dependency,
|
|
89
|
+
newAlias: oldAlias,
|
|
90
|
+
newSubscriberPackageVersionId: dependency.subscriberPackageVersionId,
|
|
91
|
+
newPackage2Id: dependency.package2Id,
|
|
92
|
+
newVersionNumber: dependency.versionNumber,
|
|
93
|
+
isSameAsOld: true,
|
|
94
|
+
});
|
|
95
|
+
dirResults.changes.push({ oldAlias, newAlias: oldAlias, changed: false });
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
this.info(messages.getMessage('info.reviewingDependency', [dependencyDisplayName]));
|
|
99
|
+
const oldAlias = versionService.getVersionAlias(dependency.subscriberPackageVersionId ?? '') ??
|
|
100
|
+
projectService.findAlias(dependency.subscriberPackageVersionId ?? dependency.package2Id ?? '') ??
|
|
101
|
+
dependencyDisplayName;
|
|
102
|
+
const isIgnored = dependenciesToIgnore.includes(package2Id) ||
|
|
103
|
+
dependenciesToIgnore.includes(versionService.getPackageAlias(package2Id) ?? '');
|
|
104
|
+
let choices = [];
|
|
105
|
+
if (isIgnored) {
|
|
106
|
+
choices =
|
|
107
|
+
dependency.subscriberPackageVersionId &&
|
|
108
|
+
versionService.knowsAboutVersion(dependency.subscriberPackageVersionId)
|
|
109
|
+
? [{ name: 'Current version specified', value: dependency.subscriberPackageVersionId, short: oldAlias }]
|
|
110
|
+
: [];
|
|
111
|
+
}
|
|
112
|
+
else if (isInteractive) {
|
|
113
|
+
choices = versionService.buildInteractiveChoices(dependency, flags.branch ?? '', branchesWithReleased);
|
|
114
|
+
}
|
|
115
|
+
else if (flags['update-to-released']) {
|
|
116
|
+
choices = versionService.buildReleasedChoices(dependency, branchesWithReleased);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
choices = versionService.buildLatestChoices(dependency);
|
|
120
|
+
}
|
|
121
|
+
this.info('');
|
|
122
|
+
if (choices.length === 0) {
|
|
123
|
+
this.info(messages.getMessage('info.noAlternatesFound', [dependencyDisplayName]));
|
|
124
|
+
dirResults.changes.push({ oldAlias, newAlias: oldAlias, changed: false });
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
let selectedValue;
|
|
128
|
+
if (isInteractive && !isIgnored) {
|
|
129
|
+
const packageDisplayName = versionService.getPackageAlias(package2Id) ?? package2Id;
|
|
130
|
+
selectedValue = await this.promptForVersion(messages.getMessage('prompt.selectVersion', [packageDisplayName]), choices);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
selectedValue = choices[0].value;
|
|
134
|
+
}
|
|
135
|
+
const change = buildChange(oldAlias, dependency, selectedValue, versionService.getVersionAlias.bind(versionService), versionService.getPackage2IdForVersion.bind(versionService));
|
|
136
|
+
changesByDirectory.get(dirPath).push(change);
|
|
137
|
+
if (isIgnored) {
|
|
138
|
+
this.info(messages.getMessage('info.versionIgnored', [dependencyDisplayName]));
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
this.info(messages.getMessage('info.versionSelected', [dependencyDisplayName, change.newAlias]));
|
|
142
|
+
}
|
|
143
|
+
dirResults.changes.push({ oldAlias, newAlias: change.newAlias, changed: !change.isSameAsOld });
|
|
144
|
+
this.info('');
|
|
145
|
+
this.info('*'.repeat(88));
|
|
146
|
+
this.info('');
|
|
147
|
+
}
|
|
148
|
+
results.push(dirResults);
|
|
149
|
+
}
|
|
150
|
+
await projectService.applyChanges(changesByDirectory);
|
|
151
|
+
return results;
|
|
152
|
+
}
|
|
153
|
+
// eslint-disable-next-line class-methods-use-this
|
|
154
|
+
async promptForVersion(message, choices) {
|
|
155
|
+
return select({ message, choices, pageSize: 8 });
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function buildDisplayName(dependency, findAlias) {
|
|
159
|
+
if (dependency.subscriberPackageVersionId) {
|
|
160
|
+
const alias = findAlias(dependency.subscriberPackageVersionId);
|
|
161
|
+
return alias ? `${alias} (${dependency.subscriberPackageVersionId})` : dependency.subscriberPackageVersionId;
|
|
162
|
+
}
|
|
163
|
+
if (dependency.package2Id && dependency.versionNumber) {
|
|
164
|
+
const alias = findAlias(dependency.package2Id);
|
|
165
|
+
const base = alias ? `${alias} (${dependency.package2Id})` : dependency.package2Id;
|
|
166
|
+
return `${base} version ${dependency.versionNumber}`;
|
|
167
|
+
}
|
|
168
|
+
return '<unknown dependency>';
|
|
169
|
+
}
|
|
170
|
+
function buildChange(oldAlias, oldDependency, selectedValue, getVersionAlias, getPackage2Id) {
|
|
171
|
+
// Pinned selection: value is a SubscriberPackageVersionId (04t)
|
|
172
|
+
if (selectedValue.startsWith('04t')) {
|
|
173
|
+
const newAlias = getVersionAlias(selectedValue) ?? selectedValue;
|
|
174
|
+
const newPackage2Id = getPackage2Id(selectedValue);
|
|
175
|
+
return {
|
|
176
|
+
oldAlias,
|
|
177
|
+
oldDependency,
|
|
178
|
+
newAlias,
|
|
179
|
+
newSubscriberPackageVersionId: selectedValue,
|
|
180
|
+
newPackage2Id,
|
|
181
|
+
isSameAsOld: selectedValue === oldDependency.subscriberPackageVersionId,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// Non-pinned selection: value is "package2Id|major.minor.patch.LATEST"
|
|
185
|
+
const [package2Id, versionNumber] = selectedValue.split('|');
|
|
186
|
+
const newAlias = (getVersionAlias(package2Id) ?? package2Id) + '@' + versionNumber;
|
|
187
|
+
return {
|
|
188
|
+
oldAlias,
|
|
189
|
+
oldDependency,
|
|
190
|
+
newAlias,
|
|
191
|
+
newPackage2Id: package2Id,
|
|
192
|
+
newVersionNumber: versionNumber,
|
|
193
|
+
isSameAsOld: package2Id === oldDependency.package2Id && versionNumber === oldDependency.versionNumber,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=manage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manage.js","sourceRoot":"","sources":["../../../../../src/commands/simply/package/dependencies/manage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Connection } from '@salesforce/core';
|
|
2
|
+
import { SfProject } from '@salesforce/core';
|
|
3
|
+
import { PackageVersionListResult } from '@salesforce/packaging';
|
|
4
|
+
import { ParsedDependency } from '../schemas/manage/parsedDependency.js';
|
|
5
|
+
export type VersionChoice = {
|
|
6
|
+
name: string;
|
|
7
|
+
value: string;
|
|
8
|
+
short: string;
|
|
9
|
+
};
|
|
10
|
+
export type PackageVersionService = {
|
|
11
|
+
knowsAboutVersion(subscriberPackageVersionId: string): boolean;
|
|
12
|
+
knowsAboutPackage(package2Id: string): boolean;
|
|
13
|
+
getPackage2IdForVersion(subscriberPackageVersionId: string): string | undefined;
|
|
14
|
+
getVersionAlias(subscriberPackageVersionId: string): string | undefined;
|
|
15
|
+
getPackageAlias(package2Id: string): string | undefined;
|
|
16
|
+
enrichDependency(dependency: ParsedDependency): ParsedDependency;
|
|
17
|
+
buildInteractiveChoices(dependency: ParsedDependency, branch: string, branchesWithReleased: string[]): VersionChoice[];
|
|
18
|
+
buildReleasedChoices(dependency: ParsedDependency, branchesWithReleased: string[]): VersionChoice[];
|
|
19
|
+
buildLatestChoices(dependency: ParsedDependency): VersionChoice[];
|
|
20
|
+
findVersionById(subscriberPackageVersionId: string): PackageVersionListResult | undefined;
|
|
21
|
+
};
|
|
22
|
+
export type VersionServiceFilterIds = {
|
|
23
|
+
package2Ids: string[];
|
|
24
|
+
subscriberVersionIds: string[];
|
|
25
|
+
};
|
|
26
|
+
export declare function buildVersionService(connection: Connection, project: SfProject, filterIds?: VersionServiceFilterIds): Promise<PackageVersionService>;
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, Clay Chipps; Copyright (c) 2026 Salesforce, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { Package, Package2Fields } from '@salesforce/packaging';
|
|
17
|
+
export async function buildVersionService(connection, project, filterIds) {
|
|
18
|
+
let packages;
|
|
19
|
+
let versions;
|
|
20
|
+
if (filterIds) {
|
|
21
|
+
const package2IdSet = new Set(filterIds.package2Ids);
|
|
22
|
+
if (filterIds.subscriberVersionIds.length > 0) {
|
|
23
|
+
const inClause = filterIds.subscriberVersionIds.map((id) => `'${id}'`).join(', ');
|
|
24
|
+
const result = await connection.autoFetchQuery(`SELECT Package2Id FROM Package2Version WHERE SubscriberPackageVersionId IN (${inClause})`, { tooling: true });
|
|
25
|
+
for (const rec of result.records) {
|
|
26
|
+
package2IdSet.add(rec.Package2Id);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const targetPackage2Ids = [...package2IdSet];
|
|
30
|
+
if (targetPackage2Ids.length === 0) {
|
|
31
|
+
packages = [];
|
|
32
|
+
versions = [];
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const apiVersion = connection.getApiVersion();
|
|
36
|
+
const fields = Package2Fields.filter((f) => apiVersion >= '59.0' || f !== 'AppAnalyticsEnabled').filter((f) => apiVersion >= '66.0' || f !== 'RecommendedVersionId');
|
|
37
|
+
const inClause = targetPackage2Ids.map((id) => `'${id}'`).join(', ');
|
|
38
|
+
const pkg2Result = await connection.autoFetchQuery(`SELECT ${fields.join(', ')} FROM Package2 WHERE Id IN (${inClause}) ORDER BY NamespacePrefix, Name`, { tooling: true });
|
|
39
|
+
packages = (pkg2Result?.records ?? []);
|
|
40
|
+
versions = await Package.listVersions(connection, project, {
|
|
41
|
+
concise: false,
|
|
42
|
+
createdLastDays: undefined,
|
|
43
|
+
modifiedLastDays: undefined,
|
|
44
|
+
orderBy: 'Package2Id, Branch, MajorVersion, MinorVersion, PatchVersion, BuildNumber',
|
|
45
|
+
isReleased: undefined,
|
|
46
|
+
verbose: true,
|
|
47
|
+
packages: targetPackage2Ids,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
packages = await Package.list(connection);
|
|
53
|
+
versions = await Package.listVersions(connection, project, {
|
|
54
|
+
concise: false,
|
|
55
|
+
createdLastDays: undefined,
|
|
56
|
+
modifiedLastDays: undefined,
|
|
57
|
+
orderBy: 'Package2Id, Branch, MajorVersion, MinorVersion, PatchVersion, BuildNumber',
|
|
58
|
+
isReleased: undefined,
|
|
59
|
+
verbose: true,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const versionsBySubscriberId = new Map();
|
|
63
|
+
const packageAliasById = new Map();
|
|
64
|
+
const versionsByPackageAndBranch = new Map();
|
|
65
|
+
const releasedVersionsByPackageAndBranch = new Map();
|
|
66
|
+
for (const pkg of packages) {
|
|
67
|
+
packageAliasById.set(pkg.Id, computePackageAlias(pkg));
|
|
68
|
+
}
|
|
69
|
+
for (const version of versions) {
|
|
70
|
+
versionsBySubscriberId.set(version.SubscriberPackageVersionId, version);
|
|
71
|
+
sortVersionIntoMap(versionsByPackageAndBranch, version);
|
|
72
|
+
if (version.IsReleased) {
|
|
73
|
+
sortVersionIntoMap(releasedVersionsByPackageAndBranch, version);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function computePackageAlias(pkg) {
|
|
77
|
+
return (pkg.NamespacePrefix ? pkg.NamespacePrefix + '.' : '') + pkg.Name;
|
|
78
|
+
}
|
|
79
|
+
function computeVersionAlias(v, branch) {
|
|
80
|
+
const seg = `${v.MajorVersion}.${v.MinorVersion}.${v.PatchVersion}-${v.BuildNumber}` + (branch ? '-' + branch : '');
|
|
81
|
+
const pkgAlias = packageAliasById.get(v.Package2Id) ?? v.Package2Id;
|
|
82
|
+
return pkgAlias + '@' + seg;
|
|
83
|
+
}
|
|
84
|
+
function sortVersionIntoMap(map, v) {
|
|
85
|
+
const branch = v.Branch ?? '';
|
|
86
|
+
const major = parseInt(v.MajorVersion, 10);
|
|
87
|
+
const minor = parseInt(v.MinorVersion, 10);
|
|
88
|
+
const patch = parseInt(v.PatchVersion, 10);
|
|
89
|
+
const build = parseInt(v.BuildNumber, 10);
|
|
90
|
+
if (!map.has(v.Package2Id))
|
|
91
|
+
map.set(v.Package2Id, new Map());
|
|
92
|
+
const byBranch = map.get(v.Package2Id);
|
|
93
|
+
if (!byBranch.has(branch))
|
|
94
|
+
byBranch.set(branch, new Map());
|
|
95
|
+
const byMajor = byBranch.get(branch);
|
|
96
|
+
if (!byMajor.has(major))
|
|
97
|
+
byMajor.set(major, new Map());
|
|
98
|
+
const byMinor = byMajor.get(major);
|
|
99
|
+
if (!byMinor.has(minor))
|
|
100
|
+
byMinor.set(minor, new Map());
|
|
101
|
+
const byPatch = byMinor.get(minor);
|
|
102
|
+
if (!byPatch.has(patch))
|
|
103
|
+
byPatch.set(patch, new Map());
|
|
104
|
+
const byBuild = byPatch.get(patch);
|
|
105
|
+
if (!byBuild.has(build))
|
|
106
|
+
byBuild.set(build, v);
|
|
107
|
+
}
|
|
108
|
+
// Walks a version map block to the latest (highest-key) entry at any depth
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
|
+
function findLatestFromBlock(block) {
|
|
111
|
+
const keys = [...block.keys()];
|
|
112
|
+
const maxKey = keys.reduce((max, k) => (k > max ? k : max), keys[0]);
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
114
|
+
const entry = block.get(maxKey);
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
116
|
+
return entry instanceof Map ? findLatestFromBlock(entry) : entry;
|
|
117
|
+
}
|
|
118
|
+
let ChunkLevel;
|
|
119
|
+
(function (ChunkLevel) {
|
|
120
|
+
ChunkLevel[ChunkLevel["Major"] = 1] = "Major";
|
|
121
|
+
ChunkLevel[ChunkLevel["Minor"] = 2] = "Minor";
|
|
122
|
+
ChunkLevel[ChunkLevel["Patch"] = 3] = "Patch";
|
|
123
|
+
})(ChunkLevel || (ChunkLevel = {}));
|
|
124
|
+
function findBlock(map, package2Id, branch, dependency, level
|
|
125
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
126
|
+
) {
|
|
127
|
+
const resolvedBranch = branch ?? '';
|
|
128
|
+
const byBranch = map.get(package2Id);
|
|
129
|
+
if (!byBranch?.has(resolvedBranch))
|
|
130
|
+
return undefined;
|
|
131
|
+
const byMajor = byBranch.get(resolvedBranch);
|
|
132
|
+
if (level === ChunkLevel.Major)
|
|
133
|
+
return byMajor;
|
|
134
|
+
const byMinor = byMajor?.get(dependency.majorVersion);
|
|
135
|
+
if (level === ChunkLevel.Minor || byMinor === undefined)
|
|
136
|
+
return byMinor;
|
|
137
|
+
return byMinor.get(dependency.minorVersion);
|
|
138
|
+
}
|
|
139
|
+
function makeVersionChoice(v, label, branch) {
|
|
140
|
+
const seg = `${v.MajorVersion}.${v.MinorVersion}.${v.PatchVersion}-${v.BuildNumber}` + (branch ? '-' + branch : '');
|
|
141
|
+
return {
|
|
142
|
+
name: `${label}: ${seg}`,
|
|
143
|
+
value: v.SubscriberPackageVersionId,
|
|
144
|
+
short: seg,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function makeLatestChoice(v, label) {
|
|
148
|
+
const seg = `${v.MajorVersion}.${v.MinorVersion}.${v.PatchVersion}.LATEST`;
|
|
149
|
+
return {
|
|
150
|
+
name: label,
|
|
151
|
+
value: `${v.Package2Id}|${seg}`,
|
|
152
|
+
short: seg,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function findLatestReleasedForBranch(package2Id, branch, dependency, seen) {
|
|
156
|
+
const block = findBlock(releasedVersionsByPackageAndBranch, package2Id, branch, dependency, ChunkLevel.Major);
|
|
157
|
+
if (!block)
|
|
158
|
+
return undefined;
|
|
159
|
+
const v = findLatestFromBlock(block);
|
|
160
|
+
if (seen.has(v.SubscriberPackageVersionId))
|
|
161
|
+
return undefined;
|
|
162
|
+
seen.add(v.SubscriberPackageVersionId);
|
|
163
|
+
const label = branch
|
|
164
|
+
? `Latest released version on build branch - ${branch}`
|
|
165
|
+
: 'Latest released version on main build branch';
|
|
166
|
+
return makeVersionChoice(v, label, branch || undefined);
|
|
167
|
+
}
|
|
168
|
+
function findLatestForBranch(package2Id, branch, dependency, level, label, seen) {
|
|
169
|
+
const block = findBlock(versionsByPackageAndBranch, package2Id, branch, dependency, level);
|
|
170
|
+
if (!block)
|
|
171
|
+
return undefined;
|
|
172
|
+
const v = findLatestFromBlock(block);
|
|
173
|
+
if (seen.has(v.SubscriberPackageVersionId))
|
|
174
|
+
return undefined;
|
|
175
|
+
seen.add(v.SubscriberPackageVersionId);
|
|
176
|
+
return makeVersionChoice(v, label, branch || undefined);
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
knowsAboutVersion(id) {
|
|
180
|
+
return versionsBySubscriberId.has(id);
|
|
181
|
+
},
|
|
182
|
+
knowsAboutPackage(package2Id) {
|
|
183
|
+
return packageAliasById.has(package2Id);
|
|
184
|
+
},
|
|
185
|
+
getPackage2IdForVersion(subscriberPackageVersionId) {
|
|
186
|
+
return versionsBySubscriberId.get(subscriberPackageVersionId)?.Package2Id;
|
|
187
|
+
},
|
|
188
|
+
getVersionAlias(subscriberPackageVersionId) {
|
|
189
|
+
const v = versionsBySubscriberId.get(subscriberPackageVersionId);
|
|
190
|
+
if (!v)
|
|
191
|
+
return undefined;
|
|
192
|
+
return computeVersionAlias(v, v.Branch || undefined);
|
|
193
|
+
},
|
|
194
|
+
getPackageAlias(package2Id) {
|
|
195
|
+
return packageAliasById.get(package2Id);
|
|
196
|
+
},
|
|
197
|
+
findVersionById(subscriberPackageVersionId) {
|
|
198
|
+
return versionsBySubscriberId.get(subscriberPackageVersionId);
|
|
199
|
+
},
|
|
200
|
+
enrichDependency(dependency) {
|
|
201
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
202
|
+
if (dependency.package2Id || !dependency.subscriberPackageVersionId)
|
|
203
|
+
return dependency;
|
|
204
|
+
const v = versionsBySubscriberId.get(dependency.subscriberPackageVersionId);
|
|
205
|
+
if (!v)
|
|
206
|
+
return dependency;
|
|
207
|
+
const parts = `${v.MajorVersion}.${v.MinorVersion}.${v.PatchVersion}.${v.BuildNumber}`.split('.');
|
|
208
|
+
return {
|
|
209
|
+
...dependency,
|
|
210
|
+
package2Id: v.Package2Id,
|
|
211
|
+
versionNumber: `${v.MajorVersion}.${v.MinorVersion}.${v.PatchVersion}.${v.BuildNumber}`,
|
|
212
|
+
majorVersion: parseInt(parts[0], 10),
|
|
213
|
+
minorVersion: parseInt(parts[1], 10),
|
|
214
|
+
patchVersion: parseInt(parts[2], 10),
|
|
215
|
+
buildVersion: parseInt(parts[3], 10),
|
|
216
|
+
};
|
|
217
|
+
},
|
|
218
|
+
// eslint-disable-next-line complexity
|
|
219
|
+
buildInteractiveChoices(dependency, branch, branchesWithReleased) {
|
|
220
|
+
const package2Id = dependency.package2Id;
|
|
221
|
+
const maj = dependency.majorVersion ?? '';
|
|
222
|
+
const min = dependency.minorVersion ?? '';
|
|
223
|
+
const pat = dependency.patchVersion ?? '';
|
|
224
|
+
const choices = [];
|
|
225
|
+
const releasedChoices = [];
|
|
226
|
+
const seen = new Set();
|
|
227
|
+
// Latest released on null/main branch and named release branches
|
|
228
|
+
const releasedMain = findLatestReleasedForBranch(package2Id, '', dependency, seen);
|
|
229
|
+
if (releasedMain)
|
|
230
|
+
releasedChoices.push(releasedMain);
|
|
231
|
+
for (const b of branchesWithReleased ?? []) {
|
|
232
|
+
const rc = findLatestReleasedForBranch(package2Id, b, dependency, seen);
|
|
233
|
+
if (rc)
|
|
234
|
+
releasedChoices.push(rc);
|
|
235
|
+
}
|
|
236
|
+
// Latest version on the specified feature branch
|
|
237
|
+
if (branch) {
|
|
238
|
+
const c = findLatestForBranch(package2Id, branch, dependency, ChunkLevel.Patch, `Latest version on '${branch}' branch`, seen);
|
|
239
|
+
if (c)
|
|
240
|
+
choices.push(c);
|
|
241
|
+
}
|
|
242
|
+
// Latest build with same Major.Minor.Patch on main branch and release branches
|
|
243
|
+
const patchMain = findLatestForBranch(package2Id, '', dependency, ChunkLevel.Patch, `Latest ${maj}.${min}.${pat} version on main build branch`, seen);
|
|
244
|
+
if (patchMain)
|
|
245
|
+
choices.push(patchMain);
|
|
246
|
+
for (const b of branchesWithReleased ?? []) {
|
|
247
|
+
const c = findLatestForBranch(package2Id, b, dependency, ChunkLevel.Patch, `Latest ${maj}.${min}.${pat} version on build branch - ${b}`, seen);
|
|
248
|
+
if (c)
|
|
249
|
+
choices.push(c);
|
|
250
|
+
}
|
|
251
|
+
// Latest build with same Major.Minor on main branch and release branches
|
|
252
|
+
const minorMain = findLatestForBranch(package2Id, '', dependency, ChunkLevel.Minor, `Latest ${maj}.${min} version on main build branch`, seen);
|
|
253
|
+
if (minorMain)
|
|
254
|
+
choices.push(minorMain);
|
|
255
|
+
for (const b of branchesWithReleased ?? []) {
|
|
256
|
+
const c = findLatestForBranch(package2Id, b, dependency, ChunkLevel.Minor, `Latest ${maj}.${min} version on build branch - ${b}`, seen);
|
|
257
|
+
if (c)
|
|
258
|
+
choices.push(c);
|
|
259
|
+
}
|
|
260
|
+
// Latest build overall on main branch and release branches
|
|
261
|
+
const majorMain = findLatestForBranch(package2Id, '', dependency, ChunkLevel.Major, 'Latest version on main build branch', seen);
|
|
262
|
+
if (majorMain)
|
|
263
|
+
choices.push(majorMain);
|
|
264
|
+
for (const b of branchesWithReleased ?? []) {
|
|
265
|
+
const c = findLatestForBranch(package2Id, b, dependency, ChunkLevel.Major, `Latest version on build branch - ${b}`, seen);
|
|
266
|
+
if (c)
|
|
267
|
+
choices.push(c);
|
|
268
|
+
}
|
|
269
|
+
// Released choices go after so they appear clearly
|
|
270
|
+
choices.push(...releasedChoices);
|
|
271
|
+
// Non-pinned latest for current Major.Minor.Patch
|
|
272
|
+
const block = findBlock(versionsByPackageAndBranch, package2Id, branch, dependency, ChunkLevel.Patch) ??
|
|
273
|
+
findBlock(versionsByPackageAndBranch, package2Id, '', dependency, ChunkLevel.Patch) ??
|
|
274
|
+
findBlock(versionsByPackageAndBranch, package2Id, '', dependency, ChunkLevel.Minor);
|
|
275
|
+
if (block) {
|
|
276
|
+
const v = findLatestFromBlock(block);
|
|
277
|
+
choices.push(makeLatestChoice(v, `Non-pinned latest ${maj}.${min}.${pat} build`));
|
|
278
|
+
}
|
|
279
|
+
// Keep the current version as last option
|
|
280
|
+
if (dependency.subscriberPackageVersionId && versionsBySubscriberId.has(dependency.subscriberPackageVersionId)) {
|
|
281
|
+
const v = versionsBySubscriberId.get(dependency.subscriberPackageVersionId);
|
|
282
|
+
choices.push(makeVersionChoice(v, 'Current version specified', v.Branch || undefined));
|
|
283
|
+
}
|
|
284
|
+
return choices;
|
|
285
|
+
},
|
|
286
|
+
buildReleasedChoices(dependency, branchesWithReleased) {
|
|
287
|
+
const package2Id = dependency.package2Id;
|
|
288
|
+
const choices = [];
|
|
289
|
+
const seen = new Set();
|
|
290
|
+
const main = findLatestReleasedForBranch(package2Id, '', dependency, seen);
|
|
291
|
+
if (main)
|
|
292
|
+
choices.push(main);
|
|
293
|
+
for (const b of branchesWithReleased ?? []) {
|
|
294
|
+
const c = findLatestReleasedForBranch(package2Id, b, dependency, seen);
|
|
295
|
+
if (c)
|
|
296
|
+
choices.push(c);
|
|
297
|
+
}
|
|
298
|
+
return choices;
|
|
299
|
+
},
|
|
300
|
+
buildLatestChoices(dependency) {
|
|
301
|
+
const package2Id = dependency.package2Id;
|
|
302
|
+
const block = findBlock(versionsByPackageAndBranch, package2Id, '', dependency, ChunkLevel.Patch) ??
|
|
303
|
+
findBlock(versionsByPackageAndBranch, package2Id, '', dependency, ChunkLevel.Minor);
|
|
304
|
+
if (!block)
|
|
305
|
+
return [];
|
|
306
|
+
const v = findLatestFromBlock(block);
|
|
307
|
+
const maj = dependency.majorVersion ?? '';
|
|
308
|
+
const min = dependency.minorVersion ?? '';
|
|
309
|
+
const pat = dependency.patchVersion ?? '';
|
|
310
|
+
return [makeLatestChoice(v, `Non-pinned latest ${maj}.${min}.${pat} build`)];
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=packageVersionService.js.map
|