Modules/businessdev.ALbuild.Feeds/Private/ConvertTo-BcAzureDevOpsFeedCoordinate.ps1

function ConvertTo-BcAzureDevOpsFeedCoordinate {
    <#
    .SYNOPSIS
        Parses an Azure DevOps Artifacts NuGet v3 feed URL into organisation, project and feed parts.
 
    .DESCRIPTION
        Internal helper for the Packaging REST API. Supports both URL shapes:
          - https://pkgs.dev.azure.com/<org>[/<project>]/_packaging/<feed>/nuget/v3/index.json
          - https://<org>.pkgs.visualstudio.com[/<project>]/_packaging/<feed>/nuget/v3/index.json
        The project segment is optional (org-scoped feeds). Throws for non-Azure-DevOps hosts, since
        feed views are an Azure DevOps-only feature.
 
    .PARAMETER Url
        The feed's NuGet v3 service index URL.
 
    .OUTPUTS
        Hashtable with BaseUrl (the pkgs host root incl. org), Project (or ''), and Feed.
    #>

    [CmdletBinding()]
    [OutputType([hashtable])]
    param(
        [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Url
    )

    $uri = [uri] $Url
    $feedHost = $uri.Host
    $isModern = $feedHost -eq 'pkgs.dev.azure.com'
    $isLegacy = $feedHost -like '*.pkgs.visualstudio.com'
    if (-not ($isModern -or $isLegacy)) {
        throw "Feed '$Url' is not an Azure DevOps Artifacts feed; view promotion is only supported there."
    }

    $feedMatch = [regex]::Match($Url, '_packaging/([^/]+)/')
    if (-not $feedMatch.Success) { throw "Cannot determine the feed name from '$Url'." }
    $feed = $feedMatch.Groups[1].Value

    # The path segments before '_packaging' identify the org and/or project (@() keeps it an array).
    $segments = @($uri.AbsolutePath.Trim('/') -split '/' | Where-Object { $_ })
    $packagingIndex = [array]::IndexOf($segments, '_packaging')
    $prefix = @(if ($packagingIndex -gt 0) { $segments[0..($packagingIndex - 1)] })

    if ($isLegacy) {
        # Legacy: org is the host subdomain; any prefix segment is the project.
        $org = $feedHost.Split('.')[0]
        $project = if ($prefix.Count -ge 1) { $prefix[0] } else { '' }
    }
    else {
        # Modern: first prefix segment is the org, an optional second is the project.
        if ($prefix.Count -lt 1) { throw "Cannot determine the organisation from '$Url'." }
        $org = $prefix[0]
        $project = if ($prefix.Count -ge 2) { $prefix[1] } else { '' }
    }

    return @{ BaseUrl = "https://pkgs.dev.azure.com/$org"; Project = $project; Feed = $feed }
}