public/Build-SfGlobalValueSetTranslationMetadata.ps1
|
function Build-SfGlobalValueSetTranslationMetadata { <# .SYNOPSIS Builds the *.globalValueSetTranslation-meta.xml files from the metadata model. .DESCRIPTION Processes the global value set translations as given in table [_GlobalValueSetTranslationss] in the metadata model. The picklist label translations will be collected from table [_PicklistValues] in the metadata model. Manifest accepts bare GlobalValueSet names (e.g. 'MyValueSet'), fully qualified 'GlobalValueSet:Name' entries, and fully qualified 'GlobalValueSetTranslation:Name-Locale' entries (e.g. 'GlobalValueSetTranslation:MyValueSet-de'), and can be piped in. Entries of any other Type (e.g. from a combined manifest list shared across multiple Build-Sf*Metadata functions) are silently ignored. Each entry is parsed via ConvertTo-SfMetadataComponent with DefaultComponentType 'GlobalValueSet', so a bare name is treated as a GlobalValueSet, not a translation. A 'GlobalValueSet' entry whose Name does not exist in table [_GlobalValueSets] produces a warning and is skipped. A 'GlobalValueSetTranslation' entry's Name is split on the last '-' into <ParentName> and <Locale>; if <ParentName> does not exist in table [_GlobalValueSets], a warning is produced and the entry is skipped. If Manifest is left empty (no pipeline input and no explicit value), all global value sets in the metadata model are built. For every GlobalValueSet to be built (via manifest or 'build all'), one translation is generated per language code in LanguageCodes. A 'GlobalValueSetTranslation:Name-Locale' manifest entry additionally requests that exact <ParentName>/<Locale> combination directly, regardless of LanguageCodes - this lets a translation be requested independently of its parent GlobalValueSet. The two sources are merged into a deduplicated set before building, so the same combination is never built twice. An empty LanguageCodes therefore builds nothing unless explicit 'GlobalValueSetTranslation:Name-Locale' manifest entries are given. .EXAMPLE # Build all global value set translations, specific languages Build-SfGlobalValueSetTranslationMetadata -MetadataModel $Model -LanguageCodes @('de', 'fr') .EXAMPLE # Build translations for two value sets, specific languages Build-SfGlobalValueSetTranslationMetadata -MetadataModel $Model -Manifest @('MyValueSet', 'OtherValueSet') -LanguageCodes @('de', 'fr') .EXAMPLE # Request one specific translation directly, independent of LanguageCodes Build-SfGlobalValueSetTranslationMetadata -MetadataModel $Model -Manifest 'GlobalValueSetTranslation:MyValueSet-de' .OUTPUTS None. Writes *.globalValueSetTranslation-meta.xml files to disk. .LINK Build-SfGlobalValueSetMetadata .LINK Import-SfMetadataModel .LINK https://codeberg.org/uwe-braig/sf-metadata-toolkit #> [CmdletBinding()] param ( # The metadata model as imported from *.csv and/or *.xlsx with Import-SfMetadataModel [Parameter(Mandatory, Position = 0)] [PSCustomObject] $MetadataModel, # Manifest entries in 'Type:Name' notation. Accepts 'GlobalValueSet:Name', bare names # (treated as GlobalValueSet), and 'GlobalValueSetTranslation:Name-Locale'. Other Types # are ignored. If left empty, all global value sets are built. Can be piped in. [Parameter(ValueFromPipeline, Position = 1)] [string[]] $Manifest, # List of language codes, e.g. ('en_US', 'de'). An empty LanguageCodes builds no # translations via the parent expansion below, unless explicit # 'GlobalValueSetTranslation:Name-Locale' manifest entries request specific ones directly. [Parameter()] [string[]] $LanguageCodes = @(), # Target path for the resulting *.xml files. Default is [./force-app/main/default]. [Parameter()] [string] $TargetPath = './force-app/main/default' ) begin { $ErrorActionPreference = 'Stop' [bool] $IsDebug = $DebugPreference -ne 'SilentlyContinue' [bool] $IsVerbose = $VerbosePreference -ne 'SilentlyContinue' [int] $ReceivedCount = 0 [Collections.Generic.List[PSCustomObject]] $ParentsToBuild = [Collections.Generic.List[PSCustomObject]]::new() [Collections.Generic.HashSet[string]] $ExplicitTranslations = [Collections.Generic.HashSet[string]]::new() $GlobalValueSetTranslationPath = Join-Path $TargetPath 'globalValueSetTranslations' [hashtable] $GlobalValueSetsByName = @{} foreach ($ValueSet in $MetadataModel.Tables._GlobalValueSets) { $GlobalValueSetsByName[$ValueSet._Name] = $ValueSet } } process { foreach ($RawEntry in $Manifest) { $ReceivedCount++ $Component = ConvertTo-SfMetadataComponent -ComponentName $RawEntry -DefaultComponentType 'GlobalValueSet' if ($null -eq $Component) { continue } if ($Component.Type -eq 'GlobalValueSet') { if (-not $GlobalValueSetsByName.ContainsKey($Component.Name)) { Write-Warning "[$($Component.Key)] Not found in metadata model." continue } $ParentsToBuild.Add($GlobalValueSetsByName[$Component.Name]) continue } if ($Component.Type -eq 'GlobalValueSetTranslation') { [int] $SplitIndex = $Component.Name.LastIndexOf('-') if ($SplitIndex -lt 0) { Write-Warning "[$($Component.Key)] Expected '<Name>-<Locale>' notation." continue } [string] $ParentName = $Component.Name.Substring(0, $SplitIndex) [string] $Locale = $Component.Name.Substring($SplitIndex + 1) if (-not $GlobalValueSetsByName.ContainsKey($ParentName)) { Write-Warning "[$($Component.Key)] Parent GlobalValueSet '$ParentName' not found in metadata model." continue } [void] $ExplicitTranslations.Add("$ParentName-$Locale") continue } # Any other Type belongs to a different Build-Sf*Metadata function - ignore silently. } } end { if ($ReceivedCount -eq 0) { foreach ($ValueSet in $MetadataModel.Tables._GlobalValueSets) { $ParentsToBuild.Add($ValueSet) } } # --- merge parent x language-code expansion with explicit manifest entries, deduplicated [Collections.Generic.HashSet[string]] $ComponentsToBuild = [Collections.Generic.HashSet[string]]::new() foreach ($ValueSet in $ParentsToBuild) { foreach ($LanguageCode in $LanguageCodes) { [void] $ComponentsToBuild.Add("$($ValueSet._Name)-$LanguageCode") } } foreach ($CompositeKey in $ExplicitTranslations) { [void] $ComponentsToBuild.Add($CompositeKey) } foreach ($CompositeKey in $ComponentsToBuild) { [int] $SplitIndex = $CompositeKey.LastIndexOf('-') [string] $ParentName = $CompositeKey.Substring(0, $SplitIndex) [string] $LanguageCode = $CompositeKey.Substring($SplitIndex + 1) $ValueSet = $GlobalValueSetsByName[$ParentName] $xmlString = ConvertTo-SfGlobalValueSetTranslationXml -ValueSet $ValueSet -LanguageCode $LanguageCode -PicklistValues $MetadataModel.Tables._PicklistValues Set-MetadataXmlFile 'GlobalValueSetTranslation' $CompositeKey '.globalValueSetTranslation-meta.xml' $GlobalValueSetTranslationPath $xmlString } } } |