ManaShell.psm1

#Region '.\private\New-QueryString.ps1' -1

function New-QueryString {
    <#
    .SYNOPSIS
    Turn a hashtable into a URI querystring
     
    .DESCRIPTION
    Turn a hashtable into a URI querystring
     
    .PARAMETER QueryParameter
    The hashtable to transform
     
    .EXAMPLE
    New-QueryString -QueryParameter @{ Animal = 'Dog'; Breed = 'Labrador'; Name = 'Dilbert'}
     
    .EXAMPLE
    New-QueryString -QueryParameter @{ Animal = 'Dog'; Breed = 'Labrador', 'Retriever'; Name = 'Dilbert'}
     
    .EXAMPLE
    New-QueryString -QueryParameter ([ordered]@{ Animal = 'Dog'; Breed = 'Labrador', 'Retriever'; Name = 'Dilbert'})
     
    .NOTES
    Shamelessly taken from https://powershellmagazine.com/2019/06/14/pstip-a-better-way-to-generate-http-query-strings-in-powershell/
    #>

    [CmdletBinding()]
    param 
    (
        [Parameter(Mandatory = $true)]
        [System.Collections.IDictionary]
        $QueryParameter
    )
    # Add System.Web
    Add-Type -AssemblyName System.Web
    
    # Create a http name value collection from an empty string
    $nvCollection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
    
    foreach ($key in $QueryParameter.Keys) {
        if ($QueryParameter[$key].GetType().ImplementedInterfaces.Contains([System.Collections.ICollection])) {
            foreach ($record in $QueryParameter[$key]) {
                $nvCollection.Add($key, $record)
            }
        } else {
            $nvCollection.Add($key, $QueryParameter.$key)
        }
    }
    
    return $nvCollection.ToString()
}
#EndRegion '.\private\New-QueryString.ps1' 49
#Region '.\private\Show-Card.ps1' -1

function Show-Card {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [PSObject]
        $CardData
    )

    end {
        $cardface = Get-SpectreImage -ImagePath $CardData.image_uris.png -Format Auto -MaxWidth 90
        $info = @'
        Card : {0}
        Released : {1}
        Type : {2}
        Oracle : {3}
'@
 -f $CardData.name, $CardData.released_at, $CardData.type_line, $CardData.oracle_text
        #$cardRow = $cardface | Format-SpectreColumns -Padding 0 | Format-SpectreRows
        $infoRow = $cardface, $info | Format-SpectreColumns -Padding 0
        @($cardface,$info) | Format-SpectreColumns -Padding 0 | Format-SpectrePanel -Title ('MtG Card: {0}' -f $CardData.name) -Color aquamarine3 -Border Rounded -Height 80 | Out-SpectreHost
    }
}
#EndRegion '.\private\Show-Card.ps1' 22
#Region '.\public\Get-MtgCard.ps1' -1

Function Get-MtgCard {
<#
.SYNOPSIS
Retrieves Magic: The Gathering card data from the Scryfall API.
 
.DESCRIPTION
The `Get-MtgCard` function retrieves Magic: The Gathering card data using the Scryfall API.
It supports searching for cards by name (exact or fuzzy matching) or retrieving a random card.
The function can also filter for random cards that are legal as commanders.
 
.PARAMETER Name
Specifies the name of the card to search for. This parameter is mandatory when using the `search` parameter set.
 
.PARAMETER Exact
Performs an exact name search for the specified card. This parameter is part of the `search` parameter set.
 
.PARAMETER Fuzzy
Performs a fuzzy name search for the specified card. This parameter is part of the `search` parameter set.
 
.PARAMETER Random
Retrieves a random Magic: The Gathering card. This parameter is mandatory when using the `random` parameter set.
 
.PARAMETER Commander
Filters random cards to only include those that are legal as commanders. This parameter is part of the `random` parameter set.
 
.PARAMETER Render
If specified, renders the card data visually using the `Show-Card` function.
 
.OUTPUTS
Returns the card data retrieved from the Scryfall API as a PowerShell object.
If the `-Render` parameter is specified, the card data is displayed visually instead of being returned.
 
.EXAMPLE
Get-MtgCard -Name "Black Lotus" -Exact
Searches for the card "Black Lotus" using an exact name match.
 
.EXAMPLE
Get-MtgCard -Name "Lotus" -Fuzzy
Searches for a card with a name similar to "Lotus" using fuzzy matching.
 
.EXAMPLE
Get-MtgCard -Random
Retrieves a random Magic: The Gathering card.
 
.EXAMPLE
Get-MtgCard -Random -Commander
Retrieves a random Magic: The Gathering card that is legal as a commander.
 
.EXAMPLE
Get-MtgCard -Name "Black Lotus" -Exact -Render
Searches for the card "Black Lotus" using an exact name match and renders the card visually.
 
.NOTES
- This function uses the Scryfall API to fetch card data.
- Ensure you have an active internet connection to use this function.
- The `Invoke-RestMethod` cmdlet is used to send the API request.
#>

    [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/ManaShell/Commands/Get-MtgCard/')]
    Param(
        [Parameter(Mandatory, ParameterSetName = 'search')]
        [String]
        $Name,

        [Parameter(ParameterSetName = 'search')]
        [Switch]
        $Exact,

        [Parameter(ParameterSetName = 'search')]
        [Switch]
        $Fuzzy,

        [Parameter(Mandatory, ParameterSetName = 'random')]
        [Switch]
        $Random,

        [Parameter(ParameterSetName = 'random')]
        [Switch]
        $Commander, 

        [Parameter()]
        [Switch]
        $Render
    )

    $headers = @{
        Accept = '*/*'
    }

    switch ($PSCmdlet.ParameterSetName) {
        'random' {
            $uri = 'https://api.scryfall.com/cards/random'
            if ($Commander) {
                $quertyString = New-QueryString -QueryParameter @{q = 'is:commander' }
                $uri = '{0}?{1}' -f $uri, $quertyString
            }

            $params = @{
                Uri         = $uri
                Headers     = $headers
                UserAgent   = 'ManaShell'
                ContentType = 'application/json'
            }

            $cardData = Invoke-RestMethod @params

            if (-not $Render) {
                return $cardData
            }
            else {
                Show-Card -CardData $cardData
            }
        }

        'search' {

            $uri = 'https://api.scryfall.com/cards/named'

            if ($Exact) { 
                $quertyString = New-QueryString -QueryParameter @{exact = $Name }
            }

            if ($fuzzy) {
                $quertyString = New-QueryString -QueryParameter @{fuzzy = $Name }
            }

            if ($Exact -and $Fuzzy) {
                throw 'Only one of -Fuzzy and -Exact may be provided!'
            }

            $uri = '{0}?{1}' -f $uri, $quertyString

            $params = @{
                Uri         = $uri
                Headers     = $headers
                UserAgent   = 'ManaShell'
                ContentType = 'application/json'
            }

            $cardData = Invoke-RestMethod @params

            return $cardData
        }
    }
}
#EndRegion '.\public\Get-MtgCard.ps1' 145
#Region '.\public\Get-MtgSet.ps1' -1

function Get-MtgSet {
<#
.SYNOPSIS
Retrieves Magic: The Gathering set data from the Scryfall API.
 
.DESCRIPTION
The `Get-MtgSet` function retrieves Magic: The Gathering set data using the Scryfall API.
It supports retrieving a specific set by its code or ID, or fetching all available sets.
 
.PARAMETER Code
Specifies the unique three- or four-character code of the set to retrieve.
For example, "LEA" for Limited Edition Alpha.
 
.PARAMETER Id
Specifies the unique Scryfall ID of the set to retrieve.
 
.OUTPUTS
If a specific set is requested (using `-Code` or `-Id`), the function returns the set data as a PowerShell object.
If no specific set is requested, the function returns an array of all available sets.
 
.EXAMPLE
Get-MtgSet -Code "LEA"
Retrieves data for the set "Limited Edition Alpha" using its code.
 
.EXAMPLE
Get-MtgSet -Id "12345678-1234-1234-1234-1234567890ab"
Retrieves data for a set using its unique Scryfall ID.
 
.EXAMPLE
Get-MtgSet
Retrieves data for all Magic: The Gathering sets.
 
.NOTES
- This function uses the Scryfall API to fetch set data.
- Ensure you have an active internet connection to use this function.
- The `Invoke-RestMethod` cmdlet is used to send the API request.
- Only one of the parameters `-Code` or `-Id` can be used at a time.
 
#>

    [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/ManaShell/Commands/Get-MtgSet/')]
    Param(
        [Parameter()]
        [String]
        $Code,

        <# This appears in the api documentation, however the tcgplayer_id property is not
            on a returned object via the sets api, so I cannot use this (at least currently)
        [Parameter()]
        [String]
        $TcgPlayerId,
        #>

        
        [Parameter()]
        [String]
        $Id
    )

    begin {
        # Fix this later, so that common parameters can be used (-Verbose, -Debug, etc)
        if ($PSBoundParameters.Count -gt 1) {
            throw 'Only one of -Code, -TcgPlayerId, and -Id are allowed!'
        }
    }
    end {
        $options = if ($PSBoundParameters['Code']) {
            @{
                uri        = 'https://api.scryfall.com/sets/{0}' -f $Code
                SingleItem = $true
            }
        }
        # This will never be hit yet due to a limitation of the api
        elseif ($PSBoundParameters['TcgPlayerId']) { 
            @{
                uri        = 'https://api.scryfall.com/sets/tcgplayer/{0}' -f $TcgPlayerId
                SingleItem = $true
            }
        }
        elseif ($PSBoundParameters['Id']) {
            @{
                uri        = 'https://api.scryfall.com/sets/{0}' -f $Id
                SingleItem = $true
            } 
            
        }
        else { 
            @{
                uri        = 'https://api.scryfall.com/sets'
                SingleItem = $false
            }
            
        }

        $params = @{
            Uri         = $options['uri']
            Headers     = @{ Accept = '*/*' }
            UserAgent   = 'ManaShell'
            ContentType = 'application/json'
        }

        $cardData = Invoke-RestMethod @params

        if ($options['SingleItem']) {
            $cardData
        }
        else {
            $cardData.data
        }
    }
}
#EndRegion '.\public\Get-MtgSet.ps1' 110
#Region '.\public\Get-MtgSymbol.ps1' -1

function Get-MtgSymbol {
<#
.SYNOPSIS
Retrieves Magic: The Gathering symbols from the Scryfall API.
 
.DESCRIPTION
The `Get-MtgSymbol` function fetches all Magic: The Gathering symbols from the Scryfall API.
It can return the full symbol data or filter for a specific symbol if the `-Symbol` parameter is provided.
 
.PARAMETER Symbol
Specifies a particular symbol to filter the results.
If this parameter is provided, only the matching symbol's data will be returned.
 
.OUTPUTS
If the `-Symbol` parameter is provided, the function returns the specific symbol's data.
If no parameter is provided, the function returns all available symbols as an array of objects.
 
.EXAMPLE
Get-MtgSymbol
Retrieves all Magic: The Gathering symbols from the Scryfall API.
 
.EXAMPLE
Get-MtgSymbol -Symbol "{W}"
Retrieves data for the white mana symbol.
 
.NOTES
- This function uses the Scryfall API to fetch symbol data.
- Ensure you have an active internet connection to use this function.
- The `Invoke-RestMethod` cmdlet is used to send the API request.
#>

    [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/ManaShell/Commands/Get-MtgSymbol/')]
    Param(
        [Parameter()]
        [String]
        $Symbol
    )

    end {
        $params = @{
            Uri         = 'https://api.scryfall.com/symbology'
            Headers     = @{ Accept = '*/*' }
            UserAgent   = 'ManaShell'
            ContentType = 'application/json'
        }

        $cardData = (Invoke-RestMethod @params).data

        if($Symbol) {
            $cardData.symbol
        }
        else {
            $cardData
        }
    }
}
#EndRegion '.\public\Get-MtgSymbol.ps1' 56
#Region '.\public\Search-Mtg.ps1' -1

function Search-Mtg {
<#
.SYNOPSIS
Searches for Magic: The Gathering cards using the Scryfall API.
 
.DESCRIPTION
The `Search-Mtg` function allows you to search for Magic: The Gathering cards based on card color and/or mana value.
It constructs a query string and sends a request to the Scryfall API to retrieve card data.
 
.PARAMETER CardColor
Specifies the color of the card to search for.
 
.PARAMETER ManaValue
Specifies the mana value (converted mana cost) of the card to search for.
 
.OUTPUTS
Returns the card data retrieved from the Scryfall API as a PowerShell object.
 
.EXAMPLE
Search-Mtg -CardColor "White"
Searches for all white cards.
 
.EXAMPLE
Search-Mtg -ManaValue D1
Searches for all cards with a mana value of 3.
 
.EXAMPLE
Search-Mtg -CardColor "White" -ManaValue D2
Searches for all blue cards with a mana value of 1.
 
.NOTES
- This function uses the Scryfall API to perform the search.
#>

    [CmdletBinding(HelpUri = 'https://steviecoaster.github.io/ManaShell/Commands/Search-Mtg/')]
    Param(
        [Parameter()]
        [String]
        $CardColor,

        [Parameter()]
        [String]
        $ManaValue
    )

    end {
        $queryString = if ($CardColor) {
            New-QueryString -QueryParameter @{q = 'c:{0}' -f $CardColor }
        }
        elseif ($ManaValue) {
            New-QueryString -QueryParameter @{q = 'mv:{0}' -f $ManaValue }
        }
        elseif ($CardColor -and $ManaValue) {
            New-QueryString -QueryParameter @{q = 'c:{0}+mv:{1}' -f $CardColor, $ManaValue }

        }
        $params = @{
            Uri         = 'https://api.scryfall.com/cards/search?{0}' -f $queryString
            Headers     = @{ Accept = '*/*' }
            UserAgent   = 'ManaShell'
            ContentType = 'application/json'
        }

        $cardData = Invoke-RestMethod @params

        return $cardData
    }
}
#EndRegion '.\public\Search-Mtg.ps1' 68
#Region '.\Suffix.ps1' -1

#EndRegion '.\Suffix.ps1' 1