private/New-SfMetadataModel.ps1
|
function New-SfMetadataModel { <# .SYNOPSIS Creates a metadata model skeleton, pre-initialized from the data dictionary schema. #> [CmdletBinding()] param ( # Path to the directory containing the schema CSV files. # Defaults to the module's own static/data-dictionary-schema directory. [string] $SchemaPath, # Path to the directory containing the validation list TXT files. # Defaults to the module's own static/data-dictionary-validations directory. [string] $ValidationsPath ) $ErrorActionPreference = 'Stop' [bool] $IsDebug = $DebugPreference -ne 'SilentlyContinue' [bool] $IsVerbose = $VerbosePreference -ne 'SilentlyContinue' # --- resolve default paths relative to module root if (-not $SchemaPath) { $SchemaPath = Join-Path $Script:ModuleRoot 'static/data-dictionary-schema' } if (-not $ValidationsPath) { $ValidationsPath = Join-Path $Script:ModuleRoot 'static/data-dictionary-validations' } Write-Debug "SchemaPath: $SchemaPath" Write-Debug "ValidationsPath: $ValidationsPath" # --- load schema-to-table mapping overrides from optional *.json files (filename = SchemaName). # --- missing/empty TableName is a silent no-op (treated as if the json did not exist); # --- invalid json is a terminating error. [hashtable] $SchemaToTableMapping = @{} foreach ($JsonFile in (Get-ChildItem -Path (Join-Path $SchemaPath '*') -Include '*.json')) { [string] $SchemaName = $JsonFile.BaseName try { $MappingDef = Get-Content -Path $JsonFile.FullName -Raw | ConvertFrom-Json } catch { throw "Failed to parse '$($JsonFile.FullName)': $_" } if (($MappingDef.PSObject.Properties.Name -contains 'TableName') -and (-not [string]::IsNullOrEmpty($MappingDef.TableName)) ) { $SchemaToTableMapping[$SchemaName] = $MappingDef.TableName } } # --- load schema: one entry per known SchemaName; default TableName = SchemaName unless already overridden above [hashtable] $Schema = @{} foreach ($File in (Get-ChildItem -Path (Join-Path $SchemaPath '*') -Include '*.csv')) { [string] $SchemaName = $File.BaseName [array] $ColumnDefs = Import-Csv -Path $File.FullName -Header 'ColumnType', 'ContentType', 'ColumnName', 'Validation' [PSCustomObject[]] $Columns = foreach ($Col in $ColumnDefs) { [string[]] $ValidValues = $null if (-not [string]::IsNullOrEmpty($Col.Validation) -and $Col.Validation -ne '-') { [string] $ValidationFile = Join-Path $ValidationsPath "$($Col.Validation).txt" [string[]] $ValidValues = Get-Content -Path $ValidationFile | ForEach-Object { ($_ -replace '#.*$', '').Trim() } | Where-Object { $_ -ne '' } } [PSCustomObject]@{ ColumnType = $Col.ColumnType ContentType = $Col.ContentType ColumnName = $Col.ColumnName ValidValues = $ValidValues } } $Schema[$SchemaName] = $Columns if (-not $SchemaToTableMapping.ContainsKey($SchemaName)) { $SchemaToTableMapping[$SchemaName] = $SchemaName } } # --- initialize Tables: one empty array per known TableName (deduplicated), in alphabetical order [hashtable] $Tables = @{} foreach ($TableName in ($SchemaToTableMapping.Values | Select-Object -Unique | Sort-Object)) { $Tables[$TableName] = @() } # --- load static metadata types map from .csv file [string] $MetadataTypesPath = Join-Path $Script:ModuleRoot 'static/metadata-types.csv' Write-Debug "MetadataTypesPath: $MetadataTypesPath" [hashtable] $MetadataTypes = @{} if (Test-Path $MetadataTypesPath) { [array] $MetadataTypesList = Import-Csv $MetadataTypesPath foreach ($Mdt in $MetadataTypesList) { $MetadataTypes[$Mdt.Type] = $Mdt } } else { Write-Warning "NOT FOUND - MetadataTypesPath: $MetadataTypesPath" } $Model = [PSCustomObject]@{ # --- schema: column definitions per SchemaName (validation source of truth) Schema = $Schema # --- SchemaName -> TableName resolution (N:1, defaults to identity) SchemaToTableMapping = $SchemaToTableMapping # --- tables: imported rows per TableName (merge target, NOT per SchemaName) Tables = $Tables # --- static metadata types reference MetadataTypes = $MetadataTypes # ################### everything below is considered legacy, to be refactored and either deleted or moved above this line ################### # --- metadata inventory map MetadataMap = @{} # --- settings (to be moved out in Dimension 2) IncludeDeprecatedTag = $false ForceFormulaTreatBlanksAs = $false # --- package.xml definition file #PackageDefinition = @() # --- Data Dictionary format - general #Objects = @() #RecordTypes = @() #RecordTypePicklistValues = @() #Fields = @() #FieldDependencies = @() #FieldLookupFilters = @() #StandardValueSets = @() #GlobalValueSets = @() #PicklistValues = @() #StateAndCountryPicklists = @() #ValidationRules = @() #BusinessProcesses = @() CustomMetadatas = @() # --- Data Dictionary format - Profiles / PermSets #Profiles = @() #PermissionSets = @() #PermissionSetGroups = @() #AccessesAndPermissions = @() #ApplicationVisibilities = @() #TabSettings = @() Roles = @() # --- raw maps (to be moved out in Dimension 2) AccessesAndPermissionsMap = @{} ApplicationVisibilitiesMap = @{} TabsMap = @{} FieldPermissionsList = @() LayoutAssignmentsList = @() ObjectPermissionsList = @() RecordTypePicklistValuesList = @() RecordTypeVisibilitiesList = @() # --- lookup maps for data dictionary (to be moved out in Dimension 2) FieldTranslationsMap = @{} PicklistValueTranslations = @{} # --- maps for matching (to be moved out in Dimension 2) ApplicationsMap = @{} FieldsMap = @{} GlobalValueSetsMap = @{} LayoutsMap = @{} ObjectsMap = @{} PagesMap = @{} RecordTypesMap = @{} RecordTypePicklistValuesMap = @{} StandardValueSetsMap = @{} # --- list fields for multi-column logic (to be moved out in Dimension 2) # ProfileKeys = @() # PermissionSetKeys = @() # LanguageKeys = @('de', 'en_US') # ################### everything above is considered legacy ################### } return $Model } |