Private/Resolve-GraphParityForEndpoint.ps1
|
function Resolve-GraphParityForEndpoint { <# .SYNOPSIS Core lookup engine behind Get-GraphParity, for one already-normalized endpoint. .DESCRIPTION Shared by both entry points of Get-GraphParity (-Endpoint and -Cmdlet) so the state computation (SdkAndOpenApi/SdkOnly/OpenApiOnly), API version coverage, estimated module and Invoke-MgGraphRequest equivalent are derived in exactly one place. #> [CmdletBinding()] [OutputType('GraphShell.Parity')] param( [Parameter(Mandatory)] [string]$NormalizedPath, [string]$Method, [Parameter(Mandatory)] [object]$ParityIndex ) $segment = ($NormalizedPath -split '/')[0] if (-not $segment) { $segment = '_root' } $segment = $segment -replace '[\\/:*?"<>|]', '_' # By-endpoint shards are keyed by the RAW catalog uri (e.g. "{application-id}"), not the # normalized "{id}" form used here, so each key is normalized before comparing. $cmdletsByMethod = [System.Collections.Generic.Dictionary[string, object]]::new([System.StringComparer]::OrdinalIgnoreCase) $shard = Get-GraphEndpointShard -Segment $segment if ($shard) { foreach ($entry in $shard.ByUri.GetEnumerator()) { if ((ConvertTo-GraphNormalizedPath -Path $entry.Key) -ne $NormalizedPath) { continue } foreach ($record in $entry.Value) { $recordMethod = $record.method.ToUpperInvariant() $list = $null if (-not $cmdletsByMethod.TryGetValue($recordMethod, [ref]$list)) { $list = [System.Collections.Generic.List[object]]::new() $cmdletsByMethod[$recordMethod] = $list } $list.Add($record) } } } $pathPresence = $null $hasPresence = $ParityIndex.Presence.TryGetValue($NormalizedPath, [ref]$pathPresence) $methodCandidates = [System.Collections.Generic.List[string]]::new() if ($Method) { $methodCandidates.Add($Method.ToUpperInvariant()) } else { $seenMethods = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) foreach ($m in $cmdletsByMethod.Keys) { if ($seenMethods.Add($m)) { $methodCandidates.Add($m) } } if ($hasPresence) { foreach ($m in $pathPresence.Keys) { if ($seenMethods.Add($m)) { $methodCandidates.Add($m) } } } } $results = [System.Collections.Generic.List[object]]::new() foreach ($candidateMethod in $methodCandidates) { $bitmask = 0 if ($hasPresence) { $pathPresence.TryGetValue($candidateMethod, [ref]$bitmask) | Out-Null } $inV1 = ($bitmask -band 1) -ne 0 $inBeta = ($bitmask -band 2) -ne 0 $records = $null $hasCmdlet = $cmdletsByMethod.TryGetValue($candidateMethod, [ref]$records) $cmdletNames = if ($hasCmdlet) { @($records | Select-Object -ExpandProperty command -Unique) } else { @() } $state = if ($hasCmdlet -and ($inV1 -or $inBeta)) { 'SdkAndOpenApi' } elseif ($hasCmdlet) { 'SdkOnly' } elseif ($inV1 -or $inBeta) { 'OpenApiOnly' } else { 'NotFound' } if ($state -eq 'NotFound') { continue } $apiVersionCoverage = if ($inV1 -and $inBeta) { 'v1.0 + beta' } elseif ($inV1) { 'v1.0 only' } elseif ($inBeta) { 'beta only' } else { $recordVersions = @($records | Select-Object -ExpandProperty apiVersion -Unique) if ($recordVersions.Count -gt 0) { $recordVersions -join ' + ' } else { 'unknown' } } $estimatedModule = $null $restEquivalent = $null if (-not $hasCmdlet) { $hint = $null if ($ParityIndex.ModuleHints.TryGetValue("$candidateMethod $NormalizedPath", [ref]$hint)) { $estimatedModule = $hint } if ($NormalizedPath -notmatch '\{id\}') { $restApiVersion = if ($inBeta -and -not $inV1) { 'beta' } else { 'v1.0' } $restEquivalent = "Invoke-MgGraphRequest -Method $candidateMethod -Uri `"https://graph.microsoft.com/$restApiVersion/$NormalizedPath`"" } } $results.Add([pscustomobject]@{ PSTypeName = 'GraphShell.Parity' Endpoint = $NormalizedPath Method = $candidateMethod State = $state ApiVersionCoverage = $apiVersionCoverage HasCmdlet = $hasCmdlet Cmdlets = $cmdletNames EstimatedModule = $estimatedModule RestEquivalent = $restEquivalent }) } return , $results.ToArray() } |