Private/SwaggerCodeText.ps1
|
# Helpers for New-FunctionsFromSwagger that turn swagger text into safe PowerShell code text (quoting, comments, # names, attributes, sample values and verbs). They have no state. # Quotes text as a PowerShell single-quoted string literal (single quotes are doubled), so text from the # swagger file is always data in generated code function ConvertTo-QuotedLiteral { param([AllowNull()][AllowEmptyString()][string] $Text) if ($null -eq $Text) { $Text = '' } # EscapeSingleQuotedStringContent also doubles the curly quotes that PowerShell accepts as single quotes return "'" + [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent($Text) + "'" } # Makes text safe for comment-based help and line comments: one line, and no sequence that ends or starts a # block comment function ConvertTo-SafeCommentText { param([AllowNull()][AllowEmptyString()][string] $Text) if ([string]::IsNullOrEmpty($Text)) { return $Text } return (($Text -replace '[\r\n]+', ' ') -replace '#>', '# >' -replace '<#', '< #') } # Replaces every {{NAME}} placeholder in one pass (unknown placeholders are left as they are), so placeholder-like # text inside values is never expanded function Expand-CodeTemplate { param( [Parameter(Mandatory = $true)][string] $Template, [Parameter(Mandatory = $true)][hashtable] $Values ) $evaluator = { param($placeholder) $name = $placeholder.Groups[1].Value if ($Values.ContainsKey($name)) { return [string]$Values[$name] } return $placeholder.Value } return [regex]::Replace($Template, '\{\{([A-Z_]+)\}\}', [System.Text.RegularExpressions.MatchEvaluator]$evaluator) } # First 8 hex characters of the SHA1 of the text (used to make colliding function names unique) function Get-ShortHash { param([Parameter(Mandatory = $true)][string] $Text) $bytes = [System.Text.Encoding]::UTF8.GetBytes($Text) $sha = [System.Security.Cryptography.SHA1]::Create() try { $hash = $sha.ComputeHash($bytes) } finally { $sha.Dispose() } $hex = ([System.BitConverter]::ToString($hash)).Replace('-', '').ToLowerInvariant() return $hex.Substring(0, 8) } function ConvertTo-PowerShellLiteral { param([object]$Value) if ($null -eq $Value) { return '$null' } if ($Value -is [bool]) { if ($Value) { return '$true' } else { return '$false' } } if ($Value -is [string]) { return ConvertTo-QuotedLiteral $Value } if ($Value -is [int] -or $Value -is [long] -or $Value -is [double] -or $Value -is [decimal]) { return $Value.ToString([System.Globalization.CultureInfo]::InvariantCulture) } if ($Value -is [datetime]) { return "(Get-Date '" + $Value.ToString('o') + "')" } if ($Value -is [array]) { $items = @() foreach ($item in $Value) { $items += ConvertTo-PowerShellLiteral $item } return '@(' + ($items -join ', ') + ')' } # Objects become ConvertFrom-Json of a quoted JSON string, so they are always data try { return '(' + (ConvertTo-QuotedLiteral ($Value | ConvertTo-Json -Compress -Depth 20)) + ' | ConvertFrom-Json)' } catch { return ConvertTo-QuotedLiteral ([string]$Value) } } function Get-ValidateSetAttributeText { param( [object[]]$Values, [string]$PSType ) if (-not $Values -or $Values.Count -eq 0) { return $null } $escaped = @() foreach ($val in $Values) { $escaped += ConvertTo-QuotedLiteral ([string]$val) } $ignoreSegment = if ($PSType -like '`[string*') { ', IgnoreCase=$true' } else { '' } return ' [ValidateSet(' + ($escaped -join ', ') + $ignoreSegment + ')]' } function Get-ValidateScriptAttributeText { param( [string]$Format, [string]$PSType ) if (-not $Format) { return $null } if ($PSType -ne '[string]') { return $null } $formatLower = $Format.ToLowerInvariant() switch ($formatLower) { 'uuid' { $formatLower = 'guid' } } switch ($formatLower) { 'guid' { $lines = @( ' [ValidateScript({', ' param($value)', ' if ($null -eq $value) { return $true }', ' $parsed = [guid]::Empty', ' if ([guid]::TryParse($value, [ref]$parsed)) { return $true }', ' throw "Invalid guid format: $value"', ' })]' ) return ($lines -join "`n") } 'date-time' { $lines = @( ' [ValidateScript({', ' param($value)', ' if ($null -eq $value) { return $true }', ' $parsed = [datetime]::MinValue', ' if ([datetime]::TryParse($value, [System.Globalization.CultureInfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::RoundtripKind, [ref]$parsed)) { return $true }', ' throw "Invalid date-time format: $value"', ' })]' ) return ($lines -join "`n") } 'date' { $lines = @( ' [ValidateScript({', ' param($value)', ' if ($null -eq $value) { return $true }', ' $parsed = [datetime]::MinValue', ' if ([datetime]::TryParse($value, [System.Globalization.CultureInfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::AssumeUniversal, [ref]$parsed)) { return $true }', ' throw "Invalid date format: $value"', ' })]' ) return ($lines -join "`n") } 'email' { $lines = @( ' [ValidateScript({', ' param($value)', ' if ($null -eq $value) { return $true }', ' if ($value -match ''^([^\s@]+)@([^\s@]+)\.([^\s@]+)$'') { return $true }', ' throw "Invalid email format: $value"', ' })]' ) return ($lines -join "`n") } 'uri' { $lines = @( ' [ValidateScript({', ' param($value)', ' if ($null -eq $value) { return $true }', ' if ([uri]::IsWellFormedUriString($value, [System.UriKind]::Absolute)) { return $true }', ' throw "Invalid uri format: $value"', ' })]' ) return ($lines -join "`n") } 'hostname' { $lines = @( ' [ValidateScript({', ' param($value)', ' if ($null -eq $value) { return $true }', ' if ($value -match ''^(?=.{1,253}$)(?!-)([A-Za-z0-9-]{0,62}[A-Za-z0-9]\.)+[A-Za-z]{2,63}$'') { return $true }', ' throw "Invalid hostname format: $value"', ' })]' ) return ($lines -join "`n") } default { return $null } } } function Test-IsGuidString { param([object]$Value) if ($null -eq $Value) { return $false } if ($Value -isnot [string]) { return $false } $parsed = [guid]::Empty return [guid]::TryParse($Value, [ref]$parsed) } function Test-UseDefaultLiteral { param( [string]$PSType, [string]$DefaultLiteral ) if ([string]::IsNullOrEmpty($DefaultLiteral)) { return $false } if ($DefaultLiteral -eq "''") { return $false } if ($DefaultLiteral -eq '$null') { return $false } if ($PSType -match '\[\]') { if ($DefaultLiteral -match '^@\(') { return $true } else { return $false } } if ($PSType -eq '[hashtable]') { if ($DefaultLiteral -match '^@\{' -or $DefaultLiteral -match '^\{') { return $true } else { return $false } } if ($PSType -eq '[hashtable[]]' -or $PSType -eq '[object[]]') { if ($DefaultLiteral -match '^@\(') { return $true } else { return $false } } return $true } function Format-HelpTextSegment { param([string]$Text) if ([string]::IsNullOrWhiteSpace($Text)) { return $Text } $normalized = ($Text -replace '\s+', ' ').Trim() if (-not $normalized) { return $normalized } $normalized = $normalized.Trim('"') $normalized = $normalized.Trim("'") $normalized = $normalized.Trim() while ($normalized.EndsWith(',')) { $normalized = $normalized.TrimEnd(',').Trim() } while ($normalized.EndsWith(';')) { $normalized = $normalized.TrimEnd(';').Trim() } return $normalized } function Get-DescriptionHint { param([string]$DescriptionText) $hints = @{} if ([string]::IsNullOrWhiteSpace($DescriptionText)) { return $hints } $normalized = $DescriptionText -replace "`r", '' $regex = [regex]"(?im)[`"'']?(?<name>[A-Za-z0-9_]+)[`"'']?\s*[:\-\u2013]\s*(?<value>[^`r`n]+)" foreach ($match in $regex.Matches($normalized)) { $name = $match.Groups['name'].Value $value = $match.Groups['value'].Value.Trim() if (-not $name) { continue } $key = $name.ToLowerInvariant() if (-not $hints.ContainsKey($key)) { $normalizedValue = Format-HelpTextSegment $value if (-not [string]::IsNullOrWhiteSpace($normalizedValue)) { $hints[$key] = $normalizedValue } } } return $hints } function ConvertTo-SafeNameComponent { param([string]$Name) $sanitized = $Name -replace '[^0-9A-Za-z]', '_' if ([string]::IsNullOrEmpty($sanitized)) { $sanitized = 'Property' } if ($sanitized.Length -gt 1) { $sanitized = $sanitized.Substring(0, 1).ToUpper() + $sanitized.Substring(1) } else { $sanitized = $sanitized.ToUpper() } return ($sanitized -replace '_+', '_') } function Get-UniqueBodyParameterName { param( [string[]]$Segments, [hashtable]$UsedNames ) $components = @() foreach ($segment in $Segments) { $components += (ConvertTo-SafeNameComponent -Name $segment) } if ($components.Count -eq 0) { $components = @('Property') } $baseName = ($components -join '') if ([string]::IsNullOrEmpty($baseName)) { $baseName = 'Property' } $candidate = $baseName $suffix = 1 while ($UsedNames.ContainsKey($candidate.ToLowerInvariant())) { $candidate = "${baseName}${suffix}" $suffix++ } $UsedNames[$candidate.ToLowerInvariant()] = $true return $candidate } function Get-SanitizedIdentifier { param( [string]$Name, [string]$Fallback = 'Value' ) $candidate = $Name if ([string]::IsNullOrWhiteSpace($candidate)) { $candidate = $Fallback } $segments = @($candidate -split '[^0-9A-Za-z]+') | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } if ($segments.Count -eq 0) { $segments = @($Fallback) } $parts = @() foreach ($segment in $segments) { $parts += (ConvertTo-SafeNameComponent -Name $segment) } if ($parts.Count -eq 0) { $parts = @($Fallback) } $identifier = ($parts -join '') if ([string]::IsNullOrWhiteSpace($identifier)) { $identifier = $Fallback } if ($identifier[0] -match '\d') { $identifier = '_' + $identifier } return $identifier } function Get-UniqueIdentifier { param( [string]$BaseName, [hashtable]$UsedNames ) $normalized = if ([string]::IsNullOrWhiteSpace($BaseName)) { 'Value' } else { $BaseName } $candidate = $normalized $suffix = 1 while ($UsedNames.ContainsKey($candidate.ToLowerInvariant())) { $candidate = "${normalized}${suffix}" $suffix++ } $UsedNames[$candidate.ToLowerInvariant()] = $true return $candidate } function Get-HintForPath { param( [hashtable]$DescriptionHints, [string[]]$PathSegments, [string]$ParameterName ) if (-not $DescriptionHints) { return $null } $candidates = @() if ($PathSegments.Count -gt 0) { $candidates += ($PathSegments -join '.') $candidates += $PathSegments[-1] } foreach ($segment in $PathSegments) { $candidates += $segment } if ($ParameterName) { $candidates += $ParameterName } foreach ($candidate in $candidates) { if ([string]::IsNullOrWhiteSpace($candidate)) { continue } $key = $candidate.ToLowerInvariant() if ($DescriptionHints.ContainsKey($key)) { return $DescriptionHints[$key] } } return $null } function Add-ParameterDescriptor { param( [hashtable]$DescriptorMap, [System.Collections.Generic.List[object]]$DescriptorList, [pscustomobject]$Descriptor, [string]$ParameterSetName ) if (-not $Descriptor) { return $null } if (-not ($Descriptor.PSObject.Properties.Name -contains 'ParameterSets')) { $Descriptor | Add-Member -NotePropertyName ParameterSets -NotePropertyValue (New-Object 'System.Collections.Generic.HashSet[string]' ([System.StringComparer]::OrdinalIgnoreCase)) -Force } if ($ParameterSetName) { $null = $Descriptor.ParameterSets.Add($ParameterSetName) } $key = $Descriptor.Name.ToLowerInvariant() if ($DescriptorMap.ContainsKey($key)) { $existing = $DescriptorMap[$key] foreach ($set in $Descriptor.ParameterSets) { $null = $existing.ParameterSets.Add($set) } if ($Descriptor.Required -and -not $existing.Required) { $existing.Required = $true } if (-not $existing.Description -and $Descriptor.Description) { $existing.Description = $Descriptor.Description } if (-not $existing.HelpSummary -and $Descriptor.HelpSummary) { $existing.HelpSummary = $Descriptor.HelpSummary } return [pscustomobject]@{ Descriptor = $existing; IsNew = $false } } [void]$DescriptorList.Add($Descriptor) $DescriptorMap[$key] = $Descriptor return [pscustomobject]@{ Descriptor = $Descriptor; IsNew = $true } } function Get-BodyAssignmentLine { param([pscustomobject]$Definition, [string]$OperationKey) $pathSegments = $Definition.PathSegments if (-not $pathSegments -or $pathSegments.Count -eq 0) { return @() } $lines = [System.Collections.Generic.List[string]]::new() $parentExpr = '$bodyPayload' for ($i = 0; $i -lt $pathSegments.Count - 1; $i++) { $segment = $pathSegments[$i] $segmentLiteral = ConvertTo-QuotedLiteral $segment $lines.Add([string]::Format(' if (-not {0}.ContainsKey({1}) -or $null -eq {0}[{1}]) {{ {0}[{1}] = @{{}} }}', $parentExpr, $segmentLiteral)) $parentExpr = "$parentExpr[$segmentLiteral]" } $lastSegment = $pathSegments[-1] $targetExpr = "$parentExpr[$(ConvertTo-QuotedLiteral $lastSegment)]" $paramName = $Definition.Name $hasChildProps = [bool]$Definition.HasChildProperties $needsConversion = $false if ($OperationKey -and $Definition.Type -and ($Definition.Type -match 'int|long|Int32|Int64|integer')) { $needsConversion = $true } if ($Definition.Required) { if ($needsConversion) { # Use $PSBoundParameters[...] to safely reference parameter values (avoid evaluating $() during generation) $lines.Add((' {0} = Convert-SwaggerParamValue -OperationKey ''{1}'' -ParamName ''{2}'' -Value $PSBoundParameters[''{3}''] -TargetType ''int''' -f $targetExpr, $OperationKey, $paramName, $paramName)) } else { $lines.Add((' {0} = $PSBoundParameters[''{1}'']' -f $targetExpr, $paramName)) } } elseif ($Definition.HasEffectiveDefault) { # If the parameter has an effective default from the swagger metadata, prefer the caller's provided # value when present; otherwise emit the swagger default into the request body so the server sees it. $defaultLiteral = if ($null -ne $Definition.DefaultLiteral) { $Definition.DefaultLiteral } else { $null } if ($needsConversion) { if ($defaultLiteral) { $lines.Add((' if ($PSBoundParameters.ContainsKey(''{0}'') -and ($PSBoundParameters[''{0}''] -ne $null)) {{ {1} = Convert-SwaggerParamValue -OperationKey ''{2}'' -ParamName ''{3}'' -Value $PSBoundParameters[''{0}''] -TargetType ''int'' }} else {{ {1} = {4} }}' -f $paramName, $targetExpr, $OperationKey, $paramName, $defaultLiteral)) } else { $lines.Add((' if ($PSBoundParameters.ContainsKey(''{0}'') -and ($PSBoundParameters[''{0}''] -ne $null)) {{ {1} = Convert-SwaggerParamValue -OperationKey ''{2}'' -ParamName ''{3}'' -Value $PSBoundParameters[''{0}''] -TargetType ''int'' }}' -f $paramName, $targetExpr, $OperationKey, $paramName)) } } else { if ($defaultLiteral) { $lines.Add((' if ($PSBoundParameters.ContainsKey(''{0}'') -and ($PSBoundParameters[''{0}''] -ne $null)) {{ {1} = $PSBoundParameters[''{0}''] }} else {{ {1} = {2} }}' -f $paramName, $targetExpr, $defaultLiteral)) } else { $lines.Add((' if ($PSBoundParameters.ContainsKey(''{0}'') -and ($PSBoundParameters[''{0}''] -ne $null)) {{ {1} = $PSBoundParameters[''{0}''] }}' -f $paramName, $targetExpr)) } } } elseif ($Definition.AllowsNull -and -not $hasChildProps) { # Option B enhancement: For optional/nullable properties, OMIT the key entirely unless caller supplied a value. # This avoids emitting explicit nulls that can conflict with conversion schemas when swagger marks default:null but lacks nullable:true. # Previous behavior set else { prop = $null }; we now drop that branch. if ($needsConversion) { $lines.Add((' if ($PSBoundParameters.ContainsKey(''{0}'')) {{ {1} = Convert-SwaggerParamValue -OperationKey ''{2}'' -ParamName ''{3}'' -Value $PSBoundParameters[''{0}''] -TargetType ''int'' }}' -f $paramName, $targetExpr, $OperationKey, $paramName)) } else { $lines.Add((' if ($PSBoundParameters.ContainsKey(''{0}'')) {{ {1} = $PSBoundParameters[''{0}''] }}' -f $paramName, $targetExpr)) } } else { if ($needsConversion) { $lines.Add((' if ($PSBoundParameters.ContainsKey(''{0}'')) {{ {1} = Convert-SwaggerParamValue -OperationKey ''{2}'' -ParamName ''{3}'' -Value $PSBoundParameters[''{0}''] -TargetType ''int'' }}' -f $paramName, $targetExpr, $OperationKey, $paramName)) } else { $lines.Add((' if ($PSBoundParameters.ContainsKey(''{0}'')) {{ {1} = $PSBoundParameters[''{0}''] }}' -f $paramName, $targetExpr)) } } return @($lines) } # Picks a PowerShell verb from the HTTP method and the path, summary and operationId function Select-OperationVerb([string]$method, [string]$path, [string]$summary, [string]$operationId) { if (-not $method) { return 'Invoke' } $m = $method.ToUpper() # Build tokens from path/operationId (for ordering) and a separate token list from the summary (for tiebreaking) $rawPath = ($path + ' ' + $(if ($null -ne $operationId) { $operationId } else { '' })) $tokens = ($rawPath -split '[^A-Za-z0-9]+' | Where-Object { $_ -ne '' }) $subtokens = @() for ($i = 0; $i -lt $tokens.Count; $i++) { $t = $tokens[$i] $tokMatches = [regex]::Matches($t, '[A-Z][a-z0-9]*') | ForEach-Object { $_.Value } foreach ($s in $tokMatches) { $subtokens += [pscustomobject]@{ Token = $s; Index = $subtokens.Count } } } $summarySubtokens = @() if ($null -ne $summary -and $summary -ne '') { $rawSummary = $summary $sTokens = ($rawSummary -split '[^A-Za-z0-9]+' | Where-Object { $_ -ne '' }) foreach ($st in $sTokens) { $smatches = [regex]::Matches($st, '[A-Z][a-z0-9]*') | ForEach-Object { $_.Value } foreach ($ss in $smatches) { $summarySubtokens += $ss } } } # helper to choose among candidate matches: prefer one that appears earliest in the summary if present, # otherwise prefer the earliest token occurrence in the path (lowest Index) function Resolve-Match([array]$candidates) { if ($candidates.Count -eq 0) { return $null } if ($candidates.Count -eq 1) { return $candidates[0].Verb } # try to find earliest in summary $best = $null $bestSummaryPos = [int]::MaxValue foreach ($c in $candidates) { $tok = $c.Token $pos = $summarySubtokens.IndexOf($tok) if ($pos -ge 0 -and $pos -lt $bestSummaryPos) { $bestSummaryPos = $pos; $best = $c } } if ($best) { return $best.Verb } # fallback: earliest token index in path $candidates = $candidates | Sort-Object -Property Index return $candidates[0].Verb } switch ($m) { 'GET' { # If the summary explicitly uses Get/Read/Retrieve/Fetch, prefer a plain Get verb $priorityGetWords = @('Get', 'Retrieve', 'Fetch', 'Read') foreach ($w in $priorityGetWords) { if ($summarySubtokens -contains $w) { return 'Get' } } # collect search-like matches $candidates = @() $findList = @('Search', 'Find', 'Matching', 'List', 'Lookup', 'Download', 'GetAll', 'GetBy') for ($i = 0; $i -lt $subtokens.Count; $i++) { $t = $subtokens[$i].Token if ($findList -contains $t) { $candidates += [pscustomobject]@{ Token = $t; Verb = 'Find'; Index = $subtokens[$i].Index } } } $resolved = Resolve-Match $candidates if ($resolved) { return $resolved } return 'Get' } 'POST' { # Token-ordered heuristics for POST: collect all matches then resolve using summary as tiebreaker $mapping = @{ 'Insert' = 'New'; 'Create' = 'New'; 'Add' = 'New'; 'New' = 'New'; 'Upload' = 'New'; 'Register' = 'New'; 'Submit' = 'New' 'Get' = 'Get'; 'GetBy' = 'Get'; 'GetAll' = 'Get' 'Update' = 'Update'; 'Set' = 'Update'; 'Change' = 'Update'; 'Patch' = 'Update'; 'Replace' = 'Update' 'Delete' = 'Remove'; 'Remove' = 'Remove' 'Approve' = 'Approve'; 'Authorize' = 'Approve'; 'Permit' = 'Approve' 'Enable' = 'Enable'; 'Disable' = 'Disable' 'Import' = 'Import'; 'Export' = 'Publish'; 'Download' = 'Publish' 'Search' = 'Find'; 'ByParameters' = 'Find' } $candidates = @() for ($i = 0; $i -lt $subtokens.Count; $i++) { $t = $subtokens[$i].Token if ($mapping.ContainsKey($t)) { $candidates += [pscustomobject]@{ Token = $t; Verb = $mapping[$t]; Index = $subtokens[$i].Index } } } $resolved = Resolve-Match $candidates if ($resolved) { return $resolved } # default for POST is Invoke (action-oriented) return 'Invoke' } 'PUT' { return 'Update' } 'PATCH' { return 'Update' } 'DELETE' { return 'Remove' } default { return 'Invoke' } } } function Get-SampleFromHint { param( [string]$psType, [string]$hint, [int]$depth = 0 ) if ([string]::IsNullOrWhiteSpace($hint)) { return $null } if ($depth -gt 3) { return $null } if ($psType -match '^\[(?<base>[a-z]+)\[\]\]$') { $baseType = "[{0}]" -f $matches['base'] $elementLiteral = Get-SampleFromHint -psType $baseType -hint $hint -depth ($depth + 1) if ($elementLiteral) { return "@($elementLiteral)" } } $normalizedSegments = ($hint -split '\|') | ForEach-Object { $_.Trim() } | Where-Object { $_ } if (-not $normalizedSegments -or $normalizedSegments.Count -eq 0) { $normalizedSegments = @($hint.Trim()) } $entries = @() foreach ($segment in $normalizedSegments) { $label = $segment $value = $segment if ($segment -match '^(?<label>[^=]+?)\s*=\s*(?<value>.+)$') { $label = $matches['label'] $value = $matches['value'] } $entries += [pscustomobject]@{ Label = ($label -replace '"|''', '').Trim() Value = ($value -replace '"|''', '').Trim() } } if ($psType -eq '[bool]') { foreach ($entry in $entries) { if ($entry.Label -match '(?i)true' -or $entry.Value -match '(?i)true') { return '$true' } if ($entry.Label -match '(?i)false' -or $entry.Value -match '(?i)false') { return '$false' } } if ($hint -match '(?i)true') { return '$true' } if ($hint -match '(?i)false') { return '$false' } return $null } if ($psType -in @('[int]', '[long]', '[double]')) { foreach ($entry in $entries) { foreach ($candidate in @($entry.Value, $entry.Label)) { $trimmed = ($candidate -replace '[^0-9\.-]', '').Trim() if (-not $trimmed) { continue } if ($psType -eq '[double]') { $doubleVal = 0.0 if ([double]::TryParse($trimmed, [System.Globalization.NumberStyles]::Float, [System.Globalization.CultureInfo]::InvariantCulture, [ref]$doubleVal)) { return ([string]::Format([System.Globalization.CultureInfo]::InvariantCulture, '{0}', $doubleVal)) } } else { $longVal = 0 if ([long]::TryParse($trimmed, [ref]$longVal)) { return [string]$longVal } } } } return $null } if ($psType -eq '[string]') { foreach ($entry in $entries) { if (-not [string]::IsNullOrWhiteSpace($entry.Label)) { return ConvertTo-PowerShellLiteral $entry.Label } if (-not [string]::IsNullOrWhiteSpace($entry.Value)) { return ConvertTo-PowerShellLiteral $entry.Value } } return $null } return $null } # Sample argument for the generated .EXAMPLE function Get-SampleValue([string]$psType, [object[]]$enumValues = @(), [bool]$hasDefault = $false, [object]$defaultValue = $null, [string]$hint = $null) { if ($enumValues -and $enumValues.Count -gt 0) { $sampleEnum = ConvertTo-PowerShellLiteral $enumValues[0] if ($psType -match '\[\]') { return '@(' + $sampleEnum + ')' } return $sampleEnum } if ($hasDefault) { $defaultLiteral = ConvertTo-PowerShellLiteral $defaultValue if (Test-UseDefaultLiteral -PSType $psType -DefaultLiteral $defaultLiteral) { return $defaultLiteral } } $hintLiteral = Get-SampleFromHint -psType $psType -hint $hint if ($hintLiteral) { return $hintLiteral } switch ($psType) { '[string]' { return "'example'" } '[int]' { return '123' } '[long]' { return '123' } '[double]' { return '3.14' } '[bool]' { return '$true' } '[switch]' { return '$true' } '[hashtable]' { return "@{ Key = 'Value' }" } '[string[]]' { return "@('example1','example2')" } '[int[]]' { return '@(1,2)' } '[long[]]' { return '@(1,2)' } '[double[]]' { return '@(1.1,2.2)' } '[bool[]]' { return '@($true,$false)' } '[hashtable[]]' { return "@(@{ Key = 'Value' })" } '[object[]]' { return "@('a','b')" } default { return "'example'" } } } |