Types/OpenPackage.Source/At.ps1

<#
.SYNOPSIS
    Gets Open Packages at a location
.DESCRIPTION
    Gets Open Packages with `@` syntax.

    Without a domain `@` will be presumed to be github.com
    With a domain `@` at will check for records using https and at protocol
#>

param(
# One or more locations, in at syntax.
# `@name` will default to github
# `@domain.name` will default to at protocol and https
[string[]]
$At,

# A list of file wildcards to include.
[Parameter(ValueFromPipelineByPropertyName)]
[SupportsWildcards()]
[string[]]
$Include,

# A list of file wildcards to exclude.
[Parameter(ValueFromPipelineByPropertyName)]
[SupportsWildcards()]
[string[]]
$Exclude,

# The base path within the package.
# Content should be added beneath this base path.
[string]
$BasePath = '/',

# A content type map.
# This maps extensions and URIs to a content type.
[Collections.IDictionary]
$TypeMap = $(
    ([PSCustomObject]@{PSTypeName='OpenPackage.ContentTypeMap'}).TypeMap
),

# The compression option.
[IO.Packaging.CompressionOption]
[Alias('CompressionLevel')]
$CompressionOption = 'Superfast',
        
# If set, will force the redownload of various resources and remove existing files or directories
[switch]
$Force,

# If set, will include hidden files and folders, except for files beneath `.git`
[Alias('IncludeDotFiles')]
[switch]
$IncludeHidden,

# If set, will include the `.git` directory contents if found.
[Alias('IncludeGitFile','IncludeGitFiles','IncludeGitDirectory')]
[switch]
$IncludeGit,

# If set, will include any content found in `/node_modules`.
[Alias('IncludeNodeModules')]
[switch]
$IncludeNodeModule,

# The current package
[IO.Packaging.Package]
$Package,

# Any additional headers to pass into a web request.
[Alias('Header')]
[Collections.IDictionary]
$Headers,

# The number of records to get
[long]
$First,

# If number of records to skip
[long]
$Skip
)


# If a package does not exist
if (-not $package) {
    # create one
    $memoryStream = [IO.MemoryStream]::new()
    $package = [IO.Packaging.Package]::Open($memoryStream, 'OpenOrCreate', 'ReadWrite')
    Add-Member -InputObject $package NoteProperty MemoryStream $memoryStream -Force
}


# Collect all of our named parameters
$namedParameters = [Ordered]@{}
foreach ($key in $MyInvocation.MyCommand.Parameters.Keys) {
    $var = $ExecutionContext.SessionState.PSVariable.Get($key)
    if (-not [string]::IsNullOrEmpty($var.value)) {
        $namedParameters[$key] = $var.value
    }
}

$namedParameters.Remove('At')
$namedParameters.Remove('Package')

$outputPackages = @()

foreach ($atSyntax in $at) {
    $parameterCopy = [Ordered]@{} + $namedParameters
    if ($atSyntax -notmatch '^@') {        
        continue
    }
    # If there is no domain name qualifier, treat it as github.com/<username>
    if ($atSyntax -notmatch '\.') {
        $parameterCopy.InputObject = $Package
        $parameterCopy.Repository = $atSyntax -replace '^@', 'https://github.com/'
        $atRepoPackage = Get-OpenPackage @parameterCopy
        foreach ($repoPackage in $atRepoPackage) {
            if (
                $repoPackage -is [IO.Packaging.Package] -and
                $outputPackages -notcontains $repoPackage
            ) {
                $outputPackages += $repoPackage
            }
        }
    }
    else {
        # Otherwise, it could be either at protocol or https.
        # Try https first
        $parameterCopy.InputObject = $package        
        $parameterCopy.Url = $atSyntax -replace '^@', 'https://'
        
        $httpsPackage = Get-OpenPackage @parameterCopy

        if ($httpsPackage) {
            $parameterCopy.InputObject = $httpsPackage
        }
        $parameterCopy.Remove('Url')
        $parameterCopy.AtUri = $atSyntax -replace '^@', 'at://'
        $atPackage = Get-OpenPackage @parameterCopy
        
        $possiblePackages = @(
            if ($httpsPackage -and ($atPackage -eq $httpsPackage)) {
                $httpsPackage
            } else {
                if ($atPackage) {
                    $atPackage
                }
                if ($httpsPackage) {
                    $httpsPackage
                }                        
            }
        )
        foreach ($possibility in $possiblePackages ) {
            if ($possibility -is [IO.Packaging.Package] -and 
                $outputPackages -notcontains $possibility) {
                $outputPackages += $possibility
            }
        }
    }
}

return $outputPackages