Private/Utils/New-ValueFromConfig.ps1
function New-ValueFromConfig { <# .SYNOPSIS Generates a value based on field configuration and action type. .DESCRIPTION This function generates values for fields based on their Type and Action properties. Supports Preserve, Anonymize, Randomize, and Link actions. Handles various data types including string, int, long, double, bool, datetime, and guid. .PARAMETER FieldConfig The field configuration hashtable containing Type and Action properties. .PARAMETER SeedValue Optional seed value to use for Preserve or Anonymize actions. .PARAMETER FieldPath The path to the field (used for error messages and warnings). .PARAMETER ResultContext Optional context hashtable for resolving linked values. .PARAMETER FullConfig Optional full configuration for on-demand generation of linked fields. .PARAMETER FullSeed Optional full seed data for on-demand generation. .PARAMETER CurrentResult Optional current result hashtable for storing generated linked values. .EXAMPLE New-ValueFromConfig -FieldConfig @{ Type = 'string'; Action = 'Randomize' } -FieldPath 'name' Generates a random string value. .OUTPUTS The generated value based on the field configuration. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [hashtable]$FieldConfig, [Parameter(Mandatory = $false)] [object]$SeedValue, [Parameter(Mandatory = $true)] [string]$FieldPath, [Parameter(Mandatory = $false)] [hashtable]$ResultContext = $null, [Parameter(Mandatory = $false)] [hashtable]$FullConfig = $null, [Parameter(Mandatory = $false)] [object]$FullSeed = $null, [Parameter(Mandatory = $false)] [hashtable]$CurrentResult = $null ) $type = $FieldConfig.Type $action = $FieldConfig.Action # Handle null type if ($type -eq 'null') { return $null } # If action is Link, get value from linked field if ($action -eq 'Link') { if ($FieldConfig.ContainsKey('LinkTo')) { $linkPath = $FieldConfig.LinkTo # First, try to find the value in ResultContext $linkedValue = Get-LinkedValue -Result $ResultContext -LinkPath $linkPath # If not found and we have config/seed, try CurrentResult (local scope) if ($null -eq $linkedValue -and $null -ne $CurrentResult) { $linkedValue = Get-LinkedValue -Result $CurrentResult -LinkPath $linkPath if ($null -ne $linkedValue) { Write-Verbose "New-ValueFromConfig: Found '$linkPath' in CurrentResult, value='$linkedValue'" } } # If still not found and we have the config, generate it on-demand if ($null -eq $linkedValue -and $null -ne $FullConfig -and $FullConfig.ContainsKey($linkPath)) { Write-Verbose "New-ValueFromConfig: Linked field '$linkPath' not found, generating on-demand" $targetConfig = $FullConfig[$linkPath] $targetSeed = Get-SeedValue -SeedObject $FullSeed -FieldPath $linkPath $linkedValue = New-ValueFromConfig -FieldConfig $targetConfig -SeedValue $targetSeed -FieldPath $linkPath -ResultContext $ResultContext -FullConfig $FullConfig -FullSeed $FullSeed -CurrentResult $CurrentResult # Store the generated value in CurrentResult so other fields can use it if ($null -ne $CurrentResult) { $CurrentResult[$linkPath] = $linkedValue Write-Verbose "New-ValueFromConfig: Stored generated value for '$linkPath' in CurrentResult" } } Write-Verbose "New-ValueFromConfig: Link action, LinkTo='$linkPath', linkedValue='$linkedValue'" return $linkedValue } else { Write-Verbose "Field '$FieldPath' has Link action but no LinkTo property. Generating random value." # Fall through to generate random value $action = 'Randomize' } } # If action is Preserve and we have seed data, use it if ($action -eq 'Preserve' -and $null -ne $SeedValue) { return $SeedValue } # Generate value based on type switch ($type) { 'string' { if ($action -eq 'Anonymize' -and $null -ne $SeedValue -and $SeedValue -is [string]) { # Simple anonymization: scramble the string but keep length $length = $SeedValue.Length return -join ((65..90) + (97..122) | Get-Random -Count ([math]::Max(1, $length)) | ForEach-Object { [char]$_ }) } else { # Generate random string $words = @('alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'theta', 'kappa', 'lambda', 'omega') return $words | Get-Random } } 'int' { if ($action -eq 'Anonymize' -and $null -ne $SeedValue -and ($SeedValue -is [int] -or $SeedValue -is [int32])) { # Keep in similar range $range = [math]::Max(100, [math]::Abs($SeedValue)) return Get-Random -Minimum ([math]::Max(0, $SeedValue - $range)) -Maximum ($SeedValue + $range) } else { return Get-Random -Minimum 1 -Maximum 1000 } } 'long' { if ($action -eq 'Anonymize' -and $null -ne $SeedValue) { $range = [math]::Max(1000, [math]::Abs($SeedValue)) return [long](Get-Random -Minimum ([math]::Max(0, $SeedValue - $range)) -Maximum ($SeedValue + $range)) } else { return [long](Get-Random -Minimum 1000 -Maximum 999999) } } 'double' { if ($action -eq 'Anonymize' -and $null -ne $SeedValue) { return [double](Get-Random -Minimum 0.0 -Maximum 1000.0) } else { return [double](Get-Random -Minimum 0.0 -Maximum 1000.0) } } 'bool' { return (Get-Random -Minimum 0 -Maximum 2) -eq 1 } 'datetime' { if ($action -eq 'Anonymize' -and $null -ne $SeedValue -and $SeedValue -is [datetime]) { # Random date within +/- 365 days $days = Get-Random -Minimum -365 -Maximum 365 return $SeedValue.AddDays($days).ToString('yyyy-MM-ddTHH:mm:ssZ') } else { $days = Get-Random -Minimum -365 -Maximum 365 return (Get-Date).AddDays($days).ToString('yyyy-MM-ddTHH:mm:ssZ') } } 'guid' { return [guid]::NewGuid().ToString() } 'array' { # Simple array - check if we have ItemType and ItemAction in FieldConfig if ($FieldConfig.ContainsKey('ItemType')) { $itemType = $FieldConfig.ItemType $itemAction = if ($FieldConfig.ContainsKey('ItemAction')) { $FieldConfig.ItemAction } else { 'Preserve' } $arrayCount = if ($FieldConfig.ContainsKey('ArrayCount')) { $FieldConfig.ArrayCount } else { 3 } # If Preserve action and we have seed value that's an array/list, use it if ($itemAction -eq 'Preserve' -and $null -ne $SeedValue) { if ($SeedValue -is [array]) { return , $SeedValue } elseif ($SeedValue -is [System.Collections.IList]) { # Convert IList to array and return with comma operator $arrayResult = @() foreach ($item in $SeedValue) { $arrayResult += $item } return , $arrayResult } } # Generate array of values based on ItemType $items = @() for ($i = 0; $i -lt $arrayCount; $i++) { # Create a simple field config for item generation $itemFieldConfig = @{ Type = $itemType Action = $itemAction } $itemValue = New-ValueFromConfig -FieldConfig $itemFieldConfig -SeedValue $null -FieldPath "$FieldPath[$i]" $items += $itemValue } return , $items } else { Write-Verbose "Array type for field '$FieldPath' has no ItemType defined, using empty array" return , @() } } default { Write-Verbose "Unknown type '$type' for field '$FieldPath', using empty string" return "" } } } |