Private/Document/Resolve-OpenApiPointer.ps1

function Resolve-OpenApiPointer {
    <#
    .SYNOPSIS
        Resolves a local reference ('#/components/schemas/Pet') against a raw document tree.
    .DESCRIPTION
        The fragment is percent-decoded, split on '/', and each segment is unescaped ('~1' -> '/',
        then '~0' -> '~'). '#/definitions/...' is read from '#/components/schemas/...' when the tree
        has no 'definitions' (Swagger 2.0 documents are converted before they are resolved).
        Returns { Found, Value, Pointer } where Pointer is the canonical JSON pointer of the target.
    #>

    [CmdletBinding()]
    [OutputType([pscustomobject])]
    param(
        [Parameter(Mandatory)]
        [AllowNull()]
        [object]$Root,

        [Parameter(Mandatory)]
        [AllowEmptyString()]
        [string]$Reference
    )

    $notFound = [pscustomobject]@{ Found = $false; Value = $null; Pointer = $null }
    if (-not $Reference.StartsWith('#')) {
        return $notFound
    }
    $fragment = $Reference.Substring(1)
    if ($fragment.Length -gt 0 -and -not $fragment.StartsWith('/')) {
        return $notFound
    }

    $segments = [System.Collections.Generic.List[string]]::new()
    if ($fragment.Length -gt 0) {
        foreach ($raw in $fragment.Substring(1).Split('/')) {
            $decoded = [System.Uri]::UnescapeDataString($raw)
            $segments.Add($decoded.Replace('~1', '/').Replace('~0', '~'))
        }
    }
    if ($segments.Count -ge 1 -and $segments[0] -ceq 'definitions' -and $Root -is [System.Collections.IDictionary] -and -not $Root.Contains('definitions')) {
        $segments[0] = 'schemas'
        $segments.Insert(0, 'components')
    }

    $current = $Root
    foreach ($segment in $segments) {
        if ($current -is [System.Collections.IDictionary]) {
            if (-not $current.Contains($segment)) {
                return $notFound
            }
            $current = $current[$segment]
        }
        elseif ($current -is [System.Collections.IList]) {
            $index = 0
            if (-not [int]::TryParse($segment, [ref]$index) -or $index -lt 0 -or $index -ge $current.Count) {
                return $notFound
            }
            $current = $current[$index]
        }
        else {
            return $notFound
        }
    }

    $pointer = ''
    if ($segments.Count -gt 0) {
        $pointer = Join-OpenApiJsonPointer -Pointer '' -Segment $segments.ToArray()
    }
    return [pscustomobject]@{ Found = $true; Value = $current; Pointer = $pointer }
}