Class/Class.ps1
class Falcon { [string] $Hostname [string] $ClientId [string] $ClientSecret [string] $MemberCid [string] $Token [datetime] $Expires [hashtable] $Endpoints [hashtable] $ItemTypes [hashtable] $Parameters [hashtable] $Patterns [hashtable] $Schema [System.Globalization.TextInfo] $Culture Falcon ($Data) { # Ingest input data generated by Falcon.psm1 and determine culture for dynamic parameter naming $this.Culture = (Get-Culture).TextInfo $this.Endpoints = $Data.Endpoints $this.ItemTypes = $Data.ItemTypes $this.Parameters = $Data.Parameters $this.Patterns = $Data.Patterns $this.Schema = $Data.Schema $this.PSObject.TypeNames.Insert(0,'Falcon') } [string] GetAbsolutePath([string] $Path) { $Output = if (-not [IO.Path]::IsPathRooted($Path)) { # Convert relative paths to absolute paths and respect OS platform $AbsolutePath = Join-Path -Path (Get-Location).Path -ChildPath $Path $AbsolutePath = Join-Path -Path $AbsolutePath -ChildPath '.' [IO.Path]::GetFullPath($AbsolutePath) } else { $Path } return $Output } [hashtable] GetEndpoint([string] $Endpoint) { $Path = $Endpoint.Split(':')[0] $Method = $Endpoint.Split(':')[1] if (-not($Path -and $Method)) { throw "Invalid endpoint: '$Endpoint'" } # Gather endpoint properties and begin output construction $Ref = $this.Endpoints.$Path.$Method $Output = @{ path = $Path method = $Method } $Ref.GetEnumerator().Where({ $_.Key -ne 'parameters' }).foreach{ if ($_.Key -eq 'description') { # Update description using ItemType $Output[$_.Key] = $this.GetItemType($Endpoint, $_.Value) } else { # Add directly to output $Output[$_.Key] = $_.Value } } if ($Ref.parameters) { $Output['parameters'] = $this.GetParameters($Ref.parameters, $Endpoint) } return $Output } [string] GetItemType([string] $Endpoint, [string] $Value) { $Output = if ($Value -match '\{0\}') { $ItemType = $this.ItemTypes.Clone().GetEnumerator().Where({ $Endpoint -match $_.Key }).Value $Value -f $ItemType } else { $Value } return $Output } [hashtable] GetParameters([hashtable] $Object, [string] $Endpoint) { $Output = $Object.Clone() if ($Object.schema) { # Collect parameters from 'Schema' $Ref = $this.GetSchema($Object.schema).Clone() $RefParameters = @( $Ref.Keys ) foreach ($Parameter in $RefParameters) { if ($Output.$Parameter) { # Compare existing parameters against 'Schema' $Properties = @( ($Ref.$Parameter).Keys ) foreach ($Property in $Properties) { if ($Output.$Parameter.$Property) { # Remove existing properties from 'Schema' definition $Ref.$Parameter.Remove($Property) } } # Merge parameter from 'Schema' $Output.$Parameter += $Ref.$Parameter } else { # Add parameter from 'Schema' $Output[$Parameter] = $Ref.$Parameter } } # Remove 'Schema' name $Output.Remove('schema') } foreach ($Pair in $Object.GetEnumerator()) { if ($this.Parameters.($Pair.Key)) { # Gather shared parameter properties $Ref = $this.Parameters.($Pair.Key).Clone() $Output.($Pair.Key).GetEnumerator().foreach{ if ($Ref.($_.Key)) { # Remove existing properties from 'Shared' definition $Ref.Remove($_.Key) } } # Merge parameter from 'Shared' $Output.($Pair.Key) += $Ref } } ($Output.GetEnumerator()).foreach{ if (-not $_.Value.dynamic) { # Generate dynamic parameter name $Output.($_.Key)['dynamic'] = $this.Culture.ToTitleCase($_.Key) -replace '[^a-zA-Z0-9]','' } if (($_.Key -eq 'id') -or ($_.Key -eq 'ids')) { # Append default RegEx pattern by endpoint $Pattern = $this.GetPattern($Endpoint) if ($Pattern) { $Output.($_.Key)['pattern'] = $this.GetPattern($Endpoint) #$Pattern } } # Update description with ItemType $Output.($_.Key)['description'] = $this.GetItemType($Endpoint, $_.Value.description) # Add ParameterSetName $Output.($_.Key)['set'] = $Endpoint } return $Output } [string] GetPattern([string] $Endpoint) { # Match Endpoint to Patterns return $this.Patterns.Clone().GetEnumerator().Where({ $Endpoint -match $_.Key }).Value } [string] GetResponse([string] $Endpoint, [int] $Code) { # Gather Endpoint.Responses and output response type $Path = $Endpoint.Split(':')[0] $Method = $Endpoint.Split(':')[1] if (-not($Path -and $Method)) { throw "Invalid endpoint: '$Endpoint'" } $Responses = $this.Endpoints.$Path.$Method.responses $Output = $Responses.GetEnumerator().Where({ $_.Value -contains $Code }).Key if ($Output) { return $Output } else { return $Responses.default } } [hashtable] GetSchema([string] $Schema) { # Gather schema and output all references as a single parameter set $Output = @{} $this.Schema.($Schema).GetEnumerator().foreach{ if ($_.Value.schema) { $Parent = $_.Key $this.GetSchema($_.Value.schema).GetEnumerator().foreach{ $Output[$_.Key] = $_.Value $Output.($_.Key)['parent'] = $Parent } } else { $Output[$_.Key] = $_.Value } } return $Output } [string] Rfc3339($Int) { # Convert number of hours into an RFC-3339 string return "$([Xml.XmlConvert]::ToString((Get-Date).AddHours($Int),[Xml.XmlDateTimeSerializationMode]::Utc))" } } |