diff --git a/src/commands/project/delete/source.ts b/src/commands/project/delete/source.ts index cce7691b..9dcb0d1c 100644 --- a/src/commands/project/delete/source.ts +++ b/src/commands/project/delete/source.ts @@ -402,7 +402,7 @@ export class Source extends SfCommand { // for custom labels, print each custom label to be deleted, not the whole file isNonDecomposedCustomLabelsOrCustomLabel(c) ? [`${c.type.name}:${c.fullName}`] - : [c.xml as string, ...c.walkContent()] ?? [] + : [c.xml, ...c.walkContent()] ?? [] ) .concat(this.mixedDeployDelete.delete.map((fr) => `${fr.fullName} (${fr.filePath})`)); diff --git a/src/utils/previewOutput.ts b/src/utils/previewOutput.ts index 07f2375e..3b4ba526 100644 --- a/src/utils/previewOutput.ts +++ b/src/utils/previewOutput.ts @@ -66,7 +66,7 @@ const resolvePaths = ( return resolver.getComponentsFromPath(filename); } catch (e) { // resolver will do logging before throw we don't do it here - return undefined; + return []; } }) .filter(isSourceComponentWithXml) diff --git a/src/utils/types.ts b/src/utils/types.ts index 1f7ce6c5..6f37978f 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -14,6 +14,7 @@ import { SourceComponent, FileResponseFailure, FileResponseSuccess, + ComponentLike, } from '@salesforce/source-deploy-retrieve'; import { isObject } from '@salesforce/ts-types'; import { DefaultReportOptions } from '@salesforce/apex-node'; @@ -89,7 +90,7 @@ export type Formatter = { }; /** validates source component with fullname, type, and xml props */ -export const isSourceComponent = (sc: unknown): sc is SourceComponent => +export const isSourceComponent = (sc: ComponentLike): sc is SourceComponent => isObject(sc) && 'type' in sc && typeof sc.type === 'object' && @@ -97,10 +98,11 @@ export const isSourceComponent = (sc: unknown): sc is SourceComponent => 'name' in sc.type && typeof sc.type.name === 'string' && 'fullName' in sc && + 'walkContent' in sc && // (typeof sc.fullName === 'string' || typeof sc.fullName === 'function'); typeof sc.fullName === 'string'; -export const isSourceComponentWithXml = (sc: unknown): sc is SourceComponent & { xml: string } => +export const isSourceComponentWithXml = (sc: ComponentLike): sc is SourceComponent & { xml: string } => isSourceComponent(sc) && 'xml' in sc && typeof sc.xml === 'string'; export const isSdrFailure = (fileResponse: FileResponse): fileResponse is FileResponseFailure => @@ -111,3 +113,5 @@ export const isSdrSuccess = (fileResponse: FileResponse): fileResponse is FileRe export const isFileResponseDeleted = (fileResponse: FileResponseSuccess): boolean => fileResponse.state === ComponentStatus.Deleted; + +export const isDefined = (value?: T): value is T => value !== undefined; diff --git a/test/utils/types.test.ts b/test/utils/types.test.ts index 94e62c26..40e17f6e 100644 --- a/test/utils/types.test.ts +++ b/test/utils/types.test.ts @@ -16,9 +16,6 @@ const type = reg.getTypeByName('ApexClass'); describe('isSourceComponent (type guard)', () => { describe('good', () => { - it('full, correct definition', () => { - expect({ fullName: 'foo', type, xml: 'fooXml', content: 'fooContent' }).to.satisfy(isSourceComponent); - }); it('SC constructed with xml', () => { expect(new SourceComponent({ name: 'foo', type, xml: 'classes/foo.cls' })).to.satisfy(isSourceComponent); }); @@ -45,9 +42,6 @@ describe('isSourceComponent (type guard)', () => { describe('isSourceComponentWithXml (type guard)', () => { describe('good', () => { - it('full, correct definition', () => { - expect({ fullName: 'foo', type, xml: 'fooXml', content: 'fooContent' }).to.satisfy(isSourceComponentWithXml); - }); it('SC constructed with xml', () => { expect(new SourceComponent({ name: 'foo', type, xml: 'classes/foo.cls' })).to.satisfy(isSourceComponentWithXml); });