@salesforce/packaging 0.0.18 → 0.0.21
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 +18 -0
- package/lib/interfaces/packagingInterfacesAndType.d.ts +31 -6
- package/lib/package/index.d.ts +1 -0
- package/lib/package/index.js +1 -0
- package/lib/package/package.d.ts +1 -0
- package/lib/package/package.js +4 -0
- package/lib/package/packageProfileApi.d.ts +12 -5
- package/lib/package/packageProfileApi.js +3 -3
- package/lib/package/packageVersion.d.ts +14 -6
- package/lib/package/packageVersion.js +52 -19
- package/lib/package/packageVersionCreate.d.ts +12 -33
- package/lib/package/packageVersionCreate.js +105 -337
- package/lib/package/packageVersionCreateRequest.d.ts +1 -1
- package/lib/package/packageVersionReport.js +7 -9
- package/lib/package1/package1VersionList.d.ts +1 -1
- package/lib/package1/package1VersionList.js +1 -1
- package/lib/utils/packageUtils.d.ts +22 -20
- package/lib/utils/packageUtils.js +15 -156
- package/messages/messages.md +6 -30
- package/messages/packageVersionCreate.md +71 -0
- package/package.json +2 -2
|
@@ -15,18 +15,16 @@ const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
|
|
|
15
15
|
const testSetup_1 = require("@salesforce/core/lib/testSetup");
|
|
16
16
|
const scratchOrgSettingsGenerator_1 = require("@salesforce/core/lib/org/scratchOrgSettingsGenerator");
|
|
17
17
|
const xml2js = require("xml2js");
|
|
18
|
-
const
|
|
18
|
+
const scratchOrgInfoGenerator_1 = require("@salesforce/core/lib/org/scratchOrgInfoGenerator");
|
|
19
19
|
const pkgUtils = require("../utils/packageUtils");
|
|
20
|
-
const constants_1 = require("../constants");
|
|
21
|
-
const utils_1 = require("../utils");
|
|
22
20
|
const versionNumber_1 = require("../utils/versionNumber");
|
|
21
|
+
const utils_1 = require("../utils");
|
|
23
22
|
const packageProfileApi_1 = require("./packageProfileApi");
|
|
24
23
|
const packageVersionCreateRequest_1 = require("./packageVersionCreateRequest");
|
|
25
24
|
core_1.Messages.importMessagesDirectory(__dirname);
|
|
26
|
-
const messages = core_1.Messages.loadMessages('@salesforce/packaging', '
|
|
25
|
+
const messages = core_1.Messages.loadMessages('@salesforce/packaging', 'packageVersionCreate');
|
|
27
26
|
const logger = core_1.Logger.childFromRoot('packageVersionCreate');
|
|
28
27
|
const DESCRIPTOR_FILE = 'package2-descriptor.json';
|
|
29
|
-
const POLL_INTERVAL_WITHOUT_VALIDATION_SECONDS = 5;
|
|
30
28
|
class PackageVersionCreate {
|
|
31
29
|
constructor(options) {
|
|
32
30
|
this.options = options;
|
|
@@ -34,17 +32,12 @@ class PackageVersionCreate {
|
|
|
34
32
|
this.project = this.options.project;
|
|
35
33
|
}
|
|
36
34
|
createPackageVersion() {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
async listRequest(createdlastdays, status) {
|
|
44
|
-
return (0, packageVersionCreateRequest_1.list)({ createdlastdays, status, connection: this.connection });
|
|
45
|
-
}
|
|
46
|
-
async listRequestById(id, connection) {
|
|
47
|
-
return (0, packageVersionCreateRequest_1.byId)(id, connection);
|
|
35
|
+
try {
|
|
36
|
+
return this.packageVersionCreate();
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
throw pkgUtils.applyErrorAction(pkgUtils.massageErrorMessage(err));
|
|
40
|
+
}
|
|
48
41
|
}
|
|
49
42
|
// convert source to mdapi format and copy to tmp dir packaging up
|
|
50
43
|
async generateMDFolderForArtifact(options) {
|
|
@@ -78,47 +71,42 @@ class PackageVersionCreate {
|
|
|
78
71
|
return convertResult;
|
|
79
72
|
}
|
|
80
73
|
}
|
|
81
|
-
validateDependencyValues(dependency) {
|
|
74
|
+
async validateDependencyValues(dependency) {
|
|
82
75
|
// If valid 04t package, just return it to be used straight away.
|
|
83
76
|
if (dependency.subscriberPackageVersionId) {
|
|
84
77
|
pkgUtils.validateId(pkgUtils.BY_LABEL.SUBSCRIBER_PACKAGE_VERSION_ID, dependency.subscriberPackageVersionId);
|
|
85
|
-
return Promise.resolve();
|
|
86
78
|
}
|
|
87
79
|
if (dependency.packageId && dependency.package) {
|
|
88
80
|
throw messages.createError('errorPackageAndPackageIdCollision', []);
|
|
89
81
|
}
|
|
90
|
-
const packageIdFromAlias = pkgUtils.getPackageIdFromAlias(dependency.packageId || dependency.package, this.project);
|
|
91
82
|
// If valid 04t package, just return it to be used straight away.
|
|
92
|
-
if (pkgUtils.validateIdNoThrow(pkgUtils.BY_LABEL.SUBSCRIBER_PACKAGE_VERSION_ID,
|
|
93
|
-
dependency.subscriberPackageVersionId =
|
|
94
|
-
return Promise.resolve();
|
|
83
|
+
if (pkgUtils.validateIdNoThrow(pkgUtils.BY_LABEL.SUBSCRIBER_PACKAGE_VERSION_ID, this.packageId)) {
|
|
84
|
+
dependency.subscriberPackageVersionId = this.packageId;
|
|
95
85
|
}
|
|
96
|
-
if (!
|
|
86
|
+
if (!this.packageId || !dependency.versionNumber) {
|
|
97
87
|
throw messages.createError('errorDependencyPair', [JSON.stringify(dependency)]);
|
|
98
88
|
}
|
|
99
89
|
// Just override dependency.packageId value to the resolved alias.
|
|
100
|
-
dependency.packageId =
|
|
90
|
+
dependency.packageId = this.packageId;
|
|
101
91
|
pkgUtils.validateId(pkgUtils.BY_LABEL.PACKAGE_ID, dependency.packageId);
|
|
102
92
|
pkgUtils.validateVersionNumber(dependency.versionNumber, versionNumber_1.BuildNumberToken.LATEST_BUILD_NUMBER_TOKEN, versionNumber_1.BuildNumberToken.RELEASED_BUILD_NUMBER_TOKEN);
|
|
103
93
|
// Validate that the Package2 id exists on the server
|
|
104
94
|
const query = `SELECT Id FROM Package2 WHERE Id = '${dependency.packageId}'`;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
});
|
|
95
|
+
const result = await this.connection.tooling.query(query);
|
|
96
|
+
if (!result.records || result.records.length !== 1) {
|
|
97
|
+
throw messages.createError('errorNoIdInHub', [dependency.packageId]);
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
111
100
|
}
|
|
112
101
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
102
|
+
* A dependency in the workspace config file may be specified using either a subscriber package version id (04t)
|
|
103
|
+
* or a package Id (0Ho) + a version number. Additionally, a build number may be the actual build number, or a
|
|
104
|
+
* keyword: LATEST or RELEASED (meaning the latest or released build number for a given major.minor.patch).
|
|
116
105
|
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
106
|
+
* This method resolves a package Id + version number to a subscriber package version id (04t)
|
|
107
|
+
* and adds it as a SubscriberPackageVersionId parameter in the dependency object.
|
|
119
108
|
*/
|
|
120
|
-
|
|
121
|
-
async retrieveSubscriberPackageVersionId(dependency, branchFromFlagOrDef) {
|
|
109
|
+
async retrieveSubscriberPackageVersionId(dependency) {
|
|
122
110
|
await this.validateDependencyValues(dependency);
|
|
123
111
|
if (dependency.subscriberPackageVersionId) {
|
|
124
112
|
delete dependency.package;
|
|
@@ -128,7 +116,7 @@ class PackageVersionCreate {
|
|
|
128
116
|
const versionNumber = versionNumber_1.VersionNumber.from(dependency.versionNumber);
|
|
129
117
|
const buildNumber = versionNumber.build;
|
|
130
118
|
// use the dependency.branch if present otherwise use the branch of the version being created
|
|
131
|
-
const branch = dependency.branch || dependency.branch === '' ? dependency.branch :
|
|
119
|
+
const branch = dependency.branch || dependency.branch === '' ? dependency.branch : this.options.branch;
|
|
132
120
|
const branchString = !branch || branch === '' ? 'null' : `'${branch}'`;
|
|
133
121
|
// resolve a build number keyword to an actual number, if needed
|
|
134
122
|
const resolvedBuildNumber = await this.resolveBuildNumber(versionNumber, dependency.packageId, branch);
|
|
@@ -138,7 +126,7 @@ class PackageVersionCreate {
|
|
|
138
126
|
const branchOrReleasedCondition = buildNumber === versionNumber_1.BuildNumberToken.RELEASED_BUILD_NUMBER_TOKEN
|
|
139
127
|
? 'AND IsReleased = true'
|
|
140
128
|
: `AND Branch = ${branchString}`;
|
|
141
|
-
const query = `SELECT SubscriberPackageVersionId FROM Package2Version WHERE Package2Id = '${dependency.packageId}' AND MajorVersion = ${versionNumber
|
|
129
|
+
const query = `SELECT SubscriberPackageVersionId FROM Package2Version WHERE Package2Id = '${dependency.packageId}' AND MajorVersion = ${versionNumber.major} AND MinorVersion = ${versionNumber.minor} AND PatchVersion = ${versionNumber.patch} AND BuildNumber = ${resolvedBuildNumber} ${branchOrReleasedCondition}`;
|
|
142
130
|
const pkgVerQueryResult = await this.connection.tooling.query(query);
|
|
143
131
|
const subRecords = pkgVerQueryResult.records;
|
|
144
132
|
if (!subRecords || subRecords.length !== 1) {
|
|
@@ -193,8 +181,7 @@ class PackageVersionCreate {
|
|
|
193
181
|
}
|
|
194
182
|
const query = `SELECT MAX(BuildNumber) FROM Package2Version WHERE Package2Id = '${packageId}' AND IsDeprecated != true AND MajorVersion = ${versionNumber.major} AND MinorVersion = ${versionNumber.minor} AND PatchVersion = ${versionNumber.patch} ${branchCondition} ${releasedCondition}`;
|
|
195
183
|
const results = await this.connection.tooling.query(query);
|
|
196
|
-
|
|
197
|
-
if (!records || records.length === 0 || records[0].expr0 == null) {
|
|
184
|
+
if (results.records?.length === 0 || results.records[0].expr0 == null) {
|
|
198
185
|
if (versionNumber.build === versionNumber_1.BuildNumberToken.RELEASED_BUILD_NUMBER_TOKEN) {
|
|
199
186
|
throw messages.createError('noReleaseVersionFound', [packageId, versionNumber.toString()]);
|
|
200
187
|
}
|
|
@@ -202,20 +189,21 @@ class PackageVersionCreate {
|
|
|
202
189
|
throw messages.createError('noReleaseVersionFoundForBranch', [packageId, branch, versionNumber.toString()]);
|
|
203
190
|
}
|
|
204
191
|
}
|
|
192
|
+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
205
193
|
return `${results.records[0].expr0}`;
|
|
206
194
|
}
|
|
207
|
-
async createRequestObject(
|
|
195
|
+
async createRequestObject(preserveFiles, packageVersTmpRoot, packageVersBlobZipFile) {
|
|
208
196
|
const zipFileBase64 = fs.readFileSync(packageVersBlobZipFile).toString('base64');
|
|
209
197
|
const requestObject = {
|
|
210
|
-
Package2Id: packageId,
|
|
198
|
+
Package2Id: this.packageId,
|
|
211
199
|
VersionInfo: zipFileBase64,
|
|
212
|
-
Tag: options.tag,
|
|
213
|
-
Branch: options.branch,
|
|
214
|
-
InstallKey: options.installationkey,
|
|
215
|
-
Instance: options.buildinstance,
|
|
216
|
-
SourceOrg: options.sourceorg,
|
|
217
|
-
CalculateCodeCoverage: options.codecoverage || false,
|
|
218
|
-
SkipValidation: options.skipvalidation || false,
|
|
200
|
+
Tag: this.options.tag,
|
|
201
|
+
Branch: this.options.branch,
|
|
202
|
+
InstallKey: this.options.installationkey,
|
|
203
|
+
Instance: this.options.buildinstance,
|
|
204
|
+
SourceOrg: this.options.sourceorg,
|
|
205
|
+
CalculateCodeCoverage: this.options.codecoverage || false,
|
|
206
|
+
SkipValidation: this.options.skipvalidation || false,
|
|
219
207
|
};
|
|
220
208
|
if (preserveFiles) {
|
|
221
209
|
logger.info(messages.getMessage('tempFileLocation', [packageVersTmpRoot]));
|
|
@@ -225,30 +213,15 @@ class PackageVersionCreate {
|
|
|
225
213
|
return fs.promises.rm(packageVersTmpRoot, { recursive: true, force: true }).then(() => requestObject);
|
|
226
214
|
}
|
|
227
215
|
}
|
|
228
|
-
getPackageDescriptorJsonFromPackageId(packageId, options) {
|
|
229
|
-
const artDir = options.path;
|
|
230
|
-
const packageDescriptorJson = this.project.getPackageDirectories().find((packageDir) => {
|
|
231
|
-
const packageDirPackageId = pkgUtils.getPackageIdFromAlias(packageDir.package, this.project);
|
|
232
|
-
return !!packageDirPackageId && packageDirPackageId === packageId ? packageDir : null;
|
|
233
|
-
});
|
|
234
|
-
if (!packageDescriptorJson) {
|
|
235
|
-
throw messages.createError('packagingDirNotFoundInConfigFile', [constants_1.consts.WORKSPACE_CONFIG_FILENAME, artDir]);
|
|
236
|
-
}
|
|
237
|
-
return packageDescriptorJson;
|
|
238
|
-
}
|
|
239
216
|
/**
|
|
240
217
|
* Convert the list of command line options to a JSON object that can be used to create an Package2VersionCreateRequest entity.
|
|
241
218
|
*
|
|
242
|
-
* @param options
|
|
243
|
-
* @param packageId
|
|
244
|
-
* @param versionNumberString
|
|
245
219
|
* @returns {{Package2Id: (*|p|boolean), Package2VersionMetadata: *, Tag: *, Branch: number}}
|
|
246
220
|
* @private
|
|
247
221
|
*/
|
|
248
|
-
async createPackageVersionCreateRequestFromOptions(
|
|
249
|
-
const
|
|
250
|
-
const
|
|
251
|
-
const uniqueHash = (0, testSetup_1.uniqid)({ template: `${packageId}-%s` });
|
|
222
|
+
async createPackageVersionCreateRequestFromOptions() {
|
|
223
|
+
const preserveFiles = !!(this.options.preserve || process.env.SFDX_PACKAGE2_VERSION_CREATE_PRESERVE);
|
|
224
|
+
const uniqueHash = (0, testSetup_1.uniqid)({ template: `${this.packageId}-%s` });
|
|
252
225
|
const packageVersTmpRoot = path.join(os.tmpdir(), `${uniqueHash}`);
|
|
253
226
|
const packageVersMetadataFolder = path.join(packageVersTmpRoot, 'md-files');
|
|
254
227
|
const unpackagedMetadataFolder = path.join(packageVersTmpRoot, 'unpackaged-md-files');
|
|
@@ -258,7 +231,7 @@ class PackageVersionCreate {
|
|
|
258
231
|
const unpackagedMetadataZipFile = path.join(packageVersBlobDirectory, 'unpackaged-metadata-package.zip');
|
|
259
232
|
const settingsZipFile = path.join(packageVersBlobDirectory, 'settings.zip');
|
|
260
233
|
const packageVersBlobZipFile = path.join(packageVersTmpRoot, 'package-version-info.zip');
|
|
261
|
-
const sourceBaseDir = path.join(this.project.getPath(),
|
|
234
|
+
const sourceBaseDir = path.join(this.project.getPath(), this.packageObject.path ?? '');
|
|
262
235
|
const mdOptions = {
|
|
263
236
|
deploydir: packageVersMetadataFolder,
|
|
264
237
|
sourceDir: sourceBaseDir,
|
|
@@ -267,14 +240,16 @@ class PackageVersionCreate {
|
|
|
267
240
|
const clientSideInfo = new Map();
|
|
268
241
|
await fs.promises.mkdir(packageVersBlobDirectory, { recursive: true });
|
|
269
242
|
const settingsGenerator = new scratchOrgSettingsGenerator_1.default({ asDirectory: true });
|
|
270
|
-
// Copy all
|
|
243
|
+
// Copy all the metadata from the workspace to a tmp folder
|
|
271
244
|
await this.generateMDFolderForArtifact(mdOptions);
|
|
272
|
-
const packageDescriptorJson = this.
|
|
245
|
+
const packageDescriptorJson = this.packageObject;
|
|
273
246
|
if (packageDescriptorJson.package) {
|
|
274
247
|
delete packageDescriptorJson.package;
|
|
275
|
-
packageDescriptorJson.id = packageId;
|
|
248
|
+
packageDescriptorJson.id = this.packageId;
|
|
276
249
|
}
|
|
277
|
-
const definitionFile =
|
|
250
|
+
const definitionFile = this.options.definitionfile
|
|
251
|
+
? this.options.definitionfile
|
|
252
|
+
: packageDescriptorJson.definitionFile;
|
|
278
253
|
if (definitionFile) {
|
|
279
254
|
// package2-descriptor.json sent to the server should contain only the features, snapshot & orgPreferences
|
|
280
255
|
// defined in the definition file.
|
|
@@ -284,56 +259,47 @@ class PackageVersionCreate {
|
|
|
284
259
|
delete packageDescriptorJson.snapshot;
|
|
285
260
|
const definitionFilePayload = await fs.promises.readFile(definitionFile, 'utf8');
|
|
286
261
|
const definitionFileJson = JSON.parse(definitionFilePayload);
|
|
287
|
-
const pkgProperties = [
|
|
288
|
-
'country',
|
|
289
|
-
'edition',
|
|
290
|
-
'language',
|
|
291
|
-
'features',
|
|
292
|
-
'orgPreferences',
|
|
293
|
-
'snapshot',
|
|
294
|
-
'release',
|
|
295
|
-
'sourceOrg',
|
|
296
|
-
];
|
|
297
262
|
// Load any settings from the definition
|
|
298
263
|
await settingsGenerator.extract(definitionFileJson);
|
|
299
264
|
if (settingsGenerator.hasSettings() && definitionFileJson.orgPreferences) {
|
|
300
265
|
// this is not allowed, exit with an error
|
|
301
|
-
|
|
266
|
+
throw messages.createError('signupDuplicateSettingsSpecified');
|
|
302
267
|
}
|
|
303
|
-
|
|
268
|
+
['country', 'edition', 'language', 'features', 'orgPreferences', 'snapshot', 'release', 'sourceOrg'].forEach((prop) => {
|
|
304
269
|
const propValue = definitionFileJson[prop];
|
|
305
270
|
if (propValue) {
|
|
306
271
|
packageDescriptorJson[prop] = propValue;
|
|
307
272
|
}
|
|
308
273
|
});
|
|
309
274
|
}
|
|
310
|
-
|
|
311
|
-
this.resolveApexTestPermissions(packageDescriptorJson, options);
|
|
275
|
+
this.resolveApexTestPermissions(packageDescriptorJson);
|
|
312
276
|
// All dependencies for the packaging dir should be resolved to an 04t id to be passed to the server.
|
|
313
277
|
// (see _retrieveSubscriberPackageVersionId for details)
|
|
314
278
|
const dependencies = packageDescriptorJson.dependencies;
|
|
315
|
-
// branch can be set via
|
|
316
|
-
options.branch =
|
|
317
|
-
const resultValues = await Promise.all(!dependencies
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
279
|
+
// branch can be set via options or descriptor; option takes precedence
|
|
280
|
+
this.options.branch = this.options.branch ?? packageDescriptorJson.branch;
|
|
281
|
+
const resultValues = await Promise.all(!dependencies ? [] : dependencies.map((dependency) => this.retrieveSubscriberPackageVersionId(dependency)));
|
|
282
|
+
const ancestorId = await (0, scratchOrgInfoGenerator_1.getAncestorIds)(
|
|
283
|
+
// TODO: investigate if it's ok to convert to ScratchOggInfoPayload
|
|
284
|
+
this.packageObject, this.options.project.getSfProjectJson(), await core_1.Org.create({ aliasOrUsername: this.options.connection.getUsername() }));
|
|
321
285
|
// If dependencies exist, the resultValues array will contain the dependencies populated with a resolved
|
|
322
286
|
// subscriber pkg version id.
|
|
323
287
|
if (resultValues.length > 0) {
|
|
324
288
|
packageDescriptorJson.dependencies = resultValues;
|
|
325
289
|
}
|
|
326
290
|
this.cleanPackageDescriptorJson(packageDescriptorJson);
|
|
327
|
-
this.setPackageDescriptorJsonValues(packageDescriptorJson
|
|
291
|
+
this.setPackageDescriptorJsonValues(packageDescriptorJson);
|
|
328
292
|
await fs.promises.mkdir(packageVersTmpRoot, { recursive: true });
|
|
329
293
|
await fs.promises.mkdir(packageVersBlobDirectory, { recursive: true });
|
|
330
294
|
if (Reflect.has(packageDescriptorJson, 'ancestorVersion')) {
|
|
331
295
|
delete packageDescriptorJson.ancestorVersion;
|
|
332
296
|
}
|
|
333
297
|
packageDescriptorJson.ancestorId = ancestorId;
|
|
334
|
-
await fs.promises.writeFile(path.join(packageVersBlobDirectory, DESCRIPTOR_FILE),
|
|
335
|
-
|
|
336
|
-
|
|
298
|
+
await fs.promises.writeFile(path.join(packageVersBlobDirectory, DESCRIPTOR_FILE), JSON.stringify(packageDescriptorJson), 'utf-8');
|
|
299
|
+
await this.cleanGeneratedPackage(packageVersMetadataFolder, packageVersProfileFolder, unpackagedMetadataFolder, metadataZipFile, settingsZipFile, packageVersBlobDirectory, packageVersBlobZipFile, unpackagedMetadataZipFile, clientSideInfo, settingsGenerator);
|
|
300
|
+
return this.createRequestObject(preserveFiles, packageVersTmpRoot, packageVersBlobZipFile);
|
|
301
|
+
}
|
|
302
|
+
async cleanGeneratedPackage(packageVersMetadataFolder, packageVersProfileFolder, unpackagedMetadataFolder, metadataZipFile, settingsZipFile, packageVersBlobDirectory, packageVersBlobZipFile, unpackagedMetadataZipFile, clientSideInfo, settingsGenerator) {
|
|
337
303
|
// As part of the source convert process, the package.xml has been written into the tmp metadata directory.
|
|
338
304
|
// The package.xml may need to be manipulated due to processing profiles in the workspace or additional
|
|
339
305
|
// metadata exclusions. If necessary, read the existing package.xml and then re-write it.
|
|
@@ -345,18 +311,19 @@ class PackageVersionCreate {
|
|
|
345
311
|
// Apply any necessary exclusions to typesArr.
|
|
346
312
|
let typesArr = packageJson.Package.types;
|
|
347
313
|
this.apiVersionFromPackageXml = packageJson.Package.version;
|
|
314
|
+
const hasUnpackagedMetadata = await this.resolveUnpackagedMetadata(this.packageObject, unpackagedMetadataFolder, clientSideInfo, this.options.codecoverage);
|
|
348
315
|
// if we're using unpackaged metadata, don't package the profiles located there
|
|
349
316
|
if (hasUnpackagedMetadata) {
|
|
350
|
-
typesArr = options.profileApi.filterAndGenerateProfilesForManifest(typesArr, [
|
|
317
|
+
typesArr = this.options.profileApi.filterAndGenerateProfilesForManifest(typesArr, [
|
|
351
318
|
clientSideInfo.get('UnpackagedMetadataPath'),
|
|
352
319
|
]);
|
|
353
320
|
}
|
|
354
321
|
else {
|
|
355
|
-
typesArr = options.profileApi.filterAndGenerateProfilesForManifest(typesArr);
|
|
322
|
+
typesArr = this.options.profileApi.filterAndGenerateProfilesForManifest(typesArr);
|
|
356
323
|
}
|
|
357
324
|
// Next generate profiles and retrieve any profiles that were excluded because they had no matching nodes.
|
|
358
|
-
const excludedProfiles = options.profileApi.generateProfiles(packageVersProfileFolder, {
|
|
359
|
-
Package:
|
|
325
|
+
const excludedProfiles = this.options.profileApi.generateProfiles(packageVersProfileFolder, {
|
|
326
|
+
Package: typesArr,
|
|
360
327
|
}, [clientSideInfo.get('UnpackagedMetadataPath')]);
|
|
361
328
|
if (excludedProfiles.length > 0) {
|
|
362
329
|
const profileIdx = typesArr.findIndex((e) => e.name[0] === 'Profile');
|
|
@@ -369,7 +336,7 @@ class PackageVersionCreate {
|
|
|
369
336
|
});
|
|
370
337
|
const xml = xmlBuilder.buildObject(packageJson);
|
|
371
338
|
// Log information about the profiles being packaged up
|
|
372
|
-
const profiles = options.profileApi.getProfileInformation();
|
|
339
|
+
const profiles = this.options.profileApi.getProfileInformation();
|
|
373
340
|
profiles.forEach((profile) => {
|
|
374
341
|
if (logger.shouldLog(core_1.LoggerLevel.DEBUG)) {
|
|
375
342
|
logger.debug(profile.logDebug());
|
|
@@ -378,8 +345,6 @@ class PackageVersionCreate {
|
|
|
378
345
|
logger.info(profile.logInfo());
|
|
379
346
|
}
|
|
380
347
|
});
|
|
381
|
-
// TODO: confirm that param xml is writeable
|
|
382
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
383
348
|
await fs.promises.writeFile(path.join(packageVersMetadataFolder, 'package.xml'), xml, 'utf-8');
|
|
384
349
|
// Zip the packageVersMetadataFolder folder and put the zip in {packageVersBlobDirectory}/package.zip
|
|
385
350
|
await (0, utils_1.zipDir)(packageVersMetadataFolder, metadataZipFile);
|
|
@@ -395,21 +360,20 @@ class PackageVersionCreate {
|
|
|
395
360
|
}
|
|
396
361
|
// Zip the Version Info and package.zip files into another zip
|
|
397
362
|
await (0, utils_1.zipDir)(packageVersBlobDirectory, packageVersBlobZipFile);
|
|
398
|
-
return this.createRequestObject(packageId, options, preserveFiles, packageVersTmpRoot, packageVersBlobZipFile);
|
|
399
363
|
}
|
|
400
|
-
resolveApexTestPermissions(packageDescriptorJson
|
|
364
|
+
resolveApexTestPermissions(packageDescriptorJson) {
|
|
401
365
|
// Process permissionSet and permissionSetLicenses that should be enabled when running Apex tests
|
|
402
366
|
// This only applies if code coverage is enabled
|
|
403
|
-
if (options.codecoverage) {
|
|
367
|
+
if (this.options.codecoverage) {
|
|
404
368
|
// Assuming no permission sets are named 0, 0n, null, undefined, false, NaN, and the empty string
|
|
405
|
-
if (packageDescriptorJson.apexTestAccess
|
|
369
|
+
if (packageDescriptorJson.apexTestAccess?.permissionSets) {
|
|
406
370
|
let permSets = packageDescriptorJson.apexTestAccess.permissionSets;
|
|
407
371
|
if (!Array.isArray(permSets)) {
|
|
408
372
|
permSets = permSets.split(',');
|
|
409
373
|
}
|
|
410
374
|
packageDescriptorJson.permissionSetNames = permSets.map((s) => s.trim());
|
|
411
375
|
}
|
|
412
|
-
if (packageDescriptorJson.apexTestAccess
|
|
376
|
+
if (packageDescriptorJson.apexTestAccess?.permissionSetLicenses) {
|
|
413
377
|
let permissionSetLicenses = packageDescriptorJson.apexTestAccess.permissionSetLicenses;
|
|
414
378
|
if (!Array.isArray(permissionSetLicenses)) {
|
|
415
379
|
permissionSetLicenses = permissionSetLicenses.split(',');
|
|
@@ -420,15 +384,10 @@ class PackageVersionCreate {
|
|
|
420
384
|
delete packageDescriptorJson.apexTestAccess;
|
|
421
385
|
}
|
|
422
386
|
async resolveUnpackagedMetadata(packageDescriptorJson, unpackagedMetadataFolder, clientSideInfo, codeCoverage) {
|
|
423
|
-
let hasUnpackagedMetadata = false;
|
|
424
387
|
// Add the Unpackaged Metadata, if any, to the output directory, only when code coverage is specified
|
|
425
388
|
if (codeCoverage && packageDescriptorJson.unpackagedMetadata && packageDescriptorJson.unpackagedMetadata.path) {
|
|
426
|
-
hasUnpackagedMetadata = true;
|
|
427
389
|
const unpackagedPath = path.join(process.cwd(), packageDescriptorJson.unpackagedMetadata.path);
|
|
428
|
-
|
|
429
|
-
fs.statSync(unpackagedPath);
|
|
430
|
-
}
|
|
431
|
-
catch (err) {
|
|
390
|
+
if (!fs.existsSync(unpackagedPath)) {
|
|
432
391
|
throw messages.createError('unpackagedMDDirectoryDoesNotExist', [
|
|
433
392
|
packageDescriptorJson.unpackagedMetadata.path,
|
|
434
393
|
]);
|
|
@@ -440,251 +399,59 @@ class PackageVersionCreate {
|
|
|
440
399
|
});
|
|
441
400
|
// Set which package is the "unpackaged" package
|
|
442
401
|
clientSideInfo.set('UnpackagedMetadataPath', packageDescriptorJson.unpackagedMetadata.path);
|
|
402
|
+
return true;
|
|
443
403
|
}
|
|
444
|
-
return
|
|
445
|
-
}
|
|
446
|
-
getPackagePropertyFromPackage(packageDirs, options) {
|
|
447
|
-
let foundByPackage = packageDirs.some((x) => x['package'] === options.package);
|
|
448
|
-
let foundById = packageDirs.some((x) => x['id'] === options.package);
|
|
449
|
-
if (foundByPackage && foundById) {
|
|
450
|
-
throw messages.createError('errorPackageAndIdCollision', []);
|
|
451
|
-
}
|
|
452
|
-
// didn't find anything? let's see if we can reverse look up
|
|
453
|
-
if (!foundByPackage && !foundById) {
|
|
454
|
-
// is it an alias?
|
|
455
|
-
const pkgId = pkgUtils.getPackageIdFromAlias(options.package, this.project);
|
|
456
|
-
if (pkgId === options.package) {
|
|
457
|
-
// not an alias, or not a valid one, try to reverse lookup an alias in case this is an id
|
|
458
|
-
const aliases = pkgUtils.getPackageAliasesFromId(options.package, this.project);
|
|
459
|
-
// if we found an alias, try to look that up in the config.
|
|
460
|
-
foundByPackage = aliases.some((alias) => packageDirs.find((x) => x['package'] === alias));
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
// it is an alias; try to lookup it's id in the config
|
|
464
|
-
foundByPackage = packageDirs.some((x) => x['package'] === pkgId);
|
|
465
|
-
foundById = packageDirs.some((x) => x['id'] === pkgId);
|
|
466
|
-
if (!foundByPackage && !foundById) {
|
|
467
|
-
// check if any configs use a different alias to that same id
|
|
468
|
-
const aliases = pkgUtils.getPackageAliasesFromId(pkgId, this.project);
|
|
469
|
-
foundByPackage = aliases.some((alias) => {
|
|
470
|
-
const pd = packageDirs.find((x) => x['package'] === alias);
|
|
471
|
-
if (pd) {
|
|
472
|
-
// if so, set this.options.package.flags.package to be this alias instead of the alternate
|
|
473
|
-
options.package = alias;
|
|
474
|
-
}
|
|
475
|
-
return pd;
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
// if we still didn't find anything, throw the error
|
|
480
|
-
if (!foundByPackage && !foundById) {
|
|
481
|
-
throw messages.createError('errorMissingPackage', [pkgId]);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
return foundByPackage ? 'package' : 'id';
|
|
485
|
-
}
|
|
486
|
-
getPackageValuePropertyFromDirectory(directoryFlag, options) {
|
|
487
|
-
const packageValue = this.getConfigPackageDirectoriesValue(this.project.getPackageDirectories(), 'package', 'path', options.path, directoryFlag, options);
|
|
488
|
-
const packageIdValue = this.getConfigPackageDirectoriesValue(this.project.getPackageDirectories(), 'id', 'path', options.path, directoryFlag, options);
|
|
489
|
-
let packagePropVal;
|
|
490
|
-
if (!packageValue && !packageIdValue) {
|
|
491
|
-
throw messages.createError('errorMissingPackage', []);
|
|
492
|
-
}
|
|
493
|
-
else if (packageValue && packageIdValue) {
|
|
494
|
-
throw messages.createError('errorPackageAndIdCollision', []);
|
|
495
|
-
}
|
|
496
|
-
else if (packageValue) {
|
|
497
|
-
packagePropVal = {
|
|
498
|
-
packageProperty: 'package',
|
|
499
|
-
packageValue,
|
|
500
|
-
};
|
|
501
|
-
}
|
|
502
|
-
else {
|
|
503
|
-
packagePropVal = {
|
|
504
|
-
packageProperty: 'id',
|
|
505
|
-
packageValue: packageIdValue,
|
|
506
|
-
};
|
|
507
|
-
}
|
|
508
|
-
return packagePropVal;
|
|
404
|
+
return false;
|
|
509
405
|
}
|
|
510
|
-
|
|
511
|
-
* Returns the property value that corresponds to the propertyToLookup. This value found for a particular
|
|
512
|
-
* package directory element that matches the knownProperty and knownValue. In other words, we locate a package
|
|
513
|
-
* directory element whose knownProperty matches the knownValue, then we grab the value for the propertyToLookup
|
|
514
|
-
* and return it.
|
|
515
|
-
*
|
|
516
|
-
* @param packageDirs The list of all the package directories from the sfdx-project.json
|
|
517
|
-
* @param propertyToLookup The property ID whose value we want to find
|
|
518
|
-
* @param knownProperty The JSON property in the packageDirectories that is already known
|
|
519
|
-
* @param knownValue The value that corresponds to the knownProperty in the packageDirectories JSON
|
|
520
|
-
* @param knownFlag The flag details e.g. short/long name, etc. Only used for the error message
|
|
521
|
-
* @param options
|
|
522
|
-
*/
|
|
523
|
-
getConfigPackageDirectoriesValue(packageDirs, propertyToLookup, knownProperty, knownValue, knownFlag, options
|
|
524
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
525
|
-
) {
|
|
526
|
-
let value;
|
|
527
|
-
let packageDir = packageDirs.find((x) => x[knownProperty] === knownValue);
|
|
528
|
-
if (!packageDir && knownFlag === 'path' && knownValue.endsWith(path.sep)) {
|
|
529
|
-
// if this is the directory flag, try removing the trailing slash added by CLI auto-complete
|
|
530
|
-
const dirWithoutTrailingSlash = knownValue.slice(0, -1);
|
|
531
|
-
packageDir = packageDirs.find((x) => x[knownProperty] === dirWithoutTrailingSlash);
|
|
532
|
-
if (packageDir) {
|
|
533
|
-
// TODO: how to deal with this side effect?
|
|
534
|
-
options.path = dirWithoutTrailingSlash;
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
// didn't find it with the package property, try a reverse lookup with alias and id
|
|
538
|
-
if (!packageDir && knownProperty === 'package') {
|
|
539
|
-
const pkgId = pkgUtils.getPackageIdFromAlias(knownValue, this.project);
|
|
540
|
-
if (pkgId !== knownValue) {
|
|
541
|
-
packageDir = packageDirs.find((x) => x[knownProperty] === pkgId);
|
|
542
|
-
}
|
|
543
|
-
else {
|
|
544
|
-
const aliases = pkgUtils.getPackageAliasesFromId(knownValue, this.project);
|
|
545
|
-
aliases.some((alias) => {
|
|
546
|
-
packageDir = packageDirs.find((x) => x[knownProperty] === alias);
|
|
547
|
-
return packageDir;
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
if (packageDir) {
|
|
552
|
-
value = packageDir[propertyToLookup];
|
|
553
|
-
}
|
|
554
|
-
else {
|
|
555
|
-
throw messages.createError('errorNoMatchingPackageDirectory', [`--${knownFlag}`, knownValue, knownProperty]);
|
|
556
|
-
}
|
|
557
|
-
return value;
|
|
558
|
-
}
|
|
559
|
-
async packageVersionCreate(options) {
|
|
406
|
+
async packageVersionCreate() {
|
|
560
407
|
// For the first rollout of validating sfdx-project.json data against schema, make it optional and defaulted
|
|
561
|
-
// to false. Validation only occurs if the
|
|
562
|
-
if (options.validateschema) {
|
|
408
|
+
// to false. Validation only occurs if the optional validateschema option has been specified.
|
|
409
|
+
if (this.options.validateschema) {
|
|
563
410
|
await this.project.getSfProjectJson().schemaValidate();
|
|
564
411
|
}
|
|
565
412
|
// Check for empty packageDirectories
|
|
566
413
|
if (this.project.getPackageDirectories()?.length === 0) {
|
|
567
414
|
throw messages.createError('errorEmptyPackageDirs');
|
|
568
415
|
}
|
|
569
|
-
|
|
570
|
-
|
|
416
|
+
// from the packageDirectories in sfdx-project.json, find the correct package entry either by finding a matching package (name) or path
|
|
417
|
+
this.packageAlias = (0, utils_1.getPackageAliasesFromId)(this.options.packageId, this.options.project).join();
|
|
418
|
+
// set on the class so we can access them in other methods without redoing this logic
|
|
419
|
+
this.packageObject = this.project.getPackageDirectories().find((pkg) => pkg.package === this.packageAlias);
|
|
420
|
+
this.options.profileApi = await this.resolveUserLicenses(this.packageObject.includeProfileUserLicenses);
|
|
421
|
+
this.packageId = (0, utils_1.getPackageIdFromAlias)(this.packageObject.package, this.project);
|
|
571
422
|
// At this point, the packageIdFromAlias should have been resolved to an Id. Now, we
|
|
572
423
|
// need to validate that the Id is correct.
|
|
573
|
-
pkgUtils.validateId(pkgUtils.BY_LABEL.PACKAGE_ID,
|
|
574
|
-
await this.
|
|
575
|
-
const
|
|
576
|
-
try {
|
|
577
|
-
fs.statSync(path.join(process.cwd(), options.path));
|
|
578
|
-
}
|
|
579
|
-
catch (err) {
|
|
580
|
-
throw messages.createError('directoryDoesNotExist', [options.path]);
|
|
581
|
-
}
|
|
582
|
-
options.profileApi = await this.resolveUserLicenses(canonicalPackageProperty, options);
|
|
583
|
-
const request = await this.createPackageVersionCreateRequestFromOptions(options, resolvedPackageId, versionNumberString);
|
|
424
|
+
pkgUtils.validateId(pkgUtils.BY_LABEL.PACKAGE_ID, this.packageId);
|
|
425
|
+
await this.validateOptionsForPackageType();
|
|
426
|
+
const request = await this.createPackageVersionCreateRequestFromOptions();
|
|
584
427
|
const createResult = await this.connection.tooling.create('Package2VersionCreateRequest', request);
|
|
585
428
|
if (!createResult.success) {
|
|
586
|
-
const errStr = createResult.errors
|
|
429
|
+
const errStr = createResult.errors?.join(', ') ?? createResult.errors;
|
|
587
430
|
throw messages.createError('failedToCreatePVCRequest', [
|
|
588
431
|
createResult.id ? ` [${createResult.id}]` : '',
|
|
589
432
|
errStr.toString(),
|
|
590
433
|
]);
|
|
591
434
|
}
|
|
592
|
-
|
|
593
|
-
let maxRetries = 0;
|
|
594
|
-
if (options.wait?.milliseconds > 0) {
|
|
595
|
-
if (options.skipvalidation === true) {
|
|
596
|
-
pollInterval = kit_1.Duration.seconds(POLL_INTERVAL_WITHOUT_VALIDATION_SECONDS);
|
|
597
|
-
}
|
|
598
|
-
maxRetries = (60 / pollInterval.seconds) * options.wait.seconds;
|
|
599
|
-
}
|
|
600
|
-
[pollInterval, maxRetries] = await this.resolveOrgDependentPollingTime(resolvedPackageId, options, pollInterval, maxRetries);
|
|
601
|
-
return (await this.listRequestById(createResult.id, this.connection))[0];
|
|
602
|
-
}
|
|
603
|
-
resolveCanonicalPackageProperty(options) {
|
|
604
|
-
let canonicalPackageProperty;
|
|
605
|
-
if (!options.package) {
|
|
606
|
-
const packageValProp = this.getPackageValuePropertyFromDirectory(options.path, options);
|
|
607
|
-
options.package = packageValProp.packageValue;
|
|
608
|
-
canonicalPackageProperty = packageValProp.packageProperty;
|
|
609
|
-
}
|
|
610
|
-
else if (!options.path) {
|
|
611
|
-
canonicalPackageProperty = this.getPackagePropertyFromPackage(this.project.getPackageDirectories(), options);
|
|
612
|
-
options.path = this.getConfigPackageDirectoriesValue(this.project.getPackageDirectories(), 'path', canonicalPackageProperty, options.package, 'package', options);
|
|
613
|
-
}
|
|
614
|
-
else {
|
|
615
|
-
canonicalPackageProperty = this.getPackagePropertyFromPackage(this.project.getPackageDirectories(), options);
|
|
616
|
-
this.getConfigPackageDirectoriesValue(this.project.getPackageDirectories(), canonicalPackageProperty, 'path', options.path, 'path', options);
|
|
617
|
-
const expectedPackageId = this.getConfigPackageDirectoriesValue(this.project.getPackageDirectories(), canonicalPackageProperty, 'path', options.path, 'path', options);
|
|
618
|
-
// This will throw an error if the package id flag value doesn't match
|
|
619
|
-
// any of the :id values in the package dirs.
|
|
620
|
-
this.getConfigPackageDirectoriesValue(this.project.getPackageDirectories(), 'path', canonicalPackageProperty, options.package, 'package', options);
|
|
621
|
-
// This will throw an error if the package id flag value doesn't match
|
|
622
|
-
// the correct corresponding directory with that packageId.
|
|
623
|
-
if (options.package !== expectedPackageId) {
|
|
624
|
-
throw messages.createError('errorDirectoryIdMismatch', ['--path', options.path, '--package', options.package]);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
return canonicalPackageProperty;
|
|
628
|
-
}
|
|
629
|
-
// TODO: should be in pkg utils
|
|
630
|
-
async validateVersionNumber(canonicalPackageProperty, resolvedPackageId, options) {
|
|
631
|
-
// validate the versionNumber flag value if specified, otherwise the descriptor value
|
|
632
|
-
const versionNumberString = options.versionnumber
|
|
633
|
-
? options.versionnumber
|
|
634
|
-
: this.getConfigPackageDirectoriesValue(this.project.getPackageDirectories(), 'versionNumber', canonicalPackageProperty, options.package, 'package', options);
|
|
635
|
-
pkgUtils.validateVersionNumber(versionNumberString, versionNumber_1.BuildNumberToken.NEXT_BUILD_NUMBER_TOKEN, null);
|
|
636
|
-
await pkgUtils.validatePatchVersion(this.connection, versionNumberString, resolvedPackageId);
|
|
637
|
-
return versionNumberString;
|
|
435
|
+
return (await (0, packageVersionCreateRequest_1.byId)(createResult.id, this.connection))[0];
|
|
638
436
|
}
|
|
639
|
-
async resolveUserLicenses(
|
|
640
|
-
// Check for an includeProfileUserLiceneses flag in the packageDirectory
|
|
641
|
-
const includeProfileUserLicenses = this.getConfigPackageDirectoriesValue(this.project.getPackageDirectories(), 'includeProfileUserLicenses', canonicalPackageProperty, options.package, 'package', options);
|
|
642
|
-
if (includeProfileUserLicenses !== undefined &&
|
|
643
|
-
includeProfileUserLicenses !== true &&
|
|
644
|
-
includeProfileUserLicenses !== false) {
|
|
645
|
-
throw messages.createError('errorProfileUserLicensesInvalidValue', [includeProfileUserLicenses]);
|
|
646
|
-
}
|
|
437
|
+
async resolveUserLicenses(includeUserLicenses) {
|
|
647
438
|
const shouldGenerateProfileInformation = logger.shouldLog(core_1.LoggerLevel.INFO) || logger.shouldLog(core_1.LoggerLevel.DEBUG);
|
|
648
|
-
return packageProfileApi_1.PackageProfileApi.create({
|
|
439
|
+
return await packageProfileApi_1.PackageProfileApi.create({
|
|
649
440
|
project: this.project,
|
|
650
|
-
includeUserLicenses
|
|
441
|
+
includeUserLicenses,
|
|
651
442
|
generateProfileInformation: shouldGenerateProfileInformation,
|
|
652
443
|
});
|
|
653
444
|
}
|
|
654
|
-
async
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
try {
|
|
661
|
-
const pkgQueryResult = await this.connection.singleRecordQuery(query, {
|
|
662
|
-
tooling: true,
|
|
663
|
-
});
|
|
664
|
-
if (pkgQueryResult.IsOrgDependent) {
|
|
665
|
-
pi = kit_1.Duration.seconds(POLL_INTERVAL_WITHOUT_VALIDATION_SECONDS);
|
|
666
|
-
mr = (60 / pollInterval.seconds) * options.wait.seconds;
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
catch {
|
|
670
|
-
// do nothing
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
return [pi, mr];
|
|
674
|
-
}
|
|
675
|
-
async validateFlagsForPackageType(packageId, options) {
|
|
676
|
-
const packageType = await pkgUtils.getPackageType(packageId, this.connection);
|
|
677
|
-
if (packageType === 'Unlocked') {
|
|
678
|
-
if (options.postinstallscript || options.uninstallscript) {
|
|
679
|
-
// migrate coreMessages to messages
|
|
680
|
-
throw messages.createError('version_create.errorScriptsNotApplicableToUnlockedPackage');
|
|
445
|
+
async validateOptionsForPackageType() {
|
|
446
|
+
this.packageType = await pkgUtils.getPackageType(this.packageId, this.connection);
|
|
447
|
+
if (this.packageType === 'Unlocked') {
|
|
448
|
+
// Don't allow scripts in unlocked packages
|
|
449
|
+
if (this.options.postinstallscript || this.options.uninstallscript) {
|
|
450
|
+
throw messages.createError('errorScriptsNotApplicableToUnlockedPackage');
|
|
681
451
|
}
|
|
682
452
|
// Don't allow ancestor in unlocked packages
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
const ancestorVersion = packageDescriptorJson.ancestorVersion;
|
|
686
|
-
if (ancestorId || ancestorVersion) {
|
|
687
|
-
throw messages.createError('version_create.errorAncestorNotApplicableToUnlockedPackage');
|
|
453
|
+
if (this.packageObject.ancestorId || this.packageObject.ancestorVersion) {
|
|
454
|
+
throw messages.createError('errorAncestorNotApplicableToUnlockedPackage');
|
|
688
455
|
}
|
|
689
456
|
}
|
|
690
457
|
}
|
|
@@ -703,7 +470,8 @@ class PackageVersionCreate {
|
|
|
703
470
|
/**
|
|
704
471
|
* Sets default or override values for packageDescriptorJSON attribs
|
|
705
472
|
*/
|
|
706
|
-
setPackageDescriptorJsonValues(packageDescriptorJson
|
|
473
|
+
setPackageDescriptorJsonValues(packageDescriptorJson) {
|
|
474
|
+
const options = this.options;
|
|
707
475
|
if (options.versionname) {
|
|
708
476
|
packageDescriptorJson.versionName = options.versionname;
|
|
709
477
|
}
|
|
@@ -725,13 +493,13 @@ class PackageVersionCreate {
|
|
|
725
493
|
if (options.releasenotesurl) {
|
|
726
494
|
packageDescriptorJson.releaseNotesUrl = options.releasenotesurl;
|
|
727
495
|
}
|
|
728
|
-
if (packageDescriptorJson.releaseNotesUrl && !
|
|
496
|
+
if (packageDescriptorJson.releaseNotesUrl && !core_1.SfdcUrl.isValidUrl(packageDescriptorJson.releaseNotesUrl)) {
|
|
729
497
|
throw messages.createError('malformedUrl', ['releaseNotesUrl', packageDescriptorJson.releaseNotesUrl]);
|
|
730
498
|
}
|
|
731
499
|
if (options.postinstallurl) {
|
|
732
500
|
packageDescriptorJson.postInstallUrl = options.postinstallurl;
|
|
733
501
|
}
|
|
734
|
-
if (packageDescriptorJson.postInstallUrl && !
|
|
502
|
+
if (packageDescriptorJson.postInstallUrl && !core_1.SfdcUrl.isValidUrl(packageDescriptorJson.postInstallUrl)) {
|
|
735
503
|
throw messages.createError('malformedUrl', ['postInstallUrl', packageDescriptorJson.postInstallUrl]);
|
|
736
504
|
}
|
|
737
505
|
if (options.postinstallscript) {
|