Public/New-PsdType.ps1
|
function New-PsdType { <# .SYNOPSIS Writes classes and enums from a schema, for autocomplete in config scripts. .DESCRIPTION Maps with Properties become classes, Enum on text becomes an enum, enums from '!types' are copied. Value types are [Nullable[T]], so properties you don't set stay $null. Use the file with: using module ./App.Types.psm1 A class made from a map, like [App]@{ ... }, keeps that map. Keys starting with ! and keys ending in a merge operator are allowed in it, and Export-Psd, ConvertTo-Psd, Merge-Psd and -Override use it, so the file holds what was written. Any other key that isn't a property throws. .PARAMETER Name The name of the top-level class. Nested classes are named after it: App, AppServer, ... .PARAMETER Constant Classes of named values, for values that are known only when the types are written. Each entry is a class with one static property per value: a list names each value after itself: Region = @('eu-west') gives [Region]::eu_west, which is 'eu-west'; a map gives the names: Port = @{ Http = 80; Https = 443 } gives [Port]::Http, which is 80. Values can be text, numbers, $true, $false, $null, lists and maps; the property is typed by the value ([string], [int], [bool], [object[]], [hashtable], ...). A character that can't be in a name becomes _, a name that starts with a digit gets _ in front. The schema doesn't check these values. .EXAMPLE New-PsdType -Schema ./app.schema.psd1 -Path ./App.Types.psm1 -Name App .EXAMPLE New-PsdType -Schema ./app.schema.psd1 -Path ./App.Types.psm1 -Name App -Constant @{ Region = @('eu-west', 'us-east'); Port = @{ Http = 80; Https = 443 } } #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [string] $Schema, [string] $Path, [Parameter(Mandatory)] [string] $Name, [System.Collections.IDictionary] $Constant ) $ctx = New-PsdContext $rules = Import-PsdSchemaRules (Resolve-PsdUserPath $Schema) $ctx $null $text = $null if ($rules) { $command = "New-PsdType -Schema $Schema" if ($Path) { $command += " -Path $Path" } $command += " -Name $Name" if ($Constant) { $command += " -Constant @{ $(@($Constant.PSBase.Keys) -join '; ') }" } $outDir = (Get-Location -PSProvider FileSystem).ProviderPath if ($Path) { $outDir = [IO.Path]::GetDirectoryName((Resolve-PsdUserPath $Path)) } $text = New-PsdTypeText $rules $Name $command $outDir $ctx $Constant } if ($ctx.Errors.Count -eq 0 -and $Path) { $full = Resolve-PsdUserPath $Path if ($PSCmdlet.ShouldProcess($full, 'Write types')) { $null = Write-PsdTextFile $full $text $false $ctx } } Write-PsdResult $PSCmdlet $ctx $null if ($ctx.Errors.Count -eq 0 -and -not $Path) { $text } } |