initial Commit
This commit is contained in:
20
Private/Assert-ConfigurationDataExpressionArgumentCount.ps1
Normal file
20
Private/Assert-ConfigurationDataExpressionArgumentCount.ps1
Normal file
@@ -0,0 +1,20 @@
|
||||
function Assert-ConfigurationDataExpressionArgumentCount {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Name,
|
||||
|
||||
[AllowNull()]
|
||||
[object[]]
|
||||
$Arguments,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[int]
|
||||
$Count
|
||||
)
|
||||
|
||||
if(@($Arguments).Count -ne $Count){
|
||||
throw "Function [$Name] expects [$Count] argument(s), but received [$(@($Arguments).Count)]."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
function Assert-ConfigurationDataExpressionMinimumArgumentCount {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Name,
|
||||
|
||||
[AllowNull()]
|
||||
[object[]]
|
||||
$Arguments,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[int]
|
||||
$Count
|
||||
)
|
||||
|
||||
if(@($Arguments).Count -lt $Count){
|
||||
throw "Function [$Name] expects at least [$Count] argument(s), but received [$(@($Arguments).Count)]."
|
||||
}
|
||||
}
|
||||
67
Private/Assert-ConfigurationDataParameter.ps1
Normal file
67
Private/Assert-ConfigurationDataParameter.ps1
Normal file
@@ -0,0 +1,67 @@
|
||||
function Assert-ConfigurationDataParameter {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Name,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Definition,
|
||||
|
||||
[AllowNull()]
|
||||
$Value,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[bool]
|
||||
$HasValue
|
||||
)
|
||||
|
||||
if(Test-ConfigurationDataMapContainsKey -Map $Definition -Key "Deprecated"){
|
||||
$Deprecated = Get-ConfigurationDataMapValue -Map $Definition -Key "Deprecated"
|
||||
$Message = "Parameter [$Name] is deprecated."
|
||||
|
||||
if((Test-ConfigurationDataMap -Value $Deprecated) -and (Test-ConfigurationDataMapContainsKey -Map $Deprecated -Key "Message")){
|
||||
$Message = Resolve-ConfigurationDataLocalizedText -Value (Get-ConfigurationDataMapValue -Map $Deprecated -Key "Message") -DefaultValue $Message
|
||||
}elseif($Deprecated -is [string] -and -not [string]::IsNullOrWhiteSpace($Deprecated)){
|
||||
$Message = $Deprecated
|
||||
}
|
||||
|
||||
Write-Warning $Message
|
||||
}
|
||||
|
||||
$Required = $false
|
||||
if(Test-ConfigurationDataMapContainsKey -Map $Definition -Key "Required"){
|
||||
$Required = [bool](Get-ConfigurationDataMapValue -Map $Definition -Key "Required")
|
||||
}
|
||||
|
||||
if($Required -and ((-not $HasValue) -or (Test-ConfigurationDataValueIsEmpty -Value $Value))){
|
||||
throw "Parameter [$Name] is required."
|
||||
}
|
||||
|
||||
if(-not $HasValue -or $null -eq $Value){
|
||||
return
|
||||
}
|
||||
|
||||
Assert-ConfigurationDataParameterAllowedValue -Name $Name -Definition $Definition -Value $Value
|
||||
|
||||
if(Test-ConfigurationDataMapContainsKey -Map $Definition -Key "MinLength"){
|
||||
$MinLength = [int](Get-ConfigurationDataMapValue -Map $Definition -Key "MinLength")
|
||||
if(([string]$Value).Length -lt $MinLength){
|
||||
throw "Parameter [$Name] value length [$(([string]$Value).Length)] is less than MinLength [$MinLength]."
|
||||
}
|
||||
}
|
||||
|
||||
if(Test-ConfigurationDataMapContainsKey -Map $Definition -Key "MaxLength"){
|
||||
$MaxLength = [int](Get-ConfigurationDataMapValue -Map $Definition -Key "MaxLength")
|
||||
if(([string]$Value).Length -gt $MaxLength){
|
||||
throw "Parameter [$Name] value length [$(([string]$Value).Length)] is greater than MaxLength [$MaxLength]."
|
||||
}
|
||||
}
|
||||
|
||||
if(Test-ConfigurationDataMapContainsKey -Map $Definition -Key "Pattern"){
|
||||
$Pattern = [string](Get-ConfigurationDataMapValue -Map $Definition -Key "Pattern")
|
||||
if(([string]$Value) -notmatch $Pattern){
|
||||
throw "Parameter [$Name] value [$Value] does not match pattern [$Pattern]."
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Private/Assert-ConfigurationDataParameterAllowedValue.ps1
Normal file
27
Private/Assert-ConfigurationDataParameterAllowedValue.ps1
Normal file
@@ -0,0 +1,27 @@
|
||||
function Assert-ConfigurationDataParameterAllowedValue {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Name,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Definition,
|
||||
|
||||
[AllowNull()]
|
||||
$Value
|
||||
)
|
||||
|
||||
if(-not (Test-ConfigurationDataMapContainsKey -Map $Definition -Key "AllowedValues")){
|
||||
return
|
||||
}
|
||||
|
||||
$AllowedValues = @(Get-ConfigurationDataMapValue -Map $Definition -Key "AllowedValues")
|
||||
if($AllowedValues.Count -eq 0){
|
||||
return
|
||||
}
|
||||
|
||||
if($AllowedValues -notcontains $Value){
|
||||
throw "Parameter [$Name] value [$Value] is not allowed. Allowed values are: $($AllowedValues -join ', ')."
|
||||
}
|
||||
}
|
||||
33
Private/ConvertTo-ConfigurationDataExpressionBoolean.ps1
Normal file
33
Private/ConvertTo-ConfigurationDataExpressionBoolean.ps1
Normal file
@@ -0,0 +1,33 @@
|
||||
function ConvertTo-ConfigurationDataExpressionBoolean {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
$Value
|
||||
)
|
||||
|
||||
if($null -eq $Value){
|
||||
return $false
|
||||
}
|
||||
|
||||
if($Value -is [bool]){
|
||||
return $Value
|
||||
}
|
||||
|
||||
if($Value -is [int]){
|
||||
return $Value -ne 0
|
||||
}
|
||||
|
||||
if($Value -is [string]){
|
||||
if($Value -match "^(?i:true|false)$"){
|
||||
return [bool]::Parse($Value)
|
||||
}
|
||||
|
||||
return $Value.Length -gt 0
|
||||
}
|
||||
|
||||
if($Value -is [System.Array]){
|
||||
return @($Value).Count -gt 0
|
||||
}
|
||||
|
||||
return [bool]$Value
|
||||
}
|
||||
19
Private/ConvertTo-ConfigurationDataSafeName.ps1
Normal file
19
Private/ConvertTo-ConfigurationDataSafeName.ps1
Normal file
@@ -0,0 +1,19 @@
|
||||
function ConvertTo-ConfigurationDataSafeName {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
[string]
|
||||
$Value,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Separator
|
||||
)
|
||||
|
||||
if($null -eq $Value){
|
||||
return ""
|
||||
}
|
||||
|
||||
$SafeName = [regex]::Replace($Value.Trim(), "[^A-Za-z0-9_-]+", $Separator)
|
||||
return Normalize-ConfigurationDataSeparator -Value $SafeName -Separator $Separator
|
||||
}
|
||||
13
Private/Get-ConfigurationDataMapValue.ps1
Normal file
13
Private/Get-ConfigurationDataMapValue.ps1
Normal file
@@ -0,0 +1,13 @@
|
||||
function Get-ConfigurationDataMapValue {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Map,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Key
|
||||
)
|
||||
|
||||
return $Map[$Key]
|
||||
}
|
||||
38
Private/Invoke-ConfigurationDataExpression.ps1
Normal file
38
Private/Invoke-ConfigurationDataExpression.ps1
Normal file
@@ -0,0 +1,38 @@
|
||||
function Invoke-ConfigurationDataExpression {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Expression,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Context
|
||||
)
|
||||
|
||||
$Expression = $Expression.Trim()
|
||||
|
||||
if($Expression -match "^'(.*)'$"){
|
||||
return $Matches[1]
|
||||
}
|
||||
|
||||
if($Expression -match "^-?\d+$"){
|
||||
return [int]$Expression
|
||||
}
|
||||
|
||||
if($Expression -match "^(?i:true|false)$"){
|
||||
return [bool]::Parse($Expression)
|
||||
}
|
||||
|
||||
if($Expression -notmatch "^([A-Za-z][A-Za-z0-9]*)\((.*)\)$"){
|
||||
throw "Invalid configuration data expression [$Expression]."
|
||||
}
|
||||
|
||||
$FunctionName = $Matches[1]
|
||||
$ArgumentText = $Matches[2]
|
||||
$Arguments = @()
|
||||
foreach($Argument in @(Split-ConfigurationDataExpressionArguments -ArgumentText $ArgumentText)){
|
||||
$Arguments += ,(Invoke-ConfigurationDataExpressionArgument -Argument $Argument -Context $Context)
|
||||
}
|
||||
|
||||
return Invoke-ConfigurationDataExpressionFunction -Name $FunctionName -Arguments $Arguments -Context $Context
|
||||
}
|
||||
35
Private/Invoke-ConfigurationDataExpressionArgument.ps1
Normal file
35
Private/Invoke-ConfigurationDataExpressionArgument.ps1
Normal file
@@ -0,0 +1,35 @@
|
||||
function Invoke-ConfigurationDataExpressionArgument {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
[string]
|
||||
$Argument,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Context
|
||||
)
|
||||
|
||||
if($null -eq $Argument){
|
||||
return $null
|
||||
}
|
||||
|
||||
$Argument = $Argument.Trim()
|
||||
|
||||
if($Argument -match "^'(.*)'$"){
|
||||
return $Matches[1]
|
||||
}
|
||||
|
||||
if($Argument -match "^-?\d+$"){
|
||||
return [int]$Argument
|
||||
}
|
||||
|
||||
if($Argument -match "^(?i:true|false)$"){
|
||||
return [bool]::Parse($Argument)
|
||||
}
|
||||
|
||||
if($Argument -match "^[A-Za-z][A-Za-z0-9]*\(.*\)$"){
|
||||
return Invoke-ConfigurationDataExpression -Expression $Argument -Context $Context
|
||||
}
|
||||
|
||||
return $Argument
|
||||
}
|
||||
279
Private/Invoke-ConfigurationDataExpressionFunction.ps1
Normal file
279
Private/Invoke-ConfigurationDataExpressionFunction.ps1
Normal file
@@ -0,0 +1,279 @@
|
||||
function Invoke-ConfigurationDataExpressionFunction {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Name,
|
||||
|
||||
[AllowNull()]
|
||||
[object[]]
|
||||
$Arguments,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Context
|
||||
)
|
||||
|
||||
$FunctionName = $Name.ToLowerInvariant()
|
||||
|
||||
switch($FunctionName){
|
||||
"parameters" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return Resolve-ConfigurationDataParameter -Name ([string]$Arguments[0]) -Context $Context
|
||||
}
|
||||
"variables" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return Resolve-ConfigurationDataVariable -Name ([string]$Arguments[0]) -Context $Context
|
||||
}
|
||||
"concat" {
|
||||
return (@($Arguments) | ForEach-Object { [string]$_ }) -join ""
|
||||
}
|
||||
"format" {
|
||||
Assert-ConfigurationDataExpressionMinimumArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return [string]::Format([string]$Arguments[0], @($Arguments | Select-Object -Skip 1))
|
||||
}
|
||||
"coalesce" {
|
||||
foreach($Argument in @($Arguments)){
|
||||
if($null -ne $Argument -and [string]$Argument -ne ""){
|
||||
return $Argument
|
||||
}
|
||||
}
|
||||
|
||||
return $null
|
||||
}
|
||||
"defaultifempty" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
if(Test-ConfigurationDataValueIsEmpty -Value $Arguments[0]){
|
||||
return $Arguments[1]
|
||||
}
|
||||
|
||||
return $Arguments[0]
|
||||
}
|
||||
"if" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 3
|
||||
if(ConvertTo-ConfigurationDataExpressionBoolean -Value $Arguments[0]){
|
||||
return $Arguments[1]
|
||||
}
|
||||
|
||||
return $Arguments[2]
|
||||
}
|
||||
"equals" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return $Arguments[0] -eq $Arguments[1]
|
||||
}
|
||||
"notequals" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return $Arguments[0] -ne $Arguments[1]
|
||||
}
|
||||
"and" {
|
||||
Assert-ConfigurationDataExpressionMinimumArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
foreach($Argument in @($Arguments)){
|
||||
if(-not (ConvertTo-ConfigurationDataExpressionBoolean -Value $Argument)){
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
"or" {
|
||||
Assert-ConfigurationDataExpressionMinimumArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
foreach($Argument in @($Arguments)){
|
||||
if(ConvertTo-ConfigurationDataExpressionBoolean -Value $Argument){
|
||||
return $true
|
||||
}
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
"not" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return -not (ConvertTo-ConfigurationDataExpressionBoolean -Value $Arguments[0])
|
||||
}
|
||||
"tolower" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return ([string]$Arguments[0]).ToLowerInvariant()
|
||||
}
|
||||
"toupper" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return ([string]$Arguments[0]).ToUpperInvariant()
|
||||
}
|
||||
"firstindexof" {
|
||||
Assert-ConfigurationDataExpressionMinimumArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return $Arguments[0]
|
||||
}
|
||||
"lastindexof" {
|
||||
Assert-ConfigurationDataExpressionMinimumArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return $Arguments[$Arguments.Count - 1]
|
||||
}
|
||||
"indexof" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return ([string]$Arguments[0])[([int]$Arguments[1])].ToString()
|
||||
}
|
||||
"substring" {
|
||||
if($Arguments.Count -eq 2){
|
||||
return ([string]$Arguments[0]).Substring([int]$Arguments[1])
|
||||
}
|
||||
|
||||
if($Arguments.Count -eq 3){
|
||||
return ([string]$Arguments[0]).Substring([int]$Arguments[1], [int]$Arguments[2])
|
||||
}
|
||||
|
||||
throw "Function [$Name] expects 2 or 3 arguments, but received [$($Arguments.Count)]."
|
||||
}
|
||||
"replace" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 3
|
||||
return ([string]$Arguments[0]).Replace([string]$Arguments[1], [string]$Arguments[2])
|
||||
}
|
||||
"sanitizeName" {
|
||||
if($Arguments.Count -eq 1){
|
||||
return ConvertTo-ConfigurationDataSafeName -Value ([string]$Arguments[0]) -Separator "_"
|
||||
}
|
||||
|
||||
if($Arguments.Count -eq 2){
|
||||
return ConvertTo-ConfigurationDataSafeName -Value ([string]$Arguments[0]) -Separator ([string]$Arguments[1])
|
||||
}
|
||||
|
||||
throw "Function [$Name] expects 1 or 2 arguments, but received [$($Arguments.Count)]."
|
||||
}
|
||||
"normalizeseparator" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return Normalize-ConfigurationDataSeparator -Value ([string]$Arguments[0]) -Separator ([string]$Arguments[1])
|
||||
}
|
||||
"prefixifnotempty" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
if(Test-ConfigurationDataValueIsEmpty -Value $Arguments[0]){
|
||||
return ""
|
||||
}
|
||||
|
||||
return ([string]$Arguments[1]) + ([string]$Arguments[0])
|
||||
}
|
||||
"suffixifnotempty" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
if(Test-ConfigurationDataValueIsEmpty -Value $Arguments[0]){
|
||||
return ""
|
||||
}
|
||||
|
||||
return ([string]$Arguments[0]) + ([string]$Arguments[1])
|
||||
}
|
||||
"contains" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
if($Arguments[0] -is [System.Array] -and $Arguments[0] -isnot [string]){
|
||||
return @($Arguments[0]) -contains $Arguments[1]
|
||||
}
|
||||
|
||||
return ([string]$Arguments[0]).Contains([string]$Arguments[1])
|
||||
}
|
||||
"startswith" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return ([string]$Arguments[0]).StartsWith([string]$Arguments[1], [System.StringComparison]::OrdinalIgnoreCase)
|
||||
}
|
||||
"endswith" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return ([string]$Arguments[0]).EndsWith([string]$Arguments[1], [System.StringComparison]::OrdinalIgnoreCase)
|
||||
}
|
||||
"split" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return ,(([string]$Arguments[0]).Split([string[]]@([string]$Arguments[1]), [System.StringSplitOptions]::None))
|
||||
}
|
||||
"join" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return (@($Arguments[0]) | ForEach-Object { [string]$_ }) -join ([string]$Arguments[1])
|
||||
}
|
||||
"joinnotempty" {
|
||||
Assert-ConfigurationDataExpressionMinimumArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
$Separator = [string]$Arguments[0]
|
||||
$Items = @()
|
||||
|
||||
foreach($Argument in @($Arguments | Select-Object -Skip 1)){
|
||||
foreach($Item in @($Argument)){
|
||||
if($null -ne $Item -and -not [string]::IsNullOrWhiteSpace([string]$Item)){
|
||||
$Items += [string]$Item
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $Items -join $Separator
|
||||
}
|
||||
"take" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return ,(@($Arguments[0]) | Select-Object -First ([int]$Arguments[1]))
|
||||
}
|
||||
"skip" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 2
|
||||
return ,(@($Arguments[0]) | Select-Object -Skip ([int]$Arguments[1]))
|
||||
}
|
||||
"first" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return @($Arguments[0])[0]
|
||||
}
|
||||
"last" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
$Items = @($Arguments[0])
|
||||
return $Items[$Items.Count - 1]
|
||||
}
|
||||
"unique" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return ,(@($Arguments[0]) | Select-Object -Unique)
|
||||
}
|
||||
"sort" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return ,(@($Arguments[0]) | Sort-Object)
|
||||
}
|
||||
"trim" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return ([string]$Arguments[0]).Trim()
|
||||
}
|
||||
"trimstart" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return ([string]$Arguments[0]).TrimStart()
|
||||
}
|
||||
"trimend" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
return ([string]$Arguments[0]).TrimEnd()
|
||||
}
|
||||
"padleft" {
|
||||
if($Arguments.Count -eq 2){
|
||||
return ([string]$Arguments[0]).PadLeft([int]$Arguments[1])
|
||||
}
|
||||
|
||||
if($Arguments.Count -eq 3){
|
||||
return ([string]$Arguments[0]).PadLeft([int]$Arguments[1], ([string]$Arguments[2])[0])
|
||||
}
|
||||
|
||||
throw "Function [$Name] expects 2 or 3 arguments, but received [$($Arguments.Count)]."
|
||||
}
|
||||
"padright" {
|
||||
if($Arguments.Count -eq 2){
|
||||
return ([string]$Arguments[0]).PadRight([int]$Arguments[1])
|
||||
}
|
||||
|
||||
if($Arguments.Count -eq 3){
|
||||
return ([string]$Arguments[0]).PadRight([int]$Arguments[1], ([string]$Arguments[2])[0])
|
||||
}
|
||||
|
||||
throw "Function [$Name] expects 2 or 3 arguments, but received [$($Arguments.Count)]."
|
||||
}
|
||||
"length" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
if($Arguments[0] -is [System.Array] -and $Arguments[0] -isnot [string]){
|
||||
return @($Arguments[0]).Count
|
||||
}
|
||||
|
||||
return ([string]$Arguments[0]).Length
|
||||
}
|
||||
"empty" {
|
||||
Assert-ConfigurationDataExpressionArgumentCount -Name $Name -Arguments $Arguments -Count 1
|
||||
if($null -eq $Arguments[0]){
|
||||
return $true
|
||||
}
|
||||
|
||||
if($Arguments[0] -is [System.Array] -and $Arguments[0] -isnot [string]){
|
||||
return @($Arguments[0]).Count -eq 0
|
||||
}
|
||||
|
||||
return [string]$Arguments[0] -eq ""
|
||||
}
|
||||
default {
|
||||
throw "Unsupported configuration data expression function [$Name]."
|
||||
}
|
||||
}
|
||||
}
|
||||
44
Private/New-ConfigurationDataResolutionContext.ps1
Normal file
44
Private/New-ConfigurationDataResolutionContext.ps1
Normal file
@@ -0,0 +1,44 @@
|
||||
function New-ConfigurationDataResolutionContext {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[System.Collections.Hashtable]
|
||||
$ConfigurationData
|
||||
)
|
||||
|
||||
$Context = [PSCustomObject]@{
|
||||
Parameters = @{}
|
||||
Variables = @{}
|
||||
VariableDefinitions = @{}
|
||||
ResolvingVariables = @{}
|
||||
}
|
||||
|
||||
if($ConfigurationData.ContainsKey("Parameters") -and $null -ne $ConfigurationData.Parameters){
|
||||
foreach($Entry in $ConfigurationData.Parameters.GetEnumerator()){
|
||||
$Definition = $Entry.Value
|
||||
|
||||
$HasExplicitValue = (Test-ConfigurationDataMap -Value $Definition) -and (Test-ConfigurationDataMapContainsKey -Map $Definition -Key "Value")
|
||||
$HasDefaultValue = (Test-ConfigurationDataMap -Value $Definition) -and (Test-ConfigurationDataMapContainsKey -Map $Definition -Key "DefaultValue")
|
||||
|
||||
if($HasExplicitValue){
|
||||
$Context.Parameters[$Entry.Name] = Get-ConfigurationDataMapValue -Map $Definition -Key "Value"
|
||||
}elseif($HasDefaultValue){
|
||||
$Context.Parameters[$Entry.Name] = Get-ConfigurationDataMapValue -Map $Definition -Key "DefaultValue"
|
||||
}else{
|
||||
$Context.Parameters[$Entry.Name] = $Definition
|
||||
}
|
||||
|
||||
if(Test-ConfigurationDataMap -Value $Definition){
|
||||
Assert-ConfigurationDataParameter -Name $Entry.Name -Definition $Definition -Value $Context.Parameters[$Entry.Name] -HasValue:($HasExplicitValue -or $HasDefaultValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($ConfigurationData.ContainsKey("Variables") -and $null -ne $ConfigurationData.Variables){
|
||||
foreach($Entry in $ConfigurationData.Variables.GetEnumerator()){
|
||||
$Context.VariableDefinitions[$Entry.Name] = $Entry.Value
|
||||
}
|
||||
}
|
||||
|
||||
return $Context
|
||||
}
|
||||
26
Private/Normalize-ConfigurationDataSeparator.ps1
Normal file
26
Private/Normalize-ConfigurationDataSeparator.ps1
Normal file
@@ -0,0 +1,26 @@
|
||||
function Normalize-ConfigurationDataSeparator {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
[string]
|
||||
$Value,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Separator
|
||||
)
|
||||
|
||||
if($null -eq $Value){
|
||||
return ""
|
||||
}
|
||||
|
||||
if([string]::IsNullOrEmpty($Separator)){
|
||||
return $Value
|
||||
}
|
||||
|
||||
$EscapedSeparator = [regex]::Escape($Separator)
|
||||
$Normalized = [regex]::Replace($Value, "($EscapedSeparator){2,}", $Separator)
|
||||
$Normalized = $Normalized.Trim()
|
||||
$Normalized = [regex]::Replace($Normalized, "^$EscapedSeparator|$EscapedSeparator$", "")
|
||||
return $Normalized
|
||||
}
|
||||
16
Private/Resolve-ConfigurationDataExpression.ps1
Normal file
16
Private/Resolve-ConfigurationDataExpression.ps1
Normal file
@@ -0,0 +1,16 @@
|
||||
function Resolve-ConfigurationDataExpression {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Expression,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Context
|
||||
)
|
||||
|
||||
$Body = $Expression.Trim()
|
||||
$Body = $Body.Substring(1, $Body.Length - 2).Trim()
|
||||
|
||||
return Invoke-ConfigurationDataExpression -Expression $Body -Context $Context
|
||||
}
|
||||
50
Private/Resolve-ConfigurationDataLocalizedText.ps1
Normal file
50
Private/Resolve-ConfigurationDataLocalizedText.ps1
Normal file
@@ -0,0 +1,50 @@
|
||||
function Resolve-ConfigurationDataLocalizedText {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
$Value,
|
||||
|
||||
[AllowNull()]
|
||||
[string]
|
||||
$DefaultValue
|
||||
)
|
||||
|
||||
if($null -eq $Value){
|
||||
return $DefaultValue
|
||||
}
|
||||
|
||||
if($Value -is [string]){
|
||||
if([string]::IsNullOrWhiteSpace($Value)){
|
||||
return $DefaultValue
|
||||
}
|
||||
|
||||
return $Value
|
||||
}
|
||||
|
||||
if(-not (Test-ConfigurationDataMap -Value $Value)){
|
||||
return [string]$Value
|
||||
}
|
||||
|
||||
$CultureNames = @(
|
||||
[System.Globalization.CultureInfo]::CurrentUICulture.Name,
|
||||
[System.Globalization.CultureInfo]::CurrentCulture.Name,
|
||||
"en-US",
|
||||
"de-DE",
|
||||
"en",
|
||||
"de"
|
||||
) | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Select-Object -Unique
|
||||
|
||||
foreach($CultureName in $CultureNames){
|
||||
if(Test-ConfigurationDataMapContainsKey -Map $Value -Key $CultureName){
|
||||
return [string](Get-ConfigurationDataMapValue -Map $Value -Key $CultureName)
|
||||
}
|
||||
}
|
||||
|
||||
foreach($Entry in $Value.GetEnumerator()){
|
||||
if($null -ne $Entry.Value -and -not [string]::IsNullOrWhiteSpace([string]$Entry.Value)){
|
||||
return [string]$Entry.Value
|
||||
}
|
||||
}
|
||||
|
||||
return $DefaultValue
|
||||
}
|
||||
17
Private/Resolve-ConfigurationDataParameter.ps1
Normal file
17
Private/Resolve-ConfigurationDataParameter.ps1
Normal file
@@ -0,0 +1,17 @@
|
||||
function Resolve-ConfigurationDataParameter {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Name,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Context
|
||||
)
|
||||
|
||||
if(-not $Context.Parameters.ContainsKey($Name)){
|
||||
throw "Parameter [$Name] is not defined."
|
||||
}
|
||||
|
||||
return Resolve-ConfigurationDataValue -Value $Context.Parameters[$Name] -Context $Context
|
||||
}
|
||||
44
Private/Resolve-ConfigurationDataValue.ps1
Normal file
44
Private/Resolve-ConfigurationDataValue.ps1
Normal file
@@ -0,0 +1,44 @@
|
||||
function Resolve-ConfigurationDataValue {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
$Value,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Context
|
||||
)
|
||||
|
||||
if($null -eq $Value){
|
||||
return $null
|
||||
}
|
||||
|
||||
if($Value -is [System.Collections.Specialized.OrderedDictionary]){
|
||||
$Resolved = [ordered]@{}
|
||||
foreach($Entry in $Value.GetEnumerator()){
|
||||
$Resolved[$Entry.Name] = Resolve-ConfigurationDataValue -Value $Entry.Value -Context $Context
|
||||
}
|
||||
return $Resolved
|
||||
}
|
||||
|
||||
if($Value -is [System.Collections.Hashtable]){
|
||||
$Resolved = @{}
|
||||
foreach($Entry in $Value.GetEnumerator()){
|
||||
$Resolved[$Entry.Name] = Resolve-ConfigurationDataValue -Value $Entry.Value -Context $Context
|
||||
}
|
||||
return $Resolved
|
||||
}
|
||||
|
||||
if($Value -is [System.Array] -and $Value -isnot [string]){
|
||||
$Resolved = @()
|
||||
foreach($Item in $Value){
|
||||
$Resolved += ,(Resolve-ConfigurationDataValue -Value $Item -Context $Context)
|
||||
}
|
||||
return ,$Resolved
|
||||
}
|
||||
|
||||
if($Value -is [string] -and (Test-ConfigurationDataExpression -Value $Value)){
|
||||
return Resolve-ConfigurationDataExpression -Expression $Value -Context $Context
|
||||
}
|
||||
|
||||
return $Value
|
||||
}
|
||||
32
Private/Resolve-ConfigurationDataVariable.ps1
Normal file
32
Private/Resolve-ConfigurationDataVariable.ps1
Normal file
@@ -0,0 +1,32 @@
|
||||
function Resolve-ConfigurationDataVariable {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Name,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Context
|
||||
)
|
||||
|
||||
if($Context.Variables.ContainsKey($Name)){
|
||||
return $Context.Variables[$Name]
|
||||
}
|
||||
|
||||
if(-not $Context.VariableDefinitions.ContainsKey($Name)){
|
||||
throw "Variable [$Name] is not defined."
|
||||
}
|
||||
|
||||
if($Context.ResolvingVariables.ContainsKey($Name)){
|
||||
throw "Circular variable reference detected for variable [$Name]."
|
||||
}
|
||||
|
||||
$Context.ResolvingVariables[$Name] = $true
|
||||
try {
|
||||
$Resolved = Resolve-ConfigurationDataValue -Value $Context.VariableDefinitions[$Name] -Context $Context
|
||||
$Context.Variables[$Name] = $Resolved
|
||||
return $Resolved
|
||||
} finally {
|
||||
$Context.ResolvingVariables.Remove($Name)
|
||||
}
|
||||
}
|
||||
47
Private/Split-ConfigurationDataExpressionArguments.ps1
Normal file
47
Private/Split-ConfigurationDataExpressionArguments.ps1
Normal file
@@ -0,0 +1,47 @@
|
||||
function Split-ConfigurationDataExpressionArguments {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
[string]
|
||||
$ArgumentText
|
||||
)
|
||||
|
||||
if([string]::IsNullOrWhiteSpace($ArgumentText)){
|
||||
return @()
|
||||
}
|
||||
|
||||
$Arguments = @()
|
||||
$Current = New-Object -TypeName System.Text.StringBuilder
|
||||
$Depth = 0
|
||||
$InString = $false
|
||||
|
||||
for($Index = 0; $Index -lt $ArgumentText.Length; $Index++){
|
||||
$Character = $ArgumentText[$Index]
|
||||
|
||||
if($Character -eq "'"){
|
||||
[void]$Current.Append($Character)
|
||||
$InString = -not $InString
|
||||
continue
|
||||
}
|
||||
|
||||
if(-not $InString){
|
||||
if($Character -eq "("){
|
||||
$Depth++
|
||||
}elseif($Character -eq ")"){
|
||||
$Depth--
|
||||
}elseif($Character -eq "," -and $Depth -eq 0){
|
||||
$Arguments += $Current.ToString().Trim()
|
||||
[void]$Current.Clear()
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
[void]$Current.Append($Character)
|
||||
}
|
||||
|
||||
if($Current.Length -gt 0){
|
||||
$Arguments += $Current.ToString().Trim()
|
||||
}
|
||||
|
||||
return $Arguments
|
||||
}
|
||||
15
Private/Test-ConfigurationDataExpression.ps1
Normal file
15
Private/Test-ConfigurationDataExpression.ps1
Normal file
@@ -0,0 +1,15 @@
|
||||
function Test-ConfigurationDataExpression {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
[string]
|
||||
$Value
|
||||
)
|
||||
|
||||
if([string]::IsNullOrWhiteSpace($Value)){
|
||||
return $false
|
||||
}
|
||||
|
||||
$Trimmed = $Value.Trim()
|
||||
return $Trimmed.StartsWith("[") -and $Trimmed.EndsWith("]")
|
||||
}
|
||||
9
Private/Test-ConfigurationDataMap.ps1
Normal file
9
Private/Test-ConfigurationDataMap.ps1
Normal file
@@ -0,0 +1,9 @@
|
||||
function Test-ConfigurationDataMap {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
$Value
|
||||
)
|
||||
|
||||
return ($Value -is [System.Collections.Hashtable]) -or ($Value -is [System.Collections.Specialized.OrderedDictionary])
|
||||
}
|
||||
21
Private/Test-ConfigurationDataMapContainsKey.ps1
Normal file
21
Private/Test-ConfigurationDataMapContainsKey.ps1
Normal file
@@ -0,0 +1,21 @@
|
||||
function Test-ConfigurationDataMapContainsKey {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Map,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Key
|
||||
)
|
||||
|
||||
if($Map -is [System.Collections.Hashtable]){
|
||||
return $Map.ContainsKey($Key)
|
||||
}
|
||||
|
||||
if($Map -is [System.Collections.Specialized.OrderedDictionary]){
|
||||
return $Map.Contains($Key)
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
21
Private/Test-ConfigurationDataValueIsEmpty.ps1
Normal file
21
Private/Test-ConfigurationDataValueIsEmpty.ps1
Normal file
@@ -0,0 +1,21 @@
|
||||
function Test-ConfigurationDataValueIsEmpty {
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[AllowNull()]
|
||||
$Value
|
||||
)
|
||||
|
||||
if($null -eq $Value){
|
||||
return $true
|
||||
}
|
||||
|
||||
if($Value -is [string]){
|
||||
return [string]::IsNullOrWhiteSpace($Value)
|
||||
}
|
||||
|
||||
if($Value -is [System.Array]){
|
||||
return @($Value).Count -eq 0
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
Reference in New Issue
Block a user