diff --git a/src/commands/force/mdapi/deploy.ts b/src/commands/force/mdapi/deploy.ts index 5fdfff84c..e0b77cd9f 100644 --- a/src/commands/force/mdapi/deploy.ts +++ b/src/commands/force/mdapi/deploy.ts @@ -8,7 +8,7 @@ import { fileURLToPath } from 'node:url'; import { dirname } from 'node:path'; import { Duration, env } from '@salesforce/kit'; import { Lifecycle, Messages, Org } from '@salesforce/core'; -import { DeployVersionData, MetadataApiDeploy } from '@salesforce/source-deploy-retrieve'; +import { AsyncResult, DeployVersionData, MetadataApiDeploy } from '@salesforce/source-deploy-retrieve'; import { arrayWithDeprecation, Flags, @@ -137,8 +137,8 @@ export class Deploy extends DeployCommand { junit: Flags.boolean({ summary: messages.getMessage('flags.junit.summary') }), }; - private flags: Interfaces.InferredFlags; - private org: Org; + private flags!: Interfaces.InferredFlags; + private org!: Org; public async run(): Promise { this.flags = (await this.parse(Deploy)).flags; @@ -167,7 +167,7 @@ export class Deploy extends DeployCommand { const deploymentOptions = this.flags.zipfile ? { zipPath: this.flags.zipfile } : { mdapiPath: this.flags.deploydir }; - const username = this.org.getUsername(); + const username = this.org.getUsername() as string; // still here? we need to deploy a zip file then const deploy = new MetadataApiDeploy({ @@ -200,7 +200,7 @@ export class Deploy extends DeployCommand { this.log(deployMessages.getMessage('apiVersionMsgBasic', [username, apiData.apiVersion, apiData.webService])); }); await deploy.start(); - this.asyncDeployResult = { id: deploy.id }; + this.asyncDeployResult = deploy.id ? { id: deploy.id } : undefined; this.updateDeployId(deploy.id); if (!this.isAsync) { @@ -237,7 +237,7 @@ export class Deploy extends DeployCommand { ? new MdDeployAsyncResultFormatter( new Ux({ jsonEnabled: this.jsonEnabled() }), formatterOptions, - this.asyncDeployResult + this.asyncDeployResult as AsyncResult ) : new MdDeployResultFormatter(new Ux({ jsonEnabled: this.jsonEnabled() }), formatterOptions, this.deployResult); diff --git a/src/commands/force/mdapi/deploy/cancel.ts b/src/commands/force/mdapi/deploy/cancel.ts index ad230544d..49ecdc21d 100644 --- a/src/commands/force/mdapi/deploy/cancel.ts +++ b/src/commands/force/mdapi/deploy/cancel.ts @@ -56,8 +56,8 @@ export class Cancel extends DeployCommand { summary: messages.getMessage('flags.jobid.summary'), }), }; - private flags: Interfaces.InferredFlags; - private conn: Connection; + private flags!: Interfaces.InferredFlags; + private conn!: Connection; public async run(): Promise { this.flags = (await this.parse(Cancel)).flags; diff --git a/src/commands/force/mdapi/deploy/report.ts b/src/commands/force/mdapi/deploy/report.ts index 86871da23..9593145db 100644 --- a/src/commands/force/mdapi/deploy/report.ts +++ b/src/commands/force/mdapi/deploy/report.ts @@ -74,8 +74,8 @@ export class Report extends DeployCommand { junit: Flags.boolean({ summary: messages.getMessage('flags.junit.summary') }), }; - private flags: Interfaces.InferredFlags; - private org: Org; + private flags!: Interfaces.InferredFlags; + private org!: Org; public async run(): Promise { this.flags = (await this.parse(Report)).flags; diff --git a/src/commands/force/mdapi/retrieve.ts b/src/commands/force/mdapi/retrieve.ts index 8d32dc89b..26664e3c3 100644 --- a/src/commands/force/mdapi/retrieve.ts +++ b/src/commands/force/mdapi/retrieve.ts @@ -102,16 +102,16 @@ export class Retrieve extends SourceCommand { }), }; - protected retrieveResult: RetrieveResult; - private sourceDir: string; - private retrieveTargetDir: string; - private zipFileName: string; - private unzip: boolean; - private wait: Duration; - private isAsync: boolean; - private mdapiRetrieve: MetadataApiRetrieve; - private flags: Interfaces.InferredFlags; - private org: Org; + protected retrieveResult: RetrieveResult | undefined; + private sourceDir: string | undefined; + private retrieveTargetDir: string | undefined; + private zipFileName: string | undefined; + private unzip: boolean | undefined; + private wait: Duration | undefined; + private isAsync: boolean | undefined; + private mdapiRetrieve: MetadataApiRetrieve | undefined; + private flags!: Interfaces.InferredFlags; + private org!: Org | undefined; public async run(): Promise { this.flags = (await this.parse(Retrieve)).flags; this.org = this.flags['target-org']; @@ -138,7 +138,7 @@ export class Retrieve extends SourceCommand { throw new SfError(messages.getMessage('InvalidPackageNames', [packagenames.toString()]), 'InvalidPackageNames'); } - this.spinner.start(spinnerMessages.getMessage('retrieve.main', [this.org.getUsername()])); + this.spinner.start(spinnerMessages.getMessage('retrieve.main', [this.org?.getUsername()])); this.spinner.status = spinnerMessages.getMessage('retrieve.componentSetBuild'); this.componentSet = await ComponentSetBuilder.build({ @@ -148,14 +148,16 @@ export class Retrieve extends SourceCommand { apiversion: this.flags.apiversion, packagenames, sourcepath: this.sourceDir ? [this.sourceDir] : undefined, - manifest: manifest && { - manifestPath: manifest, - directoryPaths: [], - }, + manifest: manifest + ? { + manifestPath: manifest, + directoryPaths: [], + } + : undefined, }); await Lifecycle.getInstance().emit('preretrieve', { packageXmlPath: manifest }); - const username = this.org.getUsername(); + const username = this.org?.getUsername() ?? ''; // eslint-disable-next-line @typescript-eslint/require-await Lifecycle.getInstance().on('apiVersionRetrieve', async (apiData: RetrieveVersionData) => { this.log( @@ -180,7 +182,7 @@ export class Retrieve extends SourceCommand { }); Stash.set('MDAPI_RETRIEVE', { - jobid: this.mdapiRetrieve.id, + jobid: this.mdapiRetrieve.id ?? '', retrievetargetdir: this.retrieveTargetDir, zipfilename: this.zipFileName, unzip: this.unzip, @@ -210,14 +212,14 @@ export class Retrieve extends SourceCommand { [RequestStatus.Canceling, 69], ]); if (!this.isAsync) { - this.setExitCode(StatusCodeMap.get(this.retrieveResult.response.status) ?? 1); + this.setExitCode(StatusCodeMap.get(this.retrieveResult?.response.status as RequestStatus) ?? 1); } } protected formatResult(): RetrieveCommandResult | RetrieveCommandAsyncResult { // async result if (this.isAsync) { - let cmdFlags = `--jobid ${this.mdapiRetrieve.id} --retrievetargetdir ${this.retrieveTargetDir}`; + let cmdFlags = `--jobid ${this.mdapiRetrieve?.id} --retrievetargetdir ${this.retrieveTargetDir}`; const targetusernameFlag = this.flags['target-org']; if (targetusernameFlag) { cmdFlags += ` --targetusername ${targetusernameFlag.getUsername()}`; @@ -226,14 +228,14 @@ export class Retrieve extends SourceCommand { this.log(messages.getMessage('checkStatus', [cmdFlags])); return { done: false, - id: this.mdapiRetrieve.id, + id: this.mdapiRetrieve?.id ?? '', state: 'Queued', status: 'Queued', timedOut: true, }; } else { const formatterOptions = { - waitTime: this.wait.quantity, + waitTime: this.wait?.quantity ?? '', verbose: this.flags.verbose ?? false, retrieveTargetDir: this.retrieveTargetDir, zipFileName: this.zipFileName, @@ -241,6 +243,8 @@ export class Retrieve extends SourceCommand { }; const formatter = new RetrieveResultFormatter( new Ux({ jsonEnabled: this.jsonEnabled() }), + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore formatterOptions, this.retrieveResult ); @@ -258,6 +262,7 @@ export class Retrieve extends SourceCommand { } catch (error) { this.debug('No SFDX project found for default package directory'); } + return ''; } private resolveRootDir(rootDir?: string): string { diff --git a/src/commands/force/mdapi/retrieve/report.ts b/src/commands/force/mdapi/retrieve/report.ts index 6ea4c1611..e772ce01e 100644 --- a/src/commands/force/mdapi/retrieve/report.ts +++ b/src/commands/force/mdapi/retrieve/report.ts @@ -70,16 +70,16 @@ export class Report extends SourceCommand { }), }; - protected retrieveResult: RetrieveResult; - protected retrieveStatus: MetadataApiRetrieveStatus; - private retrieveTargetDir: string; - private zipFileName: string; - private unzip: boolean; - private wait: Duration; - private isAsync: boolean; - private mdapiRetrieve: MetadataApiRetrieve; - private flags: Interfaces.InferredFlags; - private org: Org; + protected retrieveResult!: RetrieveResult; + protected retrieveStatus!: MetadataApiRetrieveStatus; + private retrieveTargetDir!: string; + private zipFileName!: string; + private unzip: boolean | undefined; + private wait!: Duration; + private isAsync!: boolean; + private mdapiRetrieve!: MetadataApiRetrieve; + private flags!: Interfaces.InferredFlags; + private org!: Org; public async run(): Promise { this.flags = (await this.parse(Report)).flags; @@ -104,7 +104,7 @@ export class Report extends SourceCommand { retrieveId = mdRetrieveStash.jobid; this.retrieveTargetDir = this.resolveOutputDir(mdRetrieveStash?.retrievetargetdir); this.zipFileName = resolveZipFileName(mdRetrieveStash?.zipfilename); - this.unzip = mdRetrieveStash?.unzip; + this.unzip = mdRetrieveStash.unzip; } else { this.retrieveTargetDir = this.resolveOutputDir(this.flags.retrievetargetdir); this.zipFileName = resolveZipFileName(this.flags.zipfilename); @@ -120,7 +120,7 @@ export class Report extends SourceCommand { this.mdapiRetrieve = new MetadataApiRetrieve({ id: retrieveId, - usernameOrConnection: this.org.getUsername(), + usernameOrConnection: this.org.getUsername() as string, output: this.retrieveTargetDir, format: 'metadata', zipFileName: this.zipFileName, @@ -181,7 +181,7 @@ export class Report extends SourceCommand { return formatter.getJson(); } - private resolveOutputDir(dirPath: string): string { + private resolveOutputDir(dirPath?: string): string { return this.ensureFlagPath({ flagName: 'retrievetargetdir', path: dirPath, diff --git a/src/commands/force/source/deploy.ts b/src/commands/force/source/deploy.ts index 392517e80..6e31dd0d3 100644 --- a/src/commands/force/source/deploy.ts +++ b/src/commands/force/source/deploy.ts @@ -10,7 +10,7 @@ import { dirname } from 'node:path'; import { Lifecycle, Messages, Org } from '@salesforce/core'; import { Duration, env } from '@salesforce/kit'; import { SourceTracking } from '@salesforce/source-tracking'; -import { ComponentSetBuilder, DeployVersionData } from '@salesforce/source-deploy-retrieve'; +import { AsyncResult, ComponentSetBuilder, DeployVersionData } from '@salesforce/source-deploy-retrieve'; import { arrayWithDeprecation, Flags, @@ -163,9 +163,11 @@ export class Deploy extends DeployCommand { junit: Flags.boolean({ summary: messages.getMessage('flags.junit.summary') }), }; protected readonly lifecycleEventNames = ['predeploy', 'postdeploy']; - protected tracking: SourceTracking; + protected tracking!: SourceTracking; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private flags: Interfaces.InferredFlags; - private org: Org; + private org!: Org; public async run(): Promise { this.flags = (await this.parse(Deploy)).flags; this.org = await Org.create({ aliasOrUsername: this.flags['target-org'] }); @@ -192,6 +194,7 @@ export class Deploy extends DeployCommand { // 1. synchronous - deploy metadata and wait for the deploy to complete. // 2. asynchronous - deploy metadata and immediately return. // 3. recent validation - deploy metadata that's already been validated by the org + // eslint-disable-next-line complexity protected async deploy(): Promise { const waitDuration = this.flags.wait; this.isAsync = waitDuration.quantity === 0; @@ -211,12 +214,14 @@ export class Deploy extends DeployCommand { apiversion: this.flags['api-version'], sourceapiversion: await this.getSourceApiVersion(), sourcepath: this.flags.sourcepath, - manifest: this.flags.manifest && { - manifestPath: this.flags.manifest, - directoryPaths: this.getPackageDirs(), - destructiveChangesPre: this.flags.predestructivechanges, - destructiveChangesPost: this.flags.postdestructivechanges, - }, + manifest: this.flags.manifest + ? { + manifestPath: this.flags.manifest, + directoryPaths: this.getPackageDirs(), + destructiveChangesPre: this.flags.predestructivechanges, + destructiveChangesPost: this.flags.postdestructivechanges, + } + : undefined, metadata: this.flags.metadata && { metadataEntries: this.flags.metadata, directoryPaths: this.getPackageDirs(), @@ -242,7 +247,7 @@ export class Deploy extends DeployCommand { } // fire predeploy event for sync and async deploys await Lifecycle.getInstance().emit('predeploy', this.componentSet.toArray()); - const username = this.org.getUsername(); + const username = this.org.getUsername() ?? ''; // eslint-disable-next-line @typescript-eslint/require-await Lifecycle.getInstance().on('apiVersionDeploy', async (apiData: DeployVersionData) => { this.log( @@ -273,8 +278,10 @@ export class Deploy extends DeployCommand { ...(this.flags.runtests ? { runTests: this.flags.runtests } : {}), }, }); - this.asyncDeployResult = { id: deploy.id }; - this.updateDeployId(deploy.id); + const id = deploy.id ?? ''; + + this.asyncDeployResult = { id }; + this.updateDeployId(id); if (!this.isAsync) { // we're not print JSON output @@ -318,7 +325,7 @@ export class Deploy extends DeployCommand { ? new DeployAsyncResultFormatter( new Ux({ jsonEnabled: this.jsonEnabled() }), formatterOptions, - this.asyncDeployResult + this.asyncDeployResult as AsyncResult ) : new DeployResultFormatter(new Ux({ jsonEnabled: this.jsonEnabled() }), formatterOptions, this.deployResult); diff --git a/src/commands/force/source/deploy/cancel.ts b/src/commands/force/source/deploy/cancel.ts index b6171bf9d..fd00f1f5a 100644 --- a/src/commands/force/source/deploy/cancel.ts +++ b/src/commands/force/source/deploy/cancel.ts @@ -55,6 +55,8 @@ export class Cancel extends DeployCommand { }), }; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private flags: Interfaces.InferredFlags; public async run(): Promise { @@ -79,7 +81,7 @@ export class Cancel extends DeployCommand { } protected resolveSuccess(): void { - const status = this.deployResult.response.status; + const status = this.deployResult?.response.status; if (status !== RequestStatus.Canceled) { this.setExitCode(1); } diff --git a/src/commands/force/source/deploy/report.ts b/src/commands/force/source/deploy/report.ts index 1a4ebfce1..915becc64 100644 --- a/src/commands/force/source/deploy/report.ts +++ b/src/commands/force/source/deploy/report.ts @@ -74,6 +74,8 @@ export class Report extends DeployCommand { }), junit: Flags.boolean({ summary: messages.getMessage('flags.junit.summary') }), }; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore private flags: Interfaces.InferredFlags; public async run(): Promise { @@ -102,10 +104,10 @@ export class Report extends DeployCommand { try { this.project = await SfProject.resolve(); sourcepath = this.project.getUniquePackageDirectories().map((pDir) => pDir.fullPath); + this.componentSet = await ComponentSetBuilder.build({ sourcepath }); } catch (err) { // ignore the error. this was just to get improved command output. } - this.componentSet = await ComponentSetBuilder.build({ sourcepath }); } const waitDuration = this.flags.wait; diff --git a/src/commands/force/source/pull.ts b/src/commands/force/source/pull.ts index 184880180..f51a99fc7 100644 --- a/src/commands/force/source/pull.ts +++ b/src/commands/force/source/pull.ts @@ -62,10 +62,10 @@ export default class Pull extends SourceCommand { public static requiresProject = true; protected readonly lifecycleEventNames = ['preretrieve', 'postretrieve']; - protected tracking: SourceTracking | undefined; - protected retrieveResult: RetrieveResult | undefined; - protected deleteFileResponses: FileResponse[] | undefined; - private flags: Interfaces.InferredFlags | undefined; + protected tracking!: SourceTracking; + protected retrieveResult!: RetrieveResult; + protected deleteFileResponses!: FileResponse[]; + private flags!: Interfaces.InferredFlags; public async run(): Promise { this.flags = (await this.parse(Pull)).flags; @@ -87,7 +87,7 @@ export default class Pull extends SourceCommand { protected async preChecks(): Promise { this.spinner.start('Loading source tracking information'); this.tracking = await trackingSetup({ - ignoreConflicts: this.flags.forceoverwrite ?? false, + ignoreConflicts: this.flags?.forceoverwrite ?? false, org: this.flags['target-org'], project: this.project, ux: new Ux({ jsonEnabled: this.jsonEnabled() }), @@ -101,7 +101,7 @@ export default class Pull extends SourceCommand { state: 'delete', format: 'SourceComponent', }); - this.deleteFileResponses = await this.tracking.deleteFilesAndUpdateTracking(changesToDelete); + this.deleteFileResponses = await this.tracking?.deleteFilesAndUpdateTracking(changesToDelete); } protected async retrieve(): Promise { @@ -115,7 +115,7 @@ export default class Pull extends SourceCommand { if (this.flags['api-version']) { componentSet.apiVersion = this.flags['api-version']; } - const username = this.flags['target-org'].getUsername(); + const username = this.flags['target-org'].getUsername() as string; // eslint-disable-next-line @typescript-eslint/require-await Lifecycle.getInstance().on('apiVersionRetrieve', async (apiData: RetrieveVersionData) => { this.log( diff --git a/src/commands/force/source/push.ts b/src/commands/force/source/push.ts index e87544a44..bab43bf3b 100644 --- a/src/commands/force/source/push.ts +++ b/src/commands/force/source/push.ts @@ -70,9 +70,9 @@ export default class Push extends DeployCommand { protected readonly lifecycleEventNames = ['predeploy', 'postdeploy']; private deployResults: DeployResult[] = []; - private tracking: SourceTracking; - private deletes: string[]; - private flags: Interfaces.InferredFlags; + private tracking!: SourceTracking; + private deletes!: string[]; + private flags!: Interfaces.InferredFlags; public async run(): Promise { this.flags = (await this.parse(Push)).flags; @@ -96,7 +96,7 @@ export default class Push extends DeployCommand { } protected async deploy(): Promise { - const username = this.flags['target-org'].getUsername(); + const username = this.flags['target-org'].getUsername() as string; const isSequentialDeploy = getBoolean( await this.project.resolveProjectConfig(), 'pushPackageDirectoriesSequentially', diff --git a/src/commands/force/source/retrieve.ts b/src/commands/force/source/retrieve.ts index 4d7f0e824..15c996abd 100644 --- a/src/commands/force/source/retrieve.ts +++ b/src/commands/force/source/retrieve.ts @@ -111,10 +111,10 @@ export class Retrieve extends SourceCommand { }), }; protected readonly lifecycleEventNames = ['preretrieve', 'postretrieve']; - protected retrieveResult: RetrieveResult; - protected tracking: SourceTracking; - private resolvedTargetDir: string; - private flags: Interfaces.InferredFlags; + protected retrieveResult!: RetrieveResult; + protected tracking!: SourceTracking; + private resolvedTargetDir!: string; + private flags!: Interfaces.InferredFlags; private registry = new RegistryAccess(); public async run(): Promise { @@ -150,7 +150,7 @@ export class Retrieve extends SourceCommand { } protected async retrieve(): Promise { - const username = this.flags['target-org'].getUsername(); + const username = this.flags['target-org'].getUsername() as string; // eslint-disable-next-line @typescript-eslint/require-await Lifecycle.getInstance().on('apiVersionRetrieve', async (apiData: RetrieveVersionData) => { this.log( @@ -168,10 +168,12 @@ export class Retrieve extends SourceCommand { sourceapiversion: await this.getSourceApiVersion(), packagenames: this.flags.packagenames, sourcepath: this.flags.sourcepath, - manifest: this.flags.manifest && { - manifestPath: this.flags.manifest, - directoryPaths: this.flags.retrievetargetdir ? [] : this.getPackageDirs(), - }, + manifest: this.flags.manifest + ? { + manifestPath: this.flags.manifest, + directoryPaths: this.flags.retrievetargetdir ? [] : this.getPackageDirs(), + } + : undefined, metadata: this.flags.metadata && { metadataEntries: this.flags.metadata, directoryPaths: this.flags.retrievetargetdir ? [] : this.getPackageDirs(), @@ -275,16 +277,16 @@ export class Retrieve extends SourceCommand { } private wantsToRetrieveCustomFields(): boolean { - const hasCustomField = this.componentSet.has({ + const hasCustomField = this.componentSet?.has({ type: this.registry.getTypeByName('CustomField'), fullName: ComponentSet.WILDCARD, }); - const hasCustomObject = this.componentSet.has({ + const hasCustomObject = this.componentSet?.has({ type: this.registry.getTypeByName('CustomObject'), fullName: ComponentSet.WILDCARD, }); - return hasCustomField && !hasCustomObject; + return (hasCustomField && !hasCustomObject) as boolean; } private async moveResultsForRetrieveTargetDir(): Promise { diff --git a/src/commands/force/source/status.ts b/src/commands/force/source/status.ts index 39ae3cf00..757ed66f1 100644 --- a/src/commands/force/source/status.ts +++ b/src/commands/force/source/status.ts @@ -18,7 +18,12 @@ import { SfCommand, Ux, } from '@salesforce/sf-plugins-core'; -import { StatusFormatter, StatusResult } from '../../../formatters/source/statusFormatter.js'; +import { + StatusFormatter, + StatusOrigin, + StatusResult, + StatusStateString, +} from '../../../formatters/source/statusFormatter.js'; import { trackingSetup } from '../../../trackingFunctions.js'; Messages.importMessagesDirectory(dirname(fileURLToPath(import.meta.url))); @@ -56,7 +61,7 @@ export default class Status extends SfCommand { public static readonly requiresProject = true; protected results = new Array(); protected localAdds: ChangeResult[] = []; - private flags: Interfaces.InferredFlags; + private flags!: Interfaces.InferredFlags; public async run(): Promise { this.flags = (await this.parse(Status)).flags; @@ -104,14 +109,14 @@ export default class Status extends SfCommand { */ const resultConverter = (input: StatusOutputRow): StatusResult => { const { fullName, type, ignored, filePath, conflict } = input; - const origin = originMap.get(input.origin); + const origin = originMap.get(input.origin) as StatusOrigin; const actualState = stateMap.get(input.state); return { fullName, type, // this string became the place to store information. // The JSON now breaks out that info but preserves this property for backward compatibility - state: `${origin} ${actualState}${conflict ? ' (Conflict)' : ''}`, + state: `${origin} ${actualState}${conflict ? ' (Conflict)' : ''}` as StatusStateString, ignored, filePath, origin, diff --git a/src/deployCommand.ts b/src/deployCommand.ts index 95b82aef1..e8830fd26 100644 --- a/src/deployCommand.ts +++ b/src/deployCommand.ts @@ -48,7 +48,7 @@ const messages = Messages.loadMessages('@salesforce/plugin-source', 'deployComma export const reportsFormatters = Object.keys(DefaultReportOptions); export abstract class DeployCommand extends SourceCommand { - protected displayDeployId = once((id: string) => { + protected displayDeployId = once((id?: string) => { if (!this.jsonEnabled()) { this.log(`Deploy ID: ${id}`); } @@ -57,12 +57,12 @@ export abstract class DeployCommand extends SourceCommand { protected isRest = false; protected isAsync = false; protected asyncDeployResult: AsyncResult | undefined; - protected deployResult: DeployResult | undefined; + protected deployResult!: DeployResult; protected resultsDir: string | undefined; - protected updateDeployId = once((id: string) => { + protected updateDeployId = once((id?: string) => { this.displayDeployId(id); - const stashKey = Stash.getKey(this.id); - Stash.set(stashKey, { jobid: id }); + const stashKey = Stash.getKey(this.id as string); + Stash.set(stashKey, { jobid: id ?? '' }); }); /** @@ -99,7 +99,7 @@ export abstract class DeployCommand extends SourceCommand { [RequestStatus.Canceling, 69], ]); if (!this.isAsync) { - this.setExitCode(StatusCodeMap.get(this.deployResult?.response?.status as RequestStatus) ?? 1); + this.setExitCode(StatusCodeMap.get(this.deployResult?.response?.status) ?? 1); } } @@ -118,7 +118,8 @@ export abstract class DeployCommand extends SourceCommand { if (id) { return id; } else { - const stash = Stash.get(Stash.getKey(this.id)); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const stash = Stash.get(Stash.getKey(this.id!)); if (!stash) { throw new SfError(messages.getMessage('MissingDeployId')); } @@ -130,7 +131,7 @@ export abstract class DeployCommand extends SourceCommand { // 1. SOAP is specified with the soapdeploy flag on the command // 2. The restDeploy SFDX config setting is explicitly true. protected isRestDeploy(soapdeploy = true): boolean { - if (soapdeploy === true) { + if (soapdeploy) { this.debug('soapdeploy flag === true. Using SOAP'); return false; } @@ -290,7 +291,7 @@ export const resolveUsername = async (usernameOrAlias?: string): Promise if (usernameOrAlias) return stateAggregator.aliases.resolveUsername(usernameOrAlias); // we didn't get a value, so let's see if the config has a default target org const configAggregator = await ConfigAggregator.create(); - const defaultUsernameOrAlias: string = configAggregator.getPropertyValue('target-org'); + const defaultUsernameOrAlias = configAggregator.getPropertyValue('target-org') as string; if (defaultUsernameOrAlias) return stateAggregator.aliases.resolveUsername(defaultUsernameOrAlias); throw new SfError(messages.getMessage('missingUsername'), 'MissingUsernameError'); }; diff --git a/src/formatters/codeCoverageTable.ts b/src/formatters/codeCoverageTable.ts index 8fe6b0fd9..e61344030 100644 --- a/src/formatters/codeCoverageTable.ts +++ b/src/formatters/codeCoverageTable.ts @@ -17,7 +17,10 @@ import { prepCoverageForDisplay } from '../coverageUtils.js'; * @param coverageFromMdapiResult * @param ux */ -export const maybePrintCodeCoverageTable = (coverageFromMdapiResult: CodeCoverage | CodeCoverage[], ux: Ux): void => { +export const maybePrintCodeCoverageTable = ( + coverageFromMdapiResult: CodeCoverage | CodeCoverage[] | undefined, + ux: Ux +): void => { const codeCoverage = ensureArray(coverageFromMdapiResult); if (codeCoverage.length) { diff --git a/src/formatters/deployResultFormatter.ts b/src/formatters/deployResultFormatter.ts index 641bd011b..ff4e1457a 100644 --- a/src/formatters/deployResultFormatter.ts +++ b/src/formatters/deployResultFormatter.ts @@ -200,9 +200,11 @@ export class DeployResultFormatter extends ResultFormatter { const fileResponses: FileResponse[] = []; this.fileResponses .filter((f) => f.state === 'Failed') - .map((f: FileResponse & { error: string }) => { + .map((f) => { fileResponses.push(f); - fileResponseFailures.set(`${f.type}#${f.fullName}`, f.error); + if ('error' in f) { + fileResponseFailures.set(`${f.type}#${f.fullName}`, f.error); + } }); this.sortFileResponses(fileResponses); this.asRelativePaths(fileResponses); @@ -224,6 +226,8 @@ export class DeployResultFormatter extends ResultFormatter { this.ux.log(''); this.ux.styledHeader(chalk.red(`Component Failures [${failures.length}]`)); this.ux.table( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore failures.map((entry: FileResponseFailure) => ({ fullName: entry.fullName, problemType: entry.problemType, @@ -276,6 +280,8 @@ export class DeployResultFormatter extends ResultFormatter { chalk.red(`Test Failures [${asString(this.result.response.details.runTestResult?.numFailures)}]`) ); this.ux.table( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore tests.map((entry: Failures) => ({ name: entry.name, methodName: entry.methodName, diff --git a/src/formatters/mdapi/mdDeployResultFormatter.ts b/src/formatters/mdapi/mdDeployResultFormatter.ts index 96b33bba1..8984662ab 100644 --- a/src/formatters/mdapi/mdDeployResultFormatter.ts +++ b/src/formatters/mdapi/mdDeployResultFormatter.ts @@ -184,6 +184,8 @@ export class MdDeployResultFormatter extends ResultFormatter { this.ux.log(''); this.ux.styledHeader(chalk.red(`Test Failures [${this.result.response.details.runTestResult?.numFailures}]`)); this.ux.table( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore tests.map((test: Failures) => ({ name: test.name, methodName: test.methodName, @@ -214,7 +216,7 @@ export class MdDeployResultFormatter extends ResultFormatter { } ); } - maybePrintCodeCoverageTable(this.result.response.details?.runTestResult?.codeCoverage, this.ux); + maybePrintCodeCoverageTable(this.result.response.details?.runTestResult?.codeCoverage ?? [], this.ux); } protected verboseTestTime(): void { @@ -235,5 +237,5 @@ const mdResponseSorter = (i: DeployMessage, j: DeployMessage): number => { } return i.fileName > j.fileName ? 1 : -1; } - return i.componentType > j.componentType ? 1 : -1; + return i.componentType ?? '' > (j.componentType ?? '') ? 1 : -1; }; diff --git a/src/formatters/resultFormatter.ts b/src/formatters/resultFormatter.ts index d2e3787d4..6e0c0a174 100644 --- a/src/formatters/resultFormatter.ts +++ b/src/formatters/resultFormatter.ts @@ -56,6 +56,9 @@ export abstract class ResultFormatter { if (i.filePath === j.filePath) { return i.fullName > j.fullName ? 1 : -1; } + // filepaths won't be undefined here + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore return i.filePath > j.filePath ? 1 : -1; } return i.type > j.type ? 1 : -1; @@ -107,18 +110,17 @@ export abstract class ResultFormatter { ) { this.ux.log( `Code Coverage formats, [${this.options.coverageOptions.reportFormats.join(',')}], written to ${path.join( - this.options.resultsDir, + this.options.resultsDir ?? '', 'coverage' )}` ); } if (this.options.testsRan && this.options.junitTestResults) { - this.ux.log(`Junit results written to ${path.join(this.options.resultsDir, 'junit', 'junit.xml')}`); + this.ux.log(`Junit results written to ${path.join(this.options.resultsDir ?? '', 'junit', 'junit.xml')}`); } } - protected getCoverageFileInfo(): CoverageResultsFileInfo { - /* eslint-disable @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment */ + protected getCoverageFileInfo(): CoverageResultsFileInfo | undefined { const formatters = this.options.coverageOptions?.reportFormats; if (!formatters) { return undefined; @@ -128,8 +130,14 @@ export abstract class ResultFormatter { formatters.map((formatter) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment const selectedReportOptions = reportOptions[formatter]; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore const filename = selectedReportOptions['file'] as string; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore const subdir = selectedReportOptions['subdir'] as string; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore return [formatter, path.join(...[this.options.resultsDir, subdir, filename].filter((part) => part))]; }) ) as CoverageResultsFileInfo; diff --git a/src/formatters/source/pushResultFormatter.ts b/src/formatters/source/pushResultFormatter.ts index 14f0c9d0d..ca8291522 100644 --- a/src/formatters/source/pushResultFormatter.ts +++ b/src/formatters/source/pushResultFormatter.ts @@ -13,6 +13,7 @@ import { ComponentStatus, DeployResult, FileResponse, + FileResponseFailure, MetadataResolver, SourceComponent, VirtualTreeContainer, @@ -139,23 +140,26 @@ export class PushResultFormatter extends ResultFormatter { // there may be deletes not represented in the file responses (if bundle type) const resolver = new MetadataResolver(undefined, VirtualTreeContainer.fromFilePaths(this.deletes)); - return this.deletes - .map((filePath) => { - const cmp = this.resolveComponentsOrWarn(filePath, resolver)[0]; - if ( - cmp.type.strategies?.adapter === 'bundle' && - contentFilePathFromDeployedBundles.includes(pathResolve(cmp.content ?? '')) - ) { - return { - state: ComponentStatus.Deleted, - fullName: cmp.fullName, - type: cmp.type.name, - filePath, - } as FileResponse; - } - }) - .filter((fileResponse) => fileResponse) - .concat(withoutUnchanged); + return ( + this.deletes + .map((filePath) => { + const cmp = this.resolveComponentsOrWarn(filePath, resolver)[0]; + if ( + cmp.type.strategies?.adapter === 'bundle' && + contentFilePathFromDeployedBundles.includes(pathResolve(cmp.content ?? '')) + ) { + return { + state: ComponentStatus.Deleted, + fullName: cmp.fullName, + type: cmp.type.name, + filePath, + } as FileResponse; + } + }) + .filter((fileResponse) => fileResponse) + // we can be sure there's no undefined responses because of the filter above + .concat(withoutUnchanged) as FileResponse[] + ); } protected displaySuccesses(): void { @@ -207,16 +211,17 @@ export class PushResultFormatter extends ResultFormatter { } protected displayFailures(): void { - const failures = []; + const failures: FileResponseFailure[] = []; const fileResponseFailures: Map = new Map(); if (this.fileResponses?.length) { - const fileResponses: FileResponse[] = []; + const fileResponses: FileResponseFailure[] = []; this.fileResponses .filter((f) => f.state === 'Failed') - .map((f: FileResponse & { error: string }) => { - fileResponses.push(f); - fileResponseFailures.set(`${f.type}#${f.fullName}`, f.error); + .map((f) => { + // we've filtered all of the file responses to failed errors with the state filter above + fileResponses.push(f as FileResponseFailure); + fileResponseFailures.set(`${f.type}#${f.fullName}`, (f as FileResponseFailure).error); }); this.sortFileResponses(fileResponses); this.asRelativePaths(fileResponses); @@ -229,7 +234,9 @@ export class PushResultFormatter extends ResultFormatter { deployMessages.map((deployMessage) => { if (!fileResponseFailures.has(`${deployMessage.componentType}#${deployMessage.fullName}`)) { // duplicate the problem message to the error property for displaying in the table - failures.push(Object.assign(deployMessage, { error: deployMessage.problem })); + failures.push( + Object.assign(deployMessage, { error: deployMessage.problem }) as unknown as FileResponseFailure + ); } }); } @@ -238,6 +245,8 @@ export class PushResultFormatter extends ResultFormatter { } this.ux.log(''); this.ux.styledHeader(chalk.red(`Component Failures [${failures.length}]`)); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore this.ux.table(failures, { problemType: { header: 'Type' }, fullName: { header: 'Name' }, diff --git a/src/formatters/source/statusFormatter.ts b/src/formatters/source/statusFormatter.ts index b5c391322..b59af85f1 100644 --- a/src/formatters/source/statusFormatter.ts +++ b/src/formatters/source/statusFormatter.ts @@ -15,8 +15,10 @@ Messages.importMessagesDirectory(dirname(fileURLToPath(import.meta.url))); const messages = Messages.loadMessages('@salesforce/plugin-source', 'status'); type StatusActualState = 'Deleted' | 'Add' | 'Changed' | 'Unchanged'; -type StatusOrigin = 'Local' | 'Remote'; -type StatusStateString = `${StatusOrigin} ${StatusActualState}` | `${StatusOrigin} ${StatusActualState} (Conflict)`; +export type StatusOrigin = 'Local' | 'Remote'; +export type StatusStateString = + | `${StatusOrigin} ${StatusActualState}` + | `${StatusOrigin} ${StatusActualState} (Conflict)`; export type StatusResult = { state: StatusStateString; fullName: string; diff --git a/src/hooks/diagnostics.ts b/src/hooks/diagnostics.ts index 344422f15..731c4c588 100644 --- a/src/hooks/diagnostics.ts +++ b/src/hooks/diagnostics.ts @@ -48,7 +48,7 @@ const apiVersionTest = async (doctor: SfDoctor): Promise => { // check org-api-version from ConfigAggregator const aggregator = await ConfigAggregator.create(); - const apiVersion = aggregator.getPropertyValue(OrgConfigProperties.ORG_API_VERSION); + const apiVersion = aggregator.getPropertyValue(OrgConfigProperties.ORG_API_VERSION) as string; const sourceApiVersion = await getSourceApiVersion(); @@ -119,10 +119,11 @@ const getSourceApiVersion = async (): Promise => { const errMsg = (error as Error).message; getLogger().debug(`Cannot determine sourceApiVersion due to: ${errMsg}`); } + return ''; }; // check max API version for default orgs -const getMaxApiVersion = async (aggregator: ConfigAggregator, aliasOrUsername: string): Promise => { +const getMaxApiVersion = async (aggregator: ConfigAggregator, aliasOrUsername: string): Promise => { try { const org = await Org.create({ aliasOrUsername, aggregator }); return await org.retrieveMaxApiVersion(); @@ -140,5 +141,5 @@ const getMaxApiVersion = async (aggregator: ConfigAggregator, aliasOrUsername: s // Comparing 55.0 with 56.0 would return true. const diff = (version1: string, version2: string): boolean => { getLogger().debug(`Comparing API versions: [${version1},${version2}]`); - return version1?.length && version2?.length && version1 !== version2; + return (version1?.length && version2?.length && version1 !== version2) as boolean; }; diff --git a/src/index.ts b/src/index.ts index c58111070..af79a8cd4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,4 +5,4 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ -export = {}; +export default {}; diff --git a/src/promiseQueue.ts b/src/promiseQueue.ts index b03888025..a1c5b659d 100644 --- a/src/promiseQueue.ts +++ b/src/promiseQueue.ts @@ -16,7 +16,7 @@ import { ensureArray } from '@salesforce/kit'; */ export async function promisesQueue( sourceQueue: T[], - producer: (T) => Promise, + producer: (arg0: T) => Promise, concurrency: number, queueResults = false ): Promise { diff --git a/src/sourceCommand.ts b/src/sourceCommand.ts index e23670613..6c36862cf 100644 --- a/src/sourceCommand.ts +++ b/src/sourceCommand.ts @@ -51,7 +51,7 @@ export abstract class SourceCommand extends SfCommand { protected async getSourceApiVersion(): Promise> { const projectConfig = await this.project.resolveProjectConfig(); - return getString(projectConfig, 'sourceApiVersion'); + return getString(projectConfig, 'sourceApiVersion') as string; } /** diff --git a/src/stash.ts b/src/stash.ts index e485eb9b6..53291e4ef 100644 --- a/src/stash.ts +++ b/src/stash.ts @@ -86,8 +86,8 @@ export class Stash { * @param commandId The oclif Command.id. E.g., `this.id` * @returns the `StashKey` to use for `Stash.get()` and `Stash.set()` */ - public static getKey(commandId: keyof typeof Stash.keyMap): StashKey { - const key = Stash.keyMap[commandId] as StashKey; + public static getKey(commandId: string): StashKey { + const key = Stash.keyMap[commandId as keyof typeof Stash.keyMap] as StashKey; if (!key) { const messages = Messages.loadMessages('@salesforce/plugin-source', 'stash'); throw new SfError(messages.getMessage('InvalidStashKey', [commandId]), 'InvalidStashKey'); diff --git a/src/trackingFunctions.ts b/src/trackingFunctions.ts index acbfa4b6a..0e9747b99 100644 --- a/src/trackingFunctions.ts +++ b/src/trackingFunctions.ts @@ -56,7 +56,7 @@ export const filterConflictsByComponentSet = async ({ ux: Ux; }): Promise => { const filteredConflicts = (await tracking.getConflicts()).filter((cr) => - components.has({ fullName: cr.name, type: cr.type }) + components.has({ fullName: cr.name as string, type: cr.type as string }) ); processConflicts(filteredConflicts, ux, messages.getMessage('conflictMsg')); return filteredConflicts; @@ -101,10 +101,10 @@ export const updateTracking = async ({ tracking, result, ux, fileResponses }: Tr tracking.updateLocalTracking({ files: successes .filter((fileResponse) => fileResponse.state !== ComponentStatus.Deleted) - .map((fileResponse) => fileResponse.filePath), + .map((fileResponse) => fileResponse.filePath as string), deletedFiles: successes .filter((fileResponse) => fileResponse.state === ComponentStatus.Deleted) - .map((fileResponse) => fileResponse.filePath), + .map((fileResponse) => fileResponse.filePath as string), }), tracking.updateRemoteTracking( successes.map(({ state, fullName, type, filePath }) => ({ state, fullName, type, filePath })), @@ -141,8 +141,8 @@ const processConflicts = (conflicts: ChangeResult[], ux: Ux, message: string): v c.filenames?.forEach((f) => { conflictMap.set(`${c.name}#${c.type}#${f}`, { state: 'Conflict', - fullName: c.name, - type: c.type, + fullName: c.name as string, + type: c.type as string, filePath: path.resolve(f), }); }); diff --git a/src/types.ts b/src/types.ts index a852fac4e..5909967f0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,7 +11,7 @@ export interface FsError extends Error { export interface EnsureFsFlagOptions { flagName: string; - path: string; + path?: string; type: 'dir' | 'file' | 'any'; throwOnENOENT?: boolean; } diff --git a/test/commands/source/deployResponses.ts b/test/commands/source/deployResponses.ts index 85ce53546..e35b7b52c 100644 --- a/test/commands/source/deployResponses.ts +++ b/test/commands/source/deployResponses.ts @@ -10,6 +10,7 @@ import { DeployMessage, MetadataApiDeployStatus, RequestStatus, + RunTestResult, } from '@salesforce/source-deploy-retrieve'; import { cloneJson, ensureArray } from '@salesforce/kit'; @@ -122,9 +123,10 @@ export const getDeployResponse = ( delete response.details.componentFailures.id; response.details.componentFailures.problemType = 'Error'; response.details.componentFailures.problem = 'This component has some problems'; - response.details.runTestResult.numFailures = '1'; response.runTestsEnabled = true; response.numberTestErrors = 1; + response.details.runTestResult = {} as RunTestResult; + response.details.runTestResult.numFailures = '1'; response.details.runTestResult.successes = []; response.details.runTestResult.failures = [ { @@ -164,6 +166,7 @@ export const getDeployResponse = ( delete response.details.componentFailures.id; response.details.componentFailures.problemType = 'Error'; response.details.componentFailures.problem = 'This component has some problems'; + response.details.runTestResult = {} as RunTestResult; response.details.runTestResult.numFailures = '0'; response.runTestsEnabled = true; response.numberTestErrors = 0; @@ -201,6 +204,7 @@ export const getDeployResponse = ( delete response.details.componentFailures.id; response.details.componentFailures.problemType = 'Error'; response.details.componentFailures.problem = 'This component has some problems'; + response.details.runTestResult = {} as RunTestResult; response.details.runTestResult.numFailures = '2'; response.runTestsEnabled = true; response.numberTestErrors = 2; diff --git a/test/nuts/digitalExperienceBundle/constants.ts b/test/nuts/digitalExperienceBundle/constants.ts index 50fc7ef97..57afffb8f 100644 --- a/test/nuts/digitalExperienceBundle/constants.ts +++ b/test/nuts/digitalExperienceBundle/constants.ts @@ -15,7 +15,8 @@ export const DEB_NUTS_PATH = join(process.cwd(), 'test', 'nuts', 'digitalExperie export const TYPES = { DEB: registry.types.digitalexperiencebundle, - DE: registry.types.digitalexperiencebundle.children?.types.digitalexperience, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + DE: registry.types.digitalexperiencebundle.children!.types.digitalexperience, DEC: registry.types.digitalexperienceconfig, NETWORK: registry.types.network, CUSTOM_SITE: registry.types.customsite, diff --git a/test/nuts/digitalExperienceBundle/deb.manifest.nut.ts b/test/nuts/digitalExperienceBundle/deb.manifest.nut.ts index 0b705a683..2034c2e8b 100644 --- a/test/nuts/digitalExperienceBundle/deb.manifest.nut.ts +++ b/test/nuts/digitalExperienceBundle/deb.manifest.nut.ts @@ -83,7 +83,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertAllDEBAndTheirDECounts(deployedSource); }); @@ -94,7 +94,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertDECountsOfAllDEB(deployedSource); }); @@ -107,7 +107,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertDECountOfSingleDEB(deployedSource); }); @@ -118,7 +118,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertSingleDEBAndItsDECounts(deployedSource, FULL_NAMES.DEB_A); }); @@ -129,7 +129,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertViewHome(deployedSource, 'A'); }); @@ -142,7 +142,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertAllDEBAndTheirDECounts(deployedSource); }); @@ -153,7 +153,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertAllDEBAndTheirDECounts(deployedSource); }); @@ -172,7 +172,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertAllDEBAndTheirDECounts(inboundFiles); }); @@ -183,7 +183,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertDECountsOfAllDEB(inboundFiles); }); @@ -196,7 +196,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertDECountOfSingleDEB(inboundFiles); }); @@ -207,7 +207,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertSingleDEBAndItsDECounts(inboundFiles, FULL_NAMES.DEB_A); }); @@ -218,7 +218,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertViewHome(inboundFiles, 'A'); }); @@ -231,7 +231,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertAllDEBAndTheirDECounts(inboundFiles); }); @@ -242,7 +242,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertAllDEBAndTheirDECounts(inboundFiles); }); @@ -258,7 +258,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertViewHomeFRVariantDelete(deployedSource, 'A', session.project.dir); }); @@ -273,7 +273,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertDocumentDetailPageA(deployedSource); }); @@ -284,7 +284,7 @@ describe('deb -- manifest option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertDocumentDetailPageA(deployedSource); await assertDocumentDetailPageADelete(session, false); diff --git a/test/nuts/digitalExperienceBundle/deb.metadata.nut.ts b/test/nuts/digitalExperienceBundle/deb.metadata.nut.ts index 39aa7ebaf..5177339d3 100644 --- a/test/nuts/digitalExperienceBundle/deb.metadata.nut.ts +++ b/test/nuts/digitalExperienceBundle/deb.metadata.nut.ts @@ -50,7 +50,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertAllDEBAndTheirDECounts(deployedSource, 6); }); @@ -62,7 +62,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertAllDEBAndTheirDECounts(deployedSource); }); @@ -73,7 +73,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertDECountsOfAllDEB(deployedSource); }); @@ -86,7 +86,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertDECountOfSingleDEB(deployedSource); }); @@ -97,7 +97,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertSingleDEBAndItsDECounts(deployedSource, FULL_NAMES.DEB_B); }); @@ -108,7 +108,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertViewHome(deployedSource, 'B'); }); @@ -127,7 +127,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertAllDEBAndTheirDECounts(inboundFiles); }); @@ -138,7 +138,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertDECountsOfAllDEB(inboundFiles); }); @@ -151,7 +151,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertDECountOfSingleDEB(inboundFiles); }); @@ -162,7 +162,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertSingleDEBAndItsDECounts(inboundFiles, FULL_NAMES.DEB_B); }); @@ -173,7 +173,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertViewHome(inboundFiles, 'B'); }); @@ -189,7 +189,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertViewHomeFRVariantDelete(deployedSource, 'B', session.project.dir); }); @@ -204,7 +204,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertDocumentDetailPageA(deployedSource); }); @@ -215,7 +215,7 @@ describe('deb -- metadata option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deletedSource; + ).jsonOutput?.result.deletedSource; assertDocumentDetailPageA(deletedSource); await assertDocumentDetailPageADelete(session, true); diff --git a/test/nuts/digitalExperienceBundle/deb.sourcepath.nut.ts b/test/nuts/digitalExperienceBundle/deb.sourcepath.nut.ts index 7cb00953a..e9cfc76c4 100644 --- a/test/nuts/digitalExperienceBundle/deb.sourcepath.nut.ts +++ b/test/nuts/digitalExperienceBundle/deb.sourcepath.nut.ts @@ -53,7 +53,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertAllDEBAndTheirDECounts(deployedSource, 6); }); @@ -65,7 +65,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertAllDEBAndTheirDECounts(deployedSource); }); @@ -78,7 +78,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertSingleDEBAndItsDECounts(deployedSource, FULL_NAMES.DEB_A); }); @@ -89,7 +89,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertViewHome(deployedSource, 'A'); }); @@ -104,7 +104,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertAllDEBAndTheirDECounts(inboundFiles); }); @@ -117,7 +117,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertSingleDEBAndItsDECounts(inboundFiles, FULL_NAMES.DEB_A); }); @@ -128,7 +128,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; assertViewHome(inboundFiles, 'A'); }); @@ -144,7 +144,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertViewHomeFRVariantDelete(deployedSource, 'A', session.project.dir); }); @@ -159,7 +159,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deployedSource; + ).jsonOutput?.result.deployedSource; assertDocumentDetailPageA(deployedSource); }); @@ -170,7 +170,7 @@ describe('deb -- sourcepath option', () => { { ensureExitCode: 0, } - ).jsonOutput.result.deletedSource; + ).jsonOutput?.result.deletedSource; assertDocumentDetailPageA(deletedSource); await assertDocumentDetailPageADelete(session, true); diff --git a/test/nuts/digitalExperienceBundle/deb.tracking.nut.ts b/test/nuts/digitalExperienceBundle/deb.tracking.nut.ts index 34a43487f..f0f09144e 100644 --- a/test/nuts/digitalExperienceBundle/deb.tracking.nut.ts +++ b/test/nuts/digitalExperienceBundle/deb.tracking.nut.ts @@ -41,7 +41,7 @@ describe('deb -- tracking/push/pull', () => { it('should push the whole project', () => { const pushedSource = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; assertAllDEBAndTheirDECounts(pushedSource, 10); }); @@ -61,7 +61,7 @@ describe('deb -- tracking/push/pull', () => { it('should push local change in deb_b', () => { const pushedSource = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; assertDEBMeta(pushedSource, 'B'); assertNoLocalChanges(); @@ -85,7 +85,7 @@ describe('deb -- tracking/push/pull', () => { it('should push local change in de_view_home_content of deb_b', () => { const pushedSource = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; assertViewHome(pushedSource, 'B'); assertNoLocalChanges(); @@ -108,7 +108,7 @@ describe('deb -- tracking/push/pull', () => { it('should push local change in de_view_home_meta of deb_b', () => { const pushedSource = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; assertViewHome(pushedSource, 'B'); assertNoLocalChanges(); @@ -123,7 +123,7 @@ describe('deb -- tracking/push/pull', () => { const pulledSource = execCmd('force:source:pull --forceoverwrite --json', { ensureExitCode: 0, - }).jsonOutput.result.pulledSource; + }).jsonOutput?.result.pulledSource; assertAllDEBAndTheirDECounts(pulledSource, 0, false); }); @@ -167,7 +167,7 @@ describe('deb -- tracking/push/pull', () => { it('should push locally added page (view and route de components) in deb_a', () => { const pushedSource = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; assertDocumentDetailPageA(pushedSource); assertNoLocalChanges(); @@ -186,7 +186,7 @@ describe('deb -- tracking/push/pull', () => { it('should push local delete change in deb_a [locally deleted page (view and route de components)]', async () => { const pushedSource = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; assertDocumentDetailPageA(pushedSource); assertNoLocalChanges(); diff --git a/test/nuts/digitalExperienceBundle/helper.ts b/test/nuts/digitalExperienceBundle/helper.ts index 56e43aa54..173afe825 100644 --- a/test/nuts/digitalExperienceBundle/helper.ts +++ b/test/nuts/digitalExperienceBundle/helper.ts @@ -42,7 +42,7 @@ export function assertSingleDEBAndItsDECounts(resp: CustomFileResponses, debFull expect(resp).to.have.length(52); expect( resp.reduce( - (acc: [number, number], curr: FileResponse) => { + (acc: [number, number], curr) => { if (curr.type === TYPES.DE?.name && curr.fullName.includes(debFullName)) acc[0]++; if (curr.type === TYPES.DEB.name && curr.fullName === debFullName) acc[1]++; return acc; @@ -53,11 +53,11 @@ export function assertSingleDEBAndItsDECounts(resp: CustomFileResponses, debFull ).to.deep.equal([51, 1]); } -export function assertDECountsOfAllDEB(resp: CustomFileResponses) { +export function assertDECountsOfAllDEB(resp?: CustomFileResponses) { expect(resp).to.have.length(102); expect( - resp.reduce( - (acc: [number, number], curr: FileResponse) => { + resp?.reduce( + (acc: [number, number], curr) => { if (curr.type === TYPES.DE?.name && curr.fullName.includes(FULL_NAMES.DEB_A)) acc[0]++; if (curr.type === TYPES.DE?.name && curr.fullName.includes(FULL_NAMES.DEB_B)) acc[1]++; return acc; @@ -162,10 +162,12 @@ export function assertDocumentDetailPageA(resp: CustomFileResponses) { export async function assertDocumentDetailPageADelete(session: TestSession, assertDeleteInLocal: boolean) { expect( - await isNameObsolete(session.orgs.get('default').username, TYPES.DE?.name, FULL_NAMES.DE_VIEW_DOCUMENT_DETAIL_A) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await isNameObsolete(session.orgs.get('default')!.username!, TYPES.DE.name, FULL_NAMES.DE_VIEW_DOCUMENT_DETAIL_A) ).to.be.true; expect( - await isNameObsolete(session.orgs.get('default').username, TYPES.DE?.name, FULL_NAMES.DE_ROUTE_DOCUMENT_DETAIL_A) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await isNameObsolete(session.orgs.get('default')!.username!, TYPES.DE.name, FULL_NAMES.DE_ROUTE_DOCUMENT_DETAIL_A) ).to.be.true; if (assertDeleteInLocal) { @@ -182,7 +184,7 @@ export function assertViewHomeFRVariantDelete(resp: CustomFileResponses, deb: 'A { ensureExitCode: 0, } - ).jsonOutput.result.inboundFiles; + ).jsonOutput?.result.inboundFiles; expect(inboundFiles).to.have.length(2); expect(fs.existsSync(join(projectDir, DEBS[deb].DE.VIEW_HOME.FILES.FR_VARIANT.RELATIVE_PATH))).to.be.false; @@ -191,7 +193,7 @@ export function assertViewHomeFRVariantDelete(resp: CustomFileResponses, deb: 'A export function assertNoLocalChanges() { const statusResult = execCmd('force:source:status --local --json', { ensureExitCode: 0, - }).jsonOutput.result; + }).jsonOutput?.result; expect(statusResult).to.deep.equal([]); } diff --git a/test/nuts/trackingCommands/basics.nut.ts b/test/nuts/trackingCommands/basics.nut.ts index 44445f383..c53c5e7b1 100644 --- a/test/nuts/trackingCommands/basics.nut.ts +++ b/test/nuts/trackingCommands/basics.nut.ts @@ -57,7 +57,7 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => { it('pushes the initial metadata to the org', () => { const resp = execCmd('force:source:push --json'); expect(resp.jsonOutput?.status, JSON.stringify(resp)).to.equal(0); - const pushedSource = resp.jsonOutput.result.pushedSource; + const pushedSource = resp.jsonOutput?.result.pushedSource; expect(pushedSource).to.be.an.instanceof(Array); expect(pushedSource, JSON.stringify(pushedSource)).to.have.lengthOf(itemsInEBikesPush); expect( @@ -139,7 +139,7 @@ describe('end-to-end-test for tracking with an org (single packageDir)', () => { it('pushes the local delete to the org', () => { const result = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; expect(result, JSON.stringify(result)).to.be.an.instanceof(Array).with.length(2); }); it('sees no local changes', () => { diff --git a/test/nuts/trackingCommands/conflicts.nut.ts b/test/nuts/trackingCommands/conflicts.nut.ts index 75b4d2845..e742d30c5 100644 --- a/test/nuts/trackingCommands/conflicts.nut.ts +++ b/test/nuts/trackingCommands/conflicts.nut.ts @@ -45,7 +45,7 @@ describe('conflict detection and resolution', () => { it('pushes to initiate the remote', () => { const pushResult = execCmd('force:source:push --json'); expect(pushResult.jsonOutput?.status, JSON.stringify(pushResult)).equals(0); - const pushedSource = pushResult.jsonOutput.result.pushedSource; + const pushedSource = pushResult.jsonOutput?.result.pushedSource; expect(pushedSource, JSON.stringify(pushedSource)).to.have.lengthOf(itemsInEBikesPush); expect( pushedSource.every((r) => r.state !== ComponentStatus.Failed), @@ -97,7 +97,7 @@ describe('conflict detection and resolution', () => { it('can see the conflict in status', () => { const result = execCmd('force:source:status --json', { ensureExitCode: 0, - }).jsonOutput.result.filter((app) => app.type === 'CustomApplication'); + }).jsonOutput?.result.filter((app) => app.type === 'CustomApplication'); // json is not sorted. This relies on the implementation of getConflicts() expect(result).to.deep.equal([ { diff --git a/test/nuts/trackingCommands/forceIgnore.nut.ts b/test/nuts/trackingCommands/forceIgnore.nut.ts index 91a761b4c..5f5e8b91a 100644 --- a/test/nuts/trackingCommands/forceIgnore.nut.ts +++ b/test/nuts/trackingCommands/forceIgnore.nut.ts @@ -65,7 +65,7 @@ describe('forceignore changes', () => { // nothing should push const output = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; expect(output).to.deep.equal([]); }); @@ -99,7 +99,7 @@ describe('forceignore changes', () => { // pushes with no results const ignoredOutput = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; // nothing should have been pushed expect(ignoredOutput).to.deep.equal([]); }); @@ -111,7 +111,7 @@ describe('forceignore changes', () => { // verify file pushed in results const unIgnoredOutput = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; // all 4 files should have been pushed expect(unIgnoredOutput).to.have.length(4); diff --git a/test/nuts/trackingCommands/lwc.nut.ts b/test/nuts/trackingCommands/lwc.nut.ts index 792acaeb1..7ec449230 100644 --- a/test/nuts/trackingCommands/lwc.nut.ts +++ b/test/nuts/trackingCommands/lwc.nut.ts @@ -61,7 +61,7 @@ describe('lwc', () => { it('pushes lwc css change', () => { const result = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; // we get a result for each bundle member, even though only one changed expect(result.filter((r) => r.fullName === 'heroDetails')).to.have.length(4); }); @@ -70,7 +70,7 @@ describe('lwc', () => { const result = execCmd('force:source:status --json', { ensureExitCode: 0, }) - .jsonOutput.result.filter((r) => r.origin === 'Local') + .jsonOutput?.result.filter((r) => r.origin === 'Local') .filter(filterIgnored); expect(result).to.have.length(0); }); @@ -80,7 +80,7 @@ describe('lwc', () => { const result = execCmd('force:source:status --json', { ensureExitCode: 0, }) - .jsonOutput.result.filter(filterIgnored) + .jsonOutput?.result.filter(filterIgnored) .find((r) => r.filePath === cssPathRelative); expect(result).to.deep.equal({ fullName: 'heroDetails', @@ -97,7 +97,7 @@ describe('lwc', () => { it('pushes lwc subcomponent delete', () => { const result = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; const bundleMembers = result.filter((r) => r.fullName === 'heroDetails'); expect(bundleMembers).to.have.length(4); expect(bundleMembers.filter((r) => r.state === 'Deleted')).to.have.length(1); @@ -108,7 +108,7 @@ describe('lwc', () => { const result = execCmd('force:source:status --json', { ensureExitCode: 0, }) - .jsonOutput.result.filter((r) => r.origin === 'Local') + .jsonOutput?.result.filter((r) => r.origin === 'Local') .filter(filterIgnored); expect(result).to.have.length(0); }); @@ -128,7 +128,7 @@ describe('lwc', () => { ); const result = execCmd('force:source:status --json', { ensureExitCode: 0, - }).jsonOutput.result.filter((r) => r.origin === 'Local'); + }).jsonOutput?.result.filter((r) => r.origin === 'Local'); expect(result.filter(filterIgnored)).to.have.length(4); expect(result.filter(filterIgnored).filter((r) => r.actualState === 'Deleted')).to.have.length(3); expect(result.filter(filterIgnored).filter((r) => r.actualState === 'Changed')).to.have.length(1); @@ -137,7 +137,7 @@ describe('lwc', () => { it('push deletes the LWC remotely', () => { const result = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; // there'll also be changes for the changed Hero component html, but we've already tested changing a bundle member const bundleMembers = result.filter((r) => r.fullName === 'heroDetails'); expect(bundleMembers).to.have.length(3); @@ -151,7 +151,7 @@ describe('lwc', () => { const result = execCmd('force:source:status --json', { ensureExitCode: 0, }) - .jsonOutput.result.filter((r) => r.origin === 'Local') + .jsonOutput?.result.filter((r) => r.origin === 'Local') .filter(filterIgnored); expect(result).to.have.length(0); }); diff --git a/test/nuts/trackingCommands/mpd-non-sequential.nut.ts b/test/nuts/trackingCommands/mpd-non-sequential.nut.ts index def120b64..6c0ff8c46 100644 --- a/test/nuts/trackingCommands/mpd-non-sequential.nut.ts +++ b/test/nuts/trackingCommands/mpd-non-sequential.nut.ts @@ -45,7 +45,7 @@ describe('multiple pkgDirectories pushed as one deploy', () => { it('pushes using MPD', () => { const result = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; expect(result).to.be.an.instanceof(Array); // the fields should be populated expect(result.every((row) => row.type && row.fullName)).to.equal(true); diff --git a/test/nuts/trackingCommands/mpd-sequential.nut.ts b/test/nuts/trackingCommands/mpd-sequential.nut.ts index 65ce66d6a..41504ff9c 100644 --- a/test/nuts/trackingCommands/mpd-sequential.nut.ts +++ b/test/nuts/trackingCommands/mpd-sequential.nut.ts @@ -58,7 +58,7 @@ describe('multiple pkgDirs deployed sequentially', () => { it('pushes using MPD', () => { const result = execCmd('force:source:push --json', { ensureExitCode: 0, - }).jsonOutput.result.pushedSource; + }).jsonOutput?.result.pushedSource; expect(result).to.be.an.instanceof(Array); // the fields should be populated expect(result.every((row) => row.type && row.fullName)).to.equal(true); diff --git a/test/nuts/trackingCommands/remoteChanges.nut.ts b/test/nuts/trackingCommands/remoteChanges.nut.ts index 0cf52ddb3..97838e806 100644 --- a/test/nuts/trackingCommands/remoteChanges.nut.ts +++ b/test/nuts/trackingCommands/remoteChanges.nut.ts @@ -52,7 +52,7 @@ describe('remote changes', () => { it('pushes to initiate the remote', () => { const pushResult = execCmd('force:source:push --json'); expect(pushResult.jsonOutput?.status, JSON.stringify(pushResult)).equals(0); - const pushedSource = pushResult.jsonOutput.result.pushedSource; + const pushedSource = pushResult.jsonOutput?.result.pushedSource; expect(pushedSource, JSON.stringify(pushedSource)).to.have.lengthOf(itemsInEBikesPush); expect( pushedSource.every((r) => r.state !== ComponentStatus.Failed), diff --git a/test/nuts/translation.nut.ts b/test/nuts/translation.nut.ts index 6f675a2b9..41e3d55c8 100644 --- a/test/nuts/translation.nut.ts +++ b/test/nuts/translation.nut.ts @@ -141,7 +141,7 @@ describe('translations', () => { ensureExitCode: 0, } ); - expect(result.jsonOutput.result.deployedSource.some((d) => d.type === 'CustomObjectTranslation')).to.be.true; + expect(result.jsonOutput?.result.deployedSource.some((d) => d.type === 'CustomObjectTranslation')).to.be.true; }); it('can deploy COT', () => {