Private/Get-GraphEndpointShard.ps1
|
function Get-GraphEndpointShard { <# .SYNOPSIS Loads and caches a single by-endpoint lite shard. .DESCRIPTION data/graph-command-by-endpoint/{Segment}.json groups records by the first REST path segment (e.g. "users", "groups"), so Get-GraphMapping -Endpoint only needs to load the shard matching the requested endpoint's first segment instead of the whole catalog. #> [CmdletBinding()] [OutputType([pscustomobject])] param( [Parameter(Mandatory)] [string]$Segment, [switch]$Force ) if (-not $script:GraphEndpointShardCache) { $script:GraphEndpointShardCache = [System.Collections.Generic.Dictionary[string, object]]::new([System.StringComparer]::OrdinalIgnoreCase) } if (-not $Force -and $script:GraphEndpointShardCache.ContainsKey($Segment)) { return $script:GraphEndpointShardCache[$Segment] } $paths = Get-GraphCatalogPath if (-not $paths.ByEndpointPath) { Write-Verbose 'GraphShell could not locate the graph-command-by-endpoint folder.' return $null } $shardPath = Join-Path $paths.ByEndpointPath "$Segment.json" if (-not (Test-Path -LiteralPath $shardPath)) { Write-Verbose "GraphShell endpoint shard not found: $shardPath" return $null } Write-Verbose "Loading GraphShell endpoint shard '$Segment' from $shardPath" $raw = Get-Content -LiteralPath $shardPath -Raw $parsed = $raw | ConvertFrom-Json $byUri = [System.Collections.Generic.Dictionary[string, System.Collections.Generic.List[object]]]::new([System.StringComparer]::OrdinalIgnoreCase) foreach ($property in $parsed.uris.PSObject.Properties) { $byUri[$property.Name] = [System.Collections.Generic.List[object]]$property.Value } $shardObject = [pscustomobject]@{ Segment = $Segment; ByUri = $byUri } $script:GraphEndpointShardCache[$Segment] = $shardObject return $shardObject } function Get-GraphAllEndpointSegments { <# .SYNOPSIS Lists every available endpoint shard segment name. .DESCRIPTION Used only by the -Endpoint partial-match fallback, when the requested endpoint has no exact match in its own shard. Loads and discards one shard at a time (never all of them simultaneously) so even this broader search stays lighter than the old approach of holding the entire catalog in memory at once. #> [CmdletBinding()] [OutputType([string[]])] param() $paths = Get-GraphCatalogPath if (-not $paths.ByEndpointPath) { return @() } return @(Get-ChildItem -LiteralPath $paths.ByEndpointPath -Filter '*.json' | ForEach-Object { $_.BaseName }) } |