RCPSGallery.psm1


Function Expand-URLRedirect {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [uri]
        $Uri
    )
    $ErrorActionPreferenceTemp = $ErrorActionPreference
    $ErrorActionPreference = 'SilentlyContinue'
    Invoke-WebRequest -Uri $Uri -MaximumRedirection 0 -SkipHttpErrorCheck |
    Select-Object -ExpandProperty Headers |
    ForEach-Object {$_["Location"]}
    $ErrorActionPreference = $ErrorActionPreferenceTemp
}

Function Get-RCPSGalleryPackageRegistryUri {
    Expand-URLRedirect -Uri http://psgallery.rightcloud.info
}
Function Register-RCPSRepository {
    [CmdletBinding()]
    param(

    )
    # Install Microsoft.PowerShell.PSResourceGet if not installed
    "Microsoft.PowerShell.PSResourceGet" |
    Where-Object { -not (Get-Module -ListAvailable -Name $_ )} |
    ForEach-Object { Install-Module -Name $_ -Force }

    # Get the Repo URI
    $rcGalleryURI= Get-RCPSGalleryPackageRegistryUri
    $rcGalleryRegistred = Get-PSResourceRepository | Where-Object {$_.Uri -eq $rcGalleryURI}
    # Register package repository if not registred
    If (-not ($rcGalleryRegistred)) {
        Register-PSResourceRepository -Name RCPSGallery -Uri $rcGalleryURI -Trusted
        $rcGalleryRegistred = Get-PSResourceRepository | Where-Object {$_.Uri -eq $rcGalleryURI}
    }
    Return $rcGalleryRegistred
}

Function Import-RCGitLabAPIConfiguration {
    <#
    .Synopsis
       Check for configuration and output the information.
    .DESCRIPTION
       Check for configuration and output the information. Goes into the $env:appdata for the configuration file.
    .EXAMPLE
        Import-GitLabAPIConfiguration
    #>


    [CmdletBinding()]
    param(
    )

    if ( $IsWindows -or ( [version]$PSVersionTable.PSVersion -lt [version]"5.99.0" ) ) {
        $ConfigFile = "{0}\PSGitLab\PSGitLabConfiguration.xml" -f $env:appdata
    } elseif ( $IsLinux -or $IsMacOS ) {
        $ConfigFile = "{0}/.psgitlab/PSGitLabConfiguration.xml" -f $HOME
    } else {
        Write-Error "Unknown Platform"
    }
    if (Test-Path $ConfigFile) {
        Import-Clixml $ConfigFile
    } else {
        Write-Warning 'No saved configuration information. Run Save-GitLabAPIConfiguration.'
    }
}

Function Find-RCPSResource {
    [CmdletBinding()]
    param (
        # Name of module
        [Parameter(Mandatory=$false)]
        [string]
        $Name = "*",
        # APIKey for Gitlab API, by default it will try to find locally saved key
        [Parameter(Mandatory=$false)]
        [string]
        $APIKey,
        # Retrive detailed information for Resource
        [Parameter(Mandatory=$false)]
        [switch]
        $Detailed
    )
    if(-not $APIKey) {
        $apiConfig = Import-RCGitLabAPIConfiguration -ErrorAction Stop
        $APIKey = ConvertFrom-SecureString $apiConfig.Token -AsPlainText  -ErrorAction Stop
    }
    $rcPSGalleryUri = Get-PSResourceRepository -Name RCPSGallery |
    Select-Object -ExpandProperty Uri |
    Select-Object -ExpandProperty AbsoluteUri
    $packageAPIURI = $rcPSGalleryUri -replace "/nuget/index.json"
    Invoke-RestMethod -Uri $packageAPIURI -Headers @{"PRIVATE-TOKEN" = $APIKey} |
    ForEach-Object { $_ } |
    Where-Object {$_.package_type -eq "nuget"} |
    Select-Object @{n="Name";e={$_.name}}, @{n="Version";e={[version]$_.Version}} |
    Group-Object -Property Name |
    ForEach-Object {
        $_.Group |
        Sort-Object -Property Version -Descending |
        Select-Object -First 1
    } |
    Where-Object {$_.Name -like $Name} |
    ForEach-Object {
        If ($Detailed) {
            Find-PSResource -Name $_.Name -Repository RCPSGallery
        } Else {
            $_
        }
    }

}

Function Get-RCNugetServiceIndex {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$false)]
        [uri]
        $Uri = (Get-RCPSGalleryPackageRegistryUri)
    )
    Invoke-WebRequest -Uri $Uri |
    Select-Object -ExpandProperty Content |
    ConvertFrom-Json -Depth 20 |
    Where-Object {$_.version -eq "3.0.0"} |
    Select-Object -ExpandProperty resources

}


Function Get-RCNugetPackageBaseAddress {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$false)]
        [uri]
        $Uri = (Get-RCPSGalleryPackageRegistryUri)
    )
    $rcGalleryServiceIndex = Get-RCNugetServiceIndex -Uri $Uri
    $rcPackageBaseAddress = $rcGalleryServiceIndex |
    Where-Object {$_.'@type' -eq 'PackageBaseAddress/3.0.0' } |
    Select-Object -ExpandProperty '@id'
    $rcPackageBaseAddress

}


Function Get-RCNugetPackageVersion {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]
        $ModuleName,
        [Parameter(Mandatory=$false)]
        [uri]
        $PackageBaseAddressUri = (Get-RCNugetPackageBaseAddress),
        [Parameter(Mandatory=$false)]
        [switch]
        $Latest
    )

    try {
        $versions = Invoke-RestMethod -Uri "$PackageBaseAddressUri/$ModuleName/index.json" -ErrorAction Stop |
        Select-Object -ExpandProperty versions
    }
    catch {
        throw "Could not retrive versions for module $ModuleName at $PackageBaseAddressUri/$ModuleName/index.json, error: $_"
    }
    If (-not $Latest) {
        $versions
    } Else {
        $versions |
        ForEach-Object { [version]$_ } |
        Sort-Object |
        Select-Object -Last 1 |
        ForEach-Object {$_.ToString()}
    }
}


Function Get-RCNugetPackageDownloadUri {
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory=$true)]
        [string]
        $ModuleName,
        [Parameter(Mandatory=$false)]
        [version]
        $Version,
        [Parameter(Mandatory=$false)]
        [uri]
        $PackageBaseAddressUri = (Get-RCNugetPackageBaseAddress -ErrorAction Stop)
    )
    If (-not $Version) {
        $Version = Get-RCNugetPackageVersion -ModuleName $ModuleName -Latest -ErrorAction Stop
    }
    "$PackageBaseAddressUri/$($ModuleName)/$Version/$($ModuleName).$($Version).nupkg"
}