diff --git a/package.json b/package.json index e70369ac3..9036608f7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "@oclif/config": "^1.18.2", "@salesforce/command": "^4.2.2", "@salesforce/core": "^2.35.0", - "@salesforce/source-deploy-retrieve": "^5.9.9", + "@salesforce/source-deploy-retrieve": "^5.12.2", "@salesforce/source-tracking": "^1.1.1", "chalk": "^4.1.2", "cli-ux": "^5.6.3", diff --git a/src/commands/force/mdapi/beta/convert.ts b/src/commands/force/mdapi/beta/convert.ts index f001f1351..98c7b3815 100644 --- a/src/commands/force/mdapi/beta/convert.ts +++ b/src/commands/force/mdapi/beta/convert.ts @@ -8,11 +8,10 @@ import * as os from 'os'; import { flags, FlagsConfig } from '@salesforce/command'; import { Messages } from '@salesforce/core'; -import { MetadataConverter, ConvertResult } from '@salesforce/source-deploy-retrieve'; +import { ComponentSetBuilder, ConvertResult, MetadataConverter } from '@salesforce/source-deploy-retrieve'; import { Optional } from '@salesforce/ts-types'; import { SourceCommand } from '../../../../sourceCommand'; -import { ConvertResultFormatter, ConvertCommandResult } from '../../../../formatters/mdapi/convertResultFormatter'; -import { ComponentSetBuilder } from '../../../../componentSetBuilder'; +import { ConvertCommandResult, ConvertResultFormatter } from '../../../../formatters/mdapi/convertResultFormatter'; Messages.importMessagesDirectory(__dirname); const messages = Messages.loadMessages('@salesforce/plugin-source', 'md.convert'); diff --git a/src/commands/force/mdapi/beta/retrieve.ts b/src/commands/force/mdapi/beta/retrieve.ts index ed508fb69..c002cf272 100644 --- a/src/commands/force/mdapi/beta/retrieve.ts +++ b/src/commands/force/mdapi/beta/retrieve.ts @@ -10,14 +10,18 @@ import { extname } from 'path'; import { flags, FlagsConfig } from '@salesforce/command'; import { Messages, SfdxError, SfdxProject } from '@salesforce/core'; import { Duration } from '@salesforce/kit'; -import { MetadataApiRetrieve, RequestStatus, RetrieveResult } from '@salesforce/source-deploy-retrieve'; +import { + ComponentSetBuilder, + MetadataApiRetrieve, + RequestStatus, + RetrieveResult, +} from '@salesforce/source-deploy-retrieve'; import { Optional } from '@salesforce/ts-types'; import { SourceCommand } from '../../../../sourceCommand'; import { Stash } from '../../../../stash'; -import { ComponentSetBuilder } from '../../../../componentSetBuilder'; import { - RetrieveCommandResult, RetrieveCommandAsyncResult, + RetrieveCommandResult, RetrieveResultFormatter, } from '../../../../formatters/mdapi/retrieveResultFormatter'; diff --git a/src/commands/force/source/convert.ts b/src/commands/force/source/convert.ts index a94b97fdf..e33f4f5e5 100644 --- a/src/commands/force/source/convert.ts +++ b/src/commands/force/source/convert.ts @@ -10,11 +10,10 @@ import { join, resolve } from 'path'; import * as fs from 'fs'; import { flags, FlagsConfig } from '@salesforce/command'; import { Messages } from '@salesforce/core'; -import { MetadataConverter, ConvertResult } from '@salesforce/source-deploy-retrieve'; +import { ComponentSetBuilder, ConvertResult, MetadataConverter } from '@salesforce/source-deploy-retrieve'; import { getString } from '@salesforce/ts-types'; import { SourceCommand } from '../../../sourceCommand'; -import { ConvertResultFormatter, ConvertCommandResult } from '../../../formatters/convertResultFormatter'; -import { ComponentSetBuilder } from '../../../componentSetBuilder'; +import { ConvertCommandResult, ConvertResultFormatter } from '../../../formatters/convertResultFormatter'; Messages.importMessagesDirectory(__dirname); const messages = Messages.loadMessages('@salesforce/plugin-source', 'convert'); diff --git a/src/commands/force/source/delete.ts b/src/commands/force/source/delete.ts index 204f7f195..e058f05e9 100644 --- a/src/commands/force/source/delete.ts +++ b/src/commands/force/source/delete.ts @@ -12,6 +12,7 @@ import { flags, FlagsConfig } from '@salesforce/command'; import { Messages } from '@salesforce/core'; import { ComponentSet, + ComponentSetBuilder, ComponentStatus, DestructiveChangesType, FileResponse, @@ -22,13 +23,13 @@ import { import { Duration, env } from '@salesforce/kit'; import { SourceTracking } from '@salesforce/source-tracking'; import { DeployCommand, TestLevel } from '../../../deployCommand'; -import { ComponentSetBuilder } from '../../../componentSetBuilder'; import { DeployCommandResult, DeployResultFormatter } from '../../../formatters/deployResultFormatter'; import { DeleteResultFormatter } from '../../../formatters/source/deleteResultFormatter'; import { ProgressFormatter } from '../../../formatters/progressFormatter'; import { DeployProgressBarFormatter } from '../../../formatters/deployProgressBarFormatter'; import { DeployProgressStatusFormatter } from '../../../formatters/deployProgressStatusFormatter'; -import { updateTracking, trackingSetup, filterConflictsByComponentSet } from '../../../trackingFunctions'; +import { filterConflictsByComponentSet, trackingSetup, updateTracking } from '../../../trackingFunctions'; + const fsPromises = fs.promises; Messages.importMessagesDirectory(__dirname); diff --git a/src/commands/force/source/deploy.ts b/src/commands/force/source/deploy.ts index 4a8418e69..f32524722 100644 --- a/src/commands/force/source/deploy.ts +++ b/src/commands/force/source/deploy.ts @@ -9,8 +9,8 @@ import { flags, FlagsConfig } from '@salesforce/command'; import { Messages } from '@salesforce/core'; import { Duration, env } from '@salesforce/kit'; import { SourceTracking } from '@salesforce/source-tracking'; +import { ComponentSetBuilder } from '@salesforce/source-deploy-retrieve'; import { DeployCommand, getVersionMessage, TestLevel } from '../../../deployCommand'; -import { ComponentSetBuilder } from '../../../componentSetBuilder'; import { DeployCommandResult, DeployResultFormatter } from '../../../formatters/deployResultFormatter'; import { DeployAsyncResultFormatter, @@ -19,7 +19,7 @@ import { import { ProgressFormatter } from '../../../formatters/progressFormatter'; import { DeployProgressBarFormatter } from '../../../formatters/deployProgressBarFormatter'; import { DeployProgressStatusFormatter } from '../../../formatters/deployProgressStatusFormatter'; -import { updateTracking, trackingSetup, filterConflictsByComponentSet } from '../../../trackingFunctions'; +import { filterConflictsByComponentSet, trackingSetup, updateTracking } from '../../../trackingFunctions'; Messages.importMessagesDirectory(__dirname); const messages = Messages.loadMessages('@salesforce/plugin-source', 'deploy'); diff --git a/src/commands/force/source/deploy/report.ts b/src/commands/force/source/deploy/report.ts index 654eead1d..576decaad 100644 --- a/src/commands/force/source/deploy/report.ts +++ b/src/commands/force/source/deploy/report.ts @@ -9,12 +9,12 @@ import * as os from 'os'; import { Messages, SfdxProject } from '@salesforce/core'; import { flags, FlagsConfig } from '@salesforce/command'; import { Duration, env } from '@salesforce/kit'; +import { ComponentSetBuilder } from '@salesforce/source-deploy-retrieve'; import { DeployCommand } from '../../../../deployCommand'; import { DeployReportCommandResult, DeployReportResultFormatter, } from '../../../../formatters/deployReportResultFormatter'; -import { ComponentSetBuilder } from '../../../../componentSetBuilder'; import { ProgressFormatter } from '../../../../formatters/progressFormatter'; import { DeployProgressBarFormatter } from '../../../../formatters/deployProgressBarFormatter'; import { DeployProgressStatusFormatter } from '../../../../formatters/deployProgressStatusFormatter'; diff --git a/src/commands/force/source/manifest/create.ts b/src/commands/force/source/manifest/create.ts index 95371e824..ec6794a67 100644 --- a/src/commands/force/source/manifest/create.ts +++ b/src/commands/force/source/manifest/create.ts @@ -9,8 +9,8 @@ import { join } from 'path'; import * as fs from 'fs'; import { flags, FlagsConfig } from '@salesforce/command'; import { Messages } from '@salesforce/core'; +import { ComponentSetBuilder } from '@salesforce/source-deploy-retrieve'; import { SourceCommand } from '../../../../sourceCommand'; -import { ComponentSetBuilder } from '../../../../componentSetBuilder'; Messages.importMessagesDirectory(__dirname); const messages = Messages.loadMessages('@salesforce/plugin-source', 'create'); diff --git a/src/commands/force/source/retrieve.ts b/src/commands/force/source/retrieve.ts index 6f9af15af..6d0d41af5 100644 --- a/src/commands/force/source/retrieve.ts +++ b/src/commands/force/source/retrieve.ts @@ -10,7 +10,7 @@ import { join } from 'path'; import { flags, FlagsConfig } from '@salesforce/command'; import { Messages, SfdxProject } from '@salesforce/core'; import { Duration } from '@salesforce/kit'; -import { ComponentSet, RequestStatus, RetrieveResult } from '@salesforce/source-deploy-retrieve'; +import { ComponentSet, ComponentSetBuilder, RequestStatus, RetrieveResult } from '@salesforce/source-deploy-retrieve'; import { SourceTracking } from '@salesforce/source-tracking'; import { SourceCommand } from '../../../sourceCommand'; import { @@ -18,8 +18,7 @@ import { RetrieveCommandResult, RetrieveResultFormatter, } from '../../../formatters/retrieveResultFormatter'; -import { ComponentSetBuilder } from '../../../componentSetBuilder'; -import { trackingSetup, updateTracking, filterConflictsByComponentSet } from '../../../trackingFunctions'; +import { filterConflictsByComponentSet, trackingSetup, updateTracking } from '../../../trackingFunctions'; Messages.importMessagesDirectory(__dirname); const messages = Messages.loadMessages('@salesforce/plugin-source', 'retrieve'); diff --git a/src/componentSetBuilder.ts b/src/componentSetBuilder.ts deleted file mode 100644 index aafa27e69..000000000 --- a/src/componentSetBuilder.ts +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2020, salesforce.com, inc. - * All rights reserved. - * Licensed under the BSD 3-Clause license. - * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ - -import * as path from 'path'; -import { ComponentSet, RegistryAccess } from '@salesforce/source-deploy-retrieve'; -import { fs, Logger, SfdxError, Aliases } from '@salesforce/core'; - -export type ManifestOption = { - manifestPath: string; - directoryPaths: string[]; - destructiveChangesPre?: string; - destructiveChangesPost?: string; -}; -export type MetadataOption = { - metadataEntries: string[]; - directoryPaths: string[]; -}; -export type OrgOption = { - username: string; - exclude: string[]; -}; -export type ComponentSetOptions = { - packagenames?: string[]; - sourcepath?: string[]; - manifest?: ManifestOption; - - metadata?: MetadataOption; - apiversion?: string; - sourceapiversion?: string; - org?: OrgOption; -}; - -export class ComponentSetBuilder { - /** - * Builds a ComponentSet that can be used for source conversion, - * deployment, or retrieval, using all specified options. - * - * @see https://github.com/forcedotcom/source-deploy-retrieve/blob/develop/src/collections/componentSet.ts - * - * @param options: options for creating a ComponentSet - */ - public static async build(options: ComponentSetOptions): Promise { - const logger = Logger.childFromRoot('createComponentSet'); - let componentSet: ComponentSet; - - const { sourcepath, manifest, metadata, packagenames, apiversion, sourceapiversion, org } = options; - try { - if (sourcepath) { - logger.debug(`Building ComponentSet from sourcepath: ${sourcepath.toString()}`); - const fsPaths: string[] = []; - sourcepath.forEach((filepath) => { - if (!fs.fileExistsSync(filepath)) { - throw new SfdxError(`The sourcepath "${filepath}" is not a valid source file path.`); - } - fsPaths.push(path.resolve(filepath)); - }); - componentSet = ComponentSet.fromSource({ fsPaths }); - } - - // Return empty ComponentSet and use packageNames in the library via `.retrieve` options - if (packagenames) { - logger.debug(`Building ComponentSet for packagenames: ${packagenames.toString()}`); - componentSet ??= new ComponentSet(); - } - - // Resolve manifest with source in package directories. - if (manifest) { - logger.debug(`Building ComponentSet from manifest: ${manifest.manifestPath}`); - const directoryPaths = options.manifest.directoryPaths; - logger.debug(`Searching in packageDir: ${directoryPaths.join(', ')} for matching metadata`); - componentSet = await ComponentSet.fromManifest({ - manifestPath: manifest.manifestPath, - resolveSourcePaths: options.manifest.directoryPaths, - forceAddWildcards: true, - destructivePre: options.manifest.destructiveChangesPre, - destructivePost: options.manifest.destructiveChangesPost, - }); - } - - // Resolve metadata entries with source in package directories. - if (metadata) { - logger.debug(`Building ComponentSet from metadata: ${metadata.metadataEntries.toString()}`); - const registry = new RegistryAccess(); - const compSetFilter = new ComponentSet(); - componentSet ??= new ComponentSet(); - - // Build a Set of metadata entries - metadata.metadataEntries.forEach((rawEntry) => { - const splitEntry = rawEntry.split(':').map((entry) => entry.trim()); - // The registry will throw if it doesn't know what this type is. - registry.getTypeByName(splitEntry[0]); - const entry = { - type: splitEntry[0], - fullName: splitEntry.length === 1 ? '*' : splitEntry[1], - }; - // Add to the filtered ComponentSet for resolved source paths, - // and the unfiltered ComponentSet to build the correct manifest. - compSetFilter.add(entry); - componentSet.add(entry); - }); - - const directoryPaths = options.metadata.directoryPaths; - logger.debug(`Searching for matching metadata in directories: ${directoryPaths.join(', ')}`); - const resolvedComponents = ComponentSet.fromSource({ fsPaths: directoryPaths, include: compSetFilter }); - componentSet.forceIgnoredPaths = resolvedComponents.forceIgnoredPaths; - for (const comp of resolvedComponents) { - componentSet.add(comp); - } - } - - // Resolve metadata entries with an org connection - if (org) { - logger.debug(`Building ComponentSet from targetUsername: ${org.username}`); - componentSet = await ComponentSet.fromConnection({ - usernameOrConnection: (await Aliases.fetch(org.username)) || org.username, - // exclude components based on the results of componentFilter function - // components where org.exclude includes manageableState - // components with namespacePrefix where manageableState equals undefined (e.g. InstalledPackage) are currently not excluded - componentFilter: (component): boolean => !(org.exclude && org.exclude.includes(component?.manageableState)), - }); - } - } catch (e) { - if ((e as Error).message.includes('Missing metadata type definition in registry for id')) { - // to remain generic to catch missing metadata types regardless of parameters, split on ' - // example message : Missing metadata type definition in registry for id 'NonExistentType' - const issueType = (e as Error).message.split("'")[1]; - throw new SfdxError(`The specified metadata type is unsupported: [${issueType}]`); - } else { - throw e; - } - } - - // This is only for debug output of matched files based on the command flags. - // It will log up to 20 file matches. - if (logger.debugEnabled && componentSet.size) { - logger.debug(`Matching metadata files (${componentSet.size}):`); - const components = componentSet.getSourceComponents().toArray(); - for (let i = 0; i < componentSet.size; i++) { - if (components[i]?.content) { - logger.debug(components[i].content); - } else if (components[i]?.xml) { - logger.debug(components[i].xml); - } - - if (i > 18) { - logger.debug(`(showing 20 of ${componentSet.size} matches)`); - break; - } - } - } - - if (apiversion) { - componentSet.apiVersion = apiversion; - } - - if (sourceapiversion) { - componentSet.sourceApiVersion = sourceapiversion; - } - - return componentSet; - } -} diff --git a/test/commands/mdapi/convert.test.ts b/test/commands/mdapi/convert.test.ts index 1124b8d8f..d4e7e3244 100644 --- a/test/commands/mdapi/convert.test.ts +++ b/test/commands/mdapi/convert.test.ts @@ -13,10 +13,9 @@ import { fromStub, stubInterface, stubMethod } from '@salesforce/ts-sinon'; import { IConfig } from '@oclif/config'; import { UX } from '@salesforce/command'; import { SfdxProject } from '@salesforce/core'; -import { MetadataConverter } from '@salesforce/source-deploy-retrieve'; +import { ComponentSetBuilder, MetadataConverter } from '@salesforce/source-deploy-retrieve'; import { Convert } from '../../../src/commands/force/mdapi/beta/convert'; import { FsError } from '../../../src/types'; -import { ComponentSetBuilder } from '../../../src/componentSetBuilder'; const testConvertResult = { converted: [ diff --git a/test/commands/mdapi/retrieve.test.ts b/test/commands/mdapi/retrieve.test.ts index 4afa83c48..8e813e769 100644 --- a/test/commands/mdapi/retrieve.test.ts +++ b/test/commands/mdapi/retrieve.test.ts @@ -13,11 +13,10 @@ import { Lifecycle, Org } from '@salesforce/core'; import { fromStub, stubInterface, stubMethod } from '@salesforce/ts-sinon'; import { IConfig } from '@oclif/config'; import { UX } from '@salesforce/command'; -import { RetrieveOptions } from '@salesforce/source-deploy-retrieve'; +import { ComponentSetBuilder, ComponentSetOptions, RetrieveOptions } from '@salesforce/source-deploy-retrieve'; import { Retrieve } from '../../../src/commands/force/mdapi/beta/retrieve'; import { Stash, StashData } from '../../../src/stash'; import { getRetrieveResult } from '../source/retrieveResponses'; -import { ComponentSetBuilder, ComponentSetOptions } from '../../../src/componentSetBuilder'; describe('force:mdapi:beta:retrieve', () => { const sandbox = sinon.createSandbox(); diff --git a/test/commands/source/componentSetBuilder.test.ts b/test/commands/source/componentSetBuilder.test.ts deleted file mode 100644 index 7b14d547b..000000000 --- a/test/commands/source/componentSetBuilder.test.ts +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright (c) 2020, salesforce.com, inc. - * All rights reserved. - * Licensed under the BSD 3-Clause license. - * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause - */ - -import * as path from 'path'; -import * as sinon from 'sinon'; -import { assert, expect } from 'chai'; -import { ComponentSet, FromSourceOptions } from '@salesforce/source-deploy-retrieve'; -import { stubMethod } from '@salesforce/ts-sinon'; -import { fs as fsCore, SfdxError } from '@salesforce/core'; -import { ComponentSetBuilder } from '../../../src/componentSetBuilder'; - -describe('ComponentSetBuilder', () => { - const sandbox = sinon.createSandbox(); - - afterEach(() => { - sandbox.restore(); - }); - - const apexClassComponent = { - type: 'ApexClass', - fullName: 'MyClass', - content: 'MyClass.cls', - xml: 'MyClass.cls-meta.xml', - }; - const customObjectComponent = { - type: 'CustomObject', - fullName: 'MyCustomObject__c', - content: undefined, - xml: 'MyCustomObject__c.object-meta.xml', - }; - - describe('build', () => { - let componentSet: ComponentSet; - let fileExistsSyncStub: sinon.SinonStub; - let fromSourceStub: sinon.SinonStub; - let fromManifestStub: sinon.SinonStub; - let fromConnectionStub: sinon.SinonStub; - - beforeEach(() => { - fileExistsSyncStub = stubMethod(sandbox, fsCore, 'fileExistsSync'); - fromSourceStub = stubMethod(sandbox, ComponentSet, 'fromSource'); - fromManifestStub = stubMethod(sandbox, ComponentSet, 'fromManifest'); - fromConnectionStub = stubMethod(sandbox, ComponentSet, 'fromConnection'); - componentSet = new ComponentSet(); - }); - - it('should create ComponentSet from single sourcepath', async () => { - fileExistsSyncStub.returns(true); - componentSet.add(apexClassComponent); - fromSourceStub.returns(componentSet); - const sourcepath = ['force-app']; - - const compSet = await ComponentSetBuilder.build({ - sourcepath, - manifest: undefined, - metadata: undefined, - }); - - const expectedArg = { fsPaths: [path.resolve(sourcepath[0])] }; - expect(fromSourceStub.calledOnceWith(expectedArg)).to.equal(true); - expect(compSet.size).to.equal(1); - expect(compSet.has(apexClassComponent)).to.equal(true); - }); - - it('should create ComponentSet from multiple sourcepaths', async () => { - fileExistsSyncStub.returns(true); - componentSet.add(apexClassComponent); - componentSet.add(customObjectComponent); - fromSourceStub.returns(componentSet); - const sourcepath = ['force-app', 'my-app']; - - const compSet = await ComponentSetBuilder.build({ - sourcepath, - manifest: undefined, - metadata: undefined, - }); - const expectedPath1 = path.resolve(sourcepath[0]); - const expectedPath2 = path.resolve(sourcepath[1]); - const expectedArg = { fsPaths: [expectedPath1, expectedPath2] }; - expect(fromSourceStub.calledOnceWith(expectedArg)).to.equal(true); - expect(compSet.size).to.equal(2); - expect(compSet.has(apexClassComponent)).to.equal(true); - expect(compSet.has(customObjectComponent)).to.equal(true); - }); - - it('should create ComponentSet with overridden apiVersion', async () => { - fileExistsSyncStub.returns(true); - fromSourceStub.returns(componentSet); - const sourcepath = ['force-app']; - const options = { - sourcepath, - manifest: undefined, - metadata: undefined, - apiversion: '50.0', - }; - - const compSet = await ComponentSetBuilder.build(options); - const expectedArg = { fsPaths: [path.resolve(sourcepath[0])] }; - expect(fromSourceStub.calledOnceWith(expectedArg)).to.equal(true); - expect(compSet.size).to.equal(0); - expect(compSet.apiVersion).to.equal(options.apiversion); - }); - - it('should create ComponentSet with sourceApiVersion', async () => { - fileExistsSyncStub.returns(true); - fromSourceStub.returns(componentSet); - const sourcepath = ['force-app']; - const options = { - sourcepath, - manifest: undefined, - metadata: undefined, - sourceapiversion: '50.0', - }; - - const compSet = await ComponentSetBuilder.build(options); - const expectedArg = { fsPaths: [path.resolve(sourcepath[0])] }; - expect(fromSourceStub.calledOnceWith(expectedArg)).to.equal(true); - expect(compSet.size).to.equal(0); - expect(compSet.sourceApiVersion).to.equal(options.sourceapiversion); - }); - - it('should throw with an invalid sourcepath', async () => { - fileExistsSyncStub.returns(false); - const sourcepath = ['nonexistent']; - try { - await ComponentSetBuilder.build({ - sourcepath, - manifest: undefined, - metadata: undefined, - }); - assert(false, 'should have thrown SfdxError'); - } catch (e: unknown) { - const err = e as SfdxError; - expect(fromSourceStub.notCalled).to.equal(true); - expect(err.message).to.include(sourcepath[0]); - } - }); - - it('should create empty ComponentSet from packagenames', async () => { - fileExistsSyncStub.returns(true); - - const compSet = await ComponentSetBuilder.build({ - sourcepath: undefined, - manifest: undefined, - metadata: undefined, - packagenames: ['mypackage'], - }); - expect(compSet.size).to.equal(0); - expect(fromSourceStub.notCalled).to.equal(true); - expect(fromManifestStub.notCalled).to.equal(true); - }); - - it('should create ComponentSet from wildcarded metadata (ApexClass)', async () => { - componentSet.add(apexClassComponent); - fromSourceStub.returns(componentSet); - const packageDir1 = path.resolve('force-app'); - - const compSet = await ComponentSetBuilder.build({ - sourcepath: undefined, - manifest: undefined, - metadata: { - metadataEntries: ['ApexClass'], - directoryPaths: [packageDir1], - }, - }); - expect(fromSourceStub.calledOnce).to.equal(true); - const fromSourceArgs = fromSourceStub.firstCall.args[0] as FromSourceOptions; - expect(fromSourceArgs).to.have.deep.property('fsPaths', [packageDir1]); - const filter = new ComponentSet(); - filter.add({ type: 'ApexClass', fullName: '*' }); - expect(fromSourceArgs).to.have.property('include'); - expect(fromSourceArgs.include.getSourceComponents()).to.deep.equal(filter.getSourceComponents()); - expect(compSet.size).to.equal(2); - expect(compSet.has(apexClassComponent)).to.equal(true); - expect(compSet.has({ type: 'ApexClass', fullName: '*' })).to.equal(true); - }); - - it('should create ComponentSet from metadata with spaces between : (ApexClass: MyApexClass)', async () => { - componentSet.add(apexClassComponent); - fromSourceStub.returns(componentSet); - const packageDir1 = path.resolve('force-app'); - - const compSet = await ComponentSetBuilder.build({ - sourcepath: undefined, - manifest: undefined, - metadata: { - metadataEntries: ['ApexClass: MyApexClass'], - directoryPaths: [packageDir1], - }, - }); - expect(fromSourceStub.calledOnce).to.equal(true); - const fromSourceArgs = fromSourceStub.firstCall.args[0] as FromSourceOptions; - expect(fromSourceArgs).to.have.deep.property('fsPaths', [packageDir1]); - const filter = new ComponentSet(); - filter.add({ type: 'ApexClass', fullName: 'MyApexClass' }); - expect(fromSourceArgs).to.have.property('include'); - expect(fromSourceArgs.include.getSourceComponents()).to.deep.equal(filter.getSourceComponents()); - expect(compSet.size).to.equal(2); - expect(compSet.has(apexClassComponent)).to.equal(true); - expect(compSet.has({ type: 'ApexClass', fullName: 'MyApexClass' })).to.equal(true); - }); - - it('should throw an error when it cant resolve a metadata type (Metadata)', async () => { - const packageDir1 = path.resolve('force-app'); - - try { - await ComponentSetBuilder.build({ - sourcepath: undefined, - manifest: undefined, - metadata: { - metadataEntries: ['NotAType', 'ApexClass:MyClass'], - directoryPaths: [packageDir1], - }, - }); - assert.fail('the above should throw an error'); - } catch (e) { - expect(e).to.not.be.null; - expect((e as Error).message).to.include('The specified metadata type is unsupported: [notatype]'); - } - }); - - it('should create ComponentSet from specific metadata (ApexClass:MyClass)', async () => { - componentSet.add(apexClassComponent); - fromSourceStub.returns(componentSet); - const packageDir1 = path.resolve('force-app'); - - const compSet = await ComponentSetBuilder.build({ - sourcepath: undefined, - manifest: undefined, - metadata: { - metadataEntries: ['ApexClass:MyClass'], - directoryPaths: [packageDir1], - }, - }); - expect(fromSourceStub.calledOnce).to.equal(true); - const fromSourceArgs = fromSourceStub.firstCall.args[0] as FromSourceOptions; - expect(fromSourceArgs).to.have.deep.property('fsPaths', [packageDir1]); - const filter = new ComponentSet(); - filter.add({ type: 'ApexClass', fullName: 'MyClass' }); - expect(fromSourceArgs).to.have.property('include'); - expect(fromSourceArgs.include.getSourceComponents()).to.deep.equal(filter.getSourceComponents()); - expect(compSet.size).to.equal(1); - expect(compSet.has(apexClassComponent)).to.equal(true); - }); - - it('should create ComponentSet from multiple metadata (ApexClass:MyClass,CustomObject)', async () => { - componentSet.add(apexClassComponent); - componentSet.add(customObjectComponent); - fromSourceStub.returns(componentSet); - const packageDir1 = path.resolve('force-app'); - - const compSet = await ComponentSetBuilder.build({ - sourcepath: undefined, - manifest: undefined, - metadata: { - metadataEntries: ['ApexClass:MyClass', 'CustomObject'], - directoryPaths: [packageDir1], - }, - }); - expect(fromSourceStub.calledOnce).to.equal(true); - const fromSourceArgs = fromSourceStub.firstCall.args[0] as FromSourceOptions; - expect(fromSourceArgs).to.have.deep.property('fsPaths', [packageDir1]); - const filter = new ComponentSet(); - filter.add({ type: 'ApexClass', fullName: 'MyClass' }); - filter.add({ type: 'CustomObject', fullName: '*' }); - expect(fromSourceArgs).to.have.property('include'); - expect(fromSourceArgs.include.getSourceComponents()).to.deep.equal(filter.getSourceComponents()); - expect(compSet.size).to.equal(3); - expect(compSet.has(apexClassComponent)).to.equal(true); - expect(compSet.has(customObjectComponent)).to.equal(true); - expect(compSet.has({ type: 'CustomObject', fullName: '*' })).to.equal(true); - }); - - it('should create ComponentSet from metadata and multiple package directories', async () => { - componentSet.add(apexClassComponent); - const apexClassComponent2 = { type: 'ApexClass', fullName: 'MyClass2' }; - componentSet.add(apexClassComponent2); - fromSourceStub.returns(componentSet); - const packageDir1 = path.resolve('force-app'); - const packageDir2 = path.resolve('my-app'); - - const compSet = await ComponentSetBuilder.build({ - sourcepath: undefined, - manifest: undefined, - metadata: { - metadataEntries: ['ApexClass'], - directoryPaths: [packageDir1, packageDir2], - }, - }); - expect(fromSourceStub.calledOnce).to.equal(true); - const fromSourceArgs = fromSourceStub.firstCall.args[0] as FromSourceOptions; - expect(fromSourceArgs).to.have.deep.property('fsPaths', [packageDir1, packageDir2]); - const filter = new ComponentSet(); - filter.add({ type: 'ApexClass', fullName: '*' }); - expect(fromSourceArgs).to.have.property('include'); - expect(fromSourceArgs.include.getSourceComponents()).to.deep.equal(filter.getSourceComponents()); - expect(compSet.size).to.equal(3); - expect(compSet.has(apexClassComponent)).to.equal(true); - expect(compSet.has(apexClassComponent2)).to.equal(true); - expect(compSet.has({ type: 'ApexClass', fullName: '*' })).to.equal(true); - }); - - it('should create ComponentSet from manifest', async () => { - componentSet.add(apexClassComponent); - fromManifestStub.resolves(componentSet); - const packageDir1 = path.resolve('force-app'); - const options = { - sourcepath: undefined, - metadata: undefined, - manifest: { - manifestPath: 'apex-package.xml', - directoryPaths: [packageDir1], - }, - }; - - const compSet = await ComponentSetBuilder.build(options); - expect(fromManifestStub.calledOnce).to.equal(true); - expect(fromManifestStub.firstCall.args[0]).to.deep.equal({ - forceAddWildcards: true, - manifestPath: options.manifest.manifestPath, - resolveSourcePaths: [packageDir1], - destructivePre: undefined, - destructivePost: undefined, - }); - expect(compSet.size).to.equal(1); - expect(compSet.has(apexClassComponent)).to.equal(true); - }); - - it('should create ComponentSet from org connection', async () => { - componentSet.add(apexClassComponent); - fromConnectionStub.resolves(componentSet); - const options = { - sourcepath: undefined, - metadata: undefined, - manifest: undefined, - org: { - username: 'manifest-test@org.com', - exclude: [], - }, - }; - - const compSet = await ComponentSetBuilder.build(options); - expect(fromConnectionStub.calledOnce).to.equal(true); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - expect(fromConnectionStub.firstCall.firstArg['usernameOrConnection']).equal(options.org.username); - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call - expect(fromConnectionStub.firstCall.firstArg['componentFilter'].call()).equal(true); - expect(compSet.size).to.equal(1); - expect(compSet.has(apexClassComponent)).to.equal(true); - }); - - it('should create ComponentSet from manifest and multiple package', async () => { - componentSet.add(apexClassComponent); - const apexClassComponent2 = { type: 'ApexClass', fullName: 'MyClass2' }; - componentSet.add(apexClassComponent2); - fromManifestStub.onFirstCall().resolves(componentSet); - const packageDir1 = path.resolve('force-app'); - const packageDir2 = path.resolve('my-app'); - const options = { - sourcepath: undefined, - metadata: undefined, - manifest: { - manifestPath: 'apex-package.xml', - directoryPaths: [packageDir1, packageDir2], - }, - }; - - const compSet = await ComponentSetBuilder.build(options); - expect(fromManifestStub.callCount).to.equal(1); - expect(fromManifestStub.firstCall.args[0]).to.deep.equal({ - forceAddWildcards: true, - manifestPath: options.manifest.manifestPath, - resolveSourcePaths: [packageDir1, packageDir2], - destructivePre: undefined, - destructivePost: undefined, - }); - expect(compSet.size).to.equal(2); - expect(compSet.has(apexClassComponent)).to.equal(true); - expect(compSet.has(apexClassComponent2)).to.equal(true); - }); - }); -}); diff --git a/test/commands/source/convert.test.ts b/test/commands/source/convert.test.ts index d6ecb96b5..3e1125302 100644 --- a/test/commands/source/convert.test.ts +++ b/test/commands/source/convert.test.ts @@ -6,14 +6,13 @@ */ import { join, resolve } from 'path'; -import { MetadataConverter } from '@salesforce/source-deploy-retrieve'; +import { ComponentSetBuilder, ComponentSetOptions, MetadataConverter } from '@salesforce/source-deploy-retrieve'; import * as sinon from 'sinon'; import { expect } from 'chai'; import { fromStub, stubInterface, stubMethod } from '@salesforce/ts-sinon'; import { IConfig } from '@oclif/config'; import { SfdxProject } from '@salesforce/core'; import { Convert } from '../../../src/commands/force/source/convert'; -import { ComponentSetBuilder, ComponentSetOptions } from '../../../src/componentSetBuilder'; describe('force:source:convert', () => { const sandbox = sinon.createSandbox(); diff --git a/test/commands/source/delete.test.ts b/test/commands/source/delete.test.ts index a1c4a310d..66ddee675 100644 --- a/test/commands/source/delete.test.ts +++ b/test/commands/source/delete.test.ts @@ -9,12 +9,16 @@ import * as fs from 'fs'; import { join } from 'path'; import * as sinon from 'sinon'; import { expect } from 'chai'; -import { ComponentSet, SourceComponent } from '@salesforce/source-deploy-retrieve'; +import { + ComponentSet, + ComponentSetBuilder, + ComponentSetOptions, + SourceComponent, +} from '@salesforce/source-deploy-retrieve'; import { Lifecycle, Org, SfdxProject } from '@salesforce/core'; import { fromStub, stubInterface, stubMethod } from '@salesforce/ts-sinon'; import { IConfig } from '@oclif/config'; import { UX } from '@salesforce/command'; -import { ComponentSetBuilder, ComponentSetOptions } from '../../../src/componentSetBuilder'; import { Delete } from '../../../src/commands/force/source/delete'; import { exampleDeleteResponse, exampleSourceComponent } from './testConsts'; diff --git a/test/commands/source/deploy.test.ts b/test/commands/source/deploy.test.ts index 07500b72d..af560c5f5 100644 --- a/test/commands/source/deploy.test.ts +++ b/test/commands/source/deploy.test.ts @@ -8,7 +8,7 @@ import { join } from 'path'; import * as sinon from 'sinon'; import { expect } from 'chai'; -import { MetadataApiDeployOptions } from '@salesforce/source-deploy-retrieve'; +import { ComponentSetBuilder, ComponentSetOptions, MetadataApiDeployOptions } from '@salesforce/source-deploy-retrieve'; import { fromStub, stubInterface, stubMethod } from '@salesforce/ts-sinon'; import { ConfigAggregator, Lifecycle, Messages, Org, SfdxProject } from '@salesforce/core'; import { UX } from '@salesforce/command'; @@ -19,7 +19,6 @@ import { DeployAsyncResultFormatter, DeployCommandAsyncResult, } from '../../../src/formatters/source/deployAsyncResultFormatter'; -import { ComponentSetBuilder, ComponentSetOptions } from '../../../src/componentSetBuilder'; import { DeployProgressBarFormatter } from '../../../src/formatters/deployProgressBarFormatter'; import { DeployProgressStatusFormatter } from '../../../src/formatters/deployProgressStatusFormatter'; import { getDeployResult } from './deployResponses'; @@ -142,7 +141,7 @@ describe('force:source:deploy', () => { apiversion: undefined, sourceapiversion: undefined, }; - const expectedArgs = { ...defaultArgs, ...overrides }; + const expectedArgs: Partial = { ...defaultArgs, ...overrides }; expect(buildComponentSetStub.calledOnce).to.equal(true); expect(buildComponentSetStub.firstCall.args[0]).to.deep.equal(expectedArgs); diff --git a/test/commands/source/retrieve.test.ts b/test/commands/source/retrieve.test.ts index 4b550fb88..83ad392b9 100644 --- a/test/commands/source/retrieve.test.ts +++ b/test/commands/source/retrieve.test.ts @@ -8,14 +8,20 @@ import { join } from 'path'; import * as sinon from 'sinon'; import { expect } from 'chai'; -import { RetrieveOptions, ComponentLike, ComponentSet, MetadataType } from '@salesforce/source-deploy-retrieve'; -import { Messages, Lifecycle, Org, SfdxProject } from '@salesforce/core'; +import { + ComponentLike, + ComponentSet, + ComponentSetBuilder, + ComponentSetOptions, + MetadataType, + RetrieveOptions, +} from '@salesforce/source-deploy-retrieve'; +import { Lifecycle, Messages, Org, SfdxProject } from '@salesforce/core'; import { fromStub, stubInterface, stubMethod } from '@salesforce/ts-sinon'; import { IConfig } from '@oclif/config'; import { UX } from '@salesforce/command'; import { Retrieve } from '../../../src/commands/force/source/retrieve'; import { RetrieveCommandResult, RetrieveResultFormatter } from '../../../src/formatters/retrieveResultFormatter'; -import { ComponentSetBuilder, ComponentSetOptions } from '../../../src/componentSetBuilder'; import { getRetrieveResult } from './retrieveResponses'; import { exampleSourceComponent } from './testConsts'; diff --git a/yarn.lock b/yarn.lock index 47ec90c5e..7da7cbb39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -946,13 +946,13 @@ unzipper "0.10.11" xmldom-sfdx-encoding "^0.1.29" -"@salesforce/source-deploy-retrieve@^5.9.4": - version "5.9.5" - resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-5.9.5.tgz#40cfe4e932eead8d339db7cb030a75da864ca4c6" - integrity sha512-bPUyIyPJbs1R8p7a2kY4A+KlNLuanuZOspuo6f61NhrUxYyez63YZOiUBvrcs9cGemDcZcC9vItrrhkmcKIt7g== +"@salesforce/source-deploy-retrieve@^5.12.2": + version "5.12.2" + resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-5.12.2.tgz#2749628657b34b35f93809f7f3b2ea11a85785aa" + integrity sha512-dDyNLSqCOq2UMBQYItkQBV/+jxYmzaMlmgNlrQ9CVduzwlD7A76dMSwuvdmAlF3ckKXxxUWtG0iq1oCBa28X6A== dependencies: - "@salesforce/core" "2.33.1" - "@salesforce/kit" "^1.5.0" + "@salesforce/core" "^2.35.0" + "@salesforce/kit" "^1.5.32" "@salesforce/ts-types" "^1.4.2" archiver "^5.3.0" fast-xml-parser "^3.17.4" @@ -962,13 +962,13 @@ unzipper "0.10.11" xmldom-sfdx-encoding "^0.1.29" -"@salesforce/source-deploy-retrieve@^5.9.9": - version "5.9.9" - resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-5.9.9.tgz#fcbf6034d4d5b040562815f8dc38e4d3f8c1cd90" - integrity sha512-DuKVZNkwa3yOM/3YLO1lsfzVzAqxm60PS/cbk/pyq7aDl92NGGOcbT9ViSC3h2Yjter7qOuJbgbL88gSy7rqYg== +"@salesforce/source-deploy-retrieve@^5.9.4": + version "5.9.5" + resolved "https://registry.yarnpkg.com/@salesforce/source-deploy-retrieve/-/source-deploy-retrieve-5.9.5.tgz#40cfe4e932eead8d339db7cb030a75da864ca4c6" + integrity sha512-bPUyIyPJbs1R8p7a2kY4A+KlNLuanuZOspuo6f61NhrUxYyez63YZOiUBvrcs9cGemDcZcC9vItrrhkmcKIt7g== dependencies: - "@salesforce/core" "^2.35.0" - "@salesforce/kit" "^1.5.32" + "@salesforce/core" "2.33.1" + "@salesforce/kit" "^1.5.0" "@salesforce/ts-types" "^1.4.2" archiver "^5.3.0" fast-xml-parser "^3.17.4"