diff --git a/messages/package_install.md b/messages/package_install.md index aef0e34a..773dfde3 100644 --- a/messages/package_install.md +++ b/messages/package_install.md @@ -138,14 +138,6 @@ The subscriber package version alias: [%s] isn't defined in the sfdx-project.jso Add it to the packageDirectories section and add the alias to packageAliases with its 04t ID. -# invalidPackageId - -The subscriber package version ID: [%s] is invalid. It must start with "04t". - -# invalidIdLength - -The subscriber package version ID: [%s] is invalid. It must be either 15 or 18 characters. - # promptEnableRss This package might send or receive data from these third-party websites: diff --git a/src/commands/force/package/beta/install.ts b/src/commands/force/package/beta/install.ts index 2faffffd..6ff5ffa4 100644 --- a/src/commands/force/package/beta/install.ts +++ b/src/commands/force/package/beta/install.ts @@ -87,10 +87,10 @@ export class Install extends SfdxCommand { public async run(): Promise { const noPrompt = this.flags.noprompt as boolean; - const connection = (this.connection = this.org.getConnection()); - const pkg = (this.pkg = new Package({ connection })); + this.connection = this.org.getConnection(); + this.pkg = new Package({ connection: this.connection }); - const apiVersion = parseInt(connection.getApiVersion(), 10); + const apiVersion = parseInt(this.connection.getApiVersion(), 10); if (apiVersion < 36) { throw messages.createError('apiVersionTooLow'); } @@ -105,7 +105,7 @@ export class Install extends SfdxCommand { // eslint-disable-next-line @typescript-eslint/require-await Lifecycle.getInstance().on('PackageInstallRequest:warning', async (warningMsg: string) => { - this.display(warningMsg); + this.ux.log(warningMsg); }); // If the user has specified --upgradetype Delete, then prompt for confirmation @@ -128,20 +128,18 @@ export class Install extends SfdxCommand { pollingTimeout: this.flags.wait as Duration, }; - if (!this.flags.json) { - // eslint-disable-next-line @typescript-eslint/require-await - Lifecycle.getInstance().on('PackageInstallRequest:status', async (piRequest: PackageInstallRequest) => { - this.ux.log(messages.getMessage('packageInstallPolling', [piRequest?.Status])); - }); - } + // eslint-disable-next-line @typescript-eslint/require-await + Lifecycle.getInstance().on('PackageInstallRequest:status', async (piRequest: PackageInstallRequest) => { + this.ux.log(messages.getMessage('packageInstallPolling', [piRequest?.Status])); + }); } - const pkgInstallRequest = await pkg.install(request, installOptions); + const pkgInstallRequest = await this.pkg.install(request, installOptions); const { Status } = pkgInstallRequest; if (Status === 'SUCCESS') { - this.display(messages.getMessage('packageInstallSuccess', [this.flags.package])); + this.ux.log(messages.getMessage('packageInstallSuccess', [this.flags.package])); } else if (['IN_PROGRESS', 'UNKNOWN'].includes(Status)) { - this.display(messages.getMessage('packageInstallInProgress', [pkgInstallRequest.Id, this.org.getUsername()])); + this.ux.log(messages.getMessage('packageInstallInProgress', [pkgInstallRequest.Id, this.org.getUsername()])); } else { throw messages.createError('packageInstallError', [this.parseInstallErrors(pkgInstallRequest)]); } @@ -149,12 +147,6 @@ export class Install extends SfdxCommand { return pkgInstallRequest; } - private display(message: string): void { - if (!this.flags.json) { - this.ux.log(message); - } - } - private async confirmUpgradeType(request: PackageInstallCreateRequest, noPrompt: boolean): Promise { const pkgType = await getPackageTypeBy04t(request.SubscriberPackageVersionKey, this.connection, request.Password); if (pkgType === 'Unlocked' && !noPrompt) { @@ -180,13 +172,11 @@ export class Install extends SfdxCommand { } private async waitForPublish(request: PackageInstallCreateRequest): Promise { - if (!this.flags.json) { - // eslint-disable-next-line @typescript-eslint/require-await - Lifecycle.getInstance().on('SubscriberPackageVersion:status', async (status: string) => { - const tokens = status ? [` Status = ${status}`] : []; - this.ux.log(messages.getMessage('publishWaitProgress', tokens)); - }); - } + // eslint-disable-next-line @typescript-eslint/require-await + Lifecycle.getInstance().on('SubscriberPackageVersion:status', async (status: string) => { + const tokens = status ? [` Status = ${status}`] : []; + this.ux.log(messages.getMessage('publishWaitProgress', tokens)); + }); // wait for the Subscriber Package Version ID to become available in the target org try { @@ -225,6 +215,7 @@ export class Install extends SfdxCommand { let resolvedId: string; if (idOrAlias.startsWith('04t')) { + Package.validateId(idOrAlias, 'SubscriberPackageVersionId'); resolvedId = idOrAlias; } else { let packageAliases: { [k: string]: string }; @@ -238,13 +229,7 @@ export class Install extends SfdxCommand { if (!resolvedId) { throw messages.createError('packageAliasNotFound', [idOrAlias]); } - if (!resolvedId.startsWith('04t')) { - throw messages.createError('invalidPackageId', [resolvedId]); - } - } - - if (![15, 18].includes(resolvedId.length)) { - throw messages.createError('invalidIdLength', [resolvedId]); + Package.validateId(resolvedId, 'SubscriberPackageVersionId'); } return resolvedId; diff --git a/src/commands/force/package/beta/install/report.ts b/src/commands/force/package/beta/install/report.ts index 534fc18c..03a4415c 100644 --- a/src/commands/force/package/beta/install/report.ts +++ b/src/commands/force/package/beta/install/report.ts @@ -7,11 +7,15 @@ import { flags, FlagsConfig, SfdxCommand } from '@salesforce/command'; import { Messages } from '@salesforce/core'; +import { Package, PackagingSObjects } from '@salesforce/packaging'; + +type PackageInstallRequest = PackagingSObjects.PackageInstallRequest; Messages.importMessagesDirectory(__dirname); const messages = Messages.loadMessages('@salesforce/plugin-packaging', 'package_install_report'); +const installMsgs = Messages.loadMessages('@salesforce/plugin-packaging', 'package_install'); -export class PackageInstallReportCommand extends SfdxCommand { +export class Report extends SfdxCommand { public static readonly description = messages.getMessage('cliDescription'); public static readonly longDescription = messages.getMessage('cliDescriptionLong'); public static readonly help = messages.getMessage('help'); @@ -26,8 +30,39 @@ export class PackageInstallReportCommand extends SfdxCommand { }), }; - public async run(): Promise { - process.exitCode = 1; - return Promise.resolve('Not yet implemented'); + public async run(): Promise { + const connection = this.org.getConnection(); + const pkg = new Package({ connection }); + const installRequestId = this.flags.requestid as string; + Package.validateId(installRequestId, 'PackageInstallRequestId'); + const pkgInstallRequest = await pkg.getInstallStatus(installRequestId); + this.parseStatus(pkgInstallRequest); + + return pkgInstallRequest; + } + + // @fixme: refactor with install code and any others + private parseStatus(request: PackageInstallRequest): void { + const { Status } = request; + if (Status === 'SUCCESS') { + this.ux.log(installMsgs.getMessage('packageInstallSuccess', [request.Id])); + } else if (['IN_PROGRESS', 'UNKNOWN'].includes(Status)) { + this.ux.log(installMsgs.getMessage('packageInstallInProgress', [request.Id, this.org.getUsername()])); + } else { + throw installMsgs.createError('packageInstallError', [this.parseInstallErrors(request)]); + } + } + + // @fixme: refactor with install code and any others + private parseInstallErrors(request: PackageInstallRequest): string { + const errors = request?.Errors?.errors; + if (errors?.length) { + let errorMessage = 'Installation errors: '; + for (let i = 0; i < errors.length; i++) { + errorMessage += `\n${i + 1}) ${errors[i].message}`; + } + return errorMessage; + } + return ''; } }