Private/Association/Format-JCAssociation.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
Function Format-JCAssociation
{
    Param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)][ValidateNotNullOrEmpty()][string]$Uri
        , [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 1)][ValidateNotNullOrEmpty()][string]$Method
        , [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 2)][ValidateNotNullOrEmpty()][object]$Source
        , [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 3)][ValidateNotNullOrEmpty()][string]$TargetId
        , [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 4)][ValidateNotNullOrEmpty()][bool]$IncludeInfo = $false
        , [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 5)][ValidateNotNullOrEmpty()][bool]$IncludeNames = $false
        , [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 6)][ValidateNotNullOrEmpty()][bool]$IncludeVisualPath = $false
        , [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 7)][ValidateNotNullOrEmpty()][bool]$Raw = $false
    )
    Write-Debug ('[UrlTemplate]:' + $Uri)
    $AssociationsOut = @()
    $Associations = Invoke-JCApi -Method:($Method) -Paginate:($true) -Url:($Uri)
    If ($TargetId)
    {
        $Associations = $Associations | Where-Object {$_.id -eq $TargetId}
    }
    If ($Associations -and $Associations.PSObject.Properties.name -notcontains 'NoContent')
    {
        $Associations | ForEach-Object {
            #Region Determine if association is 'direct', 'indirect', or "direct`/indirect" and apply label
            $_.paths | ForEach-Object {
                $PathCount = ($_.to | Measure-Object).Count
                $associationType = If ($PathCount -eq 0 -or $PathCount -eq 1)
                {
                    'direct'
                }
                ElseIf ($PathCount -gt 1)
                {
                    'indirect'
                }
                Else
                {
                    'associationType unknown;The count of paths is:' + [string]$PathCount
                }
                Add-Member -InputObject:($_) -MemberType:('NoteProperty') -Name:('associationType') -Value:($associationType)
            }
            $associationType = ($_.paths.associationType | Sort-Object | Select-Object -Unique) -join '/'
            #EndRegion Determine if association is 'direct', 'indirect', or "direct`/indirect" and apply label
            #Region Build record for each association
            If ($Raw)
            {
                # Raw switch allows for the user to return an unformatted version of what the api endpoint returns
                Add-Member -InputObject:($_) -NotePropertyName:('associationType') -NotePropertyValue:($associationType);
                $_.paths | ForEach-Object {$_.PSObject.Properties.Remove('associationType')}
                $AssociationsOut += $_
            }
            Else
            {
                $AssociationHash = [ordered]@{
                    'associationType'  = $associationType;
                    'id'               = $Source.($Source.ById);
                    'type'             = $Source.TypeName.TypeNameSingular;
                    'name'             = $null;
                    'info'             = $null;
                    'targetId'         = $null;
                    'targetType'       = $null;
                    'targetName'       = $null;
                    'targetInfo'       = $null;
                    'visualPathById'   = $null;
                    'visualPathByName' = $null;
                    'visualPathByType' = $null;
                };
                # Dynamically get the rest of the properties and add them to the hash
                $AssociationProperties = $_ |
                    ForEach-Object {$_.PSObject.Properties.name} |
                    Select-Object -Unique
                If ($AssociationProperties)
                {
                    ForEach ($AssociationProperty In $AssociationProperties | Where-Object {$_ -notin ('id', 'type')})
                    {
                        $AssociationHash.Add($AssociationProperty, $_.($AssociationProperty)) | Out-Null
                    }
                }
                Else
                {
                    Write-Error ('No object properties found for association record.')
                }
                # If any "Include*" switch is provided get the target object
                If ($IncludeInfo -or $IncludeNames -or $IncludeVisualPath)
                {
                    $Target = Get-JCObject -Type:($_.type) -Id:($_.id)
                }
                # If target is populated
                If ($Target)
                {
                    $AssociationHash.targetId = $Target.($Target.ById)
                    $AssociationHash.targetType = $Target.TypeName.TypeNameSingular
                }
                Else
                {
                    $AssociationHash.targetId = $_.id
                    $AssociationHash.targetType = $_.type
                }
                # Show source and target info
                If ($IncludeInfo)
                {
                    $AssociationHash.info = $Source
                    $AssociationHash.targetInfo = $Target
                }
                # Show names of source and target
                If ($IncludeNames)
                {
                    $AssociationHash.name = $Source.($Source.ByName)
                    $AssociationHash.targetName = $Target.($Target.ByName)
                }
                # Map out the associations path and show
                If ($IncludeVisualPath)
                {
                    class AssociationMap
                    {
                        [string]$Id; [string]$Name; [string]$Type;
                        AssociationMap([string]$i, [string]$n, [string]$t) {$this.Id = $i; $this.Name = $n; $this.Type = $t; }
                    }
                    $_.paths | ForEach-Object {
                        $AssociationVisualPath = @()
                        [AssociationMap]$AssociationVisualPathRecord = [AssociationMap]::new($Source.($Source.ById), $Source.($Source.ByName), $Source.TypeName.TypeNameSingular)
                        $AssociationVisualPath += $AssociationVisualPathRecord
                        $_.to | ForEach-Object {
                            $AssociationPathToItemInfo = Get-JCObject -Type:($_.type) -Id:($_.id)
                            $AssociationVisualPath += [AssociationMap]::new($_.id, $AssociationPathToItemInfo.($AssociationPathToItemInfo.ByName), $_.type)
                        }
                        ($AssociationVisualPath | ForEach-Object {$_.PSObject.Properties.name} |
                                Select-Object -Unique) |
                            ForEach-Object {
                            $KeyName_visualPath = 'visualPathBy' + $_
                            $AssociationHash.($KeyName_visualPath) = ('"' + ($AssociationVisualPath.($_) -join '" -> "') + '"')
                        }
                    }
                }
                # Convert the hashtable to an object where the Value has been populated
                $AssociationsUpdated = [PSCustomObject]@{}
                $AssociationHash.GetEnumerator() |
                    ForEach-Object {If ($_.Value -or $_.key -in ($AssociationProperties) -or $_.key -in ('targetId', 'targetType')) {Add-Member -InputObject:($AssociationsUpdated) -NotePropertyName:($_.Key) -NotePropertyValue:($_.Value)}}
                $AssociationsOut += $AssociationsUpdated
            }
        }
        #EndRegion Build record for each association
        Return $AssociationsOut
    }
}