diff --git a/CHANGELOG.md b/CHANGELOG.md index 8494e4258c..29159d7df3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# [11.1.0](https://github.com/forcedotcom/source-deploy-retrieve/compare/11.0.2...11.1.0) (2024-04-23) + + +### Features + +* allow destructive changes with MetadataOptions ([#1294](https://github.com/forcedotcom/source-deploy-retrieve/issues/1294)) ([7dad1c7](https://github.com/forcedotcom/source-deploy-retrieve/commit/7dad1c7be70cfc6a50d78671d796753d9747154b)) + + + ## [11.0.2](https://github.com/forcedotcom/source-deploy-retrieve/compare/11.0.1...11.0.2) (2024-04-21) diff --git a/METADATA_SUPPORT.md b/METADATA_SUPPORT.md index 6a79f68410..5c592882ff 100644 --- a/METADATA_SUPPORT.md +++ b/METADATA_SUPPORT.md @@ -8,631 +8,629 @@ Currently, there are 565/597 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) -|Metadata Type|Support|Notes| -|:---|:---|:---| -|AIApplication|✅|| -|AIApplicationConfig|✅|| -|AIReplyRecommendationsSettings|✅|| -|AIScoringModelDefVersion|✅|| -|AIScoringModelDefinition|✅|| -|AIUsecaseDefinition|⚠️|Supports deploy/retrieve but not source tracking| -|AccountForecastSettings|✅|| -|AccountIntelligenceSettings|✅|| -|AccountRelationshipShareRule|✅|| -|AccountSettings|✅|| -|AccountingFieldMapping|✅|| -|AccountingModelConfig|✅|| -|AccountingSettings|✅|| -|AcctMgrTargetSettings|✅|| -|ActionLauncherItemDef|✅|| -|ActionLinkGroupTemplate|✅|| -|ActionPlanTemplate|✅|| -|ActionableEventOrchDef|✅|| -|ActionableEventTypeDef|✅|| -|ActionableListDefinition|✅|| -|ActionsSettings|✅|| -|ActivationPlatform|✅|| -|ActivitiesSettings|✅|| -|ActnblListKeyPrfmIndDef|✅|| -|AddressSettings|✅|| -|AdvAccountForecastSet|✅|| -|AdvAcctForecastDimSource|✅|| -|AdvAcctForecastPeriodGroup|✅|| -|Ai4mSettings|✅|| -|AnalyticSnapshot|✅|| -|AnalyticsSettings|✅|| -|AnimationRule|✅|| -|ApexClass|✅|| -|ApexComponent|✅|| -|ApexEmailNotifications|✅|| -|ApexPage|✅|| -|ApexSettings|✅|| -|ApexTestSuite|✅|| -|ApexTrigger|✅|| -|AppAnalyticsSettings|✅|| -|AppExperienceSettings|✅|| -|AppMenu|✅|| -|ApplicationRecordTypeConfig|✅|| -|ApplicationSubtypeDefinition|✅|| -|AppointmentAssignmentPolicy|✅|| -|AppointmentSchedulingPolicy|✅|| -|ApprovalProcess|✅|| -|AssessmentConfiguration|❌|Not supported, but support could be added| -|AssessmentQuestion|✅|| -|AssessmentQuestionSet|✅|| -|AssignmentRules|✅|| -|AssistantContextItem|✅|| -|AssistantDefinition|✅|| -|AssistantSkillQuickAction|✅|| -|AssistantSkillSobjectAction|✅|| -|AssistantVersion|✅|| -|AssociationEngineSettings|✅|| -|Audience|✅|| -|AuraDefinitionBundle|✅|| -|AuthProvider|✅|| -|AutoResponseRules|✅|| -|AutomatedContactsSettings|✅|| -|BatchCalcJobDefinition|✅|| -|BatchProcessJobDefinition|✅|| -|BenefitAction|✅|| -|BlacklistedConsumer|✅|| -|BldgEnrgyIntensityCnfg|✅|| -|BlockchainSettings|✅|| -|Bot|✅|| -|BotBlock|✅|| -|BotBlockVersion|❌|Not supported, but support could be added| -|BotSettings|✅|| -|BotTemplate|✅|| -|BotVersion|✅|| -|BranchManagementSettings|✅|| -|BrandingSet|✅|| -|BriefcaseDefinition|✅|| -|BusinessHoursSettings|✅|| -|BusinessProcess|✅|| -|BusinessProcessGroup|✅|| -|BusinessProcessTypeDefinition|✅|| -|CMSConnectSource|✅|| -|CallCenter|✅|| -|CallCenterRoutingMap|✅|| -|CallCoachingMediaProvider|⚠️|Supports deploy/retrieve but not source tracking| -|CampaignInfluenceModel|✅|| -|CampaignSettings|✅|| -|CanvasMetadata|✅|| -|CareBenefitVerifySettings|✅|| -|CareLimitType|✅|| -|CareProviderAfflRoleConfig|✅|| -|CareProviderSearchConfig|✅|| -|CareRequestConfiguration|✅|| -|CareSystemFieldMapping|✅|| -|CaseSettings|✅|| -|CaseSubjectParticle|✅|| -|Certificate|✅|| -|ChannelLayout|✅|| -|ChannelObjectLinkingRule|✅|| -|ChatterAnswersSettings|✅|| -|ChatterEmailsMDSettings|✅|| -|ChatterExtension|✅|| -|ChatterSettings|✅|| -|ClaimFinancialSettings|✅|| -|ClaimMgmtFoundationEnabledSettings|✅|| -|ClauseCatgConfiguration|✅|| -|CleanDataService|✅|| -|CodeBuilderSettings|✅|| -|CollectionsDashboardSettings|✅|| -|CommandAction|✅|| -|CommerceSettings|✅|| -|CommsServiceConsoleSettings|✅|| -|CommunitiesSettings|✅|| -|Community|✅|| -|CommunityTemplateDefinition|✅|| -|CommunityThemeDefinition|✅|| -|CompactLayout|✅|| -|CompanySettings|✅|| -|ConnectedApp|✅|| -|ConnectedAppSettings|✅|| -|ContentAsset|✅|| -|ContentSettings|✅|| -|ContextDefinition|⚠️|Supports deploy/retrieve but not source tracking| -|ContractSettings|✅|| -|ContractType|❌|Not supported, but support could be added| -|ConversationChannelDefinition|✅|| -|ConversationServiceIntegrationSettings|✅|| -|ConversationVendorInfo|✅|| -|ConversationalIntelligenceSettings|✅|| -|CorsWhitelistOrigin|✅|| -|CspTrustedSite|✅|| -|CurrencySettings|✅|| -|CustomAddressFieldSettings|✅|| -|CustomApplication|✅|| -|CustomApplicationComponent|✅|| -|CustomFeedFilter|✅|| -|CustomField|✅|| -|CustomHelpMenuSection|✅|| -|CustomIndex|✅|| -|CustomLabels|✅|| -|CustomMetadata|✅|| -|CustomNotificationType|✅|| -|CustomObject|✅|| -|CustomObjectTranslation|✅|| -|CustomPageWebLink|✅|| -|CustomPermission|✅|| -|CustomSite|✅|| -|CustomTab|✅|| -|CustomValue|❌|Not supported, but support could be added| -|CustomerDataPlatformSettings|✅|| -|CustomizablePropensityScoringSettings|✅|| -|Dashboard|✅|| -|DashboardFolder|✅|| -|DataCalcInsightTemplate|✅|| -|DataCategoryGroup|✅|| -|DataConnectionParamTmpl|❌|Not supported, but support could be added| -|DataConnectorIngestApi|✅|| -|DataConnectorS3|✅|| -|DataDotComSettings|✅|| -|DataImportManagementSettings|✅|| -|DataKitObjectTemplate|✅|| -|DataPackageKitDefinition|✅|| -|DataPackageKitObject|✅|| -|DataSource|✅|| -|DataSourceBundleDefinition|✅|| -|DataSourceObject|✅|| -|DataSourceTenant|✅|| -|DataSrcDataModelFieldMap|✅|| -|DataStreamDefinition|✅|| -|DataStreamTemplate|✅|| -|DataWeaveResource|✅|| -|DecisionMatrixDefinition|✅|| -|DecisionMatrixDefinitionVersion|✅|| -|DecisionTable|✅|| -|DecisionTableDatasetLink|✅|| -|DelegateGroup|✅|| -|DeploymentSettings|✅|| -|DevHubSettings|✅|| -|DigitalExperience|✅|| -|DigitalExperienceBundle|✅|| -|DigitalExperienceConfig|✅|| -|DisclosureDefinition|✅|| -|DisclosureDefinitionVersion|✅|| -|DisclosureType|✅|| -|DiscoveryAIModel|✅|| -|DiscoveryGoal|✅|| -|DiscoverySettings|✅|| -|DiscoveryStory|✅|| -|Document|✅|| -|DocumentCategory|✅|| -|DocumentCategoryDocumentType|✅|| -|DocumentChecklistSettings|✅|| -|DocumentFolder|✅|| -|DocumentGenerationSetting|✅|| -|DocumentType|✅|| -|DuplicateRule|✅|| -|DynamicFormsSettings|✅|| -|EACSettings|✅|| -|ESignatureConfig|✅|| -|ESignatureEnvelopeConfig|✅|| -|EclairGeoData|✅|| -|EinsteinAISettings|✅|| -|EinsteinAgentSettings|✅|| -|EinsteinAssistantSettings|✅|| -|EinsteinCopilotSettings|✅|| -|EinsteinDealInsightsSettings|✅|| -|EinsteinDocumentCaptureSettings|✅|| -|EinsteinGptSettings|✅|| -|EmailAdministrationSettings|✅|| -|EmailFolder|✅|| -|EmailIntegrationSettings|✅|| -|EmailServicesFunction|✅|| -|EmailTemplate|✅|| -|EmailTemplateFolder|✅|| -|EmailTemplateSettings|✅|| -|EmbeddedServiceBranding|✅|| -|EmbeddedServiceConfig|✅|| -|EmbeddedServiceFlowConfig|✅|| -|EmbeddedServiceLiveAgent|✅|| -|EmbeddedServiceMenuSettings|✅|| -|EmployeeDataSyncProfile|❌|Not supported, but support could be added| -|EmployeeFieldAccessSettings|✅|| -|EmployeeUserSettings|✅|| -|EnhancedNotesSettings|✅|| -|EntitlementProcess|✅|| -|EntitlementSettings|✅|| -|EntitlementTemplate|✅|| -|EscalationRules|✅|| -|EssentialsSettings|✅|| -|EventLogObjectSettings|✅|| -|EventSettings|✅|| -|ExperienceBundle|✅|| -|ExperienceBundleSettings|✅|| -|ExperiencePropertyTypeBundle|✅|| -|ExplainabilityActionDefinition|✅|| -|ExplainabilityActionVersion|✅|| -|ExplainabilityMsgTemplate|✅|| -|ExpressionSetDefinition|✅|| -|ExpressionSetDefinitionVersion|✅|| -|ExpressionSetMessageToken|✅|| -|ExpressionSetObjectAlias|✅|| -|ExtDataTranFieldTemplate|❌|Not supported, but support could be added| -|ExtDataTranObjectTemplate|✅|| -|ExternalAIModel|✅|| -|ExternalClientAppSettings|✅|| -|ExternalClientApplication|✅|| -|ExternalCredential|✅|| -|ExternalDataConnector|✅|| -|ExternalDataSource|✅|| -|ExternalDataSrcDescriptor|❌|Not supported, but support could be added| -|ExternalDataTranField|❌|Not supported, but support could be added| -|ExternalDataTranObject|❌|Not supported, but support could be added| -|ExternalDocStorageConfig|❌|Not supported, but support could be added| -|ExternalServiceRegistration|✅|| -|ExtlClntAppConfigurablePolicies|✅|| -|ExtlClntAppGlobalOauthSettings|✅|| -|ExtlClntAppMobileConfigurablePolicies|✅|| -|ExtlClntAppMobileSettings|✅|| -|ExtlClntAppNotificationSettings|✅|| -|ExtlClntAppOauthConfigurablePolicies|✅|| -|ExtlClntAppOauthSettings|✅|| -|FeatureParameterBoolean|✅|| -|FeatureParameterDate|✅|| -|FeatureParameterInteger|✅|| -|FieldRestrictionRule|✅|| -|FieldServiceMobileExtension|✅|| -|FieldServiceSettings|✅|| -|FieldSet|✅|| -|FieldSrcTrgtRelationship|✅|| -|FileUploadAndDownloadSecuritySettings|✅|| -|FilesConnectSettings|✅|| -|FlexiPage|✅|| -|Flow|✅|| -|FlowCategory|✅|| -|FlowDefinition|⚠️|Supports deploy/retrieve but not source tracking| -|FlowSettings|✅|| -|FlowTest|✅|| -|ForecastingFilter|✅|| -|ForecastingFilterCondition|✅|| -|ForecastingObjectListSettings|✅|| -|ForecastingSettings|✅|| -|ForecastingSourceDefinition|✅|| -|ForecastingType|✅|| -|ForecastingTypeSource|✅|| -|FormulaSettings|✅|| -|FuelType|✅|| -|FuelTypeSustnUom|✅|| -|FunctionReference|⚠️|Supports deploy/retrieve but not source tracking| -|FundraisingConfig|✅|| -|GatewayProviderPaymentMethodType|✅|| -|GenAiFunction|❌|Not supported, but support could be added| -|GenAiPlanner|❌|Not supported, but support could be added| -|GenAiPlugin|❌|Not supported, but support could be added| -|GlobalValueSet|✅|| -|GlobalValueSetTranslation|✅|| -|GoogleAppsSettings|✅|| -|Group|✅|| -|HighVelocitySalesSettings|✅|| -|HomePageComponent|✅|| -|HomePageLayout|✅|| -|IPAddressRange|✅|| -|Icon|✅|| -|IdeasSettings|✅|| -|IdentityProviderSettings|✅|| -|IdentityVerificationProcDef|✅|| -|IframeWhiteListUrlSettings|✅|| -|InboundCertificate|✅|| -|InboundNetworkConnection|✅|| -|IncidentMgmtSettings|✅|| -|IncludeEstTaxInQuoteCPQSettings|✅|| -|IncludeEstTaxInQuoteSettings|✅|| -|Index|⚠️|Supports deploy/retrieve but not source tracking| -|IndustriesAutomotiveSettings|✅|| -|IndustriesContextSettings|✅|| -|IndustriesEinsteinFeatureSettings|✅|| -|IndustriesEventOrchSettings|✅|| -|IndustriesFieldServiceSettings|✅|| -|IndustriesGamificationSettings|✅|| -|IndustriesLoyaltySettings|✅|| -|IndustriesManufacturingSettings|✅|| -|IndustriesPricingSettings|✅|| -|IndustriesSettings|✅|| -|IndustriesUnifiedPromotionsSettings|✅|| -|InstalledPackage|⚠️|Supports deploy/retrieve but not source tracking| -|IntegrationProviderDef|✅|| -|InterestTaggingSettings|✅|| -|InternalDataConnector|✅|| -|InvLatePymntRiskCalcSettings|✅|| -|InventorySettings|✅|| -|InvocableActionSettings|✅|| -|IoTSettings|✅|| -|KeywordList|✅|| -|KnowledgeGenerationSettings|✅|| -|KnowledgeSettings|✅|| -|LanguageSettings|✅|| -|Layout|✅|| -|LeadConfigSettings|✅|| -|LeadConvertSettings|✅|| -|LearningAchievementConfig|❌|Not supported, but support could be added| -|Letterhead|✅|| -|LicensingSettings|✅|| -|LightningBolt|✅|| -|LightningComponentBundle|✅|| -|LightningExperienceSettings|✅|| -|LightningExperienceTheme|✅|| -|LightningMessageChannel|✅|| -|LightningOnboardingConfig|✅|| -|ListView|✅|| -|LiveAgentSettings|✅|| -|LiveChatAgentConfig|✅|| -|LiveChatButton|✅|| -|LiveChatDeployment|✅|| -|LiveChatSensitiveDataRule|✅|| -|LiveMessageSettings|✅|| -|LocationUse|✅|| -|LoyaltyProgramSetup|⚠️|Supports deploy/retrieve but not source tracking| -|MacroSettings|✅|| -|MailMergeSettings|✅|| -|ManagedContentType|⚠️|Supports deploy/retrieve but not source tracking| -|ManagedEventSubscription|✅|| -|ManagedTopics|✅|| -|MapsAndLocationSettings|✅|| -|MarketSegmentDefinition|✅|| -|MarketingAppExtActivity|❌|Not supported, but support could be added| -|MarketingAppExtension|✅|| -|MatchingRules|✅|| -|MediaAdSalesSettings|✅|| -|MeetingsSettings|✅|| -|MessagingChannel|⚠️|Supports deploy/retrieve but not source tracking| -|MfgProgramTemplate|✅|| -|MfgServiceConsoleSettings|✅|| -|MilestoneType|✅|| -|MktCalcInsightObjectDef|✅|| -|MktDataConnection|❌|Not supported, but support could be added| -|MktDataConnectionCred|❌|Not supported, but support could be added| -|MktDataConnectionParam|❌|Not supported, but support could be added| -|MktDataConnectionSrcParam|❌|Not supported, but support could be added| -|MktDataTranObject|✅|| -|MlDomain|✅|| -|MobSecurityCertPinConfig|✅|| -|MobileApplicationDetail|✅|| -|MobileSecurityAssignment|✅|| -|MobileSecurityPolicy|✅|| -|MobileSettings|✅|| -|ModerationRule|✅|| -|MutingPermissionSet|✅|| -|MyDomainDiscoverableLogin|✅|| -|MyDomainSettings|✅|| -|NameSettings|✅|| -|NamedCredential|✅|| -|NavigationMenu|✅|| -|Network|✅|| -|NetworkBranding|✅|| -|NotificationTypeConfig|✅|| -|NotificationsSettings|✅|| -|OauthCustomScope|✅|| -|OauthOidcSettings|✅|| -|OauthTokenExchangeHandler|✅|| -|ObjectHierarchyRelationship|✅|| -|ObjectLinkingSettings|✅|| -|ObjectSourceTargetMap|✅|| -|OcrSampleDocument|✅|| -|OcrTemplate|✅|| -|OmniChannelPricingSettings|✅|| -|OmniChannelSettings|✅|| -|OmniDataTransform|⚠️|Supports deploy/retrieve but not source tracking| -|OmniExtTrackingDef|⚠️|Supports deploy/retrieve but not source tracking| -|OmniIntegrationProcedure|⚠️|Supports deploy/retrieve but not source tracking| -|OmniInteractionAccessConfig|⚠️|Supports deploy/retrieve but not source tracking| -|OmniInteractionConfig|⚠️|Supports deploy/retrieve but not source tracking| -|OmniScript|⚠️|Supports deploy/retrieve but not source tracking| -|OmniSupervisorConfig|✅|| -|OmniTrackingGroup|⚠️|Supports deploy/retrieve but not source tracking| -|OmniUiCard|⚠️|Supports deploy/retrieve but not source tracking| -|OnlineSalesSettings|✅|| -|OpportunityScoreSettings|✅|| -|OpportunitySettings|✅|| -|OrderManagementSettings|✅|| -|OrderSettings|✅|| -|OrgSettings|✅|| -|OutboundNetworkConnection|✅|| -|PardotEinsteinSettings|✅|| -|PardotSettings|✅|| -|ParticipantRole|✅|| -|PartyDataModelSettings|✅|| -|PathAssistant|✅|| -|PathAssistantSettings|✅|| -|PaymentGatewayProvider|✅|| -|PaymentsManagementEnabledSettings|✅|| -|PaymentsSettings|✅|| -|PermissionSet|✅|| -|PermissionSetGroup|✅|| -|PermissionSetLicenseDefinition|✅|| -|PersonAccountOwnerPowerUser|✅|| -|PicklistSettings|✅|| -|PicklistValue|❌|Not supported, but support could be added| -|PipelineInspMetricConfig|✅|| -|PlatformCachePartition|✅|| -|PlatformEventChannel|✅|| -|PlatformEventChannelMember|✅|| -|PlatformEventSettings|✅|| -|PlatformEventSubscriberConfig|✅|| -|PlatformSlackSettings|✅|| -|PortalDelegablePermissionSet|❌|Not supported, but support could be added| -|PortalsSettings|✅|| -|PostTemplate|✅|| -|PredictionBuilderSettings|✅|| -|PresenceDeclineReason|✅|| -|PresenceUserConfig|✅|| -|PricingActionParameters|⚠️|Supports deploy/retrieve but not source tracking| -|PricingRecipe|✅|| -|PrivacySettings|✅|| -|ProcessFlowMigration|✅|| -|ProductAttrDisplayConfig|❌|Not supported, but support could be added| -|ProductAttributeSet|✅|| -|ProductConfiguratorSettings|✅|| -|ProductSettings|✅|| -|ProductSpecificationRecType|❌|Not supported, but support could be added| -|ProductSpecificationType|❌|Not supported, but support could be added| -|Profile|✅|| -|ProfilePasswordPolicy|✅|| -|ProfileSessionSetting|✅|| -|Prompt|✅|| -|Queue|✅|| -|QueueRoutingConfig|✅|| -|QuickAction|✅|| -|QuickTextSettings|✅|| -|QuoteSettings|✅|| -|RealTimeEventSettings|✅|| -|RecAlrtDataSrcExpSetDef|❌|Not supported, but support could be added| -|RecommendationBuilderSettings|✅|| -|RecommendationStrategy|✅|| -|RecordActionDeployment|✅|| -|RecordAggregationDefinition|✅|| -|RecordAlertCategory|✅|| -|RecordAlertDataSource|✅|| -|RecordAlertTemplate|❌|Not supported, but support could be added| -|RecordPageSettings|✅|| -|RecordType|✅|| -|RedirectWhitelistUrl|✅|| -|ReferencedDashboard|❌|Not supported, but support could be added| -|ReferralMarketingSettings|✅|| -|RegisteredExternalService|✅|| -|RelatedRecordAssocCriteria|❌|Not supported, but support could be added| -|RelationshipGraphDefinition|✅|| -|RemoteSiteSetting|✅|| -|Report|✅|| -|ReportFolder|✅|| -|ReportType|✅|| -|RestrictionRule|✅|| -|RetailExecutionSettings|✅|| -|RevenueManagementSettings|✅|| -|Role|✅|| -|SalesAgreementSettings|✅|| -|SalesWorkQueueSettings|✅|| -|SamlSsoConfig|✅|| -|SandboxSettings|✅|| -|SceGlobalModelOptOutSettings|✅|| -|SchedulingObjective|✅|| -|SchedulingRule|✅|| -|SchemaSettings|✅|| -|ScoreCategory|✅|| -|SearchSettings|✅|| -|SecuritySettings|✅|| -|ServiceAISetupDefinition|✅|| -|ServiceAISetupField|✅|| -|ServiceChannel|✅|| -|ServiceCloudVoiceSettings|✅|| -|ServicePresenceStatus|✅|| -|ServiceProcess|✅|| -|ServiceSetupAssistantSettings|✅|| -|SharingCriteriaRule|✅|| -|SharingGuestRule|✅|| -|SharingOwnerRule|✅|| -|SharingReason|✅|| -|SharingRules|⚠️|Supports deploy/retrieve but not source tracking| -|SharingSet|✅|| -|SharingSettings|✅|| -|SharingTerritoryRule|✅|| -|SiteDotCom|✅|| -|SiteSettings|✅|| -|Skill|✅|| -|SkillType|✅|| -|SlackApp|✅|| -|SocialCustomerServiceSettings|✅|| -|SourceTrackingSettings|✅|| -|StandardValue|❌|Not supported, but support could be added| -|StandardValueSet|✅|| -|StandardValueSetTranslation|✅|| -|StaticResource|✅|| -|StnryAssetEnvSrcCnfg|✅|| -|StreamingAppDataConnector|✅|| -|SubscriptionManagementSettings|✅|| -|SurveySettings|✅|| -|SustainabilityUom|✅|| -|SustnUomConversion|✅|| -|SvcCatalogCategory|✅|| -|SvcCatalogFilterCriteria|✅|| -|SvcCatalogFulfillmentFlow|✅|| -|SvcCatalogItemDef|✅|| -|SynonymDictionary|✅|| -|SystemNotificationSettings|✅|| -|Territory|✅|| -|Territory2|✅|| -|Territory2Model|✅|| -|Territory2Rule|✅|| -|Territory2Settings|✅|| -|Territory2Type|✅|| -|TimeSheetTemplate|✅|| -|TimelineObjectDefinition|✅|| -|TopicsForObjects|✅|| -|TrailheadSettings|✅|| -|TransactionSecurityPolicy|✅|| -|Translations|✅|| -|TrialOrgSettings|✅|| -|UIObjectRelationConfig|✅|| -|UiPlugin|✅|| -|UserAccessPolicy|✅|| -|UserAuthCertificate|✅|| -|UserCriteria|✅|| -|UserEngagementSettings|✅|| -|UserInterfaceSettings|✅|| -|UserManagementSettings|✅|| -|UserProfileSearchScope|✅|| -|UserProvisioningConfig|✅|| -|ValidationRule|✅|| -|VehicleAssetEmssnSrcCnfg|✅|| -|ViewDefinition|✅|| -|VirtualVisitConfig|❌|Not supported, but support could be added| -|VoiceSettings|✅|| -|WarrantyLifecycleMgmtSettings|✅|| -|WaveApplication|✅|| -|WaveComponent|✅|| -|WaveDashboard|✅|| -|WaveDataflow|✅|| -|WaveDataset|✅|| -|WaveLens|✅|| -|WaveRecipe|✅|| -|WaveTemplateBundle|✅|| -|WaveXmd|✅|| -|Web3Settings|✅|| -|WebLink|✅|| -|WebStoreBundle|✅|| -|WebStoreTemplate|✅|| -|WebToXSettings|✅|| -|WorkDotComSettings|✅|| -|WorkSkillRouting|✅|| -|Workflow|✅|| -|WorkflowAlert|✅|| -|WorkflowFieldUpdate|✅|| -|WorkflowFlowAction|❌|Not supported, but support could be added| -|WorkflowKnowledgePublish|✅|| -|WorkflowOutboundMessage|✅|| -|WorkflowRule|✅|| -|WorkflowSend|✅|| -|WorkflowTask|✅|| -|WorkforceEngagementSettings|✅|| - - +| Metadata Type | Support | Notes | +| :------------------------------------- | :------ | :----------------------------------------------- | +| AIApplication | ✅ | | +| AIApplicationConfig | ✅ | | +| AIReplyRecommendationsSettings | ✅ | | +| AIScoringModelDefVersion | ✅ | | +| AIScoringModelDefinition | ✅ | | +| AIUsecaseDefinition | ⚠️ | Supports deploy/retrieve but not source tracking | +| AccountForecastSettings | ✅ | | +| AccountIntelligenceSettings | ✅ | | +| AccountRelationshipShareRule | ✅ | | +| AccountSettings | ✅ | | +| AccountingFieldMapping | ✅ | | +| AccountingModelConfig | ✅ | | +| AccountingSettings | ✅ | | +| AcctMgrTargetSettings | ✅ | | +| ActionLauncherItemDef | ✅ | | +| ActionLinkGroupTemplate | ✅ | | +| ActionPlanTemplate | ✅ | | +| ActionableEventOrchDef | ✅ | | +| ActionableEventTypeDef | ✅ | | +| ActionableListDefinition | ✅ | | +| ActionsSettings | ✅ | | +| ActivationPlatform | ✅ | | +| ActivitiesSettings | ✅ | | +| ActnblListKeyPrfmIndDef | ✅ | | +| AddressSettings | ✅ | | +| AdvAccountForecastSet | ✅ | | +| AdvAcctForecastDimSource | ✅ | | +| AdvAcctForecastPeriodGroup | ✅ | | +| Ai4mSettings | ✅ | | +| AnalyticSnapshot | ✅ | | +| AnalyticsSettings | ✅ | | +| AnimationRule | ✅ | | +| ApexClass | ✅ | | +| ApexComponent | ✅ | | +| ApexEmailNotifications | ✅ | | +| ApexPage | ✅ | | +| ApexSettings | ✅ | | +| ApexTestSuite | ✅ | | +| ApexTrigger | ✅ | | +| AppAnalyticsSettings | ✅ | | +| AppExperienceSettings | ✅ | | +| AppMenu | ✅ | | +| ApplicationRecordTypeConfig | ✅ | | +| ApplicationSubtypeDefinition | ✅ | | +| AppointmentAssignmentPolicy | ✅ | | +| AppointmentSchedulingPolicy | ✅ | | +| ApprovalProcess | ✅ | | +| AssessmentConfiguration | ❌ | Not supported, but support could be added | +| AssessmentQuestion | ✅ | | +| AssessmentQuestionSet | ✅ | | +| AssignmentRules | ✅ | | +| AssistantContextItem | ✅ | | +| AssistantDefinition | ✅ | | +| AssistantSkillQuickAction | ✅ | | +| AssistantSkillSobjectAction | ✅ | | +| AssistantVersion | ✅ | | +| AssociationEngineSettings | ✅ | | +| Audience | ✅ | | +| AuraDefinitionBundle | ✅ | | +| AuthProvider | ✅ | | +| AutoResponseRules | ✅ | | +| AutomatedContactsSettings | ✅ | | +| BatchCalcJobDefinition | ✅ | | +| BatchProcessJobDefinition | ✅ | | +| BenefitAction | ✅ | | +| BlacklistedConsumer | ✅ | | +| BldgEnrgyIntensityCnfg | ✅ | | +| BlockchainSettings | ✅ | | +| Bot | ✅ | | +| BotBlock | ✅ | | +| BotBlockVersion | ❌ | Not supported, but support could be added | +| BotSettings | ✅ | | +| BotTemplate | ✅ | | +| BotVersion | ✅ | | +| BranchManagementSettings | ✅ | | +| BrandingSet | ✅ | | +| BriefcaseDefinition | ✅ | | +| BusinessHoursSettings | ✅ | | +| BusinessProcess | ✅ | | +| BusinessProcessGroup | ✅ | | +| BusinessProcessTypeDefinition | ✅ | | +| CMSConnectSource | ✅ | | +| CallCenter | ✅ | | +| CallCenterRoutingMap | ✅ | | +| CallCoachingMediaProvider | ⚠️ | Supports deploy/retrieve but not source tracking | +| CampaignInfluenceModel | ✅ | | +| CampaignSettings | ✅ | | +| CanvasMetadata | ✅ | | +| CareBenefitVerifySettings | ✅ | | +| CareLimitType | ✅ | | +| CareProviderAfflRoleConfig | ✅ | | +| CareProviderSearchConfig | ✅ | | +| CareRequestConfiguration | ✅ | | +| CareSystemFieldMapping | ✅ | | +| CaseSettings | ✅ | | +| CaseSubjectParticle | ✅ | | +| Certificate | ✅ | | +| ChannelLayout | ✅ | | +| ChannelObjectLinkingRule | ✅ | | +| ChatterAnswersSettings | ✅ | | +| ChatterEmailsMDSettings | ✅ | | +| ChatterExtension | ✅ | | +| ChatterSettings | ✅ | | +| ClaimFinancialSettings | ✅ | | +| ClaimMgmtFoundationEnabledSettings | ✅ | | +| ClauseCatgConfiguration | ✅ | | +| CleanDataService | ✅ | | +| CodeBuilderSettings | ✅ | | +| CollectionsDashboardSettings | ✅ | | +| CommandAction | ✅ | | +| CommerceSettings | ✅ | | +| CommsServiceConsoleSettings | ✅ | | +| CommunitiesSettings | ✅ | | +| Community | ✅ | | +| CommunityTemplateDefinition | ✅ | | +| CommunityThemeDefinition | ✅ | | +| CompactLayout | ✅ | | +| CompanySettings | ✅ | | +| ConnectedApp | ✅ | | +| ConnectedAppSettings | ✅ | | +| ContentAsset | ✅ | | +| ContentSettings | ✅ | | +| ContextDefinition | ⚠️ | Supports deploy/retrieve but not source tracking | +| ContractSettings | ✅ | | +| ContractType | ❌ | Not supported, but support could be added | +| ConversationChannelDefinition | ✅ | | +| ConversationServiceIntegrationSettings | ✅ | | +| ConversationVendorInfo | ✅ | | +| ConversationalIntelligenceSettings | ✅ | | +| CorsWhitelistOrigin | ✅ | | +| CspTrustedSite | ✅ | | +| CurrencySettings | ✅ | | +| CustomAddressFieldSettings | ✅ | | +| CustomApplication | ✅ | | +| CustomApplicationComponent | ✅ | | +| CustomFeedFilter | ✅ | | +| CustomField | ✅ | | +| CustomHelpMenuSection | ✅ | | +| CustomIndex | ✅ | | +| CustomLabels | ✅ | | +| CustomMetadata | ✅ | | +| CustomNotificationType | ✅ | | +| CustomObject | ✅ | | +| CustomObjectTranslation | ✅ | | +| CustomPageWebLink | ✅ | | +| CustomPermission | ✅ | | +| CustomSite | ✅ | | +| CustomTab | ✅ | | +| CustomValue | ❌ | Not supported, but support could be added | +| CustomerDataPlatformSettings | ✅ | | +| CustomizablePropensityScoringSettings | ✅ | | +| Dashboard | ✅ | | +| DashboardFolder | ✅ | | +| DataCalcInsightTemplate | ✅ | | +| DataCategoryGroup | ✅ | | +| DataConnectionParamTmpl | ❌ | Not supported, but support could be added | +| DataConnectorIngestApi | ✅ | | +| DataConnectorS3 | ✅ | | +| DataDotComSettings | ✅ | | +| DataImportManagementSettings | ✅ | | +| DataKitObjectTemplate | ✅ | | +| DataPackageKitDefinition | ✅ | | +| DataPackageKitObject | ✅ | | +| DataSource | ✅ | | +| DataSourceBundleDefinition | ✅ | | +| DataSourceObject | ✅ | | +| DataSourceTenant | ✅ | | +| DataSrcDataModelFieldMap | ✅ | | +| DataStreamDefinition | ✅ | | +| DataStreamTemplate | ✅ | | +| DataWeaveResource | ✅ | | +| DecisionMatrixDefinition | ✅ | | +| DecisionMatrixDefinitionVersion | ✅ | | +| DecisionTable | ✅ | | +| DecisionTableDatasetLink | ✅ | | +| DelegateGroup | ✅ | | +| DeploymentSettings | ✅ | | +| DevHubSettings | ✅ | | +| DigitalExperience | ✅ | | +| DigitalExperienceBundle | ✅ | | +| DigitalExperienceConfig | ✅ | | +| DisclosureDefinition | ✅ | | +| DisclosureDefinitionVersion | ✅ | | +| DisclosureType | ✅ | | +| DiscoveryAIModel | ✅ | | +| DiscoveryGoal | ✅ | | +| DiscoverySettings | ✅ | | +| DiscoveryStory | ✅ | | +| Document | ✅ | | +| DocumentCategory | ✅ | | +| DocumentCategoryDocumentType | ✅ | | +| DocumentChecklistSettings | ✅ | | +| DocumentFolder | ✅ | | +| DocumentGenerationSetting | ✅ | | +| DocumentType | ✅ | | +| DuplicateRule | ✅ | | +| DynamicFormsSettings | ✅ | | +| EACSettings | ✅ | | +| ESignatureConfig | ✅ | | +| ESignatureEnvelopeConfig | ✅ | | +| EclairGeoData | ✅ | | +| EinsteinAISettings | ✅ | | +| EinsteinAgentSettings | ✅ | | +| EinsteinAssistantSettings | ✅ | | +| EinsteinCopilotSettings | ✅ | | +| EinsteinDealInsightsSettings | ✅ | | +| EinsteinDocumentCaptureSettings | ✅ | | +| EinsteinGptSettings | ✅ | | +| EmailAdministrationSettings | ✅ | | +| EmailFolder | ✅ | | +| EmailIntegrationSettings | ✅ | | +| EmailServicesFunction | ✅ | | +| EmailTemplate | ✅ | | +| EmailTemplateFolder | ✅ | | +| EmailTemplateSettings | ✅ | | +| EmbeddedServiceBranding | ✅ | | +| EmbeddedServiceConfig | ✅ | | +| EmbeddedServiceFlowConfig | ✅ | | +| EmbeddedServiceLiveAgent | ✅ | | +| EmbeddedServiceMenuSettings | ✅ | | +| EmployeeDataSyncProfile | ❌ | Not supported, but support could be added | +| EmployeeFieldAccessSettings | ✅ | | +| EmployeeUserSettings | ✅ | | +| EnhancedNotesSettings | ✅ | | +| EntitlementProcess | ✅ | | +| EntitlementSettings | ✅ | | +| EntitlementTemplate | ✅ | | +| EscalationRules | ✅ | | +| EssentialsSettings | ✅ | | +| EventLogObjectSettings | ✅ | | +| EventSettings | ✅ | | +| ExperienceBundle | ✅ | | +| ExperienceBundleSettings | ✅ | | +| ExperiencePropertyTypeBundle | ✅ | | +| ExplainabilityActionDefinition | ✅ | | +| ExplainabilityActionVersion | ✅ | | +| ExplainabilityMsgTemplate | ✅ | | +| ExpressionSetDefinition | ✅ | | +| ExpressionSetDefinitionVersion | ✅ | | +| ExpressionSetMessageToken | ✅ | | +| ExpressionSetObjectAlias | ✅ | | +| ExtDataTranFieldTemplate | ❌ | Not supported, but support could be added | +| ExtDataTranObjectTemplate | ✅ | | +| ExternalAIModel | ✅ | | +| ExternalClientAppSettings | ✅ | | +| ExternalClientApplication | ✅ | | +| ExternalCredential | ✅ | | +| ExternalDataConnector | ✅ | | +| ExternalDataSource | ✅ | | +| ExternalDataSrcDescriptor | ❌ | Not supported, but support could be added | +| ExternalDataTranField | ❌ | Not supported, but support could be added | +| ExternalDataTranObject | ❌ | Not supported, but support could be added | +| ExternalDocStorageConfig | ❌ | Not supported, but support could be added | +| ExternalServiceRegistration | ✅ | | +| ExtlClntAppConfigurablePolicies | ✅ | | +| ExtlClntAppGlobalOauthSettings | ✅ | | +| ExtlClntAppMobileConfigurablePolicies | ✅ | | +| ExtlClntAppMobileSettings | ✅ | | +| ExtlClntAppNotificationSettings | ✅ | | +| ExtlClntAppOauthConfigurablePolicies | ✅ | | +| ExtlClntAppOauthSettings | ✅ | | +| FeatureParameterBoolean | ✅ | | +| FeatureParameterDate | ✅ | | +| FeatureParameterInteger | ✅ | | +| FieldRestrictionRule | ✅ | | +| FieldServiceMobileExtension | ✅ | | +| FieldServiceSettings | ✅ | | +| FieldSet | ✅ | | +| FieldSrcTrgtRelationship | ✅ | | +| FileUploadAndDownloadSecuritySettings | ✅ | | +| FilesConnectSettings | ✅ | | +| FlexiPage | ✅ | | +| Flow | ✅ | | +| FlowCategory | ✅ | | +| FlowDefinition | ⚠️ | Supports deploy/retrieve but not source tracking | +| FlowSettings | ✅ | | +| FlowTest | ✅ | | +| ForecastingFilter | ✅ | | +| ForecastingFilterCondition | ✅ | | +| ForecastingObjectListSettings | ✅ | | +| ForecastingSettings | ✅ | | +| ForecastingSourceDefinition | ✅ | | +| ForecastingType | ✅ | | +| ForecastingTypeSource | ✅ | | +| FormulaSettings | ✅ | | +| FuelType | ✅ | | +| FuelTypeSustnUom | ✅ | | +| FunctionReference | ⚠️ | Supports deploy/retrieve but not source tracking | +| FundraisingConfig | ✅ | | +| GatewayProviderPaymentMethodType | ✅ | | +| GenAiFunction | ❌ | Not supported, but support could be added | +| GenAiPlanner | ❌ | Not supported, but support could be added | +| GenAiPlugin | ❌ | Not supported, but support could be added | +| GlobalValueSet | ✅ | | +| GlobalValueSetTranslation | ✅ | | +| GoogleAppsSettings | ✅ | | +| Group | ✅ | | +| HighVelocitySalesSettings | ✅ | | +| HomePageComponent | ✅ | | +| HomePageLayout | ✅ | | +| IPAddressRange | ✅ | | +| Icon | ✅ | | +| IdeasSettings | ✅ | | +| IdentityProviderSettings | ✅ | | +| IdentityVerificationProcDef | ✅ | | +| IframeWhiteListUrlSettings | ✅ | | +| InboundCertificate | ✅ | | +| InboundNetworkConnection | ✅ | | +| IncidentMgmtSettings | ✅ | | +| IncludeEstTaxInQuoteCPQSettings | ✅ | | +| IncludeEstTaxInQuoteSettings | ✅ | | +| Index | ⚠️ | Supports deploy/retrieve but not source tracking | +| IndustriesAutomotiveSettings | ✅ | | +| IndustriesContextSettings | ✅ | | +| IndustriesEinsteinFeatureSettings | ✅ | | +| IndustriesEventOrchSettings | ✅ | | +| IndustriesFieldServiceSettings | ✅ | | +| IndustriesGamificationSettings | ✅ | | +| IndustriesLoyaltySettings | ✅ | | +| IndustriesManufacturingSettings | ✅ | | +| IndustriesPricingSettings | ✅ | | +| IndustriesSettings | ✅ | | +| IndustriesUnifiedPromotionsSettings | ✅ | | +| InstalledPackage | ⚠️ | Supports deploy/retrieve but not source tracking | +| IntegrationProviderDef | ✅ | | +| InterestTaggingSettings | ✅ | | +| InternalDataConnector | ✅ | | +| InvLatePymntRiskCalcSettings | ✅ | | +| InventorySettings | ✅ | | +| InvocableActionSettings | ✅ | | +| IoTSettings | ✅ | | +| KeywordList | ✅ | | +| KnowledgeGenerationSettings | ✅ | | +| KnowledgeSettings | ✅ | | +| LanguageSettings | ✅ | | +| Layout | ✅ | | +| LeadConfigSettings | ✅ | | +| LeadConvertSettings | ✅ | | +| LearningAchievementConfig | ❌ | Not supported, but support could be added | +| Letterhead | ✅ | | +| LicensingSettings | ✅ | | +| LightningBolt | ✅ | | +| LightningComponentBundle | ✅ | | +| LightningExperienceSettings | ✅ | | +| LightningExperienceTheme | ✅ | | +| LightningMessageChannel | ✅ | | +| LightningOnboardingConfig | ✅ | | +| ListView | ✅ | | +| LiveAgentSettings | ✅ | | +| LiveChatAgentConfig | ✅ | | +| LiveChatButton | ✅ | | +| LiveChatDeployment | ✅ | | +| LiveChatSensitiveDataRule | ✅ | | +| LiveMessageSettings | ✅ | | +| LocationUse | ✅ | | +| LoyaltyProgramSetup | ⚠️ | Supports deploy/retrieve but not source tracking | +| MacroSettings | ✅ | | +| MailMergeSettings | ✅ | | +| ManagedContentType | ⚠️ | Supports deploy/retrieve but not source tracking | +| ManagedEventSubscription | ✅ | | +| ManagedTopics | ✅ | | +| MapsAndLocationSettings | ✅ | | +| MarketSegmentDefinition | ✅ | | +| MarketingAppExtActivity | ❌ | Not supported, but support could be added | +| MarketingAppExtension | ✅ | | +| MatchingRules | ✅ | | +| MediaAdSalesSettings | ✅ | | +| MeetingsSettings | ✅ | | +| MessagingChannel | ⚠️ | Supports deploy/retrieve but not source tracking | +| MfgProgramTemplate | ✅ | | +| MfgServiceConsoleSettings | ✅ | | +| MilestoneType | ✅ | | +| MktCalcInsightObjectDef | ✅ | | +| MktDataConnection | ❌ | Not supported, but support could be added | +| MktDataConnectionCred | ❌ | Not supported, but support could be added | +| MktDataConnectionParam | ❌ | Not supported, but support could be added | +| MktDataConnectionSrcParam | ❌ | Not supported, but support could be added | +| MktDataTranObject | ✅ | | +| MlDomain | ✅ | | +| MobSecurityCertPinConfig | ✅ | | +| MobileApplicationDetail | ✅ | | +| MobileSecurityAssignment | ✅ | | +| MobileSecurityPolicy | ✅ | | +| MobileSettings | ✅ | | +| ModerationRule | ✅ | | +| MutingPermissionSet | ✅ | | +| MyDomainDiscoverableLogin | ✅ | | +| MyDomainSettings | ✅ | | +| NameSettings | ✅ | | +| NamedCredential | ✅ | | +| NavigationMenu | ✅ | | +| Network | ✅ | | +| NetworkBranding | ✅ | | +| NotificationTypeConfig | ✅ | | +| NotificationsSettings | ✅ | | +| OauthCustomScope | ✅ | | +| OauthOidcSettings | ✅ | | +| OauthTokenExchangeHandler | ✅ | | +| ObjectHierarchyRelationship | ✅ | | +| ObjectLinkingSettings | ✅ | | +| ObjectSourceTargetMap | ✅ | | +| OcrSampleDocument | ✅ | | +| OcrTemplate | ✅ | | +| OmniChannelPricingSettings | ✅ | | +| OmniChannelSettings | ✅ | | +| OmniDataTransform | ⚠️ | Supports deploy/retrieve but not source tracking | +| OmniExtTrackingDef | ⚠️ | Supports deploy/retrieve but not source tracking | +| OmniIntegrationProcedure | ⚠️ | Supports deploy/retrieve but not source tracking | +| OmniInteractionAccessConfig | ⚠️ | Supports deploy/retrieve but not source tracking | +| OmniInteractionConfig | ⚠️ | Supports deploy/retrieve but not source tracking | +| OmniScript | ⚠️ | Supports deploy/retrieve but not source tracking | +| OmniSupervisorConfig | ✅ | | +| OmniTrackingGroup | ⚠️ | Supports deploy/retrieve but not source tracking | +| OmniUiCard | ⚠️ | Supports deploy/retrieve but not source tracking | +| OnlineSalesSettings | ✅ | | +| OpportunityScoreSettings | ✅ | | +| OpportunitySettings | ✅ | | +| OrderManagementSettings | ✅ | | +| OrderSettings | ✅ | | +| OrgSettings | ✅ | | +| OutboundNetworkConnection | ✅ | | +| PardotEinsteinSettings | ✅ | | +| PardotSettings | ✅ | | +| ParticipantRole | ✅ | | +| PartyDataModelSettings | ✅ | | +| PathAssistant | ✅ | | +| PathAssistantSettings | ✅ | | +| PaymentGatewayProvider | ✅ | | +| PaymentsManagementEnabledSettings | ✅ | | +| PaymentsSettings | ✅ | | +| PermissionSet | ✅ | | +| PermissionSetGroup | ✅ | | +| PermissionSetLicenseDefinition | ✅ | | +| PersonAccountOwnerPowerUser | ✅ | | +| PicklistSettings | ✅ | | +| PicklistValue | ❌ | Not supported, but support could be added | +| PipelineInspMetricConfig | ✅ | | +| PlatformCachePartition | ✅ | | +| PlatformEventChannel | ✅ | | +| PlatformEventChannelMember | ✅ | | +| PlatformEventSettings | ✅ | | +| PlatformEventSubscriberConfig | ✅ | | +| PlatformSlackSettings | ✅ | | +| PortalDelegablePermissionSet | ❌ | Not supported, but support could be added | +| PortalsSettings | ✅ | | +| PostTemplate | ✅ | | +| PredictionBuilderSettings | ✅ | | +| PresenceDeclineReason | ✅ | | +| PresenceUserConfig | ✅ | | +| PricingActionParameters | ⚠️ | Supports deploy/retrieve but not source tracking | +| PricingRecipe | ✅ | | +| PrivacySettings | ✅ | | +| ProcessFlowMigration | ✅ | | +| ProductAttrDisplayConfig | ❌ | Not supported, but support could be added | +| ProductAttributeSet | ✅ | | +| ProductConfiguratorSettings | ✅ | | +| ProductSettings | ✅ | | +| ProductSpecificationRecType | ❌ | Not supported, but support could be added | +| ProductSpecificationType | ❌ | Not supported, but support could be added | +| Profile | ✅ | | +| ProfilePasswordPolicy | ✅ | | +| ProfileSessionSetting | ✅ | | +| Prompt | ✅ | | +| Queue | ✅ | | +| QueueRoutingConfig | ✅ | | +| QuickAction | ✅ | | +| QuickTextSettings | ✅ | | +| QuoteSettings | ✅ | | +| RealTimeEventSettings | ✅ | | +| RecAlrtDataSrcExpSetDef | ❌ | Not supported, but support could be added | +| RecommendationBuilderSettings | ✅ | | +| RecommendationStrategy | ✅ | | +| RecordActionDeployment | ✅ | | +| RecordAggregationDefinition | ✅ | | +| RecordAlertCategory | ✅ | | +| RecordAlertDataSource | ✅ | | +| RecordAlertTemplate | ❌ | Not supported, but support could be added | +| RecordPageSettings | ✅ | | +| RecordType | ✅ | | +| RedirectWhitelistUrl | ✅ | | +| ReferencedDashboard | ❌ | Not supported, but support could be added | +| ReferralMarketingSettings | ✅ | | +| RegisteredExternalService | ✅ | | +| RelatedRecordAssocCriteria | ❌ | Not supported, but support could be added | +| RelationshipGraphDefinition | ✅ | | +| RemoteSiteSetting | ✅ | | +| Report | ✅ | | +| ReportFolder | ✅ | | +| ReportType | ✅ | | +| RestrictionRule | ✅ | | +| RetailExecutionSettings | ✅ | | +| RevenueManagementSettings | ✅ | | +| Role | ✅ | | +| SalesAgreementSettings | ✅ | | +| SalesWorkQueueSettings | ✅ | | +| SamlSsoConfig | ✅ | | +| SandboxSettings | ✅ | | +| SceGlobalModelOptOutSettings | ✅ | | +| SchedulingObjective | ✅ | | +| SchedulingRule | ✅ | | +| SchemaSettings | ✅ | | +| ScoreCategory | ✅ | | +| SearchSettings | ✅ | | +| SecuritySettings | ✅ | | +| ServiceAISetupDefinition | ✅ | | +| ServiceAISetupField | ✅ | | +| ServiceChannel | ✅ | | +| ServiceCloudVoiceSettings | ✅ | | +| ServicePresenceStatus | ✅ | | +| ServiceProcess | ✅ | | +| ServiceSetupAssistantSettings | ✅ | | +| SharingCriteriaRule | ✅ | | +| SharingGuestRule | ✅ | | +| SharingOwnerRule | ✅ | | +| SharingReason | ✅ | | +| SharingRules | ⚠️ | Supports deploy/retrieve but not source tracking | +| SharingSet | ✅ | | +| SharingSettings | ✅ | | +| SharingTerritoryRule | ✅ | | +| SiteDotCom | ✅ | | +| SiteSettings | ✅ | | +| Skill | ✅ | | +| SkillType | ✅ | | +| SlackApp | ✅ | | +| SocialCustomerServiceSettings | ✅ | | +| SourceTrackingSettings | ✅ | | +| StandardValue | ❌ | Not supported, but support could be added | +| StandardValueSet | ✅ | | +| StandardValueSetTranslation | ✅ | | +| StaticResource | ✅ | | +| StnryAssetEnvSrcCnfg | ✅ | | +| StreamingAppDataConnector | ✅ | | +| SubscriptionManagementSettings | ✅ | | +| SurveySettings | ✅ | | +| SustainabilityUom | ✅ | | +| SustnUomConversion | ✅ | | +| SvcCatalogCategory | ✅ | | +| SvcCatalogFilterCriteria | ✅ | | +| SvcCatalogFulfillmentFlow | ✅ | | +| SvcCatalogItemDef | ✅ | | +| SynonymDictionary | ✅ | | +| SystemNotificationSettings | ✅ | | +| Territory | ✅ | | +| Territory2 | ✅ | | +| Territory2Model | ✅ | | +| Territory2Rule | ✅ | | +| Territory2Settings | ✅ | | +| Territory2Type | ✅ | | +| TimeSheetTemplate | ✅ | | +| TimelineObjectDefinition | ✅ | | +| TopicsForObjects | ✅ | | +| TrailheadSettings | ✅ | | +| TransactionSecurityPolicy | ✅ | | +| Translations | ✅ | | +| TrialOrgSettings | ✅ | | +| UIObjectRelationConfig | ✅ | | +| UiPlugin | ✅ | | +| UserAccessPolicy | ✅ | | +| UserAuthCertificate | ✅ | | +| UserCriteria | ✅ | | +| UserEngagementSettings | ✅ | | +| UserInterfaceSettings | ✅ | | +| UserManagementSettings | ✅ | | +| UserProfileSearchScope | ✅ | | +| UserProvisioningConfig | ✅ | | +| ValidationRule | ✅ | | +| VehicleAssetEmssnSrcCnfg | ✅ | | +| ViewDefinition | ✅ | | +| VirtualVisitConfig | ❌ | Not supported, but support could be added | +| VoiceSettings | ✅ | | +| WarrantyLifecycleMgmtSettings | ✅ | | +| WaveApplication | ✅ | | +| WaveComponent | ✅ | | +| WaveDashboard | ✅ | | +| WaveDataflow | ✅ | | +| WaveDataset | ✅ | | +| WaveLens | ✅ | | +| WaveRecipe | ✅ | | +| WaveTemplateBundle | ✅ | | +| WaveXmd | ✅ | | +| Web3Settings | ✅ | | +| WebLink | ✅ | | +| WebStoreBundle | ✅ | | +| WebStoreTemplate | ✅ | | +| WebToXSettings | ✅ | | +| WorkDotComSettings | ✅ | | +| WorkSkillRouting | ✅ | | +| Workflow | ✅ | | +| WorkflowAlert | ✅ | | +| WorkflowFieldUpdate | ✅ | | +| WorkflowFlowAction | ❌ | Not supported, but support could be added | +| WorkflowKnowledgePublish | ✅ | | +| WorkflowOutboundMessage | ✅ | | +| WorkflowRule | ✅ | | +| WorkflowSend | ✅ | | +| WorkflowTask | ✅ | | +| WorkforceEngagementSettings | ✅ | | ## Next Release (v61) -v61 introduces the following new types. Here's their current level of support +v61 introduces the following new types. Here's their current level of support -|Metadata Type|Support|Notes| -|:---|:---|:---| -|AffinityScoreDefinition|✅|| -|ContextUseCaseMapping|❌|Not supported, but support could be added| -|DocumentTemplate|❌|Not supported, but support could be added (but not for tracking)| -|DynamicFulfillmentOrchestratorSettings|✅|| -|EnablementMeasureDefinition|⚠️|Supports deploy/retrieve but not source tracking| -|EnablementProgramDefinition|⚠️|Supports deploy/retrieve but not source tracking| -|ExternalAuthIdentityProvider|❌|Not supported, but support could be added| -|ForecastingGroup|❌|Not supported, but support could be added| -|LargeQuotesandOrdersForRlmSettings|✅|| -|RetrievalSummaryDefinition|❌|Not supported, but support could be added| -|SearchCustomization|❌|Not supported, but support could be added (but not for tracking)| -|SearchOrgWideObjectConfig|❌|Not supported, but support could be added| -|WaveAnalyticAssetCollection|❌|Not supported, but support could be added| +| Metadata Type | Support | Notes | +| :------------------------------------- | :------ | :--------------------------------------------------------------- | +| AffinityScoreDefinition | ✅ | | +| ContextUseCaseMapping | ❌ | Not supported, but support could be added | +| DocumentTemplate | ❌ | Not supported, but support could be added (but not for tracking) | +| DynamicFulfillmentOrchestratorSettings | ✅ | | +| EnablementMeasureDefinition | ⚠️ | Supports deploy/retrieve but not source tracking | +| EnablementProgramDefinition | ⚠️ | Supports deploy/retrieve but not source tracking | +| ExternalAuthIdentityProvider | ❌ | Not supported, but support could be added | +| ForecastingGroup | ❌ | Not supported, but support could be added | +| LargeQuotesandOrdersForRlmSettings | ✅ | | +| RetrievalSummaryDefinition | ❌ | Not supported, but support could be added | +| SearchCustomization | ❌ | Not supported, but support could be added (but not for tracking) | +| SearchOrgWideObjectConfig | ❌ | Not supported, but support could be added | +| WaveAnalyticAssetCollection | ❌ | Not supported, but support could be added | ## Additional Types -> The following types are supported by this library but not in the coverage reports for either version. These are typically +> The following types are supported by this library but not in the coverage reports for either version. These are typically > > 1. types that have been removed from the metadata API but were supported in previous versions > 1. types that are available for pilots but not officially part of the metadata API (use with caution) diff --git a/package.json b/package.json index ae562b4f53..987a0bfa96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@salesforce/source-deploy-retrieve", - "version": "11.0.2", + "version": "11.1.0", "description": "JavaScript library to run Salesforce metadata deploys and retrieves", "main": "lib/src/index.js", "author": "Salesforce", @@ -25,8 +25,8 @@ "node": ">=18.0.0" }, "dependencies": { - "@salesforce/core": "^7.3.0", - "@salesforce/kit": "^3.1.0", + "@salesforce/core": "^7.3.1", + "@salesforce/kit": "^3.1.1", "@salesforce/ts-types": "^2.0.9", "fast-levenshtein": "^3.0.0", "fast-xml-parser": "^4.3.6", @@ -41,7 +41,7 @@ }, "devDependencies": { "@jsforce/jsforce-node": "^3.1.0", - "@salesforce/cli-plugins-testkit": "^5.2.1", + "@salesforce/cli-plugins-testkit": "^5.2.3", "@salesforce/dev-scripts": "^9.0.0", "@types/deep-equal-in-any-order": "^1.0.1", "@types/fast-levenshtein": "^0.0.4", @@ -50,7 +50,7 @@ "@types/minimatch": "^5.1.2", "deep-equal-in-any-order": "^1.1.19", "deepmerge": "^4.3.1", - "eslint-plugin-sf-plugin": "^1.18.0", + "eslint-plugin-sf-plugin": "^1.18.2", "mocha-junit-reporter": "^1.23.3", "mocha-snap": "^5.0.0", "ts-node": "^10.9.2", diff --git a/src/collections/componentSetBuilder.ts b/src/collections/componentSetBuilder.ts index 5db8cec57c..9dc12e185a 100644 --- a/src/collections/componentSetBuilder.ts +++ b/src/collections/componentSetBuilder.ts @@ -10,11 +10,12 @@ import { StateAggregator, Logger, SfError, Messages } from '@salesforce/core'; import fs from 'graceful-fs'; import minimatch from 'minimatch'; import { MetadataComponent } from '../resolve/types'; +import { SourceComponent } from '../resolve/sourceComponent'; import { ComponentSet } from '../collections/componentSet'; import { RegistryAccess } from '../registry/registryAccess'; import type { FileProperties } from '../client/types'; import { MetadataType } from '../registry/types'; -import { FromConnectionOptions } from './types'; +import { DestructiveChangesType, FromConnectionOptions } from './types'; Messages.importMessagesDirectory(__dirname); const messages = Messages.loadMessages('@salesforce/source-deploy-retrieve', 'sdr'); @@ -29,6 +30,14 @@ export type ManifestOption = { type MetadataOption = { metadataEntries: string[]; directoryPaths: string[]; + /** + * Array of metadata type:name pairs to delete before the deploy. Use of wildcards is not allowed. + */ + destructiveEntriesPre?: string[]; + /** + * Array of metadata type:name pairs to delete after the deploy. Use of wildcards is not allowed. + */ + destructiveEntriesPost?: string[]; }; type OrgOption = { @@ -114,6 +123,26 @@ export class ComponentSetBuilder { .map(addToComponentSet(componentSetFilter)); logger.debug(`Searching for matching metadata in directories: ${directoryPaths.join(', ')}`); + + // add destructive changes if defined. Because these are deletes, all entries + // are resolved to SourceComponents + if (metadata.destructiveEntriesPre) { + metadata.destructiveEntriesPre + .map(entryToTypeAndName(registryAccess)) + .map(assertNoWildcardInDestructiveEntries) + .flatMap(typeAndNameToMetadataComponents({ directoryPaths, registry: registryAccess })) + .map((mdComponent) => new SourceComponent({ type: mdComponent.type, name: mdComponent.fullName })) + .map(addToComponentSet(componentSet, DestructiveChangesType.PRE)); + } + if (metadata.destructiveEntriesPost) { + metadata.destructiveEntriesPost + .map(entryToTypeAndName(registryAccess)) + .map(assertNoWildcardInDestructiveEntries) + .flatMap(typeAndNameToMetadataComponents({ directoryPaths, registry: registryAccess })) + .map((mdComponent) => new SourceComponent({ type: mdComponent.type, name: mdComponent.fullName })) + .map(addToComponentSet(componentSet, DestructiveChangesType.POST)); + } + const resolvedComponents = ComponentSet.fromSource({ fsPaths: directoryPaths, include: componentSetFilter, @@ -162,9 +191,9 @@ export class ComponentSetBuilder { } const addToComponentSet = - (cs: ComponentSet) => + (cs: ComponentSet, deletionType?: DestructiveChangesType) => (cmp: MetadataComponent): MetadataComponent => { - cs.add(cmp); + cs.add(cmp, deletionType); return cmp; }; @@ -195,6 +224,13 @@ const assertComponentSetIsNotUndefined = (componentSet: ComponentSet | undefined return componentSet; }; +const assertNoWildcardInDestructiveEntries = (mdEntry: MetadataTypeAndMetadataName): MetadataTypeAndMetadataName => { + if (mdEntry.metadataName.includes('*')) { + throw SfError.create({ message: 'Wildcards are not supported when providing destructive metadata entries' }); + } + return mdEntry; +}; + /** This is only for debug output of matched files based on the command flags. * It will log up to 20 file matches. */ const logComponents = (logger: Logger, componentSet: ComponentSet): void => { diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/classes/OneClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/classes/OneClass.cls new file mode 100644 index 0000000000..c0bf528883 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/classes/OneClass.cls @@ -0,0 +1,5 @@ +public with sharing class OneClass { + public OneClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/classes/OneClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/classes/OneClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/classes/OneClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/destructiveChangesPost.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/destructiveChangesPost.xml new file mode 100644 index 0000000000..a1554a5ed1 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/destructiveChangesPost.xml @@ -0,0 +1,8 @@ + + + + RedClass + ApexClass + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/package.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/package.xml new file mode 100644 index 0000000000..69944ac668 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-1-deployment.expected/testOutput/post1/package.xml @@ -0,0 +1,8 @@ + + + + OneClass + ApexClass + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-no-deployment.expected/testOutput/post1-solo/destructiveChangesPost.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-no-deployment.expected/testOutput/post1-solo/destructiveChangesPost.xml new file mode 100644 index 0000000000..a1554a5ed1 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-no-deployment.expected/testOutput/post1-solo/destructiveChangesPost.xml @@ -0,0 +1,8 @@ + + + + RedClass + ApexClass + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-no-deployment.expected/testOutput/post1-solo/package.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-no-deployment.expected/testOutput/post1-solo/package.xml new file mode 100644 index 0000000000..1828aa744e --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-post-destructive-and-no-deployment.expected/testOutput/post1-solo/package.xml @@ -0,0 +1,4 @@ + + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/classes/OneClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/classes/OneClass.cls new file mode 100644 index 0000000000..c0bf528883 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/classes/OneClass.cls @@ -0,0 +1,5 @@ +public with sharing class OneClass { + public OneClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/classes/OneClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/classes/OneClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/classes/OneClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/destructiveChangesPre.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/destructiveChangesPre.xml new file mode 100644 index 0000000000..a1554a5ed1 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/destructiveChangesPre.xml @@ -0,0 +1,8 @@ + + + + RedClass + ApexClass + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/package.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/package.xml new file mode 100644 index 0000000000..69944ac668 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/1-pre-destructive-and-1-deployment.expected/testOutput/pre1/package.xml @@ -0,0 +1,8 @@ + + + + OneClass + ApexClass + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/OneClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/OneClass.cls new file mode 100644 index 0000000000..c0bf528883 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/OneClass.cls @@ -0,0 +1,5 @@ +public with sharing class OneClass { + public OneClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/OneClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/OneClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/OneClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/TwoClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/TwoClass.cls new file mode 100644 index 0000000000..87e3ab0a7d --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/TwoClass.cls @@ -0,0 +1,5 @@ +public with sharing class TwoClass { + public TwoClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/TwoClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/TwoClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/classes/TwoClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/destructiveChangesPost.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/destructiveChangesPost.xml new file mode 100644 index 0000000000..51240ec046 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/destructiveChangesPost.xml @@ -0,0 +1,9 @@ + + + + BlueClass + RedClass + ApexClass + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/package.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/package.xml new file mode 100644 index 0000000000..2682191b15 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-post-destructive-and-2-deployments.expected/testOutput/post2/package.xml @@ -0,0 +1,9 @@ + + + + OneClass + TwoClass + ApexClass + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/OneClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/OneClass.cls new file mode 100644 index 0000000000..c0bf528883 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/OneClass.cls @@ -0,0 +1,5 @@ +public with sharing class OneClass { + public OneClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/OneClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/OneClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/OneClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/TwoClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/TwoClass.cls new file mode 100644 index 0000000000..87e3ab0a7d --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/TwoClass.cls @@ -0,0 +1,5 @@ +public with sharing class TwoClass { + public TwoClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/TwoClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/TwoClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/classes/TwoClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/destructiveChangesPre.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/destructiveChangesPre.xml new file mode 100644 index 0000000000..51240ec046 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/destructiveChangesPre.xml @@ -0,0 +1,9 @@ + + + + BlueClass + RedClass + ApexClass + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/package.xml b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/package.xml new file mode 100644 index 0000000000..2682191b15 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/__snapshots__/2-pre-destructive-and-2-deployments.expected/testOutput/pre2/package.xml @@ -0,0 +1,9 @@ + + + + OneClass + TwoClass + ApexClass + + 60.0 + diff --git a/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/BlueClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/BlueClass.cls new file mode 100644 index 0000000000..621a2bf6cf --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/BlueClass.cls @@ -0,0 +1,5 @@ +public with sharing class BlueClass { + public BlueClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/BlueClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/BlueClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/BlueClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/OneClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/OneClass.cls new file mode 100644 index 0000000000..c0bf528883 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/OneClass.cls @@ -0,0 +1,5 @@ +public with sharing class OneClass { + public OneClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/OneClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/OneClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/OneClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/RedClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/RedClass.cls new file mode 100644 index 0000000000..a70f075f5a --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/RedClass.cls @@ -0,0 +1,5 @@ +public with sharing class RedClass { + public RedClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/RedClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/RedClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/RedClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/TwoClass.cls b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/TwoClass.cls new file mode 100644 index 0000000000..87e3ab0a7d --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/TwoClass.cls @@ -0,0 +1,5 @@ +public with sharing class TwoClass { + public TwoClass() { + + } +} \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/TwoClass.cls-meta.xml b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/TwoClass.cls-meta.xml new file mode 100644 index 0000000000..019e850990 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/originalSource/classes/TwoClass.cls-meta.xml @@ -0,0 +1,5 @@ + + + 59.0 + Active + \ No newline at end of file diff --git a/test/snapshot/sampleProjects/destructiveCompSets/sfdx-project.json b/test/snapshot/sampleProjects/destructiveCompSets/sfdx-project.json new file mode 100644 index 0000000000..69db9bc9e9 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/sfdx-project.json @@ -0,0 +1,12 @@ +{ + "name": "destructiveCompSetsProject", + "namespace": "", + "packageDirectories": [ + { + "default": true, + "path": "force-app" + } + ], + "sfdcLoginUrl": "https://login.salesforce.com", + "sourceApiVersion": "52.0" +} diff --git a/test/snapshot/sampleProjects/destructiveCompSets/snapshots.test.ts b/test/snapshot/sampleProjects/destructiveCompSets/snapshots.test.ts new file mode 100644 index 0000000000..547839cf86 --- /dev/null +++ b/test/snapshot/sampleProjects/destructiveCompSets/snapshots.test.ts @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2023, 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 fs from 'node:fs'; +import * as path from 'node:path'; +import { expect } from 'chai'; +import { dirsAreIdentical, dirEntsToPaths, fileSnap } from '../../helper/conversions'; +import { MetadataConverter } from '../../../../src/convert/metadataConverter'; +import { ComponentSetBuilder } from '../../../../src/collections/componentSetBuilder'; + +// we don't want failing tests outputting over each other +/* eslint-disable no-await-in-loop */ + +describe('Creating and converting ComponentSets with destructive changes', () => { + const testDir = path.join('test', 'snapshot', 'sampleProjects', 'destructiveCompSets'); + + // The directory containing metadata in source format to be converted + const sourceDir = path.join(testDir, 'originalSource'); + + // The directory of snapshots containing expected conversion results + const snapshotsDir = path.join(testDir, '__snapshots__'); + + // The directory where metadata is converted as part of testing + const testOutput = path.join(testDir, 'testOutput'); + + /** Return only the files involved in the conversion */ + const getConvertedFilePaths = async (outputDir: string): Promise => + dirEntsToPaths( + await fs.promises.readdir(outputDir, { + recursive: true, + withFileTypes: true, + }) + ); + + it('1 pre-destructive and 1 deployment', async () => { + const cs = await ComponentSetBuilder.build({ + metadata: { + metadataEntries: ['ApexClass:OneClass'], + destructiveEntriesPre: ['ApexClass:RedClass'], + directoryPaths: [sourceDir], + }, + projectDir: testDir, + }); + + const pre1TestOutputDir = path.join(testOutput, 'pre1'); + + await new MetadataConverter().convert(cs, 'metadata', { + type: 'directory', + outputDirectory: pre1TestOutputDir, + genUniqueDir: false, + }); + + const convertedFiles = await getConvertedFilePaths(pre1TestOutputDir); + for (const file of convertedFiles) { + await fileSnap(file, testDir); + } + dirsAreIdentical(path.join(snapshotsDir, 'testOutput', 'pre1'), pre1TestOutputDir); + }); + + it('2 pre-destructive and 2 deployments', async () => { + const cs = await ComponentSetBuilder.build({ + metadata: { + metadataEntries: ['ApexClass:OneClass', 'ApexClass:TwoClass'], + destructiveEntriesPre: ['ApexClass:RedClass', 'ApexClass:BlueClass'], + directoryPaths: [sourceDir], + }, + projectDir: testDir, + }); + + const pre2TestOutputDir = path.join(testOutput, 'pre2'); + + await new MetadataConverter().convert(cs, 'metadata', { + type: 'directory', + outputDirectory: pre2TestOutputDir, + genUniqueDir: false, + }); + + const convertedFiles = await getConvertedFilePaths(pre2TestOutputDir); + for (const file of convertedFiles) { + await fileSnap(file, testDir); + } + dirsAreIdentical(path.join(snapshotsDir, 'testOutput', 'pre2'), pre2TestOutputDir); + }); + + it('1 post-destructive and 1 deployment', async () => { + const cs = await ComponentSetBuilder.build({ + metadata: { + metadataEntries: ['ApexClass:OneClass'], + destructiveEntriesPost: ['ApexClass:RedClass'], + directoryPaths: [sourceDir], + }, + projectDir: testDir, + }); + + const postTestOutputDir = path.join(testOutput, 'post1'); + + await new MetadataConverter().convert(cs, 'metadata', { + type: 'directory', + outputDirectory: postTestOutputDir, + genUniqueDir: false, + }); + + const convertedFiles = await getConvertedFilePaths(postTestOutputDir); + for (const file of convertedFiles) { + await fileSnap(file, testDir); + } + dirsAreIdentical(path.join(snapshotsDir, 'testOutput', 'post1'), postTestOutputDir); + }); + + it('2 post-destructive and 2 deployments', async () => { + const cs = await ComponentSetBuilder.build({ + metadata: { + metadataEntries: ['ApexClass:OneClass', 'ApexClass:TwoClass'], + destructiveEntriesPost: ['ApexClass:RedClass', 'ApexClass:BlueClass'], + directoryPaths: [sourceDir], + }, + projectDir: testDir, + }); + + const post2TestOutputDir = path.join(testOutput, 'post2'); + + await new MetadataConverter().convert(cs, 'metadata', { + type: 'directory', + outputDirectory: post2TestOutputDir, + genUniqueDir: false, + }); + + const convertedFiles = await getConvertedFilePaths(post2TestOutputDir); + for (const file of convertedFiles) { + await fileSnap(file, testDir); + } + dirsAreIdentical(path.join(snapshotsDir, 'testOutput', 'post2'), post2TestOutputDir); + }); + + it('1 post-destructive and no deployment', async () => { + const cs = await ComponentSetBuilder.build({ + metadata: { + metadataEntries: [], + destructiveEntriesPost: ['ApexClass:RedClass'], + directoryPaths: [sourceDir], + }, + projectDir: testDir, + }); + + const postTestOutputDir = path.join(testOutput, 'post1-solo'); + + await new MetadataConverter().convert(cs, 'metadata', { + type: 'directory', + outputDirectory: postTestOutputDir, + genUniqueDir: false, + }); + + const convertedFiles = await getConvertedFilePaths(postTestOutputDir); + for (const file of convertedFiles) { + await fileSnap(file, testDir); + } + dirsAreIdentical(path.join(snapshotsDir, 'testOutput', 'post1-solo'), postTestOutputDir); + }); + + it('throws when wildcards are used in destructive changes', async () => { + try { + await ComponentSetBuilder.build({ + metadata: { + metadataEntries: ['ApexClass:OneClass'], + destructiveEntriesPost: ['ApexClass:*'], + directoryPaths: [sourceDir], + }, + projectDir: testDir, + }); + expect(true, 'using a wildcard in destructiveEntriesPost should throw').to.be.false; + } catch (e) { + expect(e).to.be.instanceof(Error); + const err = e as Error; + expect(err.message).to.include('Wildcards are not supported'); + } + }); + + after(async () => { + await fs.promises.rm(testOutput, { recursive: true, force: true }); + }); +}); diff --git a/yarn.lock b/yarn.lock index b05f486899..5614c594c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -548,13 +548,13 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@salesforce/cli-plugins-testkit@^5.2.1": - version "5.2.1" - resolved "https://registry.yarnpkg.com/@salesforce/cli-plugins-testkit/-/cli-plugins-testkit-5.2.1.tgz#24c7629057284a74d9f30a4fdc48c31f59d963af" - integrity sha512-GjvgJOLt4N/lGEMjdvQdVlJ8XlRfOfeUMisaVM94uTUWmF23u8fcD1H4zw7XvMt43CrNHs5dmBSAN0uk4ZRl5Q== +"@salesforce/cli-plugins-testkit@^5.2.3": + version "5.2.3" + resolved "https://registry.yarnpkg.com/@salesforce/cli-plugins-testkit/-/cli-plugins-testkit-5.2.3.tgz#20ce2d4e508b0bcaa60c4566b7f1c6bd99280cb8" + integrity sha512-6x24mYi2F2ywVo3Gygc3H+B1PC6e9MRdVuFwal0qp4D7PisnANrNJai7csgv1XwErG2B2fuDD9w/On1XZV+gSA== dependencies: - "@salesforce/core" "^7.2.0" - "@salesforce/kit" "^3.1.0" + "@salesforce/core" "^7.3.0" + "@salesforce/kit" "^3.1.1" "@salesforce/ts-types" "^2.0.9" "@types/shelljs" "^0.8.15" debug "^4.3.1" @@ -564,7 +564,7 @@ strip-ansi "6.0.1" ts-retry-promise "^0.8.0" -"@salesforce/core@^7.0.0", "@salesforce/core@^7.2.0", "@salesforce/core@^7.3.0": +"@salesforce/core@^7.3.0": version "7.3.0" resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-7.3.0.tgz#2ad3dfccb1ef0eb2e65b49b655e39748002bbc13" integrity sha512-c/gZLvKFHvgAv/Gyd4LjGGQykvGLn67QtCmdT7Hnm57bTDZoyr7XJXcaI+ILN0NO47guG1tEWP5eBvAi+u2DNA== @@ -587,6 +587,29 @@ semver "^7.6.0" ts-retry-promise "^0.7.1" +"@salesforce/core@^7.3.1": + version "7.3.1" + resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-7.3.1.tgz#cda324f7a5ff1be6d7381943b15b23dbe3cd5dec" + integrity sha512-jdc0GOUlV4xvyF9dPbBKNPDvQc06uj5YHFEHvdhCAFtCvqgtubpDzlyDppac2kdKujh4c7UH2KreboNvJ3LsoQ== + dependencies: + "@jsforce/jsforce-node" "^3.1.0" + "@salesforce/kit" "^3.1.1" + "@salesforce/schemas" "^1.7.0" + "@salesforce/ts-types" "^2.0.9" + ajv "^8.12.0" + change-case "^4.1.2" + faye "^1.4.0" + form-data "^4.0.0" + js2xmlparser "^4.0.1" + jsonwebtoken "9.0.2" + jszip "3.10.1" + pino "^8.19.0" + pino-abstract-transport "^1.1.0" + pino-pretty "^10.3.1" + proper-lockfile "^4.1.2" + semver "^7.6.0" + ts-retry-promise "^0.7.1" + "@salesforce/dev-config@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@salesforce/dev-config/-/dev-config-4.1.0.tgz#e529576466d074e7a5f1441236510fef123da01e" @@ -624,10 +647,18 @@ typescript "^5.4.3" wireit "^0.14.4" -"@salesforce/kit@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@salesforce/kit/-/kit-3.1.0.tgz#aa42533084c676e865f0f9c1907a16fb6f74dee7" - integrity sha512-X2d9O/U2wdQBXIrtVqQdMwo872Cv+qkYFzF0W+AQKG/LEe9cngnOzUVDYNkGD9tq3jcl+oenHXYuVDpkMhxTwA== +"@salesforce/kit@^3.1.0", "@salesforce/kit@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@salesforce/kit/-/kit-3.1.1.tgz#d2147a50887214763cdf1c456d306b6da554d928" + integrity sha512-Cjkh+USp5PtdZmD30r1Y7d+USpIhQz9B48w76esBtYpgqzhyj806LHkVgEfmorLNq2Qe8EO5rtUYd+XZ3rnV9w== + dependencies: + "@salesforce/ts-types" "^2.0.9" + tslib "^2.6.2" + +"@salesforce/kit@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@salesforce/kit/-/kit-3.1.1.tgz#d2147a50887214763cdf1c456d306b6da554d928" + integrity sha512-Cjkh+USp5PtdZmD30r1Y7d+USpIhQz9B48w76esBtYpgqzhyj806LHkVgEfmorLNq2Qe8EO5rtUYd+XZ3rnV9w== dependencies: "@salesforce/ts-types" "^2.0.9" tslib "^2.6.2" @@ -2148,12 +2179,12 @@ eslint-plugin-jsdoc@^46.10.1: semver "^7.5.4" spdx-expression-parse "^4.0.0" -eslint-plugin-sf-plugin@^1.18.0: - version "1.18.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-sf-plugin/-/eslint-plugin-sf-plugin-1.18.0.tgz#c6eca90e7738e9a114d8257588220c63a2a3e0e3" - integrity sha512-5Q4yI6Hr07v/lTaivs8A8re2FUXDEGyzzHzBk2cWi4c6iMxUYf/vaZKO6ZSSsc4eCcP11JY3RkDBQn6P33x58g== +eslint-plugin-sf-plugin@^1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-sf-plugin/-/eslint-plugin-sf-plugin-1.18.2.tgz#36e275b82eb17586dcfe77d0aafedecc30124329" + integrity sha512-QkxCu/4aglqlduTCk4d+3C6kl5KoIL6a88HJGLjgm1zWjjxduEeecsBNcHz82KN6FZtV+oONmvXPNoMlwQpvvw== dependencies: - "@salesforce/core" "^7.0.0" + "@salesforce/core" "^7.3.0" "@typescript-eslint/utils" "^6.17.0" eslint-plugin-unicorn@^50.0.1: