Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
## [12.27.2](https://github.com/forcedotcom/source-deploy-retrieve/compare/12.27.1...12.27.2) (2025-11-12)


### Bug Fixes

* add support for `DataObjectSearchIndexConf` metadata ([#1649](https://github.com/forcedotcom/source-deploy-retrieve/issues/1649)) ([46a3b00](https://github.com/forcedotcom/source-deploy-retrieve/commit/46a3b00b45c833728ebba6d734e975fd73f610c1))



## [12.27.1](https://github.com/forcedotcom/source-deploy-retrieve/compare/12.27.0...12.27.1) (2025-11-11)


### Bug Fixes

* add support for `LightningOutApp` metadata ([#1648](https://github.com/forcedotcom/source-deploy-retrieve/issues/1648)) ([bdc1fb0](https://github.com/forcedotcom/source-deploy-retrieve/commit/bdc1fb057c5ce5a325c296fb4a0999e3ced26b55))



# [12.27.0](https://github.com/forcedotcom/source-deploy-retrieve/compare/12.26.1...12.27.0) (2025-11-11)


### Features

* added RunRelevantTests test-level @W-20152151@ ([#1644](https://github.com/forcedotcom/source-deploy-retrieve/issues/1644)) ([96a176f](https://github.com/forcedotcom/source-deploy-retrieve/commit/96a176f7bc28d3671a9f50a89079373ffe1fcea9))



## [12.26.1](https://github.com/forcedotcom/source-deploy-retrieve/compare/12.26.0...12.26.1) (2025-11-11)


### Bug Fixes

* web support without cwd W-20175875 ([#1647](https://github.com/forcedotcom/source-deploy-retrieve/issues/1647)) ([6dd7c70](https://github.com/forcedotcom/source-deploy-retrieve/commit/6dd7c708defdd064ac34ba77d154cc91ab2cee2b))



# [12.26.0](https://github.com/forcedotcom/source-deploy-retrieve/compare/12.25.0...12.26.0) (2025-11-07)


Expand Down
12 changes: 6 additions & 6 deletions METADATA_SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This list compares metadata types found in Salesforce v65 with the [metadata reg

This repository is used by both the Salesforce CLIs and Salesforce's VSCode Extensions.

Currently, there are 675/719 supported metadata types.
Currently, there are 678/719 supported metadata types.
For status on any existing gaps, please search or file an issue in the [Salesforce CLI issues only repo](https://github.com/forcedotcom/cli/issues).
To contribute a new metadata type, please see the [Contributing Metadata Types to the Registry](./contributing/metadata.md)

Expand Down Expand Up @@ -45,6 +45,7 @@ To contribute a new metadata type, please see the [Contributing Metadata Types t
|AgentforceAccountManagementSettings|✅||
|AgentforceForDevelopersSettings|✅||
|Ai4mSettings|✅||
|AiAuthoringBundle|✅||
|AiEvaluationDefinition|⚠️|Supports deploy/retrieve but not source tracking|
|AiPlannerVoiceDef|❌|Not supported, but support could be added (but not for tracking)|
|AnalyticSnapshot|✅||
Expand Down Expand Up @@ -207,7 +208,7 @@ To contribute a new metadata type, please see the [Contributing Metadata Types t
|DataKitObjectDependency|✅||
|DataKitObjectTemplate|✅||
|DataObjectBuildOrgTemplate|✅||
|DataObjectSearchIndexConf|❌|Not supported, but support could be added (but not for tracking)|
|DataObjectSearchIndexConf|⚠️|Supports deploy/retrieve but not source tracking|
|DataPackageKitDefinition|✅||
|DataPackageKitObject|✅||
|DataSource|✅||
Expand Down Expand Up @@ -437,7 +438,7 @@ To contribute a new metadata type, please see the [Contributing Metadata Types t
|LightningExperienceTheme|✅||
|LightningMessageChannel|✅||
|LightningOnboardingConfig|✅||
|LightningOutApp|❌|Not supported, but support could be added|
|LightningOutApp|✅||
|LightningTypeBundle|✅||
|ListView|✅||
|LiveAgentSettings|✅||
Expand Down Expand Up @@ -715,7 +716,6 @@ To contribute a new metadata type, please see the [Contributing Metadata Types t
|WebStoreBundle|✅||
|WebStoreTemplate|✅||
|WebToXSettings|✅||
|WelcomeRecommendation|❌|Not supported, but support could be added|
|WorkDotComSettings|✅||
|WorkSkillRouting|✅||
|Workflow|✅||
Expand Down Expand Up @@ -750,8 +750,8 @@ v66 introduces the following new types. Here's their current level of support
|DynamicGanttSettings|✅||
|EmergencySettings|✅||
|ExtlClntAppAttestSettings|✅||
|GENComputingSummaryDEF|❌|Not supported, but support could be added|
|GRCIntelligenceUddSettings|✅||
|GenComputingSummaryDef|❌|Not supported, but support could be added|
|GeneralConfigSettings|✅||
|GeocodeSettings|✅||
|GiftEntryGridTemplate|✅||
Expand All @@ -774,6 +774,7 @@ v66 introduces the following new types. Here's their current level of support
|StockRotationSettings|✅||
|SynchronizeSettings|✅||
|TriggerConfigurationsSettings|✅||
|UnifiedSalesIntelligenceSettings|✅||

## Additional Types

Expand All @@ -786,7 +787,6 @@ v66 introduces the following new types. Here's their current level of support

- AccessControlPolicy
- AIAssistantTemplate
- AiAuthoringBundle
- AssignmentRule
- AssistantRecommendationType
- AutoResponseRule
Expand Down
4 changes: 4 additions & 0 deletions messages/sdr.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ Could not find parent type for %s (%s)

Component conversion failed: %s

# error_invalid_test_level

TestLevel cannot be '%s' unless API version is %s or later

# error_merge_metadata_target_unsupported

Merge convert for metadata target format currently unsupported
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@salesforce/source-deploy-retrieve",
"version": "12.26.0",
"version": "12.27.2",
"description": "JavaScript library to run Salesforce metadata deploys and retrieves",
"main": "lib/src/index.js",
"author": "Salesforce",
Expand Down
12 changes: 12 additions & 0 deletions src/client/metadataApiDeploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export class MetadataApiDeploy extends MetadataTransfer<
public constructor(options: MetadataApiDeployOptions) {
super(options);
options.apiOptions = { ...MetadataApiDeploy.DEFAULT_OPTIONS.apiOptions, ...options.apiOptions };
validateOptions(options);
this.options = Object.assign({}, options);
this.isRestDeploy = !!options.apiOptions?.rest;
this.registry = options.registry ?? new RegistryAccess();
Expand Down Expand Up @@ -524,6 +525,17 @@ const buildFileResponsesFromComponentSet =
}
return fileResponses;
};

const validateOptions = (options: MetadataApiDeployOptions): void => {
const runningRelevantTestsOnly = options.apiOptions?.testLevel === 'RunRelevantTests';
const beforeApiV66 = options.apiVersion && Number(options.apiVersion) < 66.0;
if (runningRelevantTestsOnly && beforeApiV66) {
throw new SfError(
messages.getMessage('error_invalid_test_level', ['RunRelevantTests', '66.0']),
'InvalidTestLevelSelection'
);
}
};
/**
* register a listener to `scopedPreDeploy`
*/
Expand Down
2 changes: 1 addition & 1 deletion src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ export type MetadataApiDeployOptions = {
runAllTests?: boolean;
runTests?: string[];
singlePackage?: boolean;
testLevel?: 'NoTestRun' | 'RunSpecifiedTests' | 'RunLocalTests' | 'RunAllTestsInOrg';
testLevel?: 'NoTestRun' | 'RunSpecifiedTests' | 'RunLocalTests' | 'RunAllTestsInOrg' | 'RunRelevantTests';
/**
* Set to true to use the REST API for deploying.
*/
Expand Down
20 changes: 19 additions & 1 deletion src/registry/metadataRegistry.json
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,9 @@
"dataMapperDefinition": "datamapperdefinition",
"integrationProcdDefinition": "integrationprocddefinition",
"omniscriptDefinition": "omniscriptdefinition",
"computeExtension": "computeextension"
"computeExtension": "computeextension",
"dataObjectSearchIndexConf": "dataobjectsearchindexconf",
"lightningOutApp": "lightningoutapp"
},
"types": {
"accesscontrolpolicy": {
Expand Down Expand Up @@ -5051,6 +5053,22 @@
"directoryName": "computeExtensions",
"inFolder": false,
"strictDirectoryName": false
},
"dataobjectsearchindexconf": {
"id": "dataobjectsearchindexconf",
"name": "DataObjectSearchIndexConf",
"suffix": "dataObjectSearchIndexConf",
"directoryName": "dataObjectSearchIndexConfs",
"inFolder": false,
"strictDirectoryName": false
},
"lightningoutapp": {
"id": "lightningoutapp",
"name": "LightningOutApp",
"suffix": "lightningOutApp",
"directoryName": "lightningOutApp",
"inFolder": false,
"strictDirectoryName": false
}
}
}
28 changes: 20 additions & 8 deletions src/resolve/treeContainers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ const messages = Messages.loadMessages('@salesforce/source-deploy-retrieve', 'sd
* Extend this base class to implement a custom container.
*/
export abstract class TreeContainer {
protected cwd?: string;

/** specify a cwd to use instead of the real cwd. Useful for tests and web environments where process.cwd is undefined */
public constructor(cwd?: string) {
this.cwd = cwd;
}
/**
* Searches for a metadata component file in a container directory.
*
Expand All @@ -46,14 +52,20 @@ export abstract class TreeContainer {
*/
public find(fileType: 'content' | 'metadataXml', name: string, directory: string): string | undefined {
const fileName = this.readDirectory(directory).find((entry) => {
const parsed = parseMetadataXml(join(directory, entry));
const parsed = parseMetadataXml(this.getUpdatedFsPath(join(directory, entry)));
const metaXmlCondition = fileType === 'metadataXml' ? !!parsed : !parsed;
return baseName(entry) === name && metaXmlCondition;
});
if (fileName) {
return join(directory, fileName);
return this.getUpdatedFsPath(join(directory, fileName));
}
}

/** if the container has cwd set, apply it to the path */
protected getUpdatedFsPath(fsPath: SourcePath): string {
return this.cwd ? join(this.cwd, fsPath) : fsPath;
}

/**
* Whether or not a file path exists in the container.
*
Expand Down Expand Up @@ -104,31 +116,31 @@ export abstract class TreeContainer {
export class NodeFSTreeContainer extends TreeContainer {
public isDirectory(fsPath: SourcePath): boolean {
// use stat instead of lstat to follow symlinks
return statSync(fsPath).isDirectory();
return statSync(this.getUpdatedFsPath(fsPath)).isDirectory();
}

public exists(fsPath: SourcePath): boolean {
return existsSync(fsPath);
return existsSync(this.getUpdatedFsPath(fsPath));
}

public readDirectory(fsPath: SourcePath): string[] {
return readdirSync(fsPath);
return readdirSync(this.getUpdatedFsPath(fsPath));
}

public readFile(fsPath: SourcePath): Promise<Buffer> {
// significant enough performance increase using sync instead of fs.promise version
return Promise.resolve(readFileSync(fsPath));
return Promise.resolve(readFileSync(this.getUpdatedFsPath(fsPath)));
}

public readFileSync(fsPath: SourcePath): Buffer {
return readFileSync(fsPath);
return readFileSync(this.getUpdatedFsPath(fsPath));
}

public stream(fsPath: SourcePath): Readable {
if (!this.exists(fsPath)) {
throw new Error(`File not found: ${fsPath}`);
}
return createReadStream(fsPath);
return createReadStream(this.getUpdatedFsPath(fsPath));
}
}

Expand Down
24 changes: 24 additions & 0 deletions test/client/metadataApiDeploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,30 @@ describe('MetadataApiDeploy', () => {
expect(mdOpts.zipPath).to.equal('foo/myZip.zip');
});

it('should disallow "RunRelevantTests" for API versions <66.0', () => {
const testCases = ['8.0', '10.0', '60.0', '65.0'];
const constructorError = {
name: 'InvalidTestLevelSelection',
message: messages.getMessage('error_invalid_test_level', ['RunRelevantTests', '66.0']),
};
try {
testCases.forEach((v) => {
new MetadataApiDeploy({
usernameOrConnection: 'testing',
apiOptions: {
testLevel: 'RunRelevantTests',
},
apiVersion: v,
});
assert.fail(`Should have thrown an error for API version ${v}`);
});
} catch (e) {
assert(e instanceof Error);
expect(e.name).to.equal(constructorError.name);
expect(e.message).to.equal(constructorError.message);
}
});

it('should allow mdapi path', () => {
const mdApiDeploy = new MetadataApiDeploy({
usernameOrConnection: 'testing',
Expand Down