GitHub.psm1

[Cmdletbinding()]
param()

$scriptName = $MyInvocation.MyCommand.Name
Write-Verbose "[$scriptName] Importing subcomponents"

#region - Data import
Write-Verbose "[$scriptName] - [data] - Processing folder"
$dataFolder = (Join-Path $PSScriptRoot 'data')
Write-Verbose "[$scriptName] - [data] - [$dataFolder]"
Get-ChildItem -Path "$dataFolder" -Recurse -Force -Include '*.psd1' -ErrorAction SilentlyContinue | ForEach-Object {
    Write-Verbose "[$scriptName] - [data] - [$($_.Name)] - Importing"
    New-Variable -Name $_.BaseName -Value (Import-PowerShellDataFile -Path $_.FullName) -Force
    Write-Verbose "[$scriptName] - [data] - [$($_.Name)] - Done"
}

Write-Verbose "[$scriptName] - [data] - Done"
#endregion - Data import

#region - From private
Write-Verbose "[$scriptName] - [private] - Processing folder"

#region - From private/Auth
Write-Verbose "[$scriptName] - [private/Auth] - Processing folder"

#region - From private/Auth/DeviceFlow
Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow] - Processing folder"

#region - From private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1
Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1] - Importing"

function Invoke-GitHubDeviceFlowLogin {
    <#
        .SYNOPSIS
        Starts the GitHub Device Flow login process.

        .DESCRIPTION
        Starts the GitHub Device Flow login process. This will prompt the user to visit a URL and enter a code.

        .EXAMPLE
        Invoke-GitHubDeviceFlowLogin

        This will start the GitHub Device Flow login process.
        The user gets prompted to visit a URL and enter a code.

        .NOTES
        For more info about the Device Flow visit:
        https://docs.github.com/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app
        https://docs.github.com/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps#device-flow
    #>

    [OutputType([void])]
    [CmdletBinding()]
    param(
        # The Client ID of the GitHub App.
        [Parameter(Mandatory)]
        [string] $ClientID,

        # The scope of the access token, when using OAuth authentication.
        # Provide the list of scopes as space-separated values.
        # For more information on scopes visit:
        # https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps
        [Parameter()]
        [string] $Scope,

        # The refresh token to use for re-authentication.
        [Parameter()]
        [securestring] $RefreshToken
    )

    do {
        if ($RefreshToken) {
            $tokenResponse = Wait-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken
        } else {
            $deviceCodeResponse = Request-GitHubDeviceCode -ClientID $ClientID -Scope $Scope

            $deviceCode = $deviceCodeResponse.device_code
            $interval = $deviceCodeResponse.interval
            $userCode = $deviceCodeResponse.user_code
            $verificationUri = $deviceCodeResponse.verification_uri

            Write-Host '! ' -ForegroundColor DarkYellow -NoNewline
            Write-Host "We added the code to your clipboard: [$userCode]"
            $userCode | Set-Clipboard
            Read-Host 'Press Enter to open github.com in your browser...'
            Start-Process $verificationUri

            $tokenResponse = Wait-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID -Interval $interval
        }
    } while ($tokenResponse.error)
    $tokenResponse
}

Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1] - Done"
#endregion - From private/Auth/DeviceFlow/Invoke-GitHubDeviceFlowLogin.ps1
#region - From private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1
Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1] - Importing"

function Request-GitHubAccessToken {
    <#
        .SYNOPSIS
        Request a GitHub token using the Device Flow.

        .DESCRIPTION
        Request a GitHub token using the Device Flow.
        This will poll the GitHub API until the user has entered the code.

        .EXAMPLE
        Request-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID

        This will poll the GitHub API until the user has entered the code.

        .NOTES
        For more info about the Device Flow visit:
        https://docs.github.com/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app
    #>

    [OutputType([PSCustomObject])]
    [CmdletBinding(DefaultParameterSetName = 'DeviceFlow')]
    param(
        # The Client ID of the GitHub App.
        [Parameter(Mandatory)]
        [string] $ClientID,

        # The 'device_code' used to request the access token.
        [Parameter(
            Mandatory,
            ParameterSetName = 'DeviceFlow'
        )]
        [string] $DeviceCode,

        # The refresh token used create a new access token.
        [Parameter(
            Mandatory,
            ParameterSetName = 'RefreshToken'
        )]
        [securestring] $RefreshToken
    )

    $body = @{
        'client_id' = $ClientID
    }

    if ($PSBoundParameters.ContainsKey('RefreshToken')) {
        $body += @{
            'refresh_token' = (ConvertFrom-SecureString $RefreshToken -AsPlainText)
            'grant_type'    = 'refresh_token'
        }
    }

    if ($PSBoundParameters.ContainsKey('DeviceCode')) {
        $body += @{
            'device_code' = $DeviceCode
            'grant_type'  = 'urn:ietf:params:oauth:grant-type:device_code'
        }
    }

    $RESTParams = @{
        Uri     = 'https://github.com/login/oauth/access_token'
        Method  = 'POST'
        Body    = $body
        Headers = @{ 'Accept' = 'application/json' }
    }

    try {
        Write-Verbose ($RESTParams.GetEnumerator() | Out-String)

        $tokenResponse = Invoke-RestMethod @RESTParams -Verbose:$false

        Write-Verbose ($tokenResponse | ConvertTo-Json | Out-String)
        return $tokenResponse
    } catch {
        Write-Error $_
        throw $_
    }
}

Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1] - Done"
#endregion - From private/Auth/DeviceFlow/Request-GitHubAccessToken.ps1
#region - From private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1
Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1] - Importing"

function Request-GitHubDeviceCode {
    <#
        .SYNOPSIS
        Request a GitHub Device Code.

        .DESCRIPTION
        Request a GitHub Device Code.

        .EXAMPLE
        Request-GitHubDeviceCode -ClientID $ClientID -Mode $Mode

        This will request a GitHub Device Code.

        .NOTES
        For more info about the Device Flow visit:
        https://docs.github.com/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app
    #>

    [OutputType([PSCustomObject])]
    [CmdletBinding()]
    param(
        # The Client ID of the GitHub App.
        [Parameter(Mandatory)]
        [string] $ClientID,

        # The scope of the access token, when using OAuth authentication.
        # Provide the list of scopes as space-separated values.
        # For more information on scopes visit:
        # https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps
        [Parameter()]
        [string] $Scope = 'gist, read:org, repo, workflow'
    )

    $headers = @{
        Accept = 'application/json'
    }

    $body = @{
        client_id = $ClientID
        scope     = $Scope
    }

    $RESTParams = @{
        Uri     = 'https://github.com/login/device/code'
        Method  = 'POST'
        Body    = $body
        Headers = $headers
    }

    try {
        Write-Verbose ($RESTParams.GetEnumerator() | Out-String)

        $deviceCodeResponse = Invoke-RestMethod @RESTParams -Verbose:$false
        return $deviceCodeResponse
    } catch {
        Write-Error $_
        throw $_
    }
}

Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1] - Done"
#endregion - From private/Auth/DeviceFlow/Request-GitHubDeviceCode.ps1
#region - From private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1
Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1] - Importing"

function Test-GitHubAccessTokenRefreshRequired {
    <#
        .SYNOPSIS
        Test if the GitHub access token should be refreshed.

        .DESCRIPTION
        Test if the GitHub access token should be refreshed.

        .EXAMPLE
        Test-GitHubAccessTokenRefreshRequired

        This will test if the GitHub access token should be refreshed.
    #>

    [CmdletBinding()]
    param()

    $tokenType = Get-GitHubConfig -Name 'AccessTokenType' -ErrorAction SilentlyContinue
    if ($tokenType -ne 'ghu_*') {
        Write-Verbose "The access token is not a user token. No need to refresh."
        return $false
    }

    $tokenExpirationDate = Get-GitHubConfig -Name 'AccessTokenExpirationDate' -ErrorAction SilentlyContinue
    $currentDateTime = Get-Date
    $remainingDuration = [datetime]$tokenExpirationDate - $currentDateTime

    # If the remaining time is less that $script:Auth.AccessTokenGracePeriodInHours then the token should be refreshed
    $remainingDuration.TotalHours -lt $script:Auth.AccessTokenGracePeriodInHours
}

Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1] - Done"
#endregion - From private/Auth/DeviceFlow/Test-GitHubAccessTokenRefreshRequired.ps1
#region - From private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1
Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1] - Importing"

function Wait-GitHubAccessToken {
    <#
        .SYNOPSIS
        Waits for the GitHub Device Flow to complete.

        .DESCRIPTION
        Waits for the GitHub Device Flow to complete.
        This will poll the GitHub API until the user has entered the code.

        .EXAMPLE
        Wait-GitHubAccessToken -DeviceCode $deviceCode -ClientID $ClientID -Interval $interval

        This will poll the GitHub API until the user has entered the code.

        .EXAMPLE
        Wait-GitHubAccessToken -Refresh -ClientID $ClientID

        .NOTES
        For more info about the Device Flow visit:
        https://docs.github.com/apps/creating-github-apps/writing-code-for-a-github-app/building-a-cli-with-a-github-app
    #>

    [OutputType([PSCustomObject])]
    [CmdletBinding(DefaultParameterSetName = 'DeviceFlow')]
    param(
        # The Client ID of the GitHub App.
        [Parameter(Mandatory)]
        [string] $ClientID,

        # The device code used to request the access token.
        [Parameter(
            Mandatory,
            ParameterSetName = 'DeviceFlow'
        )]
        [string] $DeviceCode,

        # The refresh token used to request a new access token.
        [Parameter(
            Mandatory,
            ParameterSetName = 'RefreshToken'
        )]
        [securestring] $RefreshToken,

        # The interval to wait between polling for the token.
        [Parameter()]
        [int] $Interval = 5

    )

    do {
        if ($RefreshToken) {
            $response = Request-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken
        } else {
            $response = Request-GitHubAccessToken -ClientID $ClientID -DeviceCode $DeviceCode
        }
        if ($response.error) {
            switch ($response.error) {
                'authorization_pending' {
                    # The user has not yet entered the code.
                    # Wait, then poll again.
                    Write-Verbose $response.error_description
                    Start-Sleep -Seconds $interval
                    continue
                }
                'slow_down' {
                    # The app polled too fast.
                    # Wait for the interval plus 5 seconds, then poll again.
                    Write-Verbose $response.error_description
                    Start-Sleep -Seconds ($interval + 5)
                    continue
                }
                'expired_token' {
                    # The 'device_code' expired, and the process needs to restart.
                    Write-Error $response.error_description
                    exit 1
                }
                'unsupported_grant_type' {
                    # The 'grant_type' is not supported.
                    Write-Error $response.error_description
                    exit 1
                }
                'incorrect_client_credentials' {
                    # The 'client_id' is not valid.
                    Write-Error $response.error_description
                    exit 1
                }
                'incorrect_device_code' {
                    # The 'device_code' is not valid.
                    Write-Error $response.error_description
                    exit 2
                }
                'access_denied' {
                    # The user cancelled the process. Stop polling.
                    Write-Error $response.error_description
                    exit 1
                }
                'device_flow_disabled' {
                    # The GitHub App does not support the Device Flow.
                    Write-Error $response.error_description
                    exit 1
                }
                default {
                    # The response contains an access token. Stop polling.
                    Write-Error 'Unknown error:'
                    Write-Error $response.error
                    Write-Error $response.error_description
                    Write-Error $response.error_uri
                    break
                }
            }
        }
    } until ($response.access_token)
    $response
}

Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1] - Done"
#endregion - From private/Auth/DeviceFlow/Wait-GitHubAccessToken.ps1

Write-Verbose "[$scriptName] - [private/Auth/DeviceFlow] - Done"
#endregion - From private/Auth/DeviceFlow


Write-Verbose "[$scriptName] - [private/Auth] - Done"
#endregion - From private/Auth

#region - From private/Config
Write-Verbose "[$scriptName] - [private/Config] - Processing folder"

#region - From private/Config/Initialize-SecretVault.ps1
Write-Verbose "[$scriptName] - [private/Config/Initialize-SecretVault.ps1] - Importing"

#Requires -Version 7.0
#Requires -Modules Microsoft.PowerShell.SecretManagement
#Requires -Modules Microsoft.PowerShell.SecretStore

function Initialize-SecretVault {
    <#
    .SYNOPSIS
    Initialize a secret vault.

    .DESCRIPTION
    Initialize a secret vault. If the vault does not exist, it will be created.

    .EXAMPLE
    Initialize-SecretVault -Name 'SecretStore' -Type 'Microsoft.PowerShell.SecretStore'

    Initializes a secret vault named 'SecretStore' using the 'Microsoft.PowerShell.SecretStore' module.

    .NOTES
    For more information about secret vaults, see https://learn.microsoft.com/en-us/powershell/utility-modules/secretmanagement/overview?view=ps-modules
    #>


    [OutputType([void])]
    [CmdletBinding()]
    param (
        # The name of the secret vault.
        [Parameter()]
        [string] $Name = 'SecretStore',

        # The type of the secret vault.
        [Parameter()]
        [Alias('ModuleName')]
        [string] $Type = 'Microsoft.PowerShell.SecretStore'
    )

    $functionName = $MyInvocation.MyCommand.Name

    $vault = Get-SecretVault | Where-Object { $_.ModuleName -eq $Type }
    if (-not $vault) {
        Write-Verbose "[$functionName] - [$Type] - Registering"

        switch ($Type) {
            'Microsoft.PowerShell.SecretStore' {
                $vaultParameters = @{
                    Authentication  = 'None'
                    PasswordTimeout = -1
                    Interaction     = 'None'
                    Scope           = 'CurrentUser'
                    WarningAction   = 'SilentlyContinue'
                    Confirm         = $false
                    Force           = $true
                }
                Reset-SecretStore @vaultParameters
            }
        }
        Write-Verbose "[$functionName] - [$Type] - Done"
    } else {
        Write-Verbose "[$functionName] - [$Type] - already registered"
    }

    $secretStore = Get-SecretVault | Where-Object { $_.Name -eq $Name }
    if (-not $secretStore) {
        Write-Verbose "[$functionName] - [$Name] - Registering"
        $secretVault = @{
            Name         = $Name
            ModuleName   = $Type
            DefaultVault = $true
            Description  = 'SecretStore'
        }
        Register-SecretVault @secretVault
        Write-Verbose "[$functionName] - [$Name] - Done"
    } else {
        Write-Verbose "[$functionName] - [$Name] - already registered"
    }
}

Write-Verbose "[$scriptName] - [private/Config/Initialize-SecretVault.ps1] - Done"
#endregion - From private/Config/Initialize-SecretVault.ps1
#region - From private/Config/Reset-GitHubConfig.ps1
Write-Verbose "[$scriptName] - [private/Config/Reset-GitHubConfig.ps1] - Importing"

function Reset-GitHubConfig {
    <#
        .SYNOPSIS
        Reset the GitHub configuration.

        .DESCRIPTION
        Reset the GitHub configuration. Specific scopes can be reset by using the Scope parameter.

        .EXAMPLE
        Reset-GitHubConfig

        Resets the entire GitHub configuration.

        .EXAMPLE
        Reset-GitHubConfig -Scope 'Auth'

        Resets the Auth related variables of the GitHub configuration.
    #>

    [Alias('Reset-GHConfig')]
    [OutputType([void])]
    [CmdletBinding()]
    param(
        # Reset the GitHub configuration for a specific scope.
        [Parameter()]
        [ValidateSet('Auth', 'All')]
        [string] $Scope = 'All'
    )

    Write-Verbose "Resetting GitHub configuration for scope '$Scope'..."
    switch ($Scope) {
        'Auth' {
            $Settings = @{
                AccessToken                = [securestring]::new()
                AccessTokenExpirationDate  = [datetime]::MinValue
                AccessTokenType            = ''
                AuthType                   = ''
                DeviceFlowType             = ''
                RefreshToken               = [securestring]::new()
                RefreshTokenExpirationDate = [datetime]::MinValue
                Scope                      = ''
            }
        }
        'All' {
            $Settings = @{
                AccessToken                = [securestring]::new()
                AccessTokenExpirationDate  = [datetime]::MinValue
                AccessTokenType            = ''
                ApiBaseUri                 = 'https://api.github.com'
                ApiVersion                 = '2022-11-28'
                AuthType                   = ''
                DeviceFlowType             = ''
                Owner                      = ''
                RefreshToken               = [securestring]::new()
                RefreshTokenExpirationDate = [datetime]::MinValue
                Repo                       = ''
                Scope                      = ''
                UserName                   = ''
            }
        }
    }
    Set-GitHubConfig @Settings
}

Write-Verbose "[$scriptName] - [private/Config/Reset-GitHubConfig.ps1] - Done"
#endregion - From private/Config/Reset-GitHubConfig.ps1

Write-Verbose "[$scriptName] - [private/Config] - Done"
#endregion - From private/Config

#region - From private/Menu
Write-Verbose "[$scriptName] - [private/Menu] - Processing folder"

#region - From private/Menu/Invoke-DrawMenu.ps1
Write-Verbose "[$scriptName] - [private/Menu/Invoke-DrawMenu.ps1] - Importing"

function Invoke-DrawMenu {
    ## supportfunction to the Menu function below
    param (
        $menuItems,
        $menuPosition,
        $menuTitel
    )
    $fcolor = $host.UI.RawUI.ForegroundColor
    $bcolor = $host.UI.RawUI.BackgroundColor
    $l = $menuItems.length + 1
    Clear-Host
    $menuwidth = $menuTitel.length + 4
    Write-Host "`t" -NoNewline
    Write-Host ('*' * $menuwidth) -fore $fcolor -back $bcolor
    Write-Host "`t" -NoNewline
    Write-Host "* $menuTitel *" -fore $fcolor -back $bcolor
    Write-Host "`t" -NoNewline
    Write-Host ('*' * $menuwidth) -fore $fcolor -back $bcolor
    Write-Host ''
    Write-Debug "L: $l MenuItems: $menuItems MenuPosition: $menuposition"
    for ($i = 0; $i -le $l; $i++) {
        Write-Host "`t" -NoNewline
        if ($i -eq $menuPosition) {
            Write-Host "$($menuItems[$i])" -fore $bcolor -back $fcolor
        } else {
            Write-Host "$($menuItems[$i])" -fore $fcolor -back $bcolor
        }
    }
}

Write-Verbose "[$scriptName] - [private/Menu/Invoke-DrawMenu.ps1] - Done"
#endregion - From private/Menu/Invoke-DrawMenu.ps1
#region - From private/Menu/Invoke-Meny.ps1
Write-Verbose "[$scriptName] - [private/Menu/Invoke-Meny.ps1] - Importing"

function Menu {
    ## Generate a small "DOS-like" menu.
    ## Choose a menuitem using up and down arrows, select by pressing ENTER
    param (
        [array]$menuItems,
        $menuTitel = 'MENU'
    )
    $vkeycode = 0
    $pos = 0
    Invoke-DrawMenu $menuItems $pos $menuTitel
    while ($vkeycode -ne 13) {
        $press = $host.ui.rawui.readkey('NoEcho,IncludeKeyDown')
        $vkeycode = $press.virtualkeycode
        Write-Host "$($press.character)" -NoNewline
        if ($vkeycode -eq 38) { $pos-- }
        if ($vkeycode -eq 40) { $pos++ }
        if ($pos -lt 0) { $pos = 0 }
        if ($pos -ge $menuItems.length) { $pos = $menuItems.length - 1 }
        Invoke-DrawMenu $menuItems $pos $menuTitel
    }
    $($menuItems[$pos])
}


<#
? What account do you want to log into? [Use arrows to move, type to filter]
> GitHub.com
  GitHub Enterprise Server
#>


Write-Verbose "[$scriptName] - [private/Menu/Invoke-Meny.ps1] - Done"
#endregion - From private/Menu/Invoke-Meny.ps1

Write-Verbose "[$scriptName] - [private/Menu] - Done"
#endregion - From private/Menu

#region - From private/Organization
Write-Verbose "[$scriptName] - [private/Organization] - Processing folder"

#region - From private/Organization/Blocking
Write-Verbose "[$scriptName] - [private/Organization/Blocking] - Processing folder"

#region - From private/Organization/Blocking/Block-GitHubUserByOrganization.ps1
Write-Verbose "[$scriptName] - [private/Organization/Blocking/Block-GitHubUserByOrganization.ps1] - Importing"

filter Block-GitHubUserByOrganization {
    <#
        .SYNOPSIS
        Block a user from an organization

        .DESCRIPTION
        Blocks the given user on behalf of the specified organization and returns a 204. If the organization cannot block the given user a 422 is returned.

        .EXAMPLE
        Block-GitHubUserByOrganization -OrganizationName 'github' -Username 'octocat'

        Blocks the user 'octocat' from the organization 'github'.
        Returns $true if successful, $false if not.

        .NOTES
        https://docs.github.com/rest/orgs/blocking#block-a-user-from-an-organization
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName,

        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/orgs/$OrganizationName/blocks/$Username"
        Method      = 'PUT'
    }

    try {
        $null = (Invoke-GitHubAPI @inputObject)
        # Should we check if user is already blocked and return true if so?
        return $true
    } catch {
        if ($_.Exception.Response.StatusCode.Value__ -eq 422) {
            return $false
        } else {
            Write-Error $_.Exception.Response
            throw $_
        }
    }
}

Write-Verbose "[$scriptName] - [private/Organization/Blocking/Block-GitHubUserByOrganization.ps1] - Done"
#endregion - From private/Organization/Blocking/Block-GitHubUserByOrganization.ps1
#region - From private/Organization/Blocking/Get-GitHubBlockedUserByOrganization.ps1
Write-Verbose "[$scriptName] - [private/Organization/Blocking/Get-GitHubBlockedUserByOrganization.ps1] - Importing"

filter Get-GitHubBlockedUserByOrganization {
    <#
        .SYNOPSIS
        List users blocked by an organization

        .DESCRIPTION
        List the users blocked by an organization.

        .EXAMPLE
        Get-GitHubBlockedUserByOrganization -OrganizationName 'github'

        Lists all users blocked by the organization `github`.

        .NOTES
        https://docs.github.com/rest/orgs/blocking#list-users-blocked-by-an-organization
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = @{
        per_page = $PerPage
    }

    $inputObject = @{
        APIEndpoint = "/orgs/$OrganizationName/blocks"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Organization/Blocking/Get-GitHubBlockedUserByOrganization.ps1] - Done"
#endregion - From private/Organization/Blocking/Get-GitHubBlockedUserByOrganization.ps1
#region - From private/Organization/Blocking/Test-GitHubBlockedUserByOrganization.ps1
Write-Verbose "[$scriptName] - [private/Organization/Blocking/Test-GitHubBlockedUserByOrganization.ps1] - Importing"

filter Test-GitHubBlockedUserByOrganization {
    <#
        .SYNOPSIS
        Check if a user is blocked by an organization

        .DESCRIPTION
        Returns a 204 if the given user is blocked by the given organization. Returns a 404 if the organization is not blocking the user, or if the user account has been identified as spam by GitHub.

        .EXAMPLE
        Test-GitHubBlockedUserByOrganization -OrganizationName 'PSModule' -Username 'octocat'

        Checks if the user `octocat` is blocked by the organization `PSModule`.
        Returns true if the user is blocked, false if not.

        .NOTES
        https://docs.github.com/rest/orgs/blocking#check-if-a-user-is-blocked-by-an-organization
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName,

        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/orgs/$OrganizationName/blocks/$Username"
        Method      = 'GET'
    }

    try {
        (Invoke-GitHubAPI @inputObject).StatusCode -eq 204
    } catch {
        if ($_.Exception.Response.StatusCode.Value__ -eq 404) {
            return $false
        } else {
            throw $_
        }
    }
}

Write-Verbose "[$scriptName] - [private/Organization/Blocking/Test-GitHubBlockedUserByOrganization.ps1] - Done"
#endregion - From private/Organization/Blocking/Test-GitHubBlockedUserByOrganization.ps1
#region - From private/Organization/Blocking/Unblock-GitHubUserByOrganization.ps1
Write-Verbose "[$scriptName] - [private/Organization/Blocking/Unblock-GitHubUserByOrganization.ps1] - Importing"

filter Unblock-GitHubUserByOrganization {
    <#
        .SYNOPSIS
        Unblock a user from an organization

        .DESCRIPTION
        Unblocks the given user on behalf of the specified organization.

        .EXAMPLE
        Unblock-GitHubUserByOrganization -OrganizationName 'github' -Username 'octocat'

        Unblocks the user 'octocat' from the organization 'github'.
        Returns $true if successful.

        .NOTES
        https://docs.github.com/rest/orgs/blocking#unblock-a-user-from-an-organization
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName,

        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/user/blocks/$Username"
        Method      = 'DELETE'
    }

    try {
        $null = (Invoke-GitHubAPI @inputObject)
        return $true
    } catch {
        Write-Error $_.Exception.Response
        throw $_
    }
}

Write-Verbose "[$scriptName] - [private/Organization/Blocking/Unblock-GitHubUserByOrganization.ps1] - Done"
#endregion - From private/Organization/Blocking/Unblock-GitHubUserByOrganization.ps1

Write-Verbose "[$scriptName] - [private/Organization/Blocking] - Done"
#endregion - From private/Organization/Blocking

#region - From private/Organization/Get-GitHubAllOrganization.ps1
Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubAllOrganization.ps1] - Importing"

filter Get-GitHubAllOrganization {
    <#
        .SYNOPSIS
        List organizations

        .DESCRIPTION
        Lists all organizations, in the order that they were created on GitHub.

        **Note:** Pagination is powered exclusively by the `since` parameter. Use the [Link header](https://docs.github.com/rest/guides/using-pagination-in-the-rest-api#using-link-headers) to get the URL for the next page of organizations.

        .EXAMPLE
        Get-GitHubAllOrganization -Since 142951047

        List organizations, starting with PSModule

        .NOTES
        https://docs.github.com/rest/orgs/orgs#list-organizations

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # A organization ID. Only return organizations with an ID greater than this ID.
        [Parameter()]
        [int] $Since = 0,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = @{
        since    = $Since
        per_page = $PerPage
    }

    $inputObject = @{
        APIEndpoint = '/organizations'
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubAllOrganization.ps1] - Done"
#endregion - From private/Organization/Get-GitHubAllOrganization.ps1
#region - From private/Organization/Get-GitHubMyOrganization.ps1
Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubMyOrganization.ps1] - Importing"

filter Get-GitHubMyOrganization {
    <#
        .SYNOPSIS
        List organizations for the authenticated user

        .DESCRIPTION
        List organizations for the authenticated user.

        **OAuth scope requirements**

        This only lists organizations that your authorization allows you to operate on in some way (e.g., you can list teams with `read:org` scope, you can publicize your organization membership with `user` scope, etc.). Therefore, this API requires at least `user` or `read:org` scope. OAuth requests with insufficient scope receive a `403 Forbidden` response.

        .EXAMPLE
        Get-GitHubMyOrganization

        List organizations for the authenticated user.

        .NOTES
        https://docs.github.com/rest/orgs/orgs#list-organizations-for-the-authenticated-user
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = @{
        per_page = $PerPage
    }

    $inputObject = @{
        APIEndpoint = '/user/orgs'
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubMyOrganization.ps1] - Done"
#endregion - From private/Organization/Get-GitHubMyOrganization.ps1
#region - From private/Organization/Get-GitHubOrganizationByName.ps1
Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubOrganizationByName.ps1] - Importing"

filter Get-GitHubOrganizationByName {
    <#
        .SYNOPSIS
        Get an organization

        .DESCRIPTION
        To see many of the organization response values, you need to be an authenticated organization owner with the `admin:org` scope. When the value of `two_factor_requirement_enabled` is `true`, the organization requires all members, billing managers, and outside collaborators to enable [two-factor authentication](https://docs.github.com/articles/securing-your-account-with-two-factor-authentication-2fa/).

        GitHub Apps with the `Organization plan` permission can use this endpoint to retrieve information about an organization's GitHub plan. See "[Authenticating with GitHub Apps](https://docs.github.com/apps/building-github-apps/authenticating-with-github-apps/)" for details. For an example response, see 'Response with GitHub plan information' below."

        .EXAMPLE
        Get-GitHubOrganizationByName -OrganizationName 'github'

        Get the 'GitHub' organization

        .NOTES
        https://docs.github.com/rest/orgs/orgs#get-an-organization
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [Alias('org')]
        [Alias('owner')]
        [string] $OrganizationName
    )


    $inputObject = @{
        APIEndpoint = "/orgs/$OrganizationName"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubOrganizationByName.ps1] - Done"
#endregion - From private/Organization/Get-GitHubOrganizationByName.ps1
#region - From private/Organization/Get-GitHubUserOrganization.ps1
Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubUserOrganization.ps1] - Importing"

filter Get-GitHubUserOrganization {
    <#
        .SYNOPSIS
        List organizations for a user

        .DESCRIPTION
        List [public organization memberships](https://docs.github.com/articles/publicizing-or-concealing-organization-membership) for the specified user.

        This method only lists _public_ memberships, regardless of authentication. If you need to fetch all of the organization memberships (public and private) for the authenticated user, use the [List organizations for the authenticated user](https://docs.github.com/rest/orgs/orgs#list-organizations-for-the-authenticated-user) API instead.

        .EXAMPLE
        Get-GitHubUserOrganization -Username 'octocat'

        List public organizations for the user 'octocat'.

        .NOTES
        https://docs.github.com/rest/orgs/orgs#list-organizations-for-a-user
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(Mandatory)]
        [string] $Username,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = @{
        per_page = $PerPage
    }

    $inputObject = @{
        APIEndpoint = "/users/$Username/orgs"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Organization/Get-GitHubUserOrganization.ps1] - Done"
#endregion - From private/Organization/Get-GitHubUserOrganization.ps1

Write-Verbose "[$scriptName] - [private/Organization] - Done"
#endregion - From private/Organization

#region - From private/Releases
Write-Verbose "[$scriptName] - [private/Releases] - Processing folder"

#region - From private/Releases/Assets
Write-Verbose "[$scriptName] - [private/Releases/Assets] - Processing folder"

#region - From private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1
Write-Verbose "[$scriptName] - [private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1] - Importing"

filter Get-GitHubReleaseAssetByID {
    <#
        .SYNOPSIS
        Get a release asset

        .DESCRIPTION
        To download the asset's binary content, set the `Accept` header of the request to [`application/octet-stream`](https://docs.github.com/rest/overview/media-types).
        The API will either redirect the client to the location, or stream it directly if possible. API clients should handle both a `200` or `302` response.

        .EXAMPLE
        Get-GitHubReleaseAssetByID -Owner 'octocat' -Repo 'hello-world' -ID '1234567'

        Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'.

        .NOTES
        https://docs.github.com/rest/releases/assets#get-a-release-asset

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The unique identifier of the asset.
        [Parameter(Mandatory)]
        [Alias('asset_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/assets/$ID"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1] - Done"
#endregion - From private/Releases/Assets/Get-GitHubReleaseAssetByID.ps1
#region - From private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1
Write-Verbose "[$scriptName] - [private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1] - Importing"

filter Get-GitHubReleaseAssetByReleaseID {
    <#
        .SYNOPSIS
        List release assets

        .DESCRIPTION
        List release assets

        .EXAMPLE
        Get-GitHubReleaseAssetByReleaseID -Owner 'octocat' -Repo 'hello-world' -ID '1234567'

        Gets the release assets for the release with the ID '1234567' for the repository 'octocat/hello-world'.

        .NOTES
        https://docs.github.com/rest/releases/assets#list-release-assets

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The unique identifier of the release.
        [Parameter(
            Mandatory,
            ParameterSetName = 'ID'
        )]
        [Alias('release_id')]
        [string] $ID,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'Owner', 'Repo', 'ID'

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/$ID/assets"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1] - Done"
#endregion - From private/Releases/Assets/Get-GitHubReleaseAssetByReleaseID.ps1

Write-Verbose "[$scriptName] - [private/Releases/Assets] - Done"
#endregion - From private/Releases/Assets

#region - From private/Releases/Releases
Write-Verbose "[$scriptName] - [private/Releases/Releases] - Processing folder"

#region - From private/Releases/Releases/Get-GitHubReleaseAll.ps1
Write-Verbose "[$scriptName] - [private/Releases/Releases/Get-GitHubReleaseAll.ps1] - Importing"

filter Get-GitHubReleaseAll {
    <#
        .SYNOPSIS
        List releases

        .DESCRIPTION
        This returns a list of releases, which does not include regular Git tags that have not been associated with a release.
        To get a list of Git tags, use the [Repository Tags API](https://docs.github.com/rest/repos/repos#list-repository-tags).
        Information about published releases are available to everyone. Only users with push access will receive listings for draft releases.

        .EXAMPLE
        Get-GitHubReleaseAll -Owner 'octocat' -Repo 'hello-world'

        Gets all the releases for the repository 'hello-world' owned by 'octocat'.

        .NOTES
        https://docs.github.com/rest/releases/releases#list-releases

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The number of results per page (max 100).
        [Parameter(ParameterSetName = 'AllUsers')]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'Owner', 'Repo'

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Releases/Releases/Get-GitHubReleaseAll.ps1] - Done"
#endregion - From private/Releases/Releases/Get-GitHubReleaseAll.ps1
#region - From private/Releases/Releases/Get-GitHubReleaseByID.ps1
Write-Verbose "[$scriptName] - [private/Releases/Releases/Get-GitHubReleaseByID.ps1] - Importing"

filter Get-GitHubReleaseByID {
    <#
        .SYNOPSIS
        Get a release

        .DESCRIPTION
        **Note:** This returns an `upload_url` key corresponding to the endpoint for uploading release assets.
        This key is a [hypermedia resource](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia).

        .EXAMPLE
        Get-GitHubReleaseById -Owner 'octocat' -Repo 'hello-world' -ID '1234567'

        Gets the release with the id '1234567' for the repository 'hello-world' owned by 'octocat'.

        .NOTES
        https://docs.github.com/rest/releases/releases#get-a-release

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The unique identifier of the release.
        [Parameter(
            Mandatory
        )]
        [Alias('release_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/$ID"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Releases/Releases/Get-GitHubReleaseByID.ps1] - Done"
#endregion - From private/Releases/Releases/Get-GitHubReleaseByID.ps1
#region - From private/Releases/Releases/Get-GitHubReleaseByTagName.ps1
Write-Verbose "[$scriptName] - [private/Releases/Releases/Get-GitHubReleaseByTagName.ps1] - Importing"

filter Get-GitHubReleaseByTagName {
    <#
        .SYNOPSIS
        Get a release by tag name

        .DESCRIPTION
        Get a published release with the specified tag.

        .EXAMPLE
        Get-GitHubReleaseByTagName -Owner 'octocat' -Repo 'hello-world' -Tag 'v1.0.0'

        Gets the release with the tag 'v1.0.0' for the repository 'hello-world' owned by 'octocat'.

        .NOTES
        https://docs.github.com/rest/releases/releases#get-a-release-by-tag-name

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The name of the tag to get a release from.
        [Parameter(
            Mandatory
        )]
        [Alias('tag_name')]
        [string] $Tag
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/tags/$Tag"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Releases/Releases/Get-GitHubReleaseByTagName.ps1] - Done"
#endregion - From private/Releases/Releases/Get-GitHubReleaseByTagName.ps1
#region - From private/Releases/Releases/Get-GitHubReleaseLatest.ps1
Write-Verbose "[$scriptName] - [private/Releases/Releases/Get-GitHubReleaseLatest.ps1] - Importing"

filter Get-GitHubReleaseLatest {
    <#
        .SYNOPSIS
        Get the latest release

        .DESCRIPTION
        View the latest published full release for the repository.
        The latest release is the most recent non-prerelease, non-draft release, sorted by the `created_at` attribute.
        The `created_at` attribute is the date of the commit used for the release, and not the date when the release was drafted or published.

        .EXAMPLE
        Get-GitHubReleaseLatest -Owner 'octocat' -Repo 'hello-world'

        Gets the latest releases for the repository 'hello-world' owned by 'octocat'.

        .NOTES
        https://docs.github.com/rest/releases/releases#get-the-latest-release

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo)

    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/latest"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Releases/Releases/Get-GitHubReleaseLatest.ps1] - Done"
#endregion - From private/Releases/Releases/Get-GitHubReleaseLatest.ps1

Write-Verbose "[$scriptName] - [private/Releases/Releases] - Done"
#endregion - From private/Releases/Releases


Write-Verbose "[$scriptName] - [private/Releases] - Done"
#endregion - From private/Releases

#region - From private/Repositories
Write-Verbose "[$scriptName] - [private/Repositories] - Processing folder"

#region - From private/Repositories/Repositories
Write-Verbose "[$scriptName] - [private/Repositories/Repositories] - Processing folder"

#region - From private/Repositories/Repositories/Get-GitHubMyRepositories.ps1
Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubMyRepositories.ps1] - Importing"

filter Get-GitHubMyRepositories {
    <#
        .SYNOPSIS
        List repositories for the authenticated user

        .DESCRIPTION
        Lists repositories that the authenticated user has explicit permission (`:read`, `:write`, or `:admin`) to access.
        The authenticated user has explicit permission to access repositories they own, repositories where they are a collaborator,
        and repositories that they can access through an organization membership.

        .EXAMPLE
        Get-GitHubMyRepositories

        Gets the repositories for the authenticated user.

        .EXAMPLE
        Get-GitHubMyRepositories -Visibility 'private'

        Gets the private repositories for the authenticated user.

        .EXAMPLE
        Get-GitHubMyRepositories -Visibility 'public' -Affiliation 'owner','collaborator' -Sort 'created' -Direction 'asc' -PerPage 100 -Since (Get-Date).AddYears(-5) -Before (Get-Date).AddDays(-1)

        Gets the public repositories for the authenticated user that are owned by the authenticated user or that the authenticated user has been added to as a collaborator.
        The results are sorted by creation date in ascending order and the results are limited to 100 repositories.
        The results are limited to repositories created between 5 years ago and 1 day ago.

        .EXAMPLE
        Get-GitHubMyRepositories -Type 'forks'

        Gets the forked repositories for the authenticated user.

        .EXAMPLE
        Get-GitHubMyRepositories -Type 'sources'

        Gets the non-forked repositories for the authenticated user.

        .EXAMPLE
        Get-GitHubMyRepositories -Type 'member'

        Gets the repositories for the authenticated user that are owned by an organization.

        .NOTES
        https://docs.github.com/rest/repos/repos#list-repositories-for-the-authenticated-user

    #>

    [CmdletBinding(DefaultParameterSetName = 'Type')]
    param (

        # Limit results to repositories with the specified visibility.
        [Parameter(
            ParameterSetName = 'Aff-Vis'
        )]
        [ValidateSet('all', 'public', 'private')]
        [string] $Visibility = 'all',

        # Comma-separated list of values. Can include:
        # - owner: Repositories that are owned by the authenticated user.
        # - collaborator: Repositories that the user has been added to as a collaborator.
        # - organization_member: Repositories that the user has access to through being a member of an organization. This includes every repository on every team that the user is on.
        # Default: owner, collaborator, organization_member
        [Parameter(
            ParameterSetName = 'Aff-Vis'
        )]
        [ValidateSet('owner', 'collaborator', 'organization_member')]
        [string[]] $Affiliation = @('owner', 'collaborator', 'organization_member'),

        # Specifies the types of repositories you want returned.
        [Parameter(
            ParameterSetName = 'Type'
        )]
        [ValidateSet('all', 'owner', 'public', 'private', 'member')]
        [string] $Type = 'all',

        # The property to sort the results by.
        [Parameter()]
        [ValidateSet('created', 'updated', 'pushed', 'full_name')]
        [string] $Sort = 'created',

        # The order to sort by.
        # Default: asc when using full_name, otherwise desc.
        [Parameter()]
        [ValidateSet('asc', 'desc')]
        [string] $Direction,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30,

        # Only show repositories updated after the given time.
        [Parameter()]
        [datetime] $Since,

        # Only show repositories updated before the given time.
        [Parameter()]
        [datetime] $Before
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramDefaultValue = Get-Variable -Name $_.Key -ValueOnly -ErrorAction SilentlyContinue
        if (-not $PSBoundParameters.ContainsKey($_.Key) -and ($null -ne $paramDefaultValue)) {
            $PSBoundParameters[$_.Key] = $paramDefaultValue
        }
    }

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'Affiliation', 'Since', 'Before'

    if ($PSBoundParameters.ContainsKey('Affiliation')) {
        $body['affiliation'] = $Affiliation -join ','
    }
    if ($PSBoundParameters.ContainsKey('Since')) {
        $body['since'] = $Since.ToString('yyyy-MM-ddTHH:mm:ssZ')
    }
    if ($PSBoundParameters.ContainsKey('Before')) {
        $body['before'] = $Before.ToString('yyyy-MM-ddTHH:mm:ssZ')
    }

    $inputObject = @{
        APIEndpoint = '/user/repos'
        Method      = 'GET'
        body        = $body
    }

    Invoke-GitHubAPI @inputObject | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubMyRepositories.ps1] - Done"
#endregion - From private/Repositories/Repositories/Get-GitHubMyRepositories.ps1
#region - From private/Repositories/Repositories/Get-GitHubRepositoryByName.ps1
Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubRepositoryByName.ps1] - Importing"

filter Get-GitHubRepositoryByName {
    <#
        .SYNOPSIS
        Get a repository

        .DESCRIPTION
        The `parent` and `source` objects are present when the repository is a fork.
        `parent` is the repository this repository was forked from, `source` is the ultimate source for the network.
        **Note:** In order to see the `security_and_analysis` block for a repository you must have admin permissions
        for the repository or be an owner or security manager for the organization that owns the repository.
        For more information, see "[Managing security managers in your organization](https://docs.github.com/organizations/managing-peoples-access-to-your-organization-with-roles/managing-security-managers-in-your-organization)."

        .EXAMPLE
        Get-GitHubRepositoryByName -Owner 'octocat' -Repo 'Hello-World'

        Gets the repository 'Hello-World' for the organization 'octocat'.

        .NOTES
        https://docs.github.com/rest/repos/repos#get-a-repository

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo)

    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo"
        Method      = 'GET'
    }

    Invoke-GitHubAPI @inputObject | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubRepositoryByName.ps1] - Done"
#endregion - From private/Repositories/Repositories/Get-GitHubRepositoryByName.ps1
#region - From private/Repositories/Repositories/Get-GitHubRepositoryListByID.ps1
Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubRepositoryListByID.ps1] - Importing"

filter Get-GitHubRepositoryListByID {
    <#
        .SYNOPSIS
        List public repositories

        .DESCRIPTION
        Lists all public repositories in the order that they were created.

        Note:
        - For GitHub Enterprise Server, this endpoint will only list repositories available to all users on the enterprise.
        - Pagination is powered exclusively by the `since` parameter. Use the [Link header](https://docs.github.com/rest/guides/using-pagination-in-the-rest-api#using-link-headers) to get the URL for the next page of repositories.

        .EXAMPLE
        Get-GitHubRepositoryListByID -Since '123456789

        Gets the repositories with an ID equals and greater than 123456789.

        .NOTES
        https://docs.github.com/rest/repos/repos#list-public-repositories

    #>

    [CmdletBinding()]
    param (
        # A repository ID. Only return repositories with an ID greater than this ID.
        [Parameter()]
        [int] $Since = 0
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)]"
        $paramDefaultValue = Get-Variable -Name $_.Key -ValueOnly -ErrorAction SilentlyContinue
        if (-not $PSBoundParameters.ContainsKey($_.Key) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose "Parameter: [$($_.Key)] = [$($_.Value)] - Adding default value"
            $PSBoundParameters[$_.Key] = $paramDefaultValue
        }
        Write-Verbose " - $($PSBoundParameters[$_.Key])"
    }

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/repositories'
        Method      = 'GET'
        Body        = $body
    }

    Invoke-GitHubAPI @inputObject | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubRepositoryListByID.ps1] - Done"
#endregion - From private/Repositories/Repositories/Get-GitHubRepositoryListByID.ps1
#region - From private/Repositories/Repositories/Get-GitHubRepositoryListByOrg.ps1
Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubRepositoryListByOrg.ps1] - Importing"

filter Get-GitHubRepositoryListByOrg {
    <#
        .SYNOPSIS
        List organization repositories

        .DESCRIPTION
        Lists repositories for the specified organization.
        **Note:** In order to see the `security_and_analysis` block for a repository you must have admin permissions for the repository
        or be an owner or security manager for the organization that owns the repository.
        For more information, see "[Managing security managers in your organization](https://docs.github.com/organizations/managing-peoples-access-to-your-organization-with-roles/managing-security-managers-in-your-organization)."

        .EXAMPLE
        Get-GitHubRepositoryListByOrg -Owner 'octocat'

        Gets the repositories for the organization 'octocat'.

        .EXAMPLE
        Get-GitHubRepositoryListByOrg -Owner 'octocat' -Type 'public'

        Gets the public repositories for the organization 'octocat'.

        .EXAMPLE
        Get-GitHubRepositoryListByOrg -Owner 'octocat' -Sort 'created' -Direction 'asc'

        Gets the repositories for the organization 'octocat' sorted by creation date in ascending order.

        .NOTES
        https://docs.github.com/rest/repos/repos#list-organization-repositories

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # Specifies the types of repositories you want returned.
        [Parameter()]
        [validateSet('all', 'public', 'private', 'forks', 'sources', 'member')]
        [string] $type = 'all',

        # The property to sort the results by.
        [Parameter()]
        [validateSet('created', 'updated', 'pushed', 'full_name')]
        [string] $Sort = 'created',

        # The order to sort by.
        # Default: asc when using full_name, otherwise desc.
        [Parameter()]
        [validateSet('asc', 'desc')]
        [string] $Direction,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramDefaultValue = Get-Variable -Name $_.Key -ValueOnly -ErrorAction SilentlyContinue
        if (-not $PSBoundParameters.ContainsKey($_.Key) -and ($null -ne $paramDefaultValue)) {
            $PSBoundParameters[$_.Key] = $paramDefaultValue
        }
    }

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'Owner'

    $inputObject = @{
        APIEndpoint = "/orgs/$Owner/repos"
        Method      = 'GET'
        Body        = $body
    }

    Invoke-GitHubAPI @inputObject | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubRepositoryListByOrg.ps1] - Done"
#endregion - From private/Repositories/Repositories/Get-GitHubRepositoryListByOrg.ps1
#region - From private/Repositories/Repositories/Get-GitHubRepositoryListByUser.ps1
Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubRepositoryListByUser.ps1] - Importing"

filter Get-GitHubRepositoryListByUser {
    <#
        .SYNOPSIS
        List repositories for a user

        .DESCRIPTION
        Lists public repositories for the specified user.
        Note: For GitHub AE, this endpoint will list internal repositories for the specified user.

        .EXAMPLE
        Get-GitHubRepositoryListByUser -Username 'octocat'

        Gets the repositories for the user 'octocat'.

        .EXAMPLE
        Get-GitHubRepositoryListByUser -Username 'octocat' -Type 'member'

        Gets the repositories of organizations where the user 'octocat' is a member.

        .EXAMPLE
        Get-GitHubRepositoryListByUser -Username 'octocat' -Sort 'created' -Direction 'asc'

        Gets the repositories for the user 'octocat' sorted by creation date in ascending order.

        .NOTES
        https://docs.github.com/rest/repos/repos#list-repositories-for-a-user

    #>

    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username,

        # Specifies the types of repositories you want returned.
        [Parameter()]
        [validateSet('all', 'owner', 'member')]
        [string] $Type = 'all',

        # The property to sort the results by.
        [Parameter()]
        [validateSet('created', 'updated', 'pushed', 'full_name')]
        [string] $Sort = 'created',

        # The order to sort by.
        # Default: asc when using full_name, otherwise desc.
        [Parameter()]
        [validateSet('asc', 'desc')]
        [string] $Direction,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramDefaultValue = Get-Variable -Name $_.Key -ValueOnly -ErrorAction SilentlyContinue
        if (-not $PSBoundParameters.ContainsKey($_.Key) -and ($null -ne $paramDefaultValue)) {
            $PSBoundParameters[$_.Key] = $paramDefaultValue
        }
    }

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'Username'

    $inputObject = @{
        APIEndpoint = "/users/$Username/repos"
        Method      = 'GET'
        Body        = $body
    }

    Invoke-GitHubAPI @inputObject | ForEach-Object {
        Write-Output $_.Response
    }
}

Write-Verbose "[$scriptName] - [private/Repositories/Repositories/Get-GitHubRepositoryListByUser.ps1] - Done"
#endregion - From private/Repositories/Repositories/Get-GitHubRepositoryListByUser.ps1

Write-Verbose "[$scriptName] - [private/Repositories/Repositories] - Done"
#endregion - From private/Repositories/Repositories


Write-Verbose "[$scriptName] - [private/Repositories] - Done"
#endregion - From private/Repositories

#region - From private/Users
Write-Verbose "[$scriptName] - [private/Users] - Processing folder"

#region - From private/Users/Blocking
Write-Verbose "[$scriptName] - [private/Users/Blocking] - Processing folder"

#region - From private/Users/Blocking/Block-GitHubUserByUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Blocking/Block-GitHubUserByUser.ps1] - Importing"

filter Block-GitHubUserByUser {
    <#
        .SYNOPSIS
        Block a user

        .DESCRIPTION
        Blocks the given user and returns a 204. If the authenticated user cannot block the given user a 422 is returned.

        .EXAMPLE
        Block-GitHubUserByUser -Username 'octocat'

        Blocks the user 'octocat' for the authenticated user.
        Returns $true if successful, $false if not.

        .NOTES
        https://docs.github.com/rest/users/blocking#block-a-user
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/user/blocks/$Username"
        Method      = 'PUT'
    }

    try {
        $null = (Invoke-GitHubAPI @inputObject)
        # Should we check if user is already blocked and return true if so?
        return $true
    } catch {
        if ($_.Exception.Response.StatusCode.Value__ -eq 422) {
            return $false
        } else {
            Write-Error $_.Exception.Response
            throw $_
        }
    }
}

Write-Verbose "[$scriptName] - [private/Users/Blocking/Block-GitHubUserByUser.ps1] - Done"
#endregion - From private/Users/Blocking/Block-GitHubUserByUser.ps1
#region - From private/Users/Blocking/Get-GitHubBlockedUserByUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Blocking/Get-GitHubBlockedUserByUser.ps1] - Importing"

filter Get-GitHubBlockedUserByUser {
    <#
        .SYNOPSIS
        List users blocked by the authenticated user

        .DESCRIPTION
        List the users you've blocked on your personal account.

        .EXAMPLE
        Get-GitHubBlockedUserByUser

        Returns a list of users blocked by the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/blocking#list-users-blocked-by-the-authenticated-user
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/blocks"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Blocking/Get-GitHubBlockedUserByUser.ps1] - Done"
#endregion - From private/Users/Blocking/Get-GitHubBlockedUserByUser.ps1
#region - From private/Users/Blocking/Test-GitHubBlockedUserByUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Blocking/Test-GitHubBlockedUserByUser.ps1] - Importing"

filter Test-GitHubBlockedUserByUser {
    <#
        .SYNOPSIS
        Check if a user is blocked by the authenticated user

        .DESCRIPTION
        Returns a 204 if the given user is blocked by the authenticated user. Returns a 404 if the given user is not blocked by the authenticated user, or if the given user account has been identified as spam by GitHub.

        .EXAMPLE
        Test-GitHubBlockedUserByUser -Username 'octocat'

        Checks if the user `octocat` is blocked by the authenticated user.
        Returns true if the user is blocked, false if not.

        .NOTES
        https://docs.github.com/rest/users/blocking#check-if-a-user-is-blocked-by-the-authenticated-user
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/blocks/$Username"
        Method      = 'GET'
        Body        = $body
    }

    try {
        (Invoke-GitHubAPI @inputObject).StatusCode -eq 204
    } catch {
        if ($_.Exception.Response.StatusCode.Value__ -eq 404) {
            return $false
        } else {
            throw $_
        }
    }

}

Write-Verbose "[$scriptName] - [private/Users/Blocking/Test-GitHubBlockedUserByUser.ps1] - Done"
#endregion - From private/Users/Blocking/Test-GitHubBlockedUserByUser.ps1
#region - From private/Users/Blocking/Unblock-GitHubUserByUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Blocking/Unblock-GitHubUserByUser.ps1] - Importing"

filter Unblock-GitHubUserByUser {
    <#
        .SYNOPSIS
        Unblock a user

        .DESCRIPTION
        Unblocks the given user and returns a 204.

        .EXAMPLE
        Unblock-GitHubUserByUser -Username 'octocat'

        Unblocks the user 'octocat' for the authenticated user.
        Returns $true if successful.

        .NOTES
        https://docs.github.com/rest/users/blocking#unblock-a-user
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/user/blocks/$Username"
        Method      = 'DELETE'
    }

    try {
        $null = (Invoke-GitHubAPI @inputObject)
        return $true
    } catch {
        Write-Error $_.Exception.Response
        throw $_
    }
}

Write-Verbose "[$scriptName] - [private/Users/Blocking/Unblock-GitHubUserByUser.ps1] - Done"
#endregion - From private/Users/Blocking/Unblock-GitHubUserByUser.ps1

Write-Verbose "[$scriptName] - [private/Users/Blocking] - Done"
#endregion - From private/Users/Blocking

#region - From private/Users/Emails
Write-Verbose "[$scriptName] - [private/Users/Emails] - Processing folder"

#region - From private/Users/Emails/Get-GitHubUserAllEmail.ps1
Write-Verbose "[$scriptName] - [private/Users/Emails/Get-GitHubUserAllEmail.ps1] - Importing"

filter Get-GitHubUserAllEmail {
    <#
        .SYNOPSIS
        List email addresses for the authenticated user

        .DESCRIPTION
        Lists all of your email addresses, and specifies which one is visible to the public. This endpoint is accessible with the `user:email` scope.

        .EXAMPLE
        Get-GitHubUserAllEmail

        Gets all email addresses for the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/emails#list-email-addresses-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/emails"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Emails/Get-GitHubUserAllEmail.ps1] - Done"
#endregion - From private/Users/Emails/Get-GitHubUserAllEmail.ps1
#region - From private/Users/Emails/Get-GitHubUserPublicEmail.ps1
Write-Verbose "[$scriptName] - [private/Users/Emails/Get-GitHubUserPublicEmail.ps1] - Importing"

filter Get-GitHubUserPublicEmail {
    <#
        .SYNOPSIS
        List public email addresses for the authenticated user

        .DESCRIPTION
        Lists your publicly visible email address, which you can set with the [Set primary email visibility for the authenticated user](https://docs.github.com/rest/users/emails#set-primary-email-visibility-for-the-authenticated-user) endpoint. This endpoint is accessible with the `user:email` scope.

        .EXAMPLE
        Get-GitHubUserPublicEmail

        Gets all public email addresses for the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/emails#list-public-email-addresses-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/public_emails"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Emails/Get-GitHubUserPublicEmail.ps1] - Done"
#endregion - From private/Users/Emails/Get-GitHubUserPublicEmail.ps1

Write-Verbose "[$scriptName] - [private/Users/Emails] - Done"
#endregion - From private/Users/Emails

#region - From private/Users/Followers
Write-Verbose "[$scriptName] - [private/Users/Followers] - Processing folder"

#region - From private/Users/Followers/Get-GitHubUserFollowersOfUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowersOfUser.ps1] - Importing"

filter Get-GitHubUserFollowersOfUser {
    <#
        .SYNOPSIS
        List followers of a user

        .DESCRIPTION
        Lists the people following the specified user.

        .EXAMPLE
        Get-GitHubUserFollowersOfUser -Username 'octocat'

        Gets all followers of user 'octocat'.

        .NOTES
        https://docs.github.com/rest/users/followers#list-followers-of-a-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'username'

    $inputObject = @{
        APIEndpoint = "/users/$Username/followers"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowersOfUser.ps1] - Done"
#endregion - From private/Users/Followers/Get-GitHubUserFollowersOfUser.ps1
#region - From private/Users/Followers/Get-GitHubUserFollowingMe.ps1
Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowingMe.ps1] - Importing"

filter Get-GitHubUserFollowingMe {
    <#
        .SYNOPSIS
        List the people the authenticated user follows

        .DESCRIPTION
        Lists the people who the authenticated user follows.

        .EXAMPLE
        Get-GitHubUserFollowingMe

        Gets all people the authenticated user follows.

        .NOTES
        https://docs.github.com/rest/users/followers#list-the-people-the-authenticated-user-follows

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/user/following'
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowingMe.ps1] - Done"
#endregion - From private/Users/Followers/Get-GitHubUserFollowingMe.ps1
#region - From private/Users/Followers/Get-GitHubUserFollowingUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowingUser.ps1] - Importing"

filter Get-GitHubUserFollowingUser {
    <#
        .SYNOPSIS
        List the people a user follows

        .DESCRIPTION
        Lists the people who the specified user follows.

        .EXAMPLE
        Get-GitHubUserFollowingUser -Username 'octocat'

        Gets all people that 'octocat' follows.

        .NOTES
        https://docs.github.com/rest/users/followers#list-the-people-a-user-follows

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'username'

    $inputObject = @{
        APIEndpoint = "/users/$Username/following"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserFollowingUser.ps1] - Done"
#endregion - From private/Users/Followers/Get-GitHubUserFollowingUser.ps1
#region - From private/Users/Followers/Get-GitHubUserMyFollowers.ps1
Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserMyFollowers.ps1] - Importing"

filter Get-GitHubUserMyFollowers {
    <#
        .SYNOPSIS
        List followers of the authenticated user

        .DESCRIPTION
        Lists the people following the authenticated user.

        .EXAMPLE
        Get-GitHubUserMyFollowers

        Gets all followers of the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/followers#list-followers-of-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/user/followers'
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Followers/Get-GitHubUserMyFollowers.ps1] - Done"
#endregion - From private/Users/Followers/Get-GitHubUserMyFollowers.ps1
#region - From private/Users/Followers/Test-GitHubUserFollowedByMe.ps1
Write-Verbose "[$scriptName] - [private/Users/Followers/Test-GitHubUserFollowedByMe.ps1] - Importing"

filter Test-GitHubUserFollowedByMe {
    <#
        .SYNOPSIS
        Check if a person is followed by the authenticated user

        .DESCRIPTION
        Returns a 204 if the given user is followed by the authenticated user.
        Returns a 404 if the user is not followed by the authenticated user.

        .EXAMPLE
        Test-GitHubUserFollowedByMe -Username 'octocat'

        Checks if the authenticated user follows the user 'octocat'.

        .NOTES
        https://docs.github.com/rest/users/followers#check-if-a-person-is-followed-by-the-authenticated-user

    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/user/following/$Username"
        Method      = 'GET'
    }

    try {
        $null = (Invoke-GitHubAPI @inputObject)
        return $true
    } catch {
        if ($_.Exception.Response.StatusCode.Value__ -eq 404) {
            return $false
        } else {
            throw $_
        }
    }
}

Write-Verbose "[$scriptName] - [private/Users/Followers/Test-GitHubUserFollowedByMe.ps1] - Done"
#endregion - From private/Users/Followers/Test-GitHubUserFollowedByMe.ps1
#region - From private/Users/Followers/Test-GitHubUserFollowedByUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Followers/Test-GitHubUserFollowedByUser.ps1] - Importing"

filter Test-GitHubUserFollowedByUser {
    <#
        .SYNOPSIS
        Check if a user follows another user

        .DESCRIPTION
        Checks if a user follows another user.

        .EXAMPLE
        Test-GitHubUserFollowedByUser -Username 'octocat' -Follows 'ratstallion'

        Checks if the user 'octocat' follows the user 'ratstallion'.

        .NOTES
        https://docs.github.com/rest/users/followers#check-if-a-user-follows-another-user

    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username,

        # The handle for the GitHub user account we want to check if user specified by $Username is following.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Follows
    )

    $inputObject = @{
        APIEndpoint = "/users/$Username/following/$Follows"
        Method      = 'GET'
    }

    try {
        $null = (Invoke-GitHubAPI @inputObject)
        return $true
    } catch {
        if ($_.Exception.Response.StatusCode.Value__ -eq 404) {
            return $false
        } else {
            throw $_
        }
    }
}

Write-Verbose "[$scriptName] - [private/Users/Followers/Test-GitHubUserFollowedByUser.ps1] - Done"
#endregion - From private/Users/Followers/Test-GitHubUserFollowedByUser.ps1

Write-Verbose "[$scriptName] - [private/Users/Followers] - Done"
#endregion - From private/Users/Followers

#region - From private/Users/GPG-Keys
Write-Verbose "[$scriptName] - [private/Users/GPG-Keys] - Processing folder"

#region - From private/Users/GPG-Keys/Get-GitHubUserGpgKeyForUser.ps1
Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserGpgKeyForUser.ps1] - Importing"

filter Get-GitHubUserGpgKeyForUser {
    <#
        .SYNOPSIS
        List GPG keys for a user

        .DESCRIPTION
        Lists the GPG keys for a user. This information is accessible by anyone.

        .EXAMPLE
        Get-GitHubUserGpgKeyForUser -Username 'octocat'

        Gets all GPG keys for the 'octocat' user.

        .NOTES
        https://docs.github.com/rest/users/gpg-keys#list-gpg-keys-for-a-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'username'

    $inputObject = @{
        APIEndpoint = "/users/$Username/gpg_keys"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserGpgKeyForUser.ps1] - Done"
#endregion - From private/Users/GPG-Keys/Get-GitHubUserGpgKeyForUser.ps1
#region - From private/Users/GPG-Keys/Get-GitHubUserMyGpgKey.ps1
Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserMyGpgKey.ps1] - Importing"

filter Get-GitHubUserMyGpgKey {
    <#
        .SYNOPSIS
        List GPG keys for the authenticated user

        .DESCRIPTION
        Lists the current user's GPG keys.
        Requires that you are authenticated via Basic Auth or via OAuth with at least `read:gpg_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).

        .EXAMPLE
        Get-GitHubUserMyGpgKey

        Gets all GPG keys for the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/gpg-keys#list-gpg-keys-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/user/gpg_keys'
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserMyGpgKey.ps1] - Done"
#endregion - From private/Users/GPG-Keys/Get-GitHubUserMyGpgKey.ps1
#region - From private/Users/GPG-Keys/Get-GitHubUserMyGpgKeyById.ps1
Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserMyGpgKeyById.ps1] - Importing"

filter Get-GitHubUserMyGpgKeyById {
    <#
        .SYNOPSIS
        Get a GPG key for the authenticated user

        .DESCRIPTION
        View extended details for a single GPG key.
        Requires that you are authenticated via Basic Auth or via OAuth with at least `read:gpg_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).

        .EXAMPLE
        Get-GitHubUserMyGpgKeyById -ID '1234567'

        Gets the GPG key with ID '1234567' for the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/gpg-keys#get-a-gpg-key-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The ID of the GPG key.
        [Parameter(
            Mandatory
        )]
        [Alias('gpg_key_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/user/gpg_keys/$ID"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/GPG-Keys/Get-GitHubUserMyGpgKeyById.ps1] - Done"
#endregion - From private/Users/GPG-Keys/Get-GitHubUserMyGpgKeyById.ps1

Write-Verbose "[$scriptName] - [private/Users/GPG-Keys] - Done"
#endregion - From private/Users/GPG-Keys

#region - From private/Users/Keys
Write-Verbose "[$scriptName] - [private/Users/Keys] - Processing folder"

#region - From private/Users/Keys/Get-GitHubUserKeyForUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Keys/Get-GitHubUserKeyForUser.ps1] - Importing"

filter Get-GitHubUserKeyForUser {
    <#
        .SYNOPSIS
        List public SSH keys for a user

        .DESCRIPTION
        Lists the _verified_ public SSH keys for a user. This is accessible by anyone.

        .EXAMPLE
        Get-GitHubUserKeyForUser -Username 'octocat'

        Gets all public SSH keys for the 'octocat' user.

        .NOTES
        https://docs.github.com/rest/users/keys#list-public-keys-for-a-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'username'

    $inputObject = @{
        APIEndpoint = "/users/$Username/keys"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Keys/Get-GitHubUserKeyForUser.ps1] - Done"
#endregion - From private/Users/Keys/Get-GitHubUserKeyForUser.ps1
#region - From private/Users/Keys/Get-GitHubUserMyKey.ps1
Write-Verbose "[$scriptName] - [private/Users/Keys/Get-GitHubUserMyKey.ps1] - Importing"

filter Get-GitHubUserMyKey {
    <#
        .SYNOPSIS
        List public SSH keys for the authenticated user

        .DESCRIPTION
        Lists the public SSH keys for the authenticated user's GitHub account.
        Requires that you are authenticated via Basic Auth or via OAuth with at least `read:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).

        .EXAMPLE
        Get-GitHubUserMyKey

        Gets all public SSH keys for the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/keys#list-public-ssh-keys-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/user/keys'
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Keys/Get-GitHubUserMyKey.ps1] - Done"
#endregion - From private/Users/Keys/Get-GitHubUserMyKey.ps1
#region - From private/Users/Keys/Get-GitHubUserMyKeyById.ps1
Write-Verbose "[$scriptName] - [private/Users/Keys/Get-GitHubUserMyKeyById.ps1] - Importing"

filter Get-GitHubUserMyKeyById {
    <#
        .SYNOPSIS
        Get a public SSH key for the authenticated user

        .DESCRIPTION
        View extended details for a single public SSH key.
        Requires that you are authenticated via Basic Auth or via OAuth with at least `read:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).

        .EXAMPLE
        Get-GitHubUserMyKeyById -ID '1234567'

        Gets the public SSH key with the ID '1234567' for the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/keys#get-a-public-ssh-key-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The unique identifier of the key.
        [Parameter(
            Mandatory
        )]
        [Alias('key_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/user/keys/$ID"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Keys/Get-GitHubUserMyKeyById.ps1] - Done"
#endregion - From private/Users/Keys/Get-GitHubUserMyKeyById.ps1

Write-Verbose "[$scriptName] - [private/Users/Keys] - Done"
#endregion - From private/Users/Keys

#region - From private/Users/Social-Accounts
Write-Verbose "[$scriptName] - [private/Users/Social-Accounts] - Processing folder"

#region - From private/Users/Social-Accounts/Get-GitHubMyUserSocials.ps1
Write-Verbose "[$scriptName] - [private/Users/Social-Accounts/Get-GitHubMyUserSocials.ps1] - Importing"

filter Get-GitHubMyUserSocials {
    <#
        .SYNOPSIS
        List social accounts for the authenticated user

        .DESCRIPTION
        Lists all of your social accounts.

        .EXAMPLE
        Get-GitHubMyUserSocials

        Lists all of your social accounts.

        .NOTES
        https://docs.github.com/rest/users/social-accounts#list-social-accounts-for-the-authenticated-user
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/user/social_accounts'
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Social-Accounts/Get-GitHubMyUserSocials.ps1] - Done"
#endregion - From private/Users/Social-Accounts/Get-GitHubMyUserSocials.ps1
#region - From private/Users/Social-Accounts/Get-GitHubUserSocialsByName.ps1
Write-Verbose "[$scriptName] - [private/Users/Social-Accounts/Get-GitHubUserSocialsByName.ps1] - Importing"

filter Get-GitHubUserSocialsByName {
    <#
        .SYNOPSIS
        List social accounts for a user

        .DESCRIPTION
        Lists social media accounts for a user. This endpoint is accessible by anyone.

        .EXAMPLE
        Get-GitHubUserSocialsByName -Username 'octocat'

        Lists social media accounts for the user 'octocat'.

        .NOTES
        https://docs.github.com/rest/users/social-accounts#list-social-accounts-for-a-user
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/users/$Username/social_accounts"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Social-Accounts/Get-GitHubUserSocialsByName.ps1] - Done"
#endregion - From private/Users/Social-Accounts/Get-GitHubUserSocialsByName.ps1

Write-Verbose "[$scriptName] - [private/Users/Social-Accounts] - Done"
#endregion - From private/Users/Social-Accounts

#region - From private/Users/SSH-Signing-Keys
Write-Verbose "[$scriptName] - [private/Users/SSH-Signing-Keys] - Processing folder"

#region - From private/Users/SSH-Signing-Keys/Get-GitHubUserMySigningKey.ps1
Write-Verbose "[$scriptName] - [private/Users/SSH-Signing-Keys/Get-GitHubUserMySigningKey.ps1] - Importing"

filter Get-GitHubUserMySigningKey {
    <#
        .SYNOPSIS
        List SSH signing keys for the authenticated user

        .DESCRIPTION
        Lists the SSH signing keys for the authenticated user's GitHub account.
        You must authenticate with Basic Authentication, or you must authenticate with OAuth with at least `read:ssh_signing_key` scope. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/)."

        .EXAMPLE
        Get-GitHubUserMySigningKey

        Lists the SSH signing keys for the authenticated user's GitHub account.

        .NOTES
        https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/user/ssh_signing_keys'
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/SSH-Signing-Keys/Get-GitHubUserMySigningKey.ps1] - Done"
#endregion - From private/Users/SSH-Signing-Keys/Get-GitHubUserMySigningKey.ps1
#region - From private/Users/SSH-Signing-Keys/Get-GitHubUserMySigningKeyById.ps1
Write-Verbose "[$scriptName] - [private/Users/SSH-Signing-Keys/Get-GitHubUserMySigningKeyById.ps1] - Importing"

filter Get-GitHubUserMySigningKeyById {
    <#
        .SYNOPSIS
        Get an SSH signing key for the authenticated user

        .DESCRIPTION
        Gets extended details for an SSH signing key.
        You must authenticate with Basic Authentication, or you must authenticate with OAuth with at least `read:ssh_signing_key` scope. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/)."

        .EXAMPLE
        Get-GitHubUserMySigningKeyById -ID '1234567'

        Gets the SSH signing key with the ID '1234567' for the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/ssh-signing-keys#get-an-ssh-signing-key-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The unique identifier of the SSH signing key.
        [Parameter(
            Mandatory
        )]
        [Alias('ssh_signing_key_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/user/ssh_signing_keys/$ID"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/SSH-Signing-Keys/Get-GitHubUserMySigningKeyById.ps1] - Done"
#endregion - From private/Users/SSH-Signing-Keys/Get-GitHubUserMySigningKeyById.ps1
#region - From private/Users/SSH-Signing-Keys/Get-GitHubUserSigningKeyForUser.ps1
Write-Verbose "[$scriptName] - [private/Users/SSH-Signing-Keys/Get-GitHubUserSigningKeyForUser.ps1] - Importing"

filter Get-GitHubUserSigningKeyForUser {
    <#
        .SYNOPSIS
        List SSH signing keys for a user

        .DESCRIPTION
        List SSH signing keys for a user

        .EXAMPLE
        Get-GitHubUserSigningKeyForUser -Username 'octocat'

        Gets the SSH signing keys for the user 'octocat'.

        .NOTES
        https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-a-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'username'

    $inputObject = @{
        APIEndpoint = "/users/$Username/ssh_signing_keys"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/SSH-Signing-Keys/Get-GitHubUserSigningKeyForUser.ps1] - Done"
#endregion - From private/Users/SSH-Signing-Keys/Get-GitHubUserSigningKeyForUser.ps1

Write-Verbose "[$scriptName] - [private/Users/SSH-Signing-Keys] - Done"
#endregion - From private/Users/SSH-Signing-Keys

#region - From private/Users/Get-GitHubAllUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Get-GitHubAllUser.ps1] - Importing"

filter Get-GitHubAllUser {
    <#
        .SYNOPSIS
        List users

        .DESCRIPTION
        Lists all users, in the order that they signed up on GitHub. This list includes personal user accounts and organization accounts.

        Note: Pagination is powered exclusively by the `since` parameter. Use the [Link header](https://docs.github.com/rest/guides/using-pagination-in-the-rest-api#using-link-headers) to get the URL for the next page of users.

        .EXAMPLE
        Get-GitHubAllUser -Since 17722253

        Get a list of users, starting with the user 'MariusStorhaug'.

        .NOTES
        https://docs.github.com/rest/users/users#list-users
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # A user ID. Only return users with an ID greater than this ID.
        [Parameter()]
        [int] $Since = 0,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/users"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Get-GitHubAllUser.ps1] - Done"
#endregion - From private/Users/Get-GitHubAllUser.ps1
#region - From private/Users/Get-GitHubMyUser.ps1
Write-Verbose "[$scriptName] - [private/Users/Get-GitHubMyUser.ps1] - Importing"

filter Get-GitHubMyUser {
    <#
        .SYNOPSIS
        Get the authenticated user

        .DESCRIPTION
        If the authenticated user is authenticated with an OAuth token with the `user` scope, then the response lists public and private profile information.
        If the authenticated user is authenticated through OAuth without the `user` scope, then the response lists only public profile information.

        .EXAMPLE
        Get-GitHubMyUser

        Get the authenticated user

        .NOTES
        https://docs.github.com/rest/users/users#get-the-authenticated-user
    #>

    [OutputType([pscustomobject])]
    [Alias('Get-GitHubContext')]
    [CmdletBinding()]
    param ()

    $inputObject = @{
        APIEndpoint = '/user'
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Get-GitHubMyUser.ps1] - Done"
#endregion - From private/Users/Get-GitHubMyUser.ps1
#region - From private/Users/Get-GitHubUserByName.ps1
Write-Verbose "[$scriptName] - [private/Users/Get-GitHubUserByName.ps1] - Importing"

filter Get-GitHubUserByName {
    <#
        .SYNOPSIS
        Get a user

        .DESCRIPTION
        Provides publicly available information about someone with a GitHub account.
        GitHub Apps with the `Plan` user permission can use this endpoint to retrieve information about a user's GitHub plan. The GitHub App must be authenticated as a user. See "[Identifying and authorizing users for GitHub Apps](https://docs.github.com/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps/)" for details about authentication. For an example response, see 'Response with GitHub plan information' below"
        The `email` key in the following response is the publicly visible email address from your GitHub [profile page](https://github.com/settings/profile). When setting up your profile, you can select a primary email address to be ΓǣpublicΓǥ which provides an email entry for this endpoint. If you do not set a public email address for `email`, then it will have a value of `null`. You only see publicly visible email addresses when authenticated with GitHub. For more information, see [Authentication](https://docs.github.com/rest/overview/resources-in-the-rest-api#authentication).
        The Emails API enables you to list all of your email addresses, and toggle a primary email to be visible publicly. For more information, see "[Emails API](https://docs.github.com/rest/users/emails)".

        .EXAMPLE
        Get-GitHubUserByName -Username 'octocat'

        Get the 'octocat' user.

        .NOTES
        https://docs.github.com/rest/users/users#get-a-user
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/users/$Username"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [private/Users/Get-GitHubUserByName.ps1] - Done"
#endregion - From private/Users/Get-GitHubUserByName.ps1

Write-Verbose "[$scriptName] - [private/Users] - Done"
#endregion - From private/Users

#region - From private/Utilities
Write-Verbose "[$scriptName] - [private/Utilities] - Processing folder"

#region - From private/Utilities/Casing
Write-Verbose "[$scriptName] - [private/Utilities/Casing] - Processing folder"

#region - From private/Utilities/Casing/Convert-StringCasingStyle.ps1
Write-Verbose "[$scriptName] - [private/Utilities/Casing/Convert-StringCasingStyle.ps1] - Importing"

filter Convert-StringCasingStyle {
    <#
    .SYNOPSIS
    Convert a string to a different casing style

    .DESCRIPTION
    This function converts a string to a different casing style.

    .EXAMPLE
    'thisIsCamelCase' | Convert-StringCasingStyle -To 'snake_case'

    Convert the string 'thisIsCamelCase' to 'this_is_camel_case'

    .EXAMPLE
    'thisIsCamelCase' | Convert-StringCasingStyle -To 'UPPER_SNAKE_CASE'

    Convert the string 'thisIsCamelCase' to 'THIS_IS_CAMEL_CASE'

    .EXAMPLE
    'thisIsCamelCase' | Convert-StringCasingStyle -To 'kebab-case'

    .NOTES
    General notes
    #>

    [OutputType([string])]
    [CmdletBinding()]
    param (
        # The string to convert
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [string] $Text,

        # The casing style to convert the string to
        [Parameter(Mandatory)]
        [ValidateSet(
            'lowercase',
            'UPPERCASE',
            'Title Case',
            'Sentencecase',
            'PascalCase',
            'camelCase',
            'kebab-case',
            'UPPER-KEBAB-CASE',
            'snake_case',
            'UPPER_SNAKE_CASE'
        )]
        [string] $To
    )

    $currentStyle = Get-StringCasingStyle -Text $Text

    $words = Split-StringByCasingStyle -Text $Text -By $currentStyle

    # Convert the words into the target style
    switch ($To) {
        'lowercase' { ($words -join '').toLower() }
        'UPPERCASE' { ($words -join '').toUpper() }
        'Title Case' { ($words | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1).ToLower() }) -join ' ' }
        'Sentencecase' { $words -join '' | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1).ToLower() } }
        'kebab-case' { ($words -join '-').ToLower() }
        'snake_case' { ($words -join '_').ToLower() }
        'PascalCase' { ($words | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1).ToLower() }) -join '' }
        'camelCase' { $words[0].toLower() + (($words | Select-Object -Skip 1 | ForEach-Object { $_.Substring(0, 1).ToUpper() + $_.Substring(1) }) -join '') }
        'UPPER_SNAKE_CASE' { ($words -join '_').toUpper() }
        'UPPER-KEBAB-CASE' { ($words -join '-').toUpper() }
    }
}

Write-Verbose "[$scriptName] - [private/Utilities/Casing/Convert-StringCasingStyle.ps1] - Done"
#endregion - From private/Utilities/Casing/Convert-StringCasingStyle.ps1
#region - From private/Utilities/Casing/Get-StringCasingStyle.ps1
Write-Verbose "[$scriptName] - [private/Utilities/Casing/Get-StringCasingStyle.ps1] - Importing"

filter Get-StringCasingStyle {
    <#
        .SYNOPSIS
        Detects the casing style of a string

        .DESCRIPTION
        This function detects the casing style of a string.

        .EXAMPLE
        'testtesttest' | Get-StringCasingStyle

        lowercase

        .EXAMPLE
        'TESTTESTTEST' | Get-StringCasingStyle

        UPPERCASE

        .EXAMPLE
        'Testtesttest' | Get-StringCasingStyle

        Sentencecase

        .EXAMPLE
        'TestTestTest' | Get-StringCasingStyle

        PascalCase

        .EXAMPLE
        'testTestTest' | Get-StringCasingStyle

        camelCase

        .EXAMPLE
        'test-test-test' | Get-StringCasingStyle

        kebab-case

        .EXAMPLE
        'TEST-TEST-TEST' | Get-StringCasingStyle

        UPPER-KEBAB-CASE

        .EXAMPLE
        'test_test_test' | Get-StringCasingStyle

        snake_case

        .EXAMPLE
        'TEST_TEST_TEST' | Get-StringCasingStyle

        UPPER_SNAKE_CASE

        .EXAMPLE
        'Test_teSt-Test' | Get-StringCasingStyle

        Unknown
    #>

    [OutputType([string])]
    [CmdletBinding()]
    param (
        # The string to check the casing style of
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [ValidateNotNullOrEmpty()]
        [string] $Text
    )

    $style = if ([regex]::Match($Text, '^[a-z][a-z0-9]*$').Success) {
        'lowercase'
    } elseif ([regex]::Match($Text, '^[A-Z][A-Z0-9]*$').Success) {
        'UPPERCASE'
    } elseif ([regex]::Match($Text, '^[A-Z][a-z0-9]*$').Success) {
        'Sentencecase'
    } elseif ([regex]::Match($Text, '^([A-Z][a-z]*)(\s+[A-Z][a-z]*)+$').Success) {
        'Title Case'
    } elseif ([regex]::Match($Text, '^[A-Z][a-z0-9]*([A-Z][a-z0-9]*)+$').Success) {
        'PascalCase'
    } elseif ([regex]::Match($Text, '^[a-z][a-z0-9]*([A-Z][a-z0-9]*)+$').Success) {
        'camelCase'
    } elseif ([regex]::Match($Text, '^[a-z][a-z0-9]*(-[a-z0-9]+)+$').Success) {
        'kebab-case'
    } elseif ([regex]::Match($Text, '^[A-Z][A-Z0-9]*(-[A-Z0-9]+)+$').Success) {
        'UPPER-KEBAB-CASE'
    } elseif ([regex]::Match($Text, '^[a-z][a-z0-9]*(_[a-z0-9]+)+$').Success) {
        'snake_case'
    } elseif ([regex]::Match($Text, '^[A-Z][A-Z0-9]*(_[A-Z0-9]+)+$').Success) {
        'UPPER_SNAKE_CASE'
    } else {
        'Unknown'
    }

    Write-Verbose "Detected casing style: [$style]"
    $style

}

Write-Verbose "[$scriptName] - [private/Utilities/Casing/Get-StringCasingStyle.ps1] - Done"
#endregion - From private/Utilities/Casing/Get-StringCasingStyle.ps1
#region - From private/Utilities/Casing/Split-StringByCasingStyle.ps1
Write-Verbose "[$scriptName] - [private/Utilities/Casing/Split-StringByCasingStyle.ps1] - Importing"

filter Split-StringByCasingStyle {
    <#
        .SYNOPSIS
        Splits a kebab-case string into an array of words

        .DESCRIPTION
        This function splits a kebab-case string into an array of words.

        .EXAMPLE
        Split-StringByCasingStyle -Text 'this-is-a-kebab-case-string' -By kebab-case

        this
        is
        a
        kebab
        case
        string

        .EXAMPLE
        Split-StringByCasingStyle -Text 'this_is_a_kebab_case_string' -By 'snake_case'

        this
        is
        a
        kebab
        case
        string

        .EXAMPLE
        Split-StringByCasingStyle -Text 'ThisIsAPascalCaseString' -By 'PascalCase'

        This
        Is
        A
        Pascal
        Case
        String

        .EXAMPLE
        Split-StringByCasingStyle -Text 'thisIsACamelCaseString' -By 'camelCase'

        this
        Is
        A
        Camel
        Case
        String

        .EXAMPLE
        Split-StringByCasingStyle -Text 'this_is_a-CamelCaseString' -By kebab-case | Split-StringByCasingStyle -By snake_case

        this_is_a
        camelcasestring


    #>

    [OutputType([string[]])]
    [CmdletBinding()]
    param (
        # The string to split
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [string] $Text,

        # The casing style to split the string by
        [Parameter()]
        [ValidateSet(
            'lowercase',
            'UPPERCASE',
            'Sentencecase',
            'Title Case',
            'PascalCase',
            'camelCase',
            'kebab-case',
            'UPPER-KEBAB-CASE',
            'snake_case',
            'UPPER_SNAKE_CASE'
        )]
        [string] $By
    )

    $styles = $PSBoundParameters | Where-Object { $_.Value -eq $true } | Select-Object -ExpandProperty Name

    Write-Verbose "Splitting string [$Text] by casing style [$($styles -join ', ' )]"
    $splitText = switch ($By) {
        'PascalCase' { [regex]::Matches($Text, '([A-Z][a-z]*)').Value; break }
        'camelCase' { [regex]::Matches($Text, '([A-Z][a-z]*)|^[a-z]+').Value; break }
        'kebab-case' { $Text -split '-'; break }
        'UPPER-KEBAB-CASE' { $Text -split '-'; break }
        'snake_case' { $Text -split '_'; break }
        'UPPER_SNAKE_CASE' { $Text -split '_'; break }
        default {
            $Text -split ' '
        }
    }

    Write-Verbose "Result: [$($splitText -join ', ')]"
    $splitText
}

Write-Verbose "[$scriptName] - [private/Utilities/Casing/Split-StringByCasingStyle.ps1] - Done"
#endregion - From private/Utilities/Casing/Split-StringByCasingStyle.ps1

Write-Verbose "[$scriptName] - [private/Utilities/Casing] - Done"
#endregion - From private/Utilities/Casing

#region - From private/Utilities/Hashtable
Write-Verbose "[$scriptName] - [private/Utilities/Hashtable] - Processing folder"

#region - From private/Utilities/Hashtable/ConvertFrom-HashTable.ps1
Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/ConvertFrom-HashTable.ps1] - Importing"

filter ConvertFrom-HashTable {
    <#
        .SYNOPSIS
        Converts a hashtable to a pscustomobject

        .DESCRIPTION
        This function converts a hashtable to a pscustomobject.

        .EXAMPLE
        $object = @{a = 1;b = 2;c = 3}
        $object | ConvertFrom-HashTable | Format-Table

        a b c
        - - -
        1 2 3

        Converts the hashtable to a pscustomobject and displays it in a table.

        .EXAMPLE
        $object = @{a = 1;b = 2;c = 3}
        $object | ConvertFrom-Dictionary | ConvertTo-Json

        {
            "a": 1,
            "b": 2,
            "c": 3
        }

        Converts the hashtable to a pscustomobject and then to JSON.
        Using the alias 'ConvertFrom-Dictionary' instead of 'ConvertFrom-HashTable'.
    #>

    [OutputType([pscustomobject])]
    [Alias('ConvertFrom-Dictionary')]
    [CmdletBinding()]
    param (
        # The hashtable to be converted. The input takes any type of dictionary. The original dictionary is not modified.
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [object]$InputObject
    )
    $InputObject | ConvertTo-Json -Depth 100 | ConvertFrom-Json
}

Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/ConvertFrom-HashTable.ps1] - Done"
#endregion - From private/Utilities/Hashtable/ConvertFrom-HashTable.ps1
#region - From private/Utilities/Hashtable/ConvertTo-HashTable.ps1
Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/ConvertTo-HashTable.ps1] - Importing"

filter ConvertTo-HashTable {
    <#
        .SYNOPSIS
        Converts an object to a hashtable

        .DESCRIPTION
        This function converts an object to a hashtable.

        .EXAMPLE
        $object = [pscustomobject]@{a = 1;b = 2;c = 3}
        $object | ConvertTo-HashTable | Format-Table

        Name Value
        ---- -----
        a 1
        b 2
        c 3

        Converts the object to a hashtable and displays it in a table.

        .EXAMPLE
        $object = [pscustomobject]@{a = 1;b = 2;c = 3}
        $object | ConvertTo-Dictionary | ConvertTo-Json

        {
            "a": 1,
            "b": 2,
            "c": 3
        }

        Converts the object to a hashtable and then to JSON.
        Using the alias 'ConvertTo-Dictionary' instead of 'ConvertTo-HashTable'.
    #>

    [OutputType([hashtable])]
    [Alias('ConvertTo-Dictionary')]
    [CmdletBinding()]
    param (
        # The object to be converted. The input takes any type of object. The original object is not modified.
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [object]$InputObject,

        # The casing style of the hashtable keys.
        [Parameter()]
        [ValidateSet(
            'lowercase',
            'UPPERCASE',
            'Title Case',
            'PascalCase',
            'camelCase',
            'kebab-case',
            'UPPER-KEBAB-CASE',
            'snake_case',
            'UPPER_SNAKE_CASE'
        )]
        [string]$NameCasingStyle
    )
    [hashtable]$hashtable = @{}

    foreach ($item in $InputObject.PSObject.Properties) {
        $name = $NameCasingStyle ? ($item.Name | Convert-StringCasingStyle -To $NameCasingStyle) : $item.Name
        $hashtable[$name] = $item.Value
    }
    $hashtable
}

Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/ConvertTo-HashTable.ps1] - Done"
#endregion - From private/Utilities/Hashtable/ConvertTo-HashTable.ps1
#region - From private/Utilities/Hashtable/Join-Object.ps1
Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/Join-Object.ps1] - Importing"

filter Join-Object {
    <#
        .SYNOPSIS
        Merges two or more objects into a single object

        .DESCRIPTION
        Merges two or more objects into a single object. The first object is the main object, and the remaining objects are overrides. The overrides are applied in order, so the last object in the list will override any previous values.

        .EXAMPLE
        $main = [pscustomobject]@{a = 1; b = 2; c = 3}
        $overrides = [pscustomobject]@{a = 4; b = 5; d = 6}
        $overrides2 = [pscustomobject]@{a = 7; b = 8; e = 9}
        Join-Object -Main $main -Overrides $overrides, $overrides2

        a b c d e
        - - - - -
        7 8 3 6 9

        Merges the three objects into a single object. The values from the last object override the values from the previous objects.

        .EXAMPLE
        $main = @{a = 1;b = 2}
        $overrides = @{a = 3;c = 4}
        Merge-Object -Main $main -Overrides $overrides -AsHashtable

        Name Value
        ---- -----
        a 3
        b 2
        c 4

        Merges the two hashtables into a single hashtable. The values from the last hashtable override the values from the previous hashtables.
        Using the alias 'Merge-Object' instead of 'Join-Object'.

        .EXAMPLE
        $main = @{a = 1;b = 1;c = 1}
        $overrides = @{b = 2;d = 2}
        $overrides2 = @{c = 3;e = 3}
        $main | Join-Object -Overrides $overrides, $overrides2 | Format-Table

        a b c d e
        - - - - -
        1 2 3 2 3

        Merges the three hashtables into a single hashtable. The values from the last hashtable override the values from the previous hashtables.
        Using the pipeline to pass the main object instead of the -Main parameter.
    #>

    [OutputType([pscustomobject])]
    [OutputType(ParameterSetName = 'AsHashTable', [hashtable])]
    [Alias('Merge-Object')]
    [CmdletBinding(DefaultParameterSetName = '__DefaultSet')]
    param (
        # The main object to merge into. This object will be cloned, so the original object will not be modified.
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [object] $Main,

        # The objects to merge into the main object
        [Parameter(Mandatory)]
        [object[]] $Overrides,

        # Return the result as a hashtable instead of a pscustomobject
        [Parameter(
            Mandatory,
            ParameterSetName = 'AsHashTable'
        )]
        [switch] $AsHashtable
    )

    if ($Main -isnot [hashtable]) {
        $Main = $Main | ConvertTo-HashTable
    }
    $hashtable = $Main.clone()

    foreach ($Override in $Overrides) {
        if ($Override -isnot [hashtable]) {
            $Override = $Override | ConvertTo-HashTable
        }

        $Override.Keys | ForEach-Object {
            $hashtable[$_] = $Override[$_]
        }
    }

    if ($AsHashtable) {
        return $hashtable
    }

    $hashtable | ConvertFrom-HashTable
}

Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/Join-Object.ps1] - Done"
#endregion - From private/Utilities/Hashtable/Join-Object.ps1
#region - From private/Utilities/Hashtable/Remove-HashTableEntries.ps1
Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/Remove-HashTableEntries.ps1] - Importing"

filter Remove-HashtableEntries {
    [OutputType([void])]
    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [hashtable] $Hashtable,

        [Parameter()]
        [switch] $NullOrEmptyValues,

        [Parameter()]
        [string[]] $RemoveTypes,

        [Parameter()]
        [string[]] $RemoveNames,

        [Parameter()]
        [string[]] $KeepTypes,

        [Parameter()]
        [string[]] $KeepNames

    )
    if ($NullOrEmptyValues) {
        Write-Verbose 'Remove keys with null or empty values'
        ($Hashtable.GetEnumerator() | Where-Object { -not $_.Value }) | ForEach-Object {
            Write-Verbose " - [$($_.Name)] - Value: [$($_.Value)] - Remove"
            $Hashtable.Remove($_.Name)
        }
    }
    if ($RemoveTypes) {
        Write-Verbose "Remove keys of type: [$RemoveTypes]"
        ($Hashtable.GetEnumerator() | Where-Object { ($_.Value.GetType().Name -in $RemoveTypes) }) | ForEach-Object {
            Write-Verbose " - [$($_.Name)] - Type: [$($_.Value.GetType().Name)] - Remove"
            $Hashtable.Remove($_.Name)
        }
    }
    if ($KeepTypes) {
        Write-Verbose "Remove keys NOT of type: [$KeepTypes]"
        ($Hashtable.GetEnumerator() | Where-Object { ($_.Value.GetType().Name -notin $KeepTypes) }) | ForEach-Object {
            Write-Verbose " - [$($_.Name)] - Type: [$($_.Value.GetType().Name)] - Remove"
            $Hashtable.Remove($_.Name)
        }
    }
    if ($RemoveNames) {
        Write-Verbose "Remove keys named: [$RemoveNames]"
        ($Hashtable.GetEnumerator() | Where-Object { $_.Name -in $RemoveNames }) | ForEach-Object {
            Write-Verbose " - [$($_.Name)] - Remove"
            $Hashtable.Remove($_.Name)
        }
    }
    if ($KeepNames) {
        Write-Verbose "Remove keys NOT named: [$KeepNames]"
        ($Hashtable.GetEnumerator() | Where-Object { $_.Name -notin $KeepNames }) | ForEach-Object {
            Write-Verbose " - [$($_.Name)] - Remove"
            $Hashtable.Remove($_.Name)
        }
    }
}

Write-Verbose "[$scriptName] - [private/Utilities/Hashtable/Remove-HashTableEntries.ps1] - Done"
#endregion - From private/Utilities/Hashtable/Remove-HashTableEntries.ps1

Write-Verbose "[$scriptName] - [private/Utilities/Hashtable] - Done"
#endregion - From private/Utilities/Hashtable

#region - From private/Utilities/Web
Write-Verbose "[$scriptName] - [private/Utilities/Web] - Processing folder"

#region - From private/Utilities/Web/ConvertTo-QueryString.ps1
Write-Verbose "[$scriptName] - [private/Utilities/Web/ConvertTo-QueryString.ps1] - Importing"

filter ConvertTo-QueryString {
    <#
        .SYNOPSIS
        Convert an object to a query string

        .DESCRIPTION
        Convert an object to a query string

        .EXAMPLE
        ConvertTo-QueryString -InputObject @{a=1;b=2}

        ?a=1&b=2

        .EXAMPLE
        ConvertTo-QueryString -InputObject @{a='this is value of a';b='valueOfB'}

        ?a=this%20is%20value%20of%20a&b=valueOfB

        .EXAMPLE
        ConvertTo-QueryString -InputObject @{a='this is value of a';b='valueOfB'} -AsURLEncoded

        ?a=this+is+value+of+a&b=valueOfB
    #>

    [OutputType([string])]
    [CmdletBinding()]
    param(
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [object] $InputObject,

        [Parameter()]
        [switch] $AsURLEncoded
    )

    if ($InputObject -isnot [hashtable]) {
        $InputObject = $InputObject | ConvertTo-HashTable
    }

    $parameters = if ($AsURLEncoded) {
        ($InputObject.GetEnumerator() | ForEach-Object { "$([System.Web.HttpUtility]::UrlEncode($_.Key))=$([System.Web.HttpUtility]::UrlEncode($_.Value))" }) -join '&'
    } else {
        ($InputObject.GetEnumerator() | ForEach-Object { "$([System.Uri]::EscapeDataString($_.Key))=$([System.Uri]::EscapeDataString($_.Value))" }) -join '&'
    }

    if ($parameters) {
        '?' + $parameters
    }
}

Write-Verbose "[$scriptName] - [private/Utilities/Web/ConvertTo-QueryString.ps1] - Done"
#endregion - From private/Utilities/Web/ConvertTo-QueryString.ps1

Write-Verbose "[$scriptName] - [private/Utilities/Web] - Done"
#endregion - From private/Utilities/Web


Write-Verbose "[$scriptName] - [private/Utilities] - Done"
#endregion - From private/Utilities


Write-Verbose "[$scriptName] - [private] - Done"
#endregion - From private

#region - From public
Write-Verbose "[$scriptName] - [public] - Processing folder"

#region - From public/Actions
Write-Verbose "[$scriptName] - [public/Actions] - Processing folder"

#region - From public/Actions/Disable-GitHubWorkflow.ps1
Write-Verbose "[$scriptName] - [public/Actions/Disable-GitHubWorkflow.ps1] - Importing"

filter Disable-GitHubWorkflow {
    <#
        .NOTES
        https://docs.github.com/rest/reference/actions#disable-a-workflow
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string[]] $ID
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/disable"
        Method      = 'PUT'
    }

    Invoke-GitHubAPI @inputObject | Out-Null

}

Write-Verbose "[$scriptName] - [public/Actions/Disable-GitHubWorkflow.ps1] - Done"
#endregion - From public/Actions/Disable-GitHubWorkflow.ps1
#region - From public/Actions/Enable-GitHubWorkflow.ps1
Write-Verbose "[$scriptName] - [public/Actions/Enable-GitHubWorkflow.ps1] - Importing"

filter Enable-GitHubWorkflow {
    <#
        .NOTES
        https://docs.github.com/rest/reference/actions#enable-a-workflow
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string[]] $ID
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/enable"
        Method      = 'PUT'
    }

    Invoke-GitHubAPI @inputObject | Out-Null

}

Write-Verbose "[$scriptName] - [public/Actions/Enable-GitHubWorkflow.ps1] - Done"
#endregion - From public/Actions/Enable-GitHubWorkflow.ps1
#region - From public/Actions/Get-GitHubWorkflow.ps1
Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflow.ps1] - Importing"

filter Get-GitHubWorkflow {
    <#
        .SYNOPSIS
        Lists the workflows in a repository.

        .DESCRIPTION
        Anyone with read access to the repository can use this endpoint.
        If the repository is private you must use an access token with the repo scope.
        GitHub Apps must have the actions:read permission to use this endpoint.

        .EXAMPLE
        Get-GitHubWorkflow -Owner 'octocat' -Repo 'hello-world'

        Gets all workflows in the 'octocat/hello-world' repository.

        .EXAMPLE
        Get-GitHubWorkflow -Owner 'octocat' -Repo 'hello-world' -Name 'hello-world.yml'

        Gets the 'hello-world.yml' workflow in the 'octocat/hello-world' repository.

        .NOTES
        https://docs.github.com/rest/actions/workflows?apiVersion=2022-11-28#list-repository-workflows
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByName')]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Parameter(ParameterSetName = 'ByName')]
        [string] $Name,

        [Parameter(ParameterSetName = 'ByID')]
        [string] $ID,

        [Parameter()]
        [int] $PerPage = 30
    )


    $body = @{
        per_page = $PerPage
    }

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/actions/workflows"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response.workflows

}

Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflow.ps1] - Done"
#endregion - From public/Actions/Get-GitHubWorkflow.ps1
#region - From public/Actions/Get-GitHubWorkflowRun.ps1
Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflowRun.ps1] - Importing"

filter Get-GitHubWorkflowRun {
    <#
        .NOTES
        https://docs.github.com/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-workflow
        https://docs.github.com/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-repository
    #>

    [CmdletBinding(DefaultParameterSetName = 'Repo')]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Parameter(ParameterSetName = 'ByName')]
        [string] $Name,

        [Parameter(ParameterSetName = 'ByID')]
        [string] $ID,

        [Parameter()]
        [int] $PerPage = 30
    )

    $body = @{
        per_page = $PerPage
    }

    if ($Name) {
        $ID = (Get-GitHubWorkflow -Owner $Owner -Repo $Repo -Name $Name).id
    }

    if ($ID) {
        $Uri = "/repos/$Owner/$Repo/actions/workflows/$ID/runs"
    } else {
        $Uri = "/repos/$Owner/$Repo/actions/runs"
    }

    $inputObject = @{
        APIEndpoint = $Uri
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response.workflow_runs

}

Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflowRun.ps1] - Done"
#endregion - From public/Actions/Get-GitHubWorkflowRun.ps1
#region - From public/Actions/Get-GitHubWorkflowUsage.ps1
Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflowUsage.ps1] - Importing"

filter Get-GitHubWorkflowUsage {
    <#
        .SYNOPSIS
        Short description

        .DESCRIPTION
        Long description

        .PARAMETER Owner
        Parameter description

        .PARAMETER Repo
        Parameter description

        .PARAMETER ID
        Parameter description

        .EXAMPLE
        An example

        .NOTES
        https://docs.github.com/rest/reference/actions#get-workflow-usage
    #>

    [CmdletBinding(
        DefaultParameterSetName = 'ByName'
    )]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string[]] $ID
    )

    $inputObject = @{
        Method      = 'GET'
        APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/timing"
    }

    (Invoke-GitHubAPI @inputObject).Response.billable

}

Write-Verbose "[$scriptName] - [public/Actions/Get-GitHubWorkflowUsage.ps1] - Done"
#endregion - From public/Actions/Get-GitHubWorkflowUsage.ps1
#region - From public/Actions/Remove-GitHubWorkflowRun.ps1
Write-Verbose "[$scriptName] - [public/Actions/Remove-GitHubWorkflowRun.ps1] - Importing"

filter Remove-GitHubWorkflowRun {
    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "repos/$Owner/$Repo/actions/runs/$ID"
        Method      = 'DELETE'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Actions/Remove-GitHubWorkflowRun.ps1] - Done"
#endregion - From public/Actions/Remove-GitHubWorkflowRun.ps1
#region - From public/Actions/Start-GitHubWorkflow.ps1
Write-Verbose "[$scriptName] - [public/Actions/Start-GitHubWorkflow.ps1] - Importing"

filter Start-GitHubWorkflow {
    <#
        .SYNOPSIS
        Start a workflow run using the workflow's ID.

        .DESCRIPTION
        Start a workflow run using the workflow's ID.

        .EXAMPLE
        Get-GitHubWorkflow | Where-Object name -NotLike '.*' | Start-GitHubWorkflow -Inputs @{
            staticValidation = $true
            deploymentValidation = $false
            removeDeployment = $true
            prerelease = $false
        }

        .NOTES
        # API Reference
        # https://docs.github.com/free-pro-team@latest/rest/actions/workflows?apiVersion=2022-11-28#create-a-workflow-dispatch-event
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Alias('workflow_id')]
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $ID,

        [Parameter(
            ValueFromPipelineByPropertyName
        )]
        [Alias('branch', 'tag')]
        [string] $Ref = 'main',

        [Parameter()]
        [hashtable] $Inputs = @{}
    )

    $body = @{
        ref    = $Ref
        inputs = $Inputs
    }

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/actions/workflows/$ID/dispatches"
        Method      = 'POST'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Actions/Start-GitHubWorkflow.ps1] - Done"
#endregion - From public/Actions/Start-GitHubWorkflow.ps1
#region - From public/Actions/Start-GitHubWorkflowReRun.ps1
Write-Verbose "[$scriptName] - [public/Actions/Start-GitHubWorkflowReRun.ps1] - Importing"

filter Start-GitHubWorkflowReRun {
    <#
        .SYNOPSIS
        Short description

        .DESCRIPTION
        Long description

        .PARAMETER Owner
        Parameter description

        .PARAMETER Repo
        Parameter description

        .PARAMETER ID
        Parameter description

        .EXAMPLE
        An example

        .NOTES
        https://docs.github.com/rest/reference/actions#re-run-a-workflow
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Alias('workflow_id')]
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $ID
    )

    $inputObject = @{
        Method      = 'POST'
        APIEndpoint = "/repos/$Owner/$Repo/actions/runs/$ID/rerun"
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Actions/Start-GitHubWorkflowReRun.ps1] - Done"
#endregion - From public/Actions/Start-GitHubWorkflowReRun.ps1
#region - From public/Actions/Stop-GitHubWorkflowRun.ps1
Write-Verbose "[$scriptName] - [public/Actions/Stop-GitHubWorkflowRun.ps1] - Importing"

filter Stop-GitHubWorkflowRun {
    <#
        .SYNOPSIS
        Short description

        .DESCRIPTION
        Long description

        .PARAMETER Owner
        Parameter description

        .PARAMETER Repo
        Parameter description

        .PARAMETER ID
        Parameter description

        .EXAMPLE
        An example

        .NOTES
        https://docs.github.com/rest/reference/actions#cancel-a-workflow-run
    #>

    [CmdletBinding()]
    [alias('Cancel-GitHubWorkflowRun')]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Alias('workflow_id')]
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $ID
    )


    $inputObject = @{
        Method      = 'POST'
        APIEndpoint = "/repos/$Owner/$Repo/actions/runs/$ID/cancel"
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Actions/Stop-GitHubWorkflowRun.ps1] - Done"
#endregion - From public/Actions/Stop-GitHubWorkflowRun.ps1

Write-Verbose "[$scriptName] - [public/Actions] - Done"
#endregion - From public/Actions

#region - From public/API
Write-Verbose "[$scriptName] - [public/API] - Processing folder"

#region - From public/API/Invoke-GitHubAPI.ps1
Write-Verbose "[$scriptName] - [public/API/Invoke-GitHubAPI.ps1] - Importing"

filter Invoke-GitHubAPI {
    <#
        .SYNOPSIS
        Calls the GitHub API using the provided parameters.

        .DESCRIPTION
        This function is a wrapper around Invoke-RestMethod tailored for calling GitHub's API.
        It automatically handles the endpoint URI construction, headers, and token authentication.

        .EXAMPLE
        Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET

        Gets all open pull requests for the specified repository.

        .EXAMPLE
        Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET -Body @{ state = 'open' }

        Gets all open pull requests for the specified repository, filtered by the 'state' parameter.

        .EXAMPLE
        Invoke-GitHubAPI -ApiEndpoint '/repos/user/repo/pulls' -Method GET -Body @{ state = 'open' } -Accept 'application/vnd.github.v3+json'

        Gets all open pull requests for the specified repository, filtered by the 'state' parameter, and using the specified 'Accept' header.
    #>

    [CmdletBinding(DefaultParameterSetName = 'ApiEndpoint')]
    param (
        # The HTTP method to be used for the API request. It can be one of the following: GET, POST, PUT, DELETE, or PATCH.
        [Parameter()]
        [Microsoft.PowerShell.Commands.WebRequestMethod] $Method = 'GET',

        # The base URI for the GitHub API. This is usually 'https://api.github.com', but can be adjusted if necessary.
        [Parameter(
            ParameterSetName = 'ApiEndpoint'
        )]
        [string] $ApiBaseUri = (Get-GitHubConfig -Name ApiBaseUri),

        # The specific endpoint for the API call, e.g., '/repos/user/repo/pulls'.
        [Parameter(
            Mandatory,
            ParameterSetName = 'ApiEndpoint'
        )]
        [string] $ApiEndpoint,

        # The body of the API request. This can be a hashtable or a string. If a hashtable is provided, it will be converted to JSON.
        [Parameter()]
        [Object] $Body,

        # The 'Accept' header for the API request. If not provided, the default will be used by GitHub's API.
        [Parameter()]
        [string] $Accept = 'application/vnd.github+json; charset=utf-8',

        # Specifies the HTTP version used for the request.
        [Parameter()]
        [version] $HttpVersion = '2.0',

        # Support Pagination Relation Links per RFC5988.
        [Parameter()]
        [bool] $FollowRelLink = $true,

        # The file path to be used for the API request. This is used for uploading files.
        [Parameter()]
        [string] $UploadFilePath,

        # The file path to be used for the API response. This is used for downloading files.
        [Parameter()]
        [string] $DownloadFilePath,

        # The full URI for the API request. This is used for custom API calls.
        [Parameter(
            Mandatory,
            ParameterSetName = 'Uri'
        )]
        [string] $URI,

        # The secure token used for authentication in the GitHub API. It should be stored as a SecureString to ensure it's kept safe in memory.
        [Parameter()]
        [SecureString] $AccessToken = (Get-GitHubConfig -Name AccessToken),

        # The 'Content-Type' header for the API request. The default is 'application/vnd.github+json'.
        [Parameter()]
        [string] $ContentType = 'application/vnd.github+json; charset=utf-8',

        # The GitHub API version to be used. By default, it pulls from a configuration script variable.
        [Parameter()]
        [string] $Version = (Get-GitHubConfig -Name ApiVersion)
    )

    if (Test-GitHubAccessTokenRefreshRequired) {
        Connect-GitHubAccount -Silent
        $AccessToken = (Get-GitHubConfig -Name AccessToken)
    }

    $functionName = $MyInvocation.MyCommand.Name

    $headers = @{
        Accept                 = $Accept
        'X-GitHub-Api-Version' = $Version
    }

    Remove-HashTableEntries -Hashtable $headers -NullOrEmptyValues

    if (-not $URI) {
        $URI = ("$ApiBaseUri/" -replace '/$', '') + ("/$ApiEndpoint" -replace '^/', '')
    }

    # $AccessTokenAsPlainText = ConvertFrom-SecureString $AccessToken -AsPlainText
    # # Swap out this by using the -Authentication Bearer -Token $AccessToken
    # switch -Regex ($AccessTokenAsPlainText) {
    # '^ghp_|^github_pat_' {
    # $headers.authorization = "token $AccessTokenAsPlainText"
    # }
    # '^ghu_|^gho_' {
    # $headers.authorization = "Bearer $AccessTokenAsPlainText"
    # }
    # default {
    # $tokenPrefix = $AccessTokenAsPlainText -replace '_.*$', '_*'
    # $errorMessage = "Unexpected AccessToken format: $tokenPrefix"
    # Write-Error $errorMessage
    # throw $errorMessage
    # }
    # }

    $APICall = @{
        Uri                     = $URI
        Method                  = $Method
        Headers                 = $Headers
        Authentication          = 'Bearer'
        Token                   = $AccessToken
        ContentType             = $ContentType
        HttpVersion             = $HttpVersion
        FollowRelLink           = $FollowRelLink
        StatusCodeVariable      = 'APICallStatusCode'
        ResponseHeadersVariable = 'APICallResponseHeaders'
        InFile                  = $UploadFilePath
        OutFile                 = $DownloadFilePath
    }

    $APICall | Remove-HashTableEntries -NullOrEmptyValues

    if ($Body) {
        # Use body to create the query string for certain situations
        if ($Method -eq 'GET') {
            $queryString = $Body | ConvertTo-QueryString
            $APICall.Uri = $APICall.Uri + $queryString
        } elseif ($Body -is [string]) {
            # Use body to create the form data
            $APICall.Body = $Body
        } else {
            $APICall.Body = $Body | ConvertTo-Json -Depth 100
        }
    }

    Invoke-RestMethod @APICall | ForEach-Object {
        $statusCode = $APICallStatusCode | ConvertTo-Json -Depth 100 | ConvertFrom-Json
        $responseHeaders = $APICallResponseHeaders | ConvertTo-Json -Depth 100 | ConvertFrom-Json

        Write-Verbose '----------------------------------'
        Write-Verbose "StatusCode: $statusCode"
        Write-Verbose '----------------------------------'
        Write-Verbose "Request: $($APICall | ConvertFrom-HashTable | Format-List | Out-String)"
        Write-Verbose '----------------------------------'
        Write-Verbose "ResponseHeaders: $($responseHeaders | Format-List | Out-String)"
        Write-Verbose '----------------------------------'

        [pscustomobject]@{
            Request         = $APICall
            Response        = $_
            StatusCode      = $statusCode
            ResponseHeaders = $responseHeaders
        }
    }
}

Write-Verbose "[$scriptName] - [public/API/Invoke-GitHubAPI.ps1] - Done"
#endregion - From public/API/Invoke-GitHubAPI.ps1

Write-Verbose "[$scriptName] - [public/API] - Done"
#endregion - From public/API

#region - From public/Auth
Write-Verbose "[$scriptName] - [public/Auth] - Processing folder"

#region - From public/Auth/Connect-GitHubAccount.ps1
Write-Verbose "[$scriptName] - [public/Auth/Connect-GitHubAccount.ps1] - Importing"

function Connect-GitHubAccount {
    <#
        .SYNOPSIS
        Connects to GitHub using a personal access token or device code login.

        .DESCRIPTION
        Connects to GitHub using a personal access token or device code login.

        For device flow / device code login:
        PowerShell requests device and user verification codes and gets the authorization URL where you will enter the user verification code.
        In GitHub you will be asked to enter a user verification code at https://github.com/login/device.
        PowerShell will keep polling GitHub for the user authentication status. Once you have authorized the device,
        the app will be able to make API calls with a new access token.

        .EXAMPLE
        Connect-GitHubAccount

        Connects to GitHub using a device flow login.
        If the user has already logged in, the access token will be refreshed.

        .EXAMPLE
        Connect-GitHubAccount -AccessToken
        ! Enter your personal access token: *************

        User gets prompted for the access token and stores it in the secret store.
        The token is used when connecting to GitHub.

        .EXAMPLE
        Connect-GitHubAccount -Mode 'OAuthApp' -Scope 'gist read:org repo workflow'

        Connects to GitHub using a device flow login and sets the scope of the access token.

        .NOTES
        https://docs.github.com/rest/overview/other-authentication-methods#authenticating-for-saml-sso
    #>

    [Alias('Connect-GHAccount')]
    [Alias('Connect-GitHub')]
    [Alias('Connect-GH')]
    [Alias('Login-GitHubAccount')]
    [Alias('Login-GHAccount')]
    [Alias('Login-GitHub')]
    [Alias('Login-GH')]
    [OutputType([void])]
    [CmdletBinding(DefaultParameterSetName = 'DeviceFlow')]
    param (
        # Choose between authentication methods, either OAuthApp or GitHubApp.
        # For more info about the types of authentication visit:
        # https://docs.github.com/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps
        [Parameter(ParameterSetName = 'DeviceFlow')]
        [ValidateSet('OAuthApp', 'GitHubApp')]
        [string] $Mode = 'GitHubApp',

        # The scope of the access token, when using OAuth authentication.
        # Provide the list of scopes as space-separated values.
        # For more information on scopes visit:
        # https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps
        [Parameter(ParameterSetName = 'DeviceFlow')]
        [string] $Scope = 'gist read:org repo workflow',

        # The personal access token to use for authentication.
        [Parameter(
            Mandatory,
            ParameterSetName = 'PAT'
        )]
        [Alias('Token')]
        [Alias('PAT')]
        [switch] $AccessToken,

        # Set the default owner to use in commands.
        [Parameter()]
        [Alias('Organization')]
        [Alias('Org')]
        [string] $Owner,

        # Set the default repository to use in commands.
        [Parameter()]
        [Alias('Repository')]
        [string] $Repo,

        # Suppresses the output of the function.
        [Parameter()]
        [Alias('Quiet')]
        [Alias('q')]
        [Alias('s')]
        [switch] $Silent
    )

    $envVars = Get-ChildItem -Path 'Env:'
    $systemToken = $envVars | Where-Object Name -In 'GH_TOKEN', 'GITHUB_TOKEN' | Select-Object -First 1
    $systemTokenPresent = $systemToken.count -gt 0
    $AuthType = $systemTokenPresent ? 'sPAT' : $PSCmdlet.ParameterSetName

    switch ($AuthType) {
        'DeviceFlow' {
            Write-Verbose 'Logging in using device flow...'
            $clientID = $script:Auth.$Mode.ClientID
            if ($Mode -ne (Get-GitHubConfig -Name DeviceFlowType -ErrorAction SilentlyContinue)) {
                Write-Verbose "Using $Mode authentication..."
                $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -Scope $Scope
            } else {
                $accessTokenValidity = [datetime](Get-GitHubConfig -Name 'AccessTokenExpirationDate') - (Get-Date)
                $accessTokenIsValid = $accessTokenValidity.Seconds -gt 0
                $hours = $accessTokenValidity.Hours.ToString().PadLeft(2, '0')
                $minutes = $accessTokenValidity.Minutes.ToString().PadLeft(2, '0')
                $seconds = $accessTokenValidity.Seconds.ToString().PadLeft(2, '0')
                $accessTokenValidityText = "$hours`:$minutes`:$seconds"
                if ($accessTokenIsValid) {
                    if ($accessTokenValidity.TotalHours -gt $script:Auth.AccessTokenGracePeriodInHours) {
                        if (-not $Silent) {
                            Write-Host '✓ ' -ForegroundColor Green -NoNewline
                            Write-Host "Access token is still valid for $accessTokenValidityText ..."
                        }
                        break
                    } else {
                        if (-not $Silent) {
                            Write-Host 'âš  ' -ForegroundColor Yellow -NoNewline
                            Write-Host "Access token remaining validity $accessTokenValidityText. Refreshing access token..."
                        }
                        $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -RefreshToken (Get-GitHubConfig -Name RefreshToken)
                    }
                } else {
                    $refreshTokenValidity = [datetime](Get-GitHubConfig -Name 'RefreshTokenExpirationDate') - (Get-Date)
                    $refreshTokenIsValid = $refreshTokenValidity.Seconds -gt 0
                    if ($refreshTokenIsValid) {
                        if (-not $Silent) {
                            Write-Host 'âš  ' -ForegroundColor Yellow -NoNewline
                            Write-Host 'Access token expired. Refreshing access token...'
                        }
                        $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -RefreshToken (Get-GitHubConfig -Name RefreshToken)
                    } else {
                        Write-Verbose "Using $Mode authentication..."
                        $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $clientID -Scope $Scope
                    }
                }
            }
            Reset-GitHubConfig -Scope 'Auth'
            switch ($Mode) {
                'GitHubApp' {
                    $settings = @{
                        AccessToken                = ConvertTo-SecureString -AsPlainText $tokenResponse.access_token
                        AccessTokenExpirationDate  = (Get-Date).AddSeconds($tokenResponse.expires_in)
                        AccessTokenType            = $tokenResponse.access_token -replace '_.*$', '_*'
                        ApiBaseUri                 = 'https://api.github.com'
                        ApiVersion                 = '2022-11-28'
                        AuthType                   = $AuthType
                        DeviceFlowType             = $Mode
                        RefreshToken               = ConvertTo-SecureString -AsPlainText $tokenResponse.refresh_token
                        RefreshTokenExpirationDate = (Get-Date).AddSeconds($tokenResponse.refresh_token_expires_in)
                        Scope                      = $tokenResponse.scope
                    }
                }
                'OAuthApp' {
                    $settings = @{
                        AccessToken     = ConvertTo-SecureString -AsPlainText $tokenResponse.access_token
                        AccessTokenType = $tokenResponse.access_token -replace '_.*$', '_*'
                        ApiBaseUri      = 'https://api.github.com'
                        ApiVersion      = '2022-11-28'
                        AuthType        = $AuthType
                        DeviceFlowType  = $Mode
                        Scope           = $tokenResponse.scope
                    }
                }
            }
            Set-GitHubConfig @settings
            break
        }
        'PAT' {
            Write-Verbose 'Logging in using personal access token...'
            Reset-GitHubConfig -Scope 'Auth'
            Write-Host '! ' -ForegroundColor DarkYellow -NoNewline
            Start-Process 'https://github.com/settings/tokens'
            $accessTokenValue = Read-Host -Prompt 'Enter your personal access token' -AsSecureString
            $accessTokenType = (ConvertFrom-SecureString $accessTokenValue -AsPlainText) -replace '_.*$', '_*'
            if ($accessTokenType -notmatch '^ghp_|^github_pat_') {
                Write-Warning 'âš  ' -ForegroundColor Yellow -NoNewline
                Write-Warning "Unexpected access token format: $accessTokenType"
            }
            $settings = @{
                AccessToken     = $accessTokenValue
                AccessTokenType = $accessTokenType
                ApiBaseUri      = 'https://api.github.com'
                ApiVersion      = '2022-11-28'
                AuthType        = $AuthType
            }
            Set-GitHubConfig @settings
            break
        }
        'sPAT' {
            Write-Verbose 'Logging in using system access token...'
            Reset-GitHubConfig -Scope 'Auth'
            $prefix = $systemToken.Value -replace '_.*$', '_*'
            $settings = @{
                AccessToken     = ConvertTo-SecureString -AsPlainText $systemToken.Value
                AccessTokenType = $prefix
                ApiBaseUri      = 'https://api.github.com'
                ApiVersion      = '2022-11-28'
                AuthType        = 'sPAT'
            }
            Set-GitHubConfig @settings
        }
    }

    if ($AuthType -ne 'sPAT') {
        $user = Get-GitHubUser
        $username = $user.login
        Set-GitHubConfig -UserName $username
    } else {
        $username = 'system'
    }

    if (-not $Silent) {
        Write-Host '✓ ' -ForegroundColor Green -NoNewline
        Write-Host "Logged in as $username!"
    }

    $systemRepo = $envVars | Where-Object Name -EQ 'GITHUB_REPOSITORY'
    $systemRepoPresent = $systemRepo.count -gt 0

    if ($Owner) {
        Set-GitHubConfig -Owner $Owner
    } elseif ($systemRepoPresent) {
        $owner = $systemRepo.Value.Split('/')[0]
        Set-GitHubConfig -Owner $owner
    }

    if ($Repo) {
        Set-GitHubConfig -Repo $Repo
    } elseif ($systemRepoPresent) {
        $repo = $systemRepo.Value.Split('/')[-1]
        Set-GitHubConfig -Repo $repo
    }
}

Write-Verbose "[$scriptName] - [public/Auth/Connect-GitHubAccount.ps1] - Done"
#endregion - From public/Auth/Connect-GitHubAccount.ps1
#region - From public/Auth/Disconnect-GitHubAccount.ps1
Write-Verbose "[$scriptName] - [public/Auth/Disconnect-GitHubAccount.ps1] - Importing"

function Disconnect-GitHubAccount {
    <#
        .SYNOPSIS
        Disconnects from GitHub and removes the current GitHub configuration.

        .DESCRIPTION
        Disconnects from GitHub and removes the current GitHub configuration.

        .EXAMPLE
        Disconnect-GitHubAccount

        Disconnects from GitHub and removes the current GitHub configuration.
    #>

    [Alias('Disconnect-GHAccount')]
    [Alias('Disconnect-GitHub')]
    [Alias('Disconnect-GH')]
    [Alias('Logout-GitHubAccount')]
    [Alias('Logout-GHAccount')]
    [Alias('Logout-GitHub')]
    [Alias('Logout-GH')]
    [Alias('Logoff-GitHubAccount')]
    [Alias('Logoff-GHAccount')]
    [Alias('Logoff-GitHub')]
    [Alias('Logoff-GH')]
    [OutputType([void])]
    [CmdletBinding()]
    param ()

    Reset-GitHubConfig -Scope 'All'

    Write-Host '✓ ' -ForegroundColor Green -NoNewline
    Write-Host 'Logged out of GitHub!'
}

Write-Verbose "[$scriptName] - [public/Auth/Disconnect-GitHubAccount.ps1] - Done"
#endregion - From public/Auth/Disconnect-GitHubAccount.ps1

Write-Verbose "[$scriptName] - [public/Auth] - Done"
#endregion - From public/Auth

#region - From public/Branches
Write-Verbose "[$scriptName] - [public/Branches] - Processing folder"

#region - From public/Branches/Get-GitHubRepoBranch.ps1
Write-Verbose "[$scriptName] - [public/Branches/Get-GitHubRepoBranch.ps1] - Importing"

filter Get-GitHubRepoBranch {
    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo)
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/branches"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Branches/Get-GitHubRepoBranch.ps1] - Done"
#endregion - From public/Branches/Get-GitHubRepoBranch.ps1

Write-Verbose "[$scriptName] - [public/Branches] - Done"
#endregion - From public/Branches

#region - From public/Config
Write-Verbose "[$scriptName] - [public/Config] - Processing folder"

#region - From public/Config/Get-GitHubConfig.ps1
Write-Verbose "[$scriptName] - [public/Config/Get-GitHubConfig.ps1] - Importing"

function Get-GitHubConfig {
    <#
        .SYNOPSIS
        Get configuration value.

        .DESCRIPTION
        Get a named configuration value from the GitHub configuration file.

        .EXAMPLE
        Get-GitHubConfig -Name ApiBaseUri

        Get the current GitHub configuration for the ApiBaseUri.
    #>

    [Alias('Get-GHConfig')]
    [Alias('GGHC')]
    [OutputType([object])]
    [CmdletBinding()]
    param (
        # Choose a configuration name to get.
        [Parameter()]
        [ValidateSet(
            'AccessToken',
            'AccessTokenExpirationDate',
            'AccessTokenType',
            'ApiBaseUri',
            'ApiVersion',
            'AuthType',
            'DeviceFlowType',
            'Owner',
            'RefreshToken',
            'RefreshTokenExpirationDate',
            'Repo',
            'Scope',
            'UserName'
        )]
        [string] $Name
    )

    $prefix = $script:SecretVault.Prefix

    $RefreshTokenData = (Get-SecretInfo -Name "$prefix`RefreshToken").Metadata | ConvertFrom-HashTable | ConvertTo-HashTable
    $AccessTokenData = (Get-SecretInfo -Name "$prefix`AccessToken").Metadata | ConvertFrom-HashTable | ConvertTo-HashTable
    $metadata = Join-Object -Main $RefreshTokenData -Overrides $AccessTokenData -AsHashtable

    switch($Name) {
        'AccessToken' {
            Get-Secret -Name "$prefix`AccessToken"
        }
        'RefreshToken' {
            Get-Secret -Name "$prefix`RefreshToken"
        }
        default {
            if ($Name) {
                $metadata.$Name
            } else {
                $metadata.GetEnumerator() | Sort-Object -Property Name
            }
        }
    }
}

Write-Verbose "[$scriptName] - [public/Config/Get-GitHubConfig.ps1] - Done"
#endregion - From public/Config/Get-GitHubConfig.ps1
#region - From public/Config/Set-GitHubConfig.ps1
Write-Verbose "[$scriptName] - [public/Config/Set-GitHubConfig.ps1] - Importing"

function Set-GitHubConfig {
    <#
        .SYNOPSIS
        Set the GitHub configuration.

        .DESCRIPTION
        Set the GitHub configuration. Specific scopes can be set by using the parameters.

        .EXAMPLE
        Set-GitHubConfig -APIBaseURI 'https://api.github.com" -APIVersion '2022-11-28'

        Sets the App.API scope of the GitHub configuration.

        .EXAMPLE
        Set-GitHubConfig -Name "MyFavouriteRepo" -Value 'https://github.com/PSModule/GitHub'

        Sets a item called 'MyFavouriteRepo' in the GitHub configuration.
    #>

    [Alias('Set-GHConfig')]
    [CmdletBinding()]
    param (
        # Set the access token type.
        [Parameter()]
        [string] $AccessTokenType,

        # Set the access token.
        [Parameter()]
        [securestring] $AccessToken,

        # Set the access token expiration date.
        [Parameter()]
        [datetime] $AccessTokenExpirationDate,

        # Set the API Base URI.
        [Parameter()]
        [string] $ApiBaseUri,

        # Set the GitHub API Version.
        [Parameter()]
        [string] $ApiVersion,

        # Set the authentication type.
        [Parameter()]
        [string] $AuthType,

        # Set the device flow type.
        [Parameter()]
        [string] $DeviceFlowType,

        # Set the default for the Owner parameter.
        [Parameter()]
        [string] $Owner,

        # Set the refresh token.
        [Parameter()]
        [securestring] $RefreshToken,

        # Set the refresh token expiration date.
        [Parameter()]
        [datetime] $RefreshTokenExpirationDate,

        # Set the default for the Repo parameter.
        [Parameter()]
        [string] $Repo,

        # Set the scope.
        [Parameter()]
        [string] $Scope,

        # Set the GitHub username.
        [Parameter()]
        [string] $UserName
    )

    $prefix = $script:SecretVault.Prefix

    #region AccessToken
    $secretName = "$prefix`AccessToken"
    $removeKeys = 'AccessToken', 'RefreshToken', 'RefreshTokenExpirationDate'
    $keepTypes = 'String', 'Int', 'DateTime'

    # Get existing metadata if it exists
    $newSecretMetadata = @{}
    if (Get-SecretInfo -Name $secretName) {
        $secretGetInfoParam = @{
            Name  = $secretName
            Vault = $script:SecretVault.Name
        }
        $secretInfo = Get-SecretInfo @secretGetInfoParam
        Write-Verbose "$secretName - secretInfo : $($secretInfo | Out-String)"
        $secretMetadata = $secretInfo.Metadata | ConvertFrom-HashTable | ConvertTo-HashTable
        $newSecretMetadata = Join-Object -Main $newSecretMetadata -Overrides $secretMetadata -AsHashtable
    }

    # Get metadata updates from parameters and clean up unwanted data
    $updateSecretMetadata = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable
    Write-Verbose "updateSecretMetadata : $($updateSecretMetadata | Out-String)"
    Write-Verbose "updateSecretMetadataType : $($updateSecretMetadata.GetType())"
    Remove-HashTableEntries -Hashtable $updateSecretMetadata -KeepTypes $keepTypes -RemoveNames $removeKeys
    Write-Verbose "updateSecretMetadata : $($updateSecretMetadata | Out-String)"

    $newSecretMetadata = Join-Object -Main $newSecretMetadata -Overrides $updateSecretMetadata -AsHashtable
    Write-Verbose "newSecretMetadata : $($newSecretMetadata | Out-String)"
    Write-Verbose "newSecretMetadataType : $($newSecretMetadata.GetType())"

    if ($AccessToken) {
        $accessTokenSetParam = @{
            Name               = $secretName
            Vault              = $script:SecretVault.Name
            SecureStringSecret = $AccessToken
        }
        Set-Secret @accessTokenSetParam
    }

    if (Get-SecretInfo -Name $secretName) {
        $secretSetInfoParam = @{
            Name     = $secretName
            Vault    = $script:SecretVault.Name
            Metadata = $newSecretMetadata
        }
        Set-SecretInfo @secretSetInfoParam
    }
    #endregion AccessToken

    #region RefreshToken
    $secretName = "$prefix`RefreshToken"
    $removeKeys = 'AccessToken', 'RefreshToken', 'AccessTokenExpirationDate'

    # Get existing metadata if it exists
    $newSecretMetadata = @{}
    if (Get-SecretInfo -Name $secretName) {
        $secretGetInfoParam = @{
            Name  = $secretName
            Vault = $script:SecretVault.Name
        }
        $secretInfo = Get-SecretInfo @secretGetInfoParam
        Write-Verbose "$secretName - secretInfo : $($secretInfo | Out-String)"
        $secretMetadata = $secretInfo.Metadata | ConvertFrom-HashTable | ConvertTo-HashTable
        $newSecretMetadata = Join-Object -Main $newSecretMetadata -Overrides $secretMetadata -AsHashtable
    }

    # Get metadata updates from parameters and clean up unwanted data
    $updateSecretMetadata = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable
    Write-Verbose "updateSecretMetadata : $($updateSecretMetadata | Out-String)"
    Write-Verbose "updateSecretMetadataType : $($updateSecretMetadata.GetType())"
    Remove-HashTableEntries -Hashtable $updateSecretMetadata -KeepTypes $keepTypes -RemoveNames $removeKeys
    Write-Verbose "updateSecretMetadata : $($updateSecretMetadata | Out-String)"

    $newSecretMetadata = Join-Object -Main $newSecretMetadata -Overrides $updateSecretMetadata -AsHashtable
    Write-Verbose "newSecretMetadata : $($newSecretMetadata | Out-String)"
    Write-Verbose "newSecretMetadataType : $($newSecretMetadata.GetType())"

    if ($RefreshToken) {
        $refreshTokenSetParam = @{
            Name               = $secretName
            Vault              = $script:SecretVault.Name
            SecureStringSecret = $RefreshToken
        }
        Set-Secret @refreshTokenSetParam
    }

    if (Get-SecretInfo -Name $secretName) {
        $secretSetInfoParam = @{
            Name     = $secretName
            Vault    = $script:SecretVault.Name
            Metadata = $newSecretMetadata
        }
        Set-SecretInfo @secretSetInfoParam
    }
    #endregion AccessToken
}

Write-Verbose "[$scriptName] - [public/Config/Set-GitHubConfig.ps1] - Done"
#endregion - From public/Config/Set-GitHubConfig.ps1

Write-Verbose "[$scriptName] - [public/Config] - Done"
#endregion - From public/Config

#region - From public/Deployments
Write-Verbose "[$scriptName] - [public/Deployments] - Processing folder"

#region - From public/Deployments/Get-GitHubEnvironment.ps1
Write-Verbose "[$scriptName] - [public/Deployments/Get-GitHubEnvironment.ps1] - Importing"

filter Get-GitHubEnvironment {
    <#
        .SYNOPSIS
        Get GitHub environment

        .DESCRIPTION
        Long description

        .PARAMETER Owner
        Parameter description

        .PARAMETER Repo
        Parameter description

        .EXAMPLE
        An example

        .NOTES
        https://docs.github.com/rest/reference/repos#get-all-environments
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo)
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/environments"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Deployments/Get-GitHubEnvironment.ps1] - Done"
#endregion - From public/Deployments/Get-GitHubEnvironment.ps1
#region - From public/Deployments/Get-GitHubEnvironmentSecrets.ps1
Write-Verbose "[$scriptName] - [public/Deployments/Get-GitHubEnvironmentSecrets.ps1] - Importing"

filter Get-GitHubEnvironmentSecrets {
    <#
    .SYNOPSIS
    Get GitHub environment secrets

    .DESCRIPTION
    Long description

    .PARAMETER Owner
    Parameter description

    .PARAMETER Repo
    Parameter description

    .PARAMETER EnvironmentName
    Parameter description

    .EXAMPLE
    An example

    .NOTES
    https://docs.github.com/rest/reference/repos#get-all-environments
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [Alias('name')]
        [string] $EnvironmentName
    )

    $RepoID = (Get-GitHubRepo).id

    $inputObject = @{
        APIEndpoint = "/repositories/$RepoID/environments/$EnvironmentName/secrets"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Deployments/Get-GitHubEnvironmentSecrets.ps1] - Done"
#endregion - From public/Deployments/Get-GitHubEnvironmentSecrets.ps1
#region - From public/Deployments/Update-GitHubEnvironment.ps1
Write-Verbose "[$scriptName] - [public/Deployments/Update-GitHubEnvironment.ps1] - Importing"

filter Update-GitHubEnvironment {
    <#
        .NOTES
        https://docs.github.com/rest/reference/repos#create-or-update-an-environment
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        [Alias('environment_name')]
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Name
    )

    $body = @{
        owner            = $Owner
        repo             = $Repo
        environment_name = $Name
    }

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/environments/$Name"
        Method      = 'PUT'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Deployments/Update-GitHubEnvironment.ps1] - Done"
#endregion - From public/Deployments/Update-GitHubEnvironment.ps1

Write-Verbose "[$scriptName] - [public/Deployments] - Done"
#endregion - From public/Deployments

#region - From public/Emojis
Write-Verbose "[$scriptName] - [public/Emojis] - Processing folder"

#region - From public/Emojis/Get-GitHubEmojis.ps1
Write-Verbose "[$scriptName] - [public/Emojis/Get-GitHubEmojis.ps1] - Importing"

filter Get-GitHubEmojis {
    <#
        .NOTES
        https://docs.github.com/rest/reference/emojis#get-emojis
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Destination
    )

    $inputObject = @{
        APIEndpoint = '/emojis'
        Method      = 'GET'
    }

    $response = (Invoke-GitHubAPI @inputObject).Response

    if (Test-Path -Path $Destination) {
        $response.PSObject.Properties | ForEach-Object -Parallel {
            Invoke-WebRequest -Uri $_.Value -OutFile "$using:Destination/$($_.Name).png"
        }
    } else {
        $response
    }
}

Write-Verbose "[$scriptName] - [public/Emojis/Get-GitHubEmojis.ps1] - Done"
#endregion - From public/Emojis/Get-GitHubEmojis.ps1

Write-Verbose "[$scriptName] - [public/Emojis] - Done"
#endregion - From public/Emojis

#region - From public/Markdown
Write-Verbose "[$scriptName] - [public/Markdown] - Processing folder"

#region - From public/Markdown/Get-GitHubMarkdown.ps1
Write-Verbose "[$scriptName] - [public/Markdown/Get-GitHubMarkdown.ps1] - Importing"

filter Get-GitHubMarkdown {
    <#
        .NOTES
        https://docs.github.com/rest/reference/meta#github-api-root
    #>

    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [switch] $Text,

        [Parameter()]
        [ValidateSet('markdown', 'gfm')]
        [string] $Mode,

        [Parameter()]
        [string] $Context
    )

    $body = @{
        context = $Context
        mode    = $Mode
        text    = $Text
    }

    $inputObject = @{
        APIEndpoint = '/markdown'
        Method      = 'POST'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Markdown/Get-GitHubMarkdown.ps1] - Done"
#endregion - From public/Markdown/Get-GitHubMarkdown.ps1
#region - From public/Markdown/Get-GitHubMarkdownRaw.ps1
Write-Verbose "[$scriptName] - [public/Markdown/Get-GitHubMarkdownRaw.ps1] - Importing"

filter Get-GitHubMarkdownRaw {
    <#
        .NOTES
        https://docs.github.com/rest/reference/meta#github-api-root
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Text
    )

    $inputObject = @{
        APIEndpoint = '/markdown/raw'
        ContentType = 'text/plain'
        Body        = $Text
        Method      = 'POST'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Markdown/Get-GitHubMarkdownRaw.ps1] - Done"
#endregion - From public/Markdown/Get-GitHubMarkdownRaw.ps1

Write-Verbose "[$scriptName] - [public/Markdown] - Done"
#endregion - From public/Markdown

#region - From public/Meta
Write-Verbose "[$scriptName] - [public/Meta] - Processing folder"

#region - From public/Meta/Get-GitHubApiVersions.ps1
Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubApiVersions.ps1] - Importing"

filter Get-GitHubApiVersions {
    <#
        .SYNOPSIS
        Get all API versions.

        .DESCRIPTION
        Get all supported GitHub API versions.

        .EXAMPLE
        Get-GitHubApiVersions

        Get all supported GitHub API versions.

        .NOTES
        https://docs.github.com/rest/meta/meta#get-all-api-versions
    #>

    [OutputType([string[]])]
    [CmdletBinding()]
    param ()

    $inputObject = @{
        ApiEndpoint = '/versions'
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubApiVersions.ps1] - Done"
#endregion - From public/Meta/Get-GitHubApiVersions.ps1
#region - From public/Meta/Get-GitHubMeta.ps1
Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubMeta.ps1] - Importing"

filter Get-GitHubMeta {
    <#
        .SYNOPSIS
        Get GitHub meta information.

        .DESCRIPTION
        Returns meta information about GitHub, including a list of GitHub's IP addresses. For more information, see "[About GitHub's IP addresses](https://docs.github.com/articles/about-github-s-ip-addresses/)."

        The API's response also includes a list of GitHub's domain names.

        The values shown in the documentation's response are example values. You must always query the API directly to get the latest values.

        **Note:** This endpoint returns both IPv4 and IPv6 addresses. However, not all features support IPv6. You should refer to the specific documentation for each feature to determine if IPv6 is supported.

        .EXAMPLE
        Get-GitHubMeta

        Returns meta information about GitHub, including a list of GitHub's IP addresses.

        .NOTES
        https://docs.github.com/rest/meta/meta#get-apiname-meta-information
    #>

    [OutputType([object])]
    [CmdletBinding()]
    param ()

    $inputObject = @{
        ApiEndpoint = '/meta'
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubMeta.ps1] - Done"
#endregion - From public/Meta/Get-GitHubMeta.ps1
#region - From public/Meta/Get-GitHubOctocat.ps1
Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubOctocat.ps1] - Importing"

filter Get-GitHubOctocat {
    <#
        .SYNOPSIS
        Get Octocat.

        .DESCRIPTION
        Get the octocat as ASCII art.

        .EXAMPLE
        Get-GitHubOctocat

        Get the octocat as ASCII art

        .EXAMPLE
        Get-GitHubOctocat -S "Hello world"

        Get the octocat as ASCII art with a custom saying

        .NOTES
        https://docs.github.com/rest/meta/meta#get-octocat
    #>

    [OutputType([string])]
    [CmdletBinding()]
    param (
        # The words to show in Octocat's speech bubble
        [Parameter()]
        [Alias('Say')]
        [Alias('Saying')]
        [string] $S
    )

    $body = @{
        s = $S
    }

    $inputObject = @{
        APIEndpoint = '/octocat'
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubOctocat.ps1] - Done"
#endregion - From public/Meta/Get-GitHubOctocat.ps1
#region - From public/Meta/Get-GitHubRoot.ps1
Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubRoot.ps1] - Importing"

filter Get-GitHubRoot {
    <#
        .SYNOPSIS
        GitHub API Root.

        .DESCRIPTION
        Get Hypermedia links to resources accessible in GitHub's REST API.

        .EXAMPLE
        Get-GitHubRoot

        Get the root endpoint for the GitHub API.

        .NOTES
        https://docs.github.com/rest/meta/meta#github-api-root
    #>

    [CmdletBinding()]
    param ()

    $inputObject = @{
        APIEndpoint = '/'
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubRoot.ps1] - Done"
#endregion - From public/Meta/Get-GitHubRoot.ps1
#region - From public/Meta/Get-GitHubZen.ps1
Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubZen.ps1] - Importing"

filter Get-GitHubZen {
    <#
    .SYNOPSIS
    Get the Zen of GitHub.

    .DESCRIPTION
    Get a random sentence from the Zen of GitHub.

    .EXAMPLE
    Get-GitHubZen

    Get a random sentence from the Zen of GitHub.

    .NOTES
    https://docs.github.com/rest/meta/meta#get-the-zen-of-github
    #>

    [CmdletBinding()]
    param ()

    $inputObject = @{
        APIEndpoint = '/zen'
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Meta/Get-GitHubZen.ps1] - Done"
#endregion - From public/Meta/Get-GitHubZen.ps1

Write-Verbose "[$scriptName] - [public/Meta] - Done"
#endregion - From public/Meta

#region - From public/Organization
Write-Verbose "[$scriptName] - [public/Organization] - Processing folder"

#region - From public/Organization/Get-GitHubOrganization.ps1
Write-Verbose "[$scriptName] - [public/Organization/Get-GitHubOrganization.ps1] - Importing"

filter Get-GitHubOrganization {
    <#
        .SYNOPSIS
        List organization

        .DESCRIPTION
        List organizations for the authenticated user - if no parameters are provided.
        List organizations for a user - if a username is provided.
        Lists all organizations, in the order that they were created on GitHub - if '-All' is provided.
        Get an organization - if a organization name is provided.

        .EXAMPLE
        Get-GitHubOrganization

        List organizations for the authenticated user.

        .EXAMPLE
        Get-GitHubOrganization -Username 'octocat'

        List public organizations for the user 'octocat'.

        .EXAMPLE
        Get-GitHubOrganization -All -Since 142951047

        List organizations, starting with PSModule.

        .EXAMPLE
        Get-GitHubOrganization -Name 'PSModule'

        Get the organization 'PSModule'.

        .NOTES
        https://docs.github.com/rest/orgs/orgs
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(DefaultParameterSetName = '__DefaultSet')]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ParameterSetName = 'NamedOrg',
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [Alias('org')]
        [Alias('owner')]
        [string] $OrganizationName,

        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ParameterSetName = 'NamedUser',
            ValueFromPipelineByPropertyName
        )]
        [string] $Username,

        # List all organizations. Use '-Since' to start at a specific organization id.
        [Parameter(
            Mandatory,
            ParameterSetName = 'AllOrg'
        )]
        [switch] $All,

        # A organization ID. Only return organizations with an ID greater than this ID.
        [Parameter(ParameterSetName = 'AllOrg')]
        [int] $Since = 0,

        # The number of results per page (max 100).
        [Parameter(ParameterSetName = 'AllOrg')]
        [Parameter(ParameterSetName = 'UserOrg')]
        [Parameter(ParameterSetName = '__DefaultSet')]
        [int] $PerPage = 30
    )

    switch ($PSCmdlet.ParameterSetName) {
        '__DefaultSet' {
            Get-GitHubMyOrganization -PerPage $PerPage | Get-GitHubOrganizationByName
        }
        'NamedOrg' {
            Get-GitHubOrganizationByName -OrganizationName $OrganizationName
        }
        'NamedUser' {
            Get-GitHubUserOrganization -Username $Username
        }
        'AllOrg' {
            Get-GitHubAllOrganization -Since $Since -PerPage $PerPage
        }
    }
}

Write-Verbose "[$scriptName] - [public/Organization/Get-GitHubOrganization.ps1] - Done"
#endregion - From public/Organization/Get-GitHubOrganization.ps1
#region - From public/Organization/Get-GitHubOrganizationAppInstallation.ps1
Write-Verbose "[$scriptName] - [public/Organization/Get-GitHubOrganizationAppInstallation.ps1] - Importing"

filter Get-GitHubOrganizationAppInstallation {
    <#
        .SYNOPSIS
        List app installations for an organization

        .DESCRIPTION
        Lists all GitHub Apps in an organization. The installation count includes all GitHub Apps installed on repositories in the organization. You must be an organization owner with `admin:read` scope to use this endpoint.

        .EXAMPLE
        Get-GitHubOrganizationAppInstallation -OrganizationName 'github'

        Gets all GitHub Apps in the organization `github`.

        .NOTES
        https://docs.github.com/rest/orgs/orgs#list-app-installations-for-an-organization

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    $body = @{
        per_page = $PerPage
    }

    $inputObject = @{
        APIEndpoint = "/orgs/$OrganizationName/installations"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response.installations

}

Write-Verbose "[$scriptName] - [public/Organization/Get-GitHubOrganizationAppInstallation.ps1] - Done"
#endregion - From public/Organization/Get-GitHubOrganizationAppInstallation.ps1
#region - From public/Organization/Remove-GitHubOrganization.ps1
Write-Verbose "[$scriptName] - [public/Organization/Remove-GitHubOrganization.ps1] - Importing"

filter Remove-GitHubOrganization {
    <#
        .SYNOPSIS
        Delete an organization

        .DESCRIPTION
        Deletes an organization and all its repositories.
        The organization login will be unavailable for 90 days after deletion.
        Please review the Terms of Service regarding account deletion before using this endpoint:
        https://docs.github.com/site-policy/github-terms/github-terms-of-service

        .EXAMPLE
        Remove-GitHubOrganization -OrganizationName 'github'

        Deletes the organization 'github' and all its repositories.

        .NOTES
        https://docs.github.com/rest/orgs/orgs#delete-an-organization
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName
    )

    $inputObject = @{
        APIEndpoint = "/orgs/$OrganizationName"
        Method      = 'DELETE'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Organization/Remove-GitHubOrganization.ps1] - Done"
#endregion - From public/Organization/Remove-GitHubOrganization.ps1
#region - From public/Organization/Set-GitHubOrganization.ps1
Write-Verbose "[$scriptName] - [public/Organization/Set-GitHubOrganization.ps1] - Importing"

filter Set-GitHubOrganization {
    <#
        .SYNOPSIS
        Update an organization

        .DESCRIPTION
        **Parameter Deprecation Notice:** GitHub will replace and discontinue `members_allowed_repository_creation_type` in favor of more granular permissions. The new input parameters are `members_can_create_public_repositories`, `members_can_create_private_repositories` for all organizations and `members_can_create_internal_repositories` for organizations associated with an enterprise account using GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+. For more information, see the [blog post](https://developer.github.com/changes/2019-12-03-internal-visibility-changes).

        Enables an authenticated organization owner with the `admin:org` scope or the `repo` scope to update the organization's profile and member privileges.

        .EXAMPLE
        Set-GitHubOrganization -OrganizationName 'github' -Blog 'https://github.blog'

        Sets the blog URL for the organization 'github' to 'https://github.blog'.

        .EXAMPLE
        $param = @{
            OrganizationName = 'github'
            MembersCanCreatePublicRepositories = $true
            MembersCanCreatePrivateRepositories = $true
            MembersCanCreateInternalRepositories = $true
        }
        Set-GitHubOrganization @param

        Sets the repository creation permissions for the organization 'github' to allow all members to create public, private, and internal repositories.

        .NOTES
        https://docs.github.com/rest/orgs/orgs#update-an-organization

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName,

        # Billing email address. This address is not publicized.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('billing_email')]
        [string] $BillingEmail,

        # The company name.
        [Parameter(ValueFromPipelineByPropertyName)]
        [string] $Company,

        # The publicly visible email address.
        [Parameter(ValueFromPipelineByPropertyName)]
        [string] $Email,

        # The Twitter username of the company.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('twitter_username')]
        [string] $TwitterUsername,

        # The location.
        [Parameter(ValueFromPipelineByPropertyName)]
        [string] $Location,

        # The shorthand name of the company.
        [Parameter(ValueFromPipelineByPropertyName)]
        [string] $Name,

        # The description of the company.
        [Parameter(ValueFromPipelineByPropertyName)]
        [string] $Description,

        # Whether an organization can use organization projects.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('has_organization_projects')]
        [bool] $HasOrganizationProjects,

        # Whether repositories that belong to the organization can use repository projects.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('has_repository_projects')]
        [bool] $HasRepositoryProjects,

        # Default permission level members have for organization repositories.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('default_repository_permission')]
        [ValidateSet('read', 'write', 'admin', 'none')]
        [string] $DefaultRepositoryPermission,

        # Whether of non-admin organization members can create repositories. Note: A parameter can override this parameter. See members_allowed_repository_creation_type in this table for details.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('members_can_create_repositories')]
        [bool] $MembersCanCreateRepositories = $true,

        # Whether organization members can create internal repositories, which are visible to all enterprise members. You can only allow members to create internal repositories if your organization is associated with an enterprise account using GitHub Enterprise Cloud or GitHub Enterprise Server 2.20+. For more information, see "Restricting repository creation in your organization" in the GitHub Help documentation.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('members_can_create_internal_repositories')]
        [bool] $MembersCanCreateInternalRepositories,

        # Whether organization members can create private repositories, which are visible to organization members with permission. For more information, see "Restricting repository creation in your organization" in the GitHub Help documentation.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('members_can_create_private_repositories')]
        [bool] $MembersCanCreatePrivateRepositories,

        # Whether organization members can create public repositories, which are visible to anyone. For more information, see "Restricting repository creation in your organization" in the GitHub Help documentation.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('members_can_create_public_repositories')]
        [bool] $MembersCanCreatePublicRepositories,

        # Specifies which types of repositories non-admin organization members can create. private is only available to repositories that are part of an organization on GitHub Enterprise Cloud. Note: This parameter is deprecated and will be removed in the future. Its return value ignores internal repositories. Using this parameter overrides values set in members_can_create_repositories. See the parameter deprecation notice in the operation description for details.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('members_allowed_repository_creation_type')]
        [ValidateSet('all', 'private', 'none')]
        [string] $MembersAllowedRepositoryCreationType,

        # Whether organization members can create GitHub Pages sites. Existing published sites will not be impacted.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('members_can_create_pages')]
        [bool] $MembersCanCreatePages = $true,

        # Whether organization members can create public GitHub Pages sites. Existing published sites will not be impacted.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('members_can_create_public_pages')]
        [bool] $MembersCanCreatePublicPages = $true,

        # Whether organization members can create private GitHub Pages sites. Existing published sites will not be impacted.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('members_can_create_private_pages')]
        [bool] $MembersCanCreatePrivatePages = $true,

        # Whether organization members can fork private organization repositories.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('members_can_fork_private_repositories')]
        [bool] $MembersCanForkPrivateRepositories = $false,

        # Whether contributors to organization repositories are required to sign off on commits they make through GitHub's web interface.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('web_commit_signoff_required')]
        [bool] $WebCommitSignoffRequired = $false,

        # Path to the organization's blog.
        [Parameter(ValueFromPipelineByPropertyName)]
        [string] $Blog,

        # Whether GitHub Advanced Security is automatically enabled for new repositories.
        # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization."
        # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('advanced_security_enabled_for_new_repositories')]
        [bool] $AdvancedSecurityEnabledForNewRepositories = $false,

        # Whether Dependabot alerts is automatically enabled for new repositories.
        # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization."
        # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('dependabot_alerts_enabled_for_new_repositories')]
        [bool] $DependabotAlertsEnabledForNewRepositories = $false,

        # Whether Dependabot security updates is automatically enabled for new repositories.
        # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization."
        # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('dependabot_security_updates_enabled_for_new_repositories')]
        [bool] $DependabotSecurityUpdatesEnabledForNewRepositories = $false,

        # Whether dependency graph is automatically enabled for new repositories.
        # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization."
        # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('dependency_graph_enabled_for_new_repositories')]
        [bool] $DependencyGraphEnabledForNewRepositories = $false,

        # Whether secret scanning is automatically enabled for new repositories.
        # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization."
        # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('secret_scanning_enabled_for_new_repositories')]
        [bool] $SecretScanningEnabledForNewRepositories = $false,

        # Whether secret scanning push protection is automatically enabled for new repositories.
        # To use this parameter, you must have admin permissions for the repository or be an owner or security manager for the organization that owns the repository. For more information, see "Managing security managers in your organization."
        # You can check which security and analysis features are currently enabled by using a GET /orgs/{org} request.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('secret_scanning_push_protection_enabled_for_new_repositories')]
        [bool] $SecretScanningPushProtectionEnabledForNewRepositories = $false,

        # Whether a custom link is shown to contributors who are blocked from pushing a secret by push protection.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('secret_scanning_push_protection_custom_link_enabled')]
        [bool] $SecretScanningPushProtectionCustomLinkEnabled = $false,

        # If secret_scanning_push_protection_custom_link_enabled is true, the URL that will be displayed to contributors who are blocked from pushing a secret.
        [Parameter(ValueFromPipelineByPropertyName)]
        [Alias('secret_scanning_push_protection_custom_link')]
        [string] $SecretScanningPushProtectionCustomLink
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashTableEntries -Hashtable $body -RemoveNames 'organization_name'

    $inputObject = @{
        APIEndpoint = "/orgs/$OrganizationName"
        Method      = 'PATCH'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Organization/Set-GitHubOrganization.ps1] - Done"
#endregion - From public/Organization/Set-GitHubOrganization.ps1
#region - From public/Organization/Set-GitHubOrganizationSecurityFeature.ps1
Write-Verbose "[$scriptName] - [public/Organization/Set-GitHubOrganizationSecurityFeature.ps1] - Importing"

filter Set-GitHubOrganizationSecurityFeature {
    <#
        .SYNOPSIS
        Enable or disable a security feature for an organization

        .DESCRIPTION
        Enables or disables the specified security feature for all eligible repositories in an organization.

        To use this endpoint, you must be an organization owner or be member of a team with the security manager role.
        A token with the 'write:org' scope is also required.

        GitHub Apps must have the `organization_administration:write` permission to use this endpoint.

        For more information, see "[Managing security managers in your organization](https://docs.github.com/organizations/managing-peoples-access-to-your-organization-with-roles/managing-security-managers-in-your-organization)."

        .EXAMPLE
        Set-GitHubOrganizationSecurityFeature -OrganizationName 'github' -SecurityProduct 'dependency_graph' -Enablement 'enable_all'

        Enable the dependency graph for all repositories in the organization `github`.

        .NOTES
        https://docs.github.com/rest/orgs/orgs#enable-or-disable-a-security-feature-for-an-organization
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName,

        # The security feature to enable or disable.
        [Parameter(Mandatory)]
        [Alias('security_product')]
        [ValidateSet('dependency_graph', 'dependabot_alerts', 'dependabot_security_updates', 'advanced_security', 'code_scanning_default_setup', 'secret_scanning', 'secret_scanning_push_protection')]
        [string] $SecurityProduct,

        # The action to take.
        # enable_all means to enable the specified security feature for all repositories in the organization. disable_all means to disable the specified security feature for all repositories in the organization.
        [Parameter(Mandatory)]
        [ValidateSet('enable_all', 'disable_all')]
        [string] $Enablement,

        # CodeQL query suite to be used. If you specify the query_suite parameter, the default setup will be configured with this query suite only on all repositories that didn't have default setup already configured. It will not change the query suite on repositories that already have default setup configured. If you don't specify any query_suite in your request, the preferred query suite of the organization will be applied.
        [Parameter()]
        [Alias('query_suite')]
        [ValidateSet('default', 'extended')]
        [string] $QuerySuite
    )

    $body = @{
        query_suite = $QuerySuite
    }

    $inputObject = @{
        APIEndpoint = "/orgs/$OrganizationName/$SecurityProduct/$Enablement"
        Method      = 'POST'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Organization/Set-GitHubOrganizationSecurityFeature.ps1] - Done"
#endregion - From public/Organization/Set-GitHubOrganizationSecurityFeature.ps1

Write-Verbose "[$scriptName] - [public/Organization] - Done"
#endregion - From public/Organization

#region - From public/Rate-Limit
Write-Verbose "[$scriptName] - [public/Rate-Limit] - Processing folder"

#region - From public/Rate-Limit/Get-GitHubRateLimit.ps1
Write-Verbose "[$scriptName] - [public/Rate-Limit/Get-GitHubRateLimit.ps1] - Importing"

filter Get-GitHubRateLimit {
    <#
        .SYNOPSIS
        Get rate limit status for the authenticated user

        .DESCRIPTION
        **Note:** Accessing this endpoint does not count against your REST API rate limit.

        Some categories of endpoints have custom rate limits that are separate from the rate limit governing the other REST API endpoints. For this reason, the API response categorizes your rate limit. Under `resources`, you'll see objects relating to different categories:
        * The `core` object provides your rate limit status for all non-search-related resources in the REST API.
        * The `search` object provides your rate limit status for the REST API for searching (excluding code searches). For more information, see "[Search](https://docs.github.com/rest/search)."
        * The `code_search` object provides your rate limit status for the REST API for searching code. For more information, see "[Search code](https://docs.github.com/rest/search/search#search-code)."
        * The `graphql` object provides your rate limit status for the GraphQL API. For more information, see "[Resource limitations](https://docs.github.com/graphql/overview/resource-limitations#rate-limit)."
        * The `integration_manifest` object provides your rate limit status for the `POST /app-manifests/{code}/conversions` operation. For more information, see "[Creating a GitHub App from a manifest](https://docs.github.com/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app-from-a-manifest#3-you-exchange-the-temporary-code-to-retrieve-the-app-configuration)."
        * The `dependency_snapshots` object provides your rate limit status for submitting snapshots to the dependency graph. For more information, see "[Dependency graph](https://docs.github.com/rest/dependency-graph)."
        * The `code_scanning_upload` object provides your rate limit status for uploading SARIF results to code scanning. For more information, see "[Uploading a SARIF file to GitHub](https://docs.github.com/code-security/code-scanning/integrating-with-code-scanning/uploading-a-sarif-file-to-github)."
        * The `actions_runner_registration` object provides your rate limit status for registering self-hosted runners in GitHub Actions. For more information, see "[Self-hosted runners](https://docs.github.com/rest/actions/self-hosted-runners)."
        * The `source_import` object is no longer in use for any API endpoints, and it will be removed in the next API version. For more information about API versions, see "[API Versions](https://docs.github.com/rest/overview/api-versions)."

        **Note:** The `rate` object is deprecated. If you're writing new API client code or updating existing code, you should use the `core` object instead of the `rate` object. The `core` object contains the same information that is present in the `rate` object.

        .EXAMPLE
        Get-GitHubRateLimit

        Gets the rate limit status for the authenticated user.

        .NOTES
        https://docs.github.com/rest/rate-limit/rate-limit#get-rate-limit-status-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param ()

    $inputObject = @{
        APIEndpoint = "/rate_limit"
        Method      = 'GET'
    }

    (Invoke-GitHubAPI @inputObject).Response.Resources

}

Write-Verbose "[$scriptName] - [public/Rate-Limit/Get-GitHubRateLimit.ps1] - Done"
#endregion - From public/Rate-Limit/Get-GitHubRateLimit.ps1

Write-Verbose "[$scriptName] - [public/Rate-Limit] - Done"
#endregion - From public/Rate-Limit

#region - From public/Releases
Write-Verbose "[$scriptName] - [public/Releases] - Processing folder"

#region - From public/Releases/Assets
Write-Verbose "[$scriptName] - [public/Releases/Assets] - Processing folder"

#region - From public/Releases/Assets/Add-GitHubReleaseAsset.ps1
Write-Verbose "[$scriptName] - [public/Releases/Assets/Add-GitHubReleaseAsset.ps1] - Importing"

filter Add-GitHubReleaseAsset {
    <#
        .SYNOPSIS
        Upload a release asset

        .DESCRIPTION
        This endpoint makes use of [a Hypermedia relation](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in
        the response of the [Create a release endpoint](https://docs.github.com/rest/releases/releases#create-a-release) to upload a release asset.

        You need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.

        Most libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example:

        `application/zip`

        GitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,
        you'll still need to pass your authentication to be able to upload an asset.

        When an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.

        **Notes:**
        * GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The "[List release assets](https://docs.github.com/rest/releases/assets#list-release-assets)"
        endpoint lists the renamed filenames. For more information and help, contact [GitHub Support](https://support.github.com/contact?tags=dotcom-rest-api).
        * To find the `release_id` query the [`GET /repos/{owner}/{repo}/releases/latest` endpoint](https://docs.github.com/rest/releases/releases#get-the-latest-release).
        * If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.

        .EXAMPLE
        Add-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '7654321' -FilePath 'C:\Users\octocat\Downloads\hello-world.zip'

        Gets the release assets for the release with the ID '1234567' for the repository 'octocat/hello-world'.

        .NOTES
        https://docs.github.com/rest/releases/assets#upload-a-release-asset

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The unique identifier of the release.
        [Parameter(Mandatory)]
        [Alias('release_id')]
        [string] $ID,

        #The file name of the asset.
        [Parameter()]
        [string] $Name,

        # An alternate short description of the asset. Used in place of the filename.
        [Parameter()]
        [string] $Label,

        # The content type of the asset.
        [Parameter()]
        [string] $ContentType,

        # The path to the asset file.
        [Parameter(Mandatory)]
        [alias('fullname')]
        [string] $FilePath
    )

    # If name is not provided, use the file name
    if (!$Name) {
        $Name = (Get-Item $FilePath).Name
    }

    # If label is not provided, use the file name
    if (!$Label) {
        $Label = (Get-Item $FilePath).Name
    }

    # If content type is not provided, use the file extension
    if (!$ContentType) {
        $ContentType = switch ((Get-Item $FilePath).Extension) {
            '.zip' { 'application/zip' }
            '.tar' { 'application/x-tar' }
            '.gz' { 'application/gzip' }
            '.bz2' { 'application/x-bzip2' }
            '.xz' { 'application/x-xz' }
            '.7z' { 'application/x-7z-compressed' }
            '.rar' { 'application/vnd.rar' }
            '.tar.gz' { 'application/gzip' }
            '.tgz' { 'application/gzip' }
            '.tar.bz2' { 'application/x-bzip2' }
            '.tar.xz' { 'application/x-xz' }
            '.tar.7z' { 'application/x-7z-compressed' }
            '.tar.rar' { 'application/vnd.rar' }
            '.png' { 'image/png' }
            '.json' { 'application/json' }
            '.txt' { 'text/plain' }
            '.md' { 'text/markdown' }
            '.html' { 'text/html' }
            default { 'application/octet-stream' }
        }
    }

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'Owner', 'Repo', 'ID', 'FilePath'

    $body['name'] = $Name
    $body['label'] = $Label

    Remove-HashtableEntries -Hashtable $body -NullOrEmptyValues

    $release = Get-GitHubRelease -Owner $Owner -Repo $Repo -ID $ID
    $uploadURI = $release.upload_url -replace '{\?name,label}', "?name=$($Name)&label=$($Label)"

    $inputObject = @{
        URI            = $uploadURI
        Method         = 'POST'
        ContentType    = $ContentType
        UploadFilePath = $FilePath
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Releases/Assets/Add-GitHubReleaseAsset.ps1] - Done"
#endregion - From public/Releases/Assets/Add-GitHubReleaseAsset.ps1
#region - From public/Releases/Assets/Get-GitHubReleaseAsset.ps1
Write-Verbose "[$scriptName] - [public/Releases/Assets/Get-GitHubReleaseAsset.ps1] - Importing"

filter Get-GitHubReleaseAsset {
    <#
        .SYNOPSIS
        List release assets based on a release ID or asset ID

        .DESCRIPTION
        If an asset id is provided, the asset is returned.
        If a release id is provided, all assets for the release are returned.

        .EXAMPLE
        Get-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '1234567'

        Gets the release asset with the ID '1234567' for the repository 'octocat/hello-world'.

        .EXAMPLE
        Get-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ReleaseID '7654321'

        Gets the release assets for the release with the ID '7654321' for the repository 'octocat/hello-world'.

        .NOTES
        https://docs.github.com/rest/releases/assets#get-a-release-asset

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The unique identifier of the asset.
        [Parameter(
            Mandatory,
            ParameterSetName = 'ID'
        )]
        [Alias('asset_id')]
        [string] $ID,

        # The unique identifier of the release.
        [Parameter(
            Mandatory,
            ParameterSetName = 'ReleaseID'
        )]
        [Alias('release_id')]
        [string] $ReleaseID
    )

    if ($ReleaseID) {
        Get-GitHubReleaseAssetByReleaseID -Owner $Owner -Repo $Repo -ReleaseID $ReleaseID
    }
    if ($ID) {
        Get-GitHubReleaseAssetByID -Owner $Owner -Repo $Repo -ID $ID
    }

}

Write-Verbose "[$scriptName] - [public/Releases/Assets/Get-GitHubReleaseAsset.ps1] - Done"
#endregion - From public/Releases/Assets/Get-GitHubReleaseAsset.ps1
#region - From public/Releases/Assets/Remove-GitHubReleaseAsset.ps1
Write-Verbose "[$scriptName] - [public/Releases/Assets/Remove-GitHubReleaseAsset.ps1] - Importing"

filter Remove-GitHubReleaseAsset {
    <#
        .SYNOPSIS
        Delete a release asset

        .DESCRIPTION
        Delete a release asset

        .EXAMPLE
        Remove-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '1234567'

        Deletes the release asset with the ID '1234567' for the repository 'octocat/hello-world'.

        .NOTES
        https://docs.github.com/rest/releases/assets#delete-a-release-asset

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The unique identifier of the asset.
        [Parameter(Mandatory)]
        [Alias('asset_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/assets/$ID"
        Method      = 'DELETE'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Releases/Assets/Remove-GitHubReleaseAsset.ps1] - Done"
#endregion - From public/Releases/Assets/Remove-GitHubReleaseAsset.ps1
#region - From public/Releases/Assets/Set-GitHubReleaseAsset.ps1
Write-Verbose "[$scriptName] - [public/Releases/Assets/Set-GitHubReleaseAsset.ps1] - Importing"

filter Set-GitHubReleaseAsset {
    <#
        .SYNOPSIS
        Update a release asset

        .DESCRIPTION
        Users with push access to the repository can edit a release asset.

        .EXAMPLE
        Set-GitHubReleaseAsset -Owner 'octocat' -Repo 'hello-world' -ID '1234567' -Name 'new_asset_name' -Label 'new_asset_label'

        Updates the release asset with the ID '1234567' for the repository 'octocat/hello-world' with the new name 'new_asset_name' and label 'new_asset_label'.

        .NOTES
        https://docs.github.com/rest/releases/assets#update-a-release-asset

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The unique identifier of the asset.
        [Parameter(Mandatory)]
        [Alias('asset_id')]
        [string] $ID,

        #The file name of the asset.
        [Parameter()]
        [string] $Name,

        # An alternate short description of the asset. Used in place of the filename.
        [Parameter()]
        [string] $Label,

        # State of the release asset.
        [Parameter()]
        [ValidateSet('uploaded', 'open')]
        [string] $State

    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'Owner', 'Repo','ID'

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/assets/$ID"
        Method      = 'PATCH'
        Body        = $requestBody
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Releases/Assets/Set-GitHubReleaseAsset.ps1] - Done"
#endregion - From public/Releases/Assets/Set-GitHubReleaseAsset.ps1

Write-Verbose "[$scriptName] - [public/Releases/Assets] - Done"
#endregion - From public/Releases/Assets

#region - From public/Releases/Releases
Write-Verbose "[$scriptName] - [public/Releases/Releases] - Processing folder"

#region - From public/Releases/Releases/Get-GitHubRelease.ps1
Write-Verbose "[$scriptName] - [public/Releases/Releases/Get-GitHubRelease.ps1] - Importing"

filter Get-GitHubRelease {
    <#
        .SYNOPSIS
        List releases

        .DESCRIPTION
        This returns a list of releases, which does not include regular Git tags that have not been associated with a release.
        To get a list of Git tags, use the [Repository Tags API](https://docs.github.com/rest/repos/repos#list-repository-tags).
        Information about published releases are available to everyone. Only users with push access will receive listings for draft releases.

        .EXAMPLE
        Get-GitHubRelease -Owner 'octocat' -Repo 'hello-world'

        Gets the releases for the repository 'hello-world' owned by 'octocat'.

        .EXAMPLE
        Get-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -Latest

        Gets the latest releases for the repository 'hello-world' owned by 'octocat'.

        .EXAMPLE
        Get-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -Tag 'v1.0.0'

        Gets the release with the tag 'v1.0.0' for the repository 'hello-world' owned by 'octocat'.

        .EXAMPLE
        Get-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -ID '1234567'

        Gets the release with the id '1234567' for the repository 'hello-world' owned by 'octocat'.

        .NOTES
        https://docs.github.com/rest/releases/releases#list-releases
        https://docs.github.com/rest/releases/releases#get-the-latest-release

    #>

    [CmdletBinding(DefaultParameterSetName = 'All')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The number of results per page (max 100).
        [Parameter(ParameterSetName = 'All')]
        [int] $PerPage = 30,

        # Get the latest release only
        [Parameter(
            Mandatory,
            ParameterSetName = 'Latest'
        )]
        [switch] $Latest,

        # The name of the tag to get a release from.
        [Parameter(
            Mandatory,
            ParameterSetName = 'Tag'
        )]
        [Alias('tag_name')]
        [string] $Tag,

        # The unique identifier of the release.
        [Parameter(
            Mandatory,
            ParameterSetName = 'Id'
        )]
        [Alias('release_id')]
        [string] $ID
    )

    switch ($PSCmdlet.ParameterSetName) {
        'All' { Get-GitHubReleaseAll -Owner $Owner -Repo $Repo -PerPage $PerPage }
        'Latest' { Get-GitHubReleaseLatest -Owner $Owner -Repo $Repo }
        'Tag' { Get-GitHubReleaseByTagName -Owner $Owner -Repo $Repo -Tag $Tag }
        'Id' { Get-GitHubReleaseByID -Owner $Owner -Repo $Repo -ID $ID }
    }

}

Write-Verbose "[$scriptName] - [public/Releases/Releases/Get-GitHubRelease.ps1] - Done"
#endregion - From public/Releases/Releases/Get-GitHubRelease.ps1
#region - From public/Releases/Releases/New-GitHubRelease.ps1
Write-Verbose "[$scriptName] - [public/Releases/Releases/New-GitHubRelease.ps1] - Importing"

filter New-GitHubRelease {
    <#
        .SYNOPSIS
        Create a release

        .DESCRIPTION
        Users with push access to the repository can create a release.
        This endpoint triggers [notifications](https://docs.github.com/github/managing-subscriptions-and-notifications-on-github/about-notifications).
        Creating content too quickly using this endpoint may result in secondary rate limiting.
        See "[Secondary rate limits](https://docs.github.com/rest/overview/resources-in-the-rest-api#secondary-rate-limits)"
        and "[Dealing with secondary rate limits](https://docs.github.com/rest/guides/best-practices-for-integrators#dealing-with-secondary-rate-limits)" for details.

        .EXAMPLE
        New-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -TagName 'v1.0.0' -TargetCommitish 'main' -Body 'Release notes'

        Creates a release for the repository 'octocat/hello-world' with the tag 'v1.0.0' and the target commitish 'main'.

        .NOTES
        https://docs.github.com/rest/releases/releases#create-a-release

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The name of the tag.
        [Parameter(Mandatory)]
        [Alias('tag_name')]
        [string] $TagName,

        # Specifies the commitish value that determines where the Git tag is created from.
        # Can be any branch or commit SHA. Unused if the Git tag already exists.
        # API Default: the repository's default branch.
        [Parameter()]
        [Alias('target_commitish')]
        [string] $TargetCommitish = 'main',

        # The name of the release.
        [Parameter()]
        [string] $Name,

        # Text describing the contents of the tag.
        [Parameter()]
        [string] $Body,

        # Whether the release is a draft.
        [Parameter()]
        [switch] $Draft,

        # Whether to identify the release as a prerelease.
        [Parameter()]
        [switch] $Prerelease,

        # If specified, a discussion of the specified category is created and linked to the release.
        # The value must be a category that already exists in the repository.
        # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository).
        [Parameter()]
        [Alias('discussion_category_name')]
        [string] $DiscussionCategoryName,

        # Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise,a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes.
        [Parameter()]
        [Alias('generate_release_notes')]
        [switch] $GenerateReleaseNotes,

        # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation date and higher semantic version.
        [Parameter()]
        [Alias('make_latest')]
        [ValidateSet('true', 'false', 'legacy')]
        [string] $MakeLatest = 'true'
    )

    $requestBody = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $requestBody -RemoveNames 'Owner', 'Repo', 'GenerateReleaseNotes', 'Draft', 'Prerelease'
    $requestBody =  Join-Object -AsHashtable -Main $requestBody -Overrides @{
        generate_release_notes = $GenerateReleaseNotes.IsPresent
        draft                  = $Draft.IsPresent
        prerelease             = $Prerelease.IsPresent
    }
    Remove-HashtableEntries -Hashtable $requestBody -NullOrEmptyValues

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases"
        Method      = 'POST'
        Body        = $requestBody
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Releases/Releases/New-GitHubRelease.ps1] - Done"
#endregion - From public/Releases/Releases/New-GitHubRelease.ps1
#region - From public/Releases/Releases/New-GitHubReleaseNotes.ps1
Write-Verbose "[$scriptName] - [public/Releases/Releases/New-GitHubReleaseNotes.ps1] - Importing"

filter New-GitHubReleaseNotes {
    <#
        .SYNOPSIS
        List releases

        .DESCRIPTION
        This returns a list of releases, which does not include regular Git tags that have not been associated with a release.
        To get a list of Git tags, use the [Repository Tags API](https://docs.github.com/rest/repos/repos#list-repository-tags).
        Information about published releases are available to everyone. Only users with push access will receive listings for draft releases.

        .EXAMPLE
        $params = @{
            Owner = 'octocat'
            Repo = 'hello-world'
            TagName = 'v1.0.0'
        }
        New-GitHubReleaseNotes @params

        Creates a new release notes draft for the repository 'hello-world' owned by 'octocat' with the tag name 'v1.0.0'.
        In this example the tag 'v1.0.0' has to exist in the repository.
        The configuration file '.github/release.yml' or '.github/release.yaml' will be used.

        .EXAMPLE
        $params = @{
            Owner = 'octocat'
            Repo = 'hello-world'
            TagName = 'v1.0.0'
            TargetCommitish = 'main'
        }
        New-GitHubReleaseNotes @params

        Creates a new release notes draft for the repository 'hello-world' owned by 'octocat' with the tag name 'v1.0.0'.
        In this example the tag 'v1.0.0' has to exist in the repository.


        .EXAMPLE
        $params = @{
            Owner = 'octocat'
            Repo = 'hello-world'
            TagName = 'v1.0.0'
            TargetCommitish = 'main'
            PreviousTagName = 'v0.9.2'
            ConfigurationFilePath = '.github/custom_release_config.yml'
        }
        New-GitHubReleaseNotes @params

        Creates a new release notes draft for the repository 'hello-world' owned by 'octocat' with the tag name 'v1.0.0'.
        The release notes will be based on the changes between the tags 'v0.9.2' and 'v1.0.0' and generated based on the
        configuration file located in the repository at '.github/custom_release_config.yml'.

        .NOTES
        https://docs.github.com/rest/releases/releases#list-releases

    #>

    [OutputType([pscustomobject])]
    [Alias('Generate-GitHubReleaseNotes')]
    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The tag name for the release. This can be an existing tag or a new one.
        [Parameter(Mandatory)]
        [Alias('tag_name')]
        [string] $TagName,

        # Specifies the commitish value that will be the target for the release's tag.
        # Required if the supplied tag_name does not reference an existing tag.
        # Ignored if the tag_name already exists.
        [Parameter()]
        [Alias('target_commitish')]
        [string] $TargetCommitish,

        # The name of the previous tag to use as the starting point for the release notes.
        # Use to manually specify the range for the set of changes considered as part this release.
        [Parameter()]
        [Alias('previous_tag_name')]
        [string] $PreviousTagName,


        # Specifies a path to a file in the repository containing configuration settings used for generating the release notes.
        # If unspecified, the configuration file located in the repository at '.github/release.yml' or '.github/release.yaml' will be used.
        # If that is not present, the default configuration will be used.
        [Parameter()]
        [Alias('configuration_file_path')]
        [string] $ConfigurationFilePath

    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'Owner', 'Repo'

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/generate-notes"
        Method      = 'POST'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Releases/Releases/New-GitHubReleaseNotes.ps1] - Done"
#endregion - From public/Releases/Releases/New-GitHubReleaseNotes.ps1
#region - From public/Releases/Releases/Remove-GitHubRelease.ps1
Write-Verbose "[$scriptName] - [public/Releases/Releases/Remove-GitHubRelease.ps1] - Importing"

filter Remove-GitHubRelease {
    <#
        .SYNOPSIS
        Delete a release

        .DESCRIPTION
        Users with push access to the repository can delete a release.

        .EXAMPLE
        Remove-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -ID '1234567'

        Deletes the release with the ID '1234567' for the repository 'octocat/hello-world'.

        .NOTES
        https://docs.github.com/rest/releases/releases#delete-a-release

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The unique identifier of the release.
        [Parameter(
            Mandatory
        )]
        [Alias('release_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/$ID"
        Method      = 'DELETE'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Releases/Releases/Remove-GitHubRelease.ps1] - Done"
#endregion - From public/Releases/Releases/Remove-GitHubRelease.ps1
#region - From public/Releases/Releases/Set-GitHubRelease.ps1
Write-Verbose "[$scriptName] - [public/Releases/Releases/Set-GitHubRelease.ps1] - Importing"

filter Set-GitHubRelease {
    <#
        .SYNOPSIS
        Update a release

        .DESCRIPTION
        Users with push access to the repository can edit a release.

        .EXAMPLE
        Set-GitHubRelease -Owner 'octocat' -Repo 'hello-world' -ID '1234567' -Body 'Release notes'

        Updates the release with the ID '1234567' for the repository 'octocat/hello-world' with the body 'Release notes'.

        .NOTES
        https://docs.github.com/rest/releases/releases#update-a-release

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The unique identifier of the release.
        [Parameter(Mandatory)]
        [Alias('release_id')]
        [string] $ID,

        # The name of the tag.
        [Parameter()]
        [Alias('tag_name')]
        [string] $TagName,

        # Specifies the commitish value that determines where the Git tag is created from.
        # Can be any branch or commit SHA. Unused if the Git tag already exists.
        # API Default: the repository's default branch.
        [Parameter()]
        [Alias('target_commitish')]
        [string] $TargetCommitish,

        # The name of the release.
        [Parameter()]
        [string] $Name,

        # Text describing the contents of the tag.
        [Parameter()]
        [string] $Body,

        # Whether the release is a draft.
        [Parameter()]
        [switch] $Draft,

        # Whether to identify the release as a prerelease.
        [Parameter()]
        [switch] $Prerelease,

        # If specified, a discussion of the specified category is created and linked to the release.
        # The value must be a category that already exists in the repository.
        # For more information, see [Managing categories for discussions in your repository](https://docs.github.com/discussions/managing-discussions-for-your-community/managing-categories-for-discussions-in-your-repository).
        [Parameter()]
        [Alias('discussion_category_name')]
        [string] $DiscussionCategoryName,

        # Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. Defaults to true for newly published releases. legacy specifies that the latest release should be determined based on the release creation date and higher semantic version.
        [Parameter()]
        [Alias('make_latest')]
        [ValidateSet('true', 'false', 'legacy')]
        [string] $MakeLatest = 'true'
    )

    $requestBody = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $requestBody -RemoveNames 'Owner', 'Repo', 'Draft', 'Prerelease'
    $requestBody =  Join-Object -AsHashtable -Main $requestBody -Overrides @{
        draft                  = $Draft.IsPresent ? $Draft : $false
        prerelease             = $Prerelease.IsPresent ? $Prerelease : $false
    }

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/$ID"
        Method      = 'PATCH'
        Body        = $requestBody
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Releases/Releases/Set-GitHubRelease.ps1] - Done"
#endregion - From public/Releases/Releases/Set-GitHubRelease.ps1

Write-Verbose "[$scriptName] - [public/Releases/Releases] - Done"
#endregion - From public/Releases/Releases


Write-Verbose "[$scriptName] - [public/Releases] - Done"
#endregion - From public/Releases

#region - From public/Repositories
Write-Verbose "[$scriptName] - [public/Repositories] - Processing folder"

#region - From public/Repositories/Repositories
Write-Verbose "[$scriptName] - [public/Repositories/Repositories] - Processing folder"

#region - From public/Repositories/Repositories/Get-GitHubRepository.ps1
Write-Verbose "[$scriptName] - [public/Repositories/Repositories/Get-GitHubRepository.ps1] - Importing"

filter Get-GitHubRepository {
    <#
        .SYNOPSIS
        Gets a specific repository or list of repositories.

        .DESCRIPTION
        Gets a specific repository or list of repositories based on parameter sets.
        If no parameters are specified, the authenticated user's repositories are returned.
        If a Username parameter is specified, the specified user's public repositories are returned.
        If the SinceId parameter is specified, the repositories with an ID greater than the specified ID are returned.
        If an Owner and Repo parameters are specified, the specified repository is returned.
        If the Owner and Repo parameters are specified, the specified repository is returned.

        .PARAMETER Type
        Specifies the types of repositories you want returned.

        .EXAMPLE
        Get-GitHubRepository

        Gets the repositories for the authenticated user.

        .EXAMPLE
        Get-GitHubRepository -Type 'owner'

        Gets the repositories owned by the authenticated user.

        .EXAMPLE
        Get-GitHubRepository -Username 'octocat'

        Gets the repositories for the specified user.

        .EXAMPLE
        Get-GitHubRepository -SinceID 123456789

        Gets the repositories with an ID equals and greater than 123456789.

        .EXAMPLE
        Get-GitHubRepository -Owner 'github' -Repo 'octocat'

        Gets the specified repository.

        .NOTES
        https://docs.github.com/rest/repos/repos#list-repositories-for-the-authenticated-user
        https://docs.github.com/rest/repos/repos#get-a-repository
        https://docs.github.com/rest/repos/repos#list-public-repositories
        https://docs.github.com/rest/repos/repos#list-organization-repositories
        https://docs.github.com/rest/repos/repos#list-repositories-for-a-user

    #>

    [CmdletBinding(DefaultParameterSetName = 'MyRepos_Type')]
    param (
        #Limit results to repositories with the specified visibility.
        [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')]
        [ValidateSet('all', 'public', 'private')]
        [string] $Visibility = 'all',

        # Comma-separated list of values. Can include:
        # - owner: Repositories that are owned by the authenticated user.
        # - collaborator: Repositories that the user has been added to as a collaborator.
        # - organization_member: Repositories that the user has access to through being a member of an organization. This includes every repository on every team that the user is on.
        # Default: owner, collaborator, organization_member
        [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')]
        [ValidateSet('owner', 'collaborator', 'organization_member')]
        [string[]] $Affiliation = @('owner', 'collaborator', 'organization_member'),

        # A repository ID. Only return repositories with an ID greater than this ID.
        [Parameter(ParameterSetName = 'ListByID')]
        [int] $SinceID = 0,

        # Only show repositories updated after the given time.
        [Parameter(ParameterSetName = 'MyRepos_Type')]
        [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')]
        [datetime] $Since,

        # Only show repositories updated before the given time.
        [Parameter(ParameterSetName = 'MyRepos_Type')]
        [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')]
        [datetime] $Before,

        # The account owner of the repository. The name is not case sensitive.
        [Parameter(ParameterSetName = 'ByName')]
        [Parameter(ParameterSetName = 'ListByOrg')]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ParameterSetName = 'ByName'
        )]
        [string] $Repo = (Get-GitHubConfig -Name Repo),

        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            ParameterSetName = 'ListByUser'
        )]
        [Alias('login')]
        [string] $Username,

        # The property to sort the results by.
        [Parameter(ParameterSetName = 'MyRepos_Type')]
        [Parameter(ParameterSetName = 'MyRepos_Aff-Vis')]
        [Parameter(ParameterSetName = 'ListByOrg')]
        [Parameter(ParameterSetName = 'ListByUser')]
        [ValidateSet('created', 'updated', 'pushed', 'full_name')]
        [string] $Sort = 'created',

        # The order to sort by.
        # Default: asc when using full_name, otherwise desc.
        [Parameter(ParameterSetName = 'MyRepos')]
        [Parameter(ParameterSetName = 'ListByOrg')]
        [Parameter(ParameterSetName = 'ListByUser')]
        [ValidateSet('asc', 'desc')]
        [string] $Direction,

        # The number of results per page (max 100).
        [Parameter(ParameterSetName = 'MyRepos')]
        [Parameter(ParameterSetName = 'ListByOrg')]
        [Parameter(ParameterSetName = 'ListByUser')]
        [int] $PerPage = 30

    )

    DynamicParam {
        $runtimeDefinedParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]

        if ($PSCmdlet.ParameterSetName -in 'MyRepos_Type', 'ListByOrg', 'ListByUser') {
            $parameterName = 'Type'
            $parameterAttribute = New-Object System.Management.Automation.ParameterAttribute

            switch ($PSCmdlet.ParameterSetName) {
                'MyRepos_Type' {
                    $parameterAttribute.Mandatory = $false
                    $parameterAttribute.ParameterSetName = 'MyRepos_Type'
                }
                'ListByOrg' {
                    $parameterAttribute.Mandatory = $false
                    $parameterAttribute.ParameterSetName = 'ListByOrg'
                }
                'ListByUser' {
                    $parameterAttribute.Mandatory = $false
                    $parameterAttribute.ParameterSetName = 'ListByUser'
                }
            }
            $attributeCollection.Add($parameterAttribute)

            switch ($PSCmdlet.ParameterSetName) {
                'MyRepos_Type' {
                    $parameterValidateSet = 'all', 'owner', 'public', 'private', 'member'
                }
                'ListByOrg' {
                    $parameterValidateSet = 'all', 'public', 'private', 'forks', 'sources', 'member'
                }
                'ListByUser' {
                    $parameterValidateSet = 'all', 'owner', 'member'
                }
            }
            $validateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($parameterValidateSet)
            $attributeCollection.Add($validateSetAttribute)

            $runtimeDefinedParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($parameterName, [string], $attributeCollection)
            $runtimeDefinedParameterDictionary.Add($parameterName, $runtimeDefinedParameter)
        }
        return $runtimeDefinedParameterDictionary
    }

    Process {
        $Type = $PSBoundParameters['Type']

        switch ($PSCmdlet.ParameterSetName) {
            'MyRepos_Type' {
                $params = @{
                    Type      = $Type
                    Sort      = $Sort
                    Direction = $Direction
                    PerPage   = $PerPage
                    Since     = $Since
                    Before    = $Before
                }
                Remove-HashTableEntries -Hashtable $params -NullOrEmptyValues
                Get-GitHubMyRepositories @params
            }
            'MyRepos_Aff-Vis' {
                $params = @{
                    Visibility  = $Visibility
                    Affiliation = $Affiliation
                    Sort        = $Sort
                    Direction   = $Direction
                    PerPage     = $PerPage
                    Since       = $Since
                    Before      = $Before
                }
                Remove-HashTableEntries -Hashtable $params -NullOrEmptyValues
                Get-GitHubMyRepositories @params
            }
            'ByName' {
                $params = @{
                    Owner = $Owner
                    Repo  = $Repo
                }
                Remove-HashTableEntries -Hashtable $params -NullOrEmptyValues
                Get-GitHubRepositoryByName @params
            }
            'ListByID' {
                $params = @{
                    Since = $SinceID
                }
                Remove-HashTableEntries -Hashtable $params -NullOrEmptyValues
                Get-GitHubRepositoryListByID @params
            }
            'ListByOrg' {
                $params = @{
                    Owner     = $Owner
                    Type      = $Type
                    Sort      = $Sort
                    Direction = $Direction
                    PerPage   = $PerPage
                }
                Remove-HashTableEntries -Hashtable $params -NullOrEmptyValues
                Get-GitHubRepositoryListByOrg @params
            }
            'ListByUser' {
                $params = @{
                    Username  = $Username
                    Type      = $Type
                    Sort      = $Sort
                    Direction = $Direction
                    PerPage   = $PerPage
                }
                Remove-HashTableEntries -Hashtable $params -NullOrEmptyValues
                Get-GitHubRepositoryListByUser @params
            }
        }
    }
}

Write-Verbose "[$scriptName] - [public/Repositories/Repositories/Get-GitHubRepository.ps1] - Done"
#endregion - From public/Repositories/Repositories/Get-GitHubRepository.ps1
#region - From public/Repositories/Repositories/New-GitHubRepositoryOrg.ps1
Write-Verbose "[$scriptName] - [public/Repositories/Repositories/New-GitHubRepositoryOrg.ps1] - Importing"

filter New-GitHubRepositoryOrg {
    <#
        .SYNOPSIS
        Create an organization repository

        .DESCRIPTION
        Creates a new repository in the specified organization. The authenticated user must be a member of the organization.

        **OAuth scope requirements**

        When using [OAuth](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/), authorizations must include:

        * `public_repo` scope or `repo` scope to create a public repository. Note: For GitHub AE, use `repo` scope to create an internal repository.
        * `repo` scope to create a private repository

        .EXAMPLE
        $params = @{
            Owner = 'PSModule'
            Name = 'Hello-World'
            Description = 'This is your first repository'
            Homepage = 'https://github.com'
            HasIssues = $true
            HasProjects = $true
            HasWiki = $true
            HasDownloads = $true
            IsTemplate = $true
            AutoInit = $true
            AllowSquashMerge = $true
            AllowAutoMerge = $true
            DeleteBranchOnMerge = $true
            SquashMergeCommitTitle = 'PR_TITLE'
            SquashMergeCommitMessage = 'PR_BODY'
        }
        New-GitHubRepositoryOrg @params

        .NOTES
        https://docs.github.com/rest/repos/repos#create-an-organization-repository

    #>

    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        # The name of the repository.
        [Parameter(Mandatory)]
        [string] $Name,

        # A short description of the repository.
        [Parameter()]
        [string] $Description,

        # A URL with more information about the repository.
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [uri] $Homepage,

        # Whether the repository is private.
        [Parameter()]
        [switch] $Private,

        #The visibility of the repository.
        [Parameter()]
        [ValidateSet('public', 'private')]
        [string] $Visibility,

        # Either true to enable issues for this repository or false to disable them.
        [Parameter()]
        [Alias('has_issues')]
        [switch] $HasIssues,

        # Either true to enable projects for this repository or false to disable them.
        # Note: If you're creating a repository in an organization that has disabled repository projects, the default is false, and if you pass true, the API returns an error.
        [Parameter()]
        [Alias('has_projects')]
        [switch] $HasProjects,

        # Either true to enable the wiki for this repository or false to disable it.
        [Parameter()]
        [Alias('has_wiki')]
        [switch] $HasWiki,

        # Whether downloads are enabled.
        [Parameter()]
        [Alias('has_downloads')]
        [switch] $HasDownloads,

        # Either true to make this repo available as a template repository or false to prevent it.
        [Parameter()]
        [Alias('is_template')]
        [switch] $IsTemplate,

        # The id of the team that will be granted access to this repository. This is only valid when creating a repository in an organization.
        [Parameter()]
        [Alias('team_id')]
        [int] $TeamID,

        # Pass true to create an initial commit with empty README.
        [Parameter()]
        [Alias('auto_init')]
        [switch] $AutoInit,

        # Desired language or platform .gitignore template to apply. Use the name of the template without the extension. For example, "Haskell".
        [Parameter()]
        [Alias('gitignore_template')]
        [string] $GitignoreTemplate,

        # Choose an open source license template that best suits your needs, and then use the license keyword as the license_template string. For example, "mit" or "mpl-2.0".
        [Parameter()]
        [Alias('license_template')]
        [string] $LicenseTemplate,

        # Either true to allow squash-merging pull requests, or false to prevent squash-merging.
        [Parameter()]
        [Alias('allow_squash_merge')]
        [switch] $AllowSquashMerge,

        # Either true to allow merging pull requests with a merge commit, or false to prevent merging pull requests with merge commits.
        [Parameter()]
        [Alias('allow_merge_commit')]
        [switch] $AllowMergeCommit,

        # Either true to allow rebase-merging pull requests, or false to prevent rebase-merging.
        [Parameter()]
        [Alias('allow_rebase_merge')]
        [switch] $AllowRebaseMerge,

        # Either true to allow auto-merge on pull requests, or false to disallow auto-merge.
        [Parameter()]
        [Alias('allow_auto_merge')]
        [switch] $AllowAutoMerge,

        # Either true to allow automatically deleting head branches when pull requests are merged, or false to prevent automatic deletion. The authenticated user must be an organization owner to set this property to true.
        [Parameter()]
        [Alias('delete_branch_on_merge')]
        [switch] $DeleteBranchOnMerge,

        # The default value for a squash merge commit title:
        # - PR_TITLE - default to the pull request's title.
        # - COMMIT_OR_PR_TITLE - default to the commit's title (if only one commit) or the pull request's title (when more than one commit).
        [Parameter()]
        [ValidateSet('PR_TITLE', 'COMMIT_OR_PR_TITLE')]
        [Alias('squash_merge_commit_title')]
        [string] $SquashMergeCommitTitle,

        # The default value for a squash merge commit message:
        # - PR_BODY - default to the pull request's body.
        # - COMMIT_MESSAGES - default to the branch's commit messages.
        # - BLANK - default to a blank commit message.
        [Parameter()]
        [ValidateSet('PR_BODY', 'COMMIT_MESSAGES', 'BLANK')]
        [Alias('squash_merge_commit_message')]
        [string] $SquashMergeCommitMessage,

        # The default value for a merge commit title.
        # - PR_TITLE - default to the pull request's title.
        # - MERGE_MESSAGE - default to the classic title for a merge message (e.g.,Merge pull request #123 from branch-name).
        [Parameter()]
        [ValidateSet('PR_TITLE', 'MERGE_MESSAGE')]
        [Alias('merge_commit_title')]
        [string] $MergeCommitTitle,

        # The default value for a merge commit message.
        # - PR_BODY - default to the pull request's body.
        # - PR_TITLE - default to the pull request's title.
        # - BLANK - default to a blank commit message.
        [Parameter()]
        [ValidateSet('PR_BODY', 'PR_TITLE', 'BLANK')]
        [Alias('merge_commit_message')]
        [string] $MergeCommitMessage
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramDefaultValue = Get-Variable -Name $_.Key -ValueOnly -ErrorAction SilentlyContinue
        if (-not $PSBoundParameters.ContainsKey($_.Key) -and ($null -ne $paramDefaultValue)) {
            $PSBoundParameters[$_.Key] = $paramDefaultValue
        }
    }

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntries -Hashtable $body -RemoveNames 'Owner'

    $inputObject = @{
        APIEndpoint = "/orgs/$Owner/repos"
        Method      = 'POST'
        Body        = $body
    }

    Invoke-GitHubAPI @inputObject | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [public/Repositories/Repositories/New-GitHubRepositoryOrg.ps1] - Done"
#endregion - From public/Repositories/Repositories/New-GitHubRepositoryOrg.ps1

Write-Verbose "[$scriptName] - [public/Repositories/Repositories] - Done"
#endregion - From public/Repositories/Repositories


Write-Verbose "[$scriptName] - [public/Repositories] - Done"
#endregion - From public/Repositories

#region - From public/Status
Write-Verbose "[$scriptName] - [public/Status] - Processing folder"

#region - From public/Status/Get-GitHubScheduledMaintenance.ps1
Write-Verbose "[$scriptName] - [public/Status/Get-GitHubScheduledMaintenance.ps1] - Importing"

function Get-GitHubScheduledMaintenance {
    <#
        .SYNOPSIS
        Gets the status of GitHub scheduled maintenance

        .DESCRIPTION
        Scheduled maintenances are planned outages, upgrades, or general notices that you're working
        on infrastructure and disruptions may occurr. A close sibling of Incidents, each usually goes
        through a progression of statuses listed below, with an impact calculated from a blend of
        component statuses (or an optional override).

        Status: Scheduled, In Progress, Verifying, or Completed
        Impact: None (black), Minor (yellow), Major (orange), or Critical (red)

        .EXAMPLE
        Get-GitHubScheduledMaintenance

        Get a list of the 50 most recent scheduled maintenances.
        This includes scheduled maintenances as described in the above two endpoints, as well as those in the Completed state.

        .EXAMPLE
        Get-GitHubScheduledMaintenance -Active

        Get a list of any active maintenances.

        .EXAMPLE
        Get-GitHubScheduledMaintenance -Upcoming

        Get a list of any upcoming maintenances.

        .NOTES
        https://www.githubstatus.com/api#scheduled-maintenances
    #>

    param(
        # Get a list of any active maintenances.
        # This endpoint will only return scheduled maintenances in the In Progress or Verifying state.
        [Parameter()]
        [switch] $Active,

        # Get a list of any upcoming maintenances.
        # This endpoint will only return scheduled maintenances still in the Scheduled state.
        [Parameter()]
        [switch] $Upcoming
    )

    if ($Active) {
        $APIURI = 'https://www.githubstatus.com/api/v2/scheduled-maintenances/active.json'
        $response = Invoke-RestMethod -Uri $APIURI -Method Get
        $response.scheduled_maintenances
        return
    }

    if ($Upcoming) {
        $APIURI = 'https://www.githubstatus.com/api/v2/scheduled-maintenances/upcoming.json'
        $response = Invoke-RestMethod -Uri $APIURI -Method Get
        $response.scheduled_maintenances
        return
    }

    $APIURI = 'https://www.githubstatus.com/api/v2/scheduled-maintenances.json'
    $response = Invoke-RestMethod -Uri $APIURI -Method Get
    $response.scheduled_maintenances

}

Write-Verbose "[$scriptName] - [public/Status/Get-GitHubScheduledMaintenance.ps1] - Done"
#endregion - From public/Status/Get-GitHubScheduledMaintenance.ps1
#region - From public/Status/Get-GitHubStatus.ps1
Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatus.ps1] - Importing"

function Get-GitHubStatus {
    <#
        .SYNOPSIS
        Gets the status of GitHub services

        .DESCRIPTION
        Get a summary of the status page, including a status indicator, component statuses, unresolved incidents, and any upcoming or in-progress scheduled maintenances.
        Get the status rollup for the whole page. This endpoint includes an indicator - one of none, minor, major, or critical, as well as a human description of the blended component status. Examples of the blended status include "All Systems Operational", "Partial System Outage", and "Major Service Outage".

        .EXAMPLE
        Get-GitHubStatus

        Gets the status of GitHub services

        .EXAMPLE
        Get-GitHubStatus -Summary

        Gets a summary of the status page, including a status indicator, component statuses, unresolved incidents, and any upcoming or in-progress scheduled maintenances.

        .NOTES
        https://www.githubstatus.com/api#summary
        https://www.githubstatus.com/api#status
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param(
        # Gets a summary of the status page, including a status indicator, component statuses, unresolved incidents, and any upcoming or in-progress scheduled maintenances.
        [Parameter()]
        [switch] $Summary
    )

    if ($Summary) {
        $APIURI = 'https://www.githubstatus.com/api/v2/summary.json'
        $response = Invoke-RestMethod -Uri $APIURI -Method Get
        $response
        return
    }

    $APIURI = 'https://www.githubstatus.com/api/v2/status.json'
    $response = Invoke-RestMethod -Uri $APIURI -Method Get
    $response.status

}

Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatus.ps1] - Done"
#endregion - From public/Status/Get-GitHubStatus.ps1
#region - From public/Status/Get-GitHubStatusComponents.ps1
Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatusComponents.ps1] - Importing"

function Get-GitHubStatusComponents {
    <#
        .SYNOPSIS
        Gets the status of GitHub components

        .DESCRIPTION
        Get the components for the page. Each component is listed along with its status - one of operational, degraded_performance, partial_outage, or major_outage.

        .EXAMPLE
        Get-GitHubStatusComponents

        Gets the status of GitHub components

        .NOTES
        https://www.githubstatus.com/api#components
    #>

    [OutputType([pscustomobject[]])]
    [CmdletBinding()]
    param()

    $APIURI = 'https://www.githubstatus.com/api/v2/components.json'
    $response = Invoke-RestMethod -Uri $APIURI -Method Get
    $response.components
}

Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatusComponents.ps1] - Done"
#endregion - From public/Status/Get-GitHubStatusComponents.ps1
#region - From public/Status/Get-GitHubStatusIncidents.ps1
Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatusIncidents.ps1] - Importing"

function Get-GitHubStatusIncidents {
    <#
        .SYNOPSIS
        Gets the status of GitHub incidents

        .DESCRIPTION
        Incidents are the cornerstone of any status page, being composed of many incident updates.
        Each incident usually goes through a progression of statuses listed below, with an impact
        calculated from a blend of component statuses (or an optional override).

        Status: Investigating, Identified, Monitoring, Resolved, or Postmortem
        Impact: None (black), Minor (yellow), Major (orange), or Critical (red)

        .EXAMPLE
        Get-GitHubStatusIncidents

        Gets the status of GitHub incidents

        .EXAMPLE
        Get-GitHubStatusIncidents -Unresolved

        Gets the status of GitHub incidents that are unresolved

        .NOTES
        https://www.githubstatus.com/api#incidents
    #>

    [OutputType([pscustomobject[]])]
    [CmdletBinding()]
    param(
        # Gets the status of GitHub incidents that are unresolved
        [Parameter()]
        [switch] $Unresolved
    )

    if ($Unresolved) {
        $APIURI = 'https://www.githubstatus.com/api/v2/incidents/unresolved.json'
        $response = Invoke-RestMethod -Uri $APIURI -Method Get
        $response.incidents
        return
    }

    $APIURI = 'https://www.githubstatus.com/api/v2/incidents.json'
    $response = Invoke-RestMethod -Uri $APIURI -Method Get
    $response.incidents

}

Write-Verbose "[$scriptName] - [public/Status/Get-GitHubStatusIncidents.ps1] - Done"
#endregion - From public/Status/Get-GitHubStatusIncidents.ps1

Write-Verbose "[$scriptName] - [public/Status] - Done"
#endregion - From public/Status

#region - From public/Teams
Write-Verbose "[$scriptName] - [public/Teams] - Processing folder"

#region - From public/Teams/Get-GitHubRepoTeam.ps1
Write-Verbose "[$scriptName] - [public/Teams/Get-GitHubRepoTeam.ps1] - Importing"

filter Get-GitHubRepoTeam {
    <#
        .NOTES
        https://docs.github.com/rest/reference/repos#get-a-repository
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubConfig -Name Owner),

        [Parameter()]
        [string] $Repo = (Get-GitHubConfig -Name Repo)
    )

    $inputObject = @{
        Method      = 'Get'
        APIEndpoint = "/repos/$Owner/$Repo/teams"
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Teams/Get-GitHubRepoTeam.ps1] - Done"
#endregion - From public/Teams/Get-GitHubRepoTeam.ps1

Write-Verbose "[$scriptName] - [public/Teams] - Done"
#endregion - From public/Teams

#region - From public/Users
Write-Verbose "[$scriptName] - [public/Users] - Processing folder"

#region - From public/Users/Blocking
Write-Verbose "[$scriptName] - [public/Users/Blocking] - Processing folder"

#region - From public/Users/Blocking/Block-GitHubUser.ps1
Write-Verbose "[$scriptName] - [public/Users/Blocking/Block-GitHubUser.ps1] - Importing"

filter Block-GitHubUser {
    <#
        .SYNOPSIS
        Block a user from user or an organization.

        .DESCRIPTION
        Blocks the given user and returns true.
        If the user cannot be blocked false is returned.

        .EXAMPLE
        Block-GitHubUser -Username 'octocat'

        Blocks the user 'octocat' for the authenticated user.
        Returns $true if successful, $false if not.

        .EXAMPLE
        Block-GitHubUser -OrganizationName 'github' -Username 'octocat'

        Blocks the user 'octocat' from the organization 'github'.
        Returns $true if successful, $false if not.

        .NOTES
        https://docs.github.com/rest/users/blocking#block-a-user
        https://docs.github.com/rest/orgs/blocking#block-a-user-from-an-organization
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username,

        # The organization name. The name is not case sensitive.
        [Parameter(
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName
    )

    if ($OrganizationName) {
        Block-GitHubUserByOrganization -OrganizationName $OrganizationName -Username $Username
    } else {
        Block-GitHubUserByUser -Username $Username
    }

}

Write-Verbose "[$scriptName] - [public/Users/Blocking/Block-GitHubUser.ps1] - Done"
#endregion - From public/Users/Blocking/Block-GitHubUser.ps1
#region - From public/Users/Blocking/Get-GitHubBlockedUser.ps1
Write-Verbose "[$scriptName] - [public/Users/Blocking/Get-GitHubBlockedUser.ps1] - Importing"

filter Get-GitHubBlockedUser {
    <#
        .SYNOPSIS
        List blocked users.

        .DESCRIPTION
        List the users that are blocked on your personal account or a given organization.

        .EXAMPLE
        Get-GitHubBlockedUser

        Returns a list of users blocked by the authenticated user.

        .EXAMPLE
        Get-GitHubBlockedUser -OrganizationName 'github'

        Lists all users blocked by the organization `github`.

        .NOTES
        https://docs.github.com/rest/users/blocking#list-users-blocked-by-the-authenticated-user
        https://docs.github.com/rest/orgs/blocking#list-users-blocked-by-an-organization
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    if ($OrganizationName) {
        Get-GitHubBlockedUserByOrganization -OrganizationName $OrganizationName -PerPage $PerPage
    } else {
        Get-GitHubBlockedUserByUser -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [public/Users/Blocking/Get-GitHubBlockedUser.ps1] - Done"
#endregion - From public/Users/Blocking/Get-GitHubBlockedUser.ps1
#region - From public/Users/Blocking/Test-GitHubBlockedUser.ps1
Write-Verbose "[$scriptName] - [public/Users/Blocking/Test-GitHubBlockedUser.ps1] - Importing"

filter Test-GitHubBlockedUser {
    <#
        .SYNOPSIS
        Check if a user is blocked by the authenticated user or an organization.

        .DESCRIPTION
        Returns a 204 if the given user is blocked by the authenticated user or organization.
        Returns a 404 if the given user is not blocked, or if the given user account has been identified as spam by GitHub.

        .EXAMPLE
        Test-GitHubBlockedUser -Username 'octocat'

        Checks if the user `octocat` is blocked by the authenticated user.
        Returns true if the user is blocked, false if not.

        .EXAMPLE
        Test-GitHubBlockedUser -OrganizationName 'github' -Username 'octocat'

        Checks if the user `octocat` is blocked by the organization `github`.
        Returns true if the user is blocked, false if not.

        .NOTES
        https://docs.github.com/rest/users/blocking#check-if-a-user-is-blocked-by-the-authenticated-user
        https://docs.github.com/rest/orgs/blocking#check-if-a-user-is-blocked-by-an-organization
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username,

        # The organization name. The name is not case sensitive.
        [Parameter(
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    if ($OrganizationName) {
        Test-GitHubBlockedUserByOrganization -OrganizationName $OrganizationName -Username $Username -PerPage $PerPage
    } else {
        Test-GitHubBlockedUserByUser -Username $Username -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [public/Users/Blocking/Test-GitHubBlockedUser.ps1] - Done"
#endregion - From public/Users/Blocking/Test-GitHubBlockedUser.ps1
#region - From public/Users/Blocking/Unblock-GitHubUser.ps1
Write-Verbose "[$scriptName] - [public/Users/Blocking/Unblock-GitHubUser.ps1] - Importing"

filter Unblock-GitHubUser {
    <#
        .SYNOPSIS
        Unblock a user

        .DESCRIPTION
        Unblocks the given user and returns true.

        .EXAMPLE
        Unblock-GitHubUser -Username 'octocat'

        Unblocks the user 'octocat' for the authenticated user.
        Returns $true if successful.

        .EXAMPLE
        Unblock-GitHubUser -OrganizationName 'github' -Username 'octocat'

        Unblocks the user 'octocat' from the organization 'github'.
        Returns $true if successful.

        .NOTES
        https://docs.github.com/rest/users/blocking#unblock-a-user
        https://docs.github.com/rest/orgs/blocking#unblock-a-user-from-an-organization
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username,

        # The organization name. The name is not case sensitive.
        [Parameter(
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('org')]
        [Alias('owner')]
        [Alias('login')]
        [string] $OrganizationName
    )

    if ($OrganizationName) {
        Unblock-GitHubUserByOrganization -OrganizationName $OrganizationName -Username $Username
    } else {
        Unblock-GitHubUserByUser -Username $Username
    }
}

Write-Verbose "[$scriptName] - [public/Users/Blocking/Unblock-GitHubUser.ps1] - Done"
#endregion - From public/Users/Blocking/Unblock-GitHubUser.ps1

Write-Verbose "[$scriptName] - [public/Users/Blocking] - Done"
#endregion - From public/Users/Blocking

#region - From public/Users/Emails
Write-Verbose "[$scriptName] - [public/Users/Emails] - Processing folder"

#region - From public/Users/Emails/Add-GitHubUserEmail.ps1
Write-Verbose "[$scriptName] - [public/Users/Emails/Add-GitHubUserEmail.ps1] - Importing"

filter Add-GitHubUserEmail {
    <#
        .SYNOPSIS
        Add an email address for the authenticated user

        .DESCRIPTION
        This endpoint is accessible with the `user` scope.

        .EXAMPLE
        Add-GitHubUserEmail -Emails 'octocat@github.com','firstname.lastname@work.com'

        Adds the email addresses 'octocat@github.com' and 'firstname.lastname@work.com' to the authenticated user's account.

        .NOTES
        https://docs.github.com/rest/users/emails#add-an-email-address-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # Adds one or more email addresses to your GitHub account.
        # Must contain at least one email address.
        # Note: Alternatively, you can pass a single email address or an array of emails addresses directly,
        # but we recommend that you pass an object using the emails key.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [string[]] $Emails
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/emails"
        Method      = 'POST'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Emails/Add-GitHubUserEmail.ps1] - Done"
#endregion - From public/Users/Emails/Add-GitHubUserEmail.ps1
#region - From public/Users/Emails/Get-GitHubUserEmail.ps1
Write-Verbose "[$scriptName] - [public/Users/Emails/Get-GitHubUserEmail.ps1] - Importing"

filter Get-GitHubUserEmail {
    <#
        .SYNOPSIS
        List email addresses for the authenticated user

        .DESCRIPTION
        Lists all of your email addresses, and specifies which one is visible to the public. This endpoint is accessible with the `user:email` scope.
        Specifying '-Public' will return only the publicly visible email address, which you can set with the [Set primary email visibility for the authenticated user](https://docs.github.com/rest/users/emails#set-primary-email-visibility-for-the-authenticated-user) endpoint.

        .EXAMPLE
        Get-GitHubUserEmail

        Gets all email addresses for the authenticated user.

        .EXAMPLE
        Get-GitHubUserEmail -Public

        Gets the publicly visible email address for the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/emails#list-email-addresses-for-the-authenticated-user
        https://docs.github.com/en/rest/users/emails#list-public-email-addresses-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30,

        [Parameter()]
        [switch] $Public
    )

    if ($Public) {
        Get-GitHubUserPublicEmail -PerPage $PerPage
    } else {
        Get-GitHubUserAllEmail -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [public/Users/Emails/Get-GitHubUserEmail.ps1] - Done"
#endregion - From public/Users/Emails/Get-GitHubUserEmail.ps1
#region - From public/Users/Emails/Remove-GitHubUserEmail.ps1
Write-Verbose "[$scriptName] - [public/Users/Emails/Remove-GitHubUserEmail.ps1] - Importing"

filter Remove-GitHubUserEmail {
    <#
        .SYNOPSIS
        Delete an email address for the authenticated user

        .DESCRIPTION
        This endpoint is accessible with the `user` scope.

        .EXAMPLE
        Remove-GitHubUserEmail -Emails 'octocat@github.com','firstname.lastname@work.com'

        Removes the email addresses 'octocat@github.com' and 'firstname.lastname@work.com' from the authenticated user's account.

        .NOTES
        https://docs.github.com/rest/users/emails#delete-an-email-address-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # Email addresses associated with the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [string[]] $Emails
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/emails"
        Method      = 'DELETE'
        Body        = $body
    }

    $null = (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Emails/Remove-GitHubUserEmail.ps1] - Done"
#endregion - From public/Users/Emails/Remove-GitHubUserEmail.ps1
#region - From public/Users/Emails/Set-GitHubUserEmailVisibility.ps1
Write-Verbose "[$scriptName] - [public/Users/Emails/Set-GitHubUserEmailVisibility.ps1] - Importing"

filter Set-GitHubUserEmailVisibility {
    <#
        .SYNOPSIS
        Set primary email visibility for the authenticated user

        .DESCRIPTION
        Sets the visibility for your primary email addresses.

        .EXAMPLE
        Set-GitHubUserEmailVisibility -Visibility public

        Sets the visibility for your primary email addresses to public.

        .EXAMPLE
        Set-GitHubUserEmailVisibility -Visibility private

        Sets the visibility for your primary email addresses to private.

        .NOTES
        https://docs.github.com/rest/users/emails#set-primary-email-visibility-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # Denotes whether an email is publicly visible.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [ValidateSet('public', 'private')]
        [string] $Visibility
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/email/visibility"
        Method      = 'PATCH'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Emails/Set-GitHubUserEmailVisibility.ps1] - Done"
#endregion - From public/Users/Emails/Set-GitHubUserEmailVisibility.ps1

Write-Verbose "[$scriptName] - [public/Users/Emails] - Done"
#endregion - From public/Users/Emails

#region - From public/Users/Followers
Write-Verbose "[$scriptName] - [public/Users/Followers] - Processing folder"

#region - From public/Users/Followers/Add-GitHubUserFollowing.ps1
Write-Verbose "[$scriptName] - [public/Users/Followers/Add-GitHubUserFollowing.ps1] - Importing"

filter Add-GitHubUserFollowing {
    <#
        .SYNOPSIS
        Follow a user

        .DESCRIPTION
        Note that you'll need to set `Content-Length` to zero when calling out to this endpoint.
        For more information, see "[HTTP verbs](https://docs.github.com/rest/overview/resources-in-the-rest-api#http-verbs)."
        Following a user requires the user to be logged in and authenticated with basic auth or OAuth with the `user:follow` scope.

        .EXAMPLE
        Follow-GitHubUser -Username 'octocat'

        Follows the user with the username 'octocat'.

        .NOTES
        https://docs.github.com/rest/users/followers#follow-a-user

    #>

    [OutputType([pscustomobject])]
    [Alias('Follow-GitHubUser')]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/user/following/$Username"
        Method      = 'PUT'
    }

    $null = (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Followers/Add-GitHubUserFollowing.ps1] - Done"
#endregion - From public/Users/Followers/Add-GitHubUserFollowing.ps1
#region - From public/Users/Followers/Get-GitHubUserFollowers.ps1
Write-Verbose "[$scriptName] - [public/Users/Followers/Get-GitHubUserFollowers.ps1] - Importing"

filter Get-GitHubUserFollowers {
    <#
        .SYNOPSIS
        List followers of a given user or the authenticated user

        .DESCRIPTION
        Lists the people following a given user or the authenticated user.

        .EXAMPLE
        Get-GitHubUserFollowers

        Gets all followers of the authenticated user.

        .EXAMPLE
        Get-GitHubUserFollowers -Username 'octocat'

        Gets all followers of the user 'octocat'.

        .NOTES
        https://docs.github.com/rest/users/followers#list-followers-of-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    if ($Username) {
        Get-GitHubUserFollowersOfUser -Username $Username -PerPage $PerPage
    } else {
        Get-GitHubUserMyFollowers -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [public/Users/Followers/Get-GitHubUserFollowers.ps1] - Done"
#endregion - From public/Users/Followers/Get-GitHubUserFollowers.ps1
#region - From public/Users/Followers/Get-GitHubUserFollowing.ps1
Write-Verbose "[$scriptName] - [public/Users/Followers/Get-GitHubUserFollowing.ps1] - Importing"

filter Get-GitHubUserFollowing {
    <#
        .SYNOPSIS
        List the people a given user or the authenticated user follows

        .DESCRIPTION
        Lists the people who a given user or the authenticated user follows.

        .EXAMPLE
        Get-GitHubUserFollowing

        Gets all people the authenticated user follows.

        .EXAMPLE
        Get-GitHubUserFollowing -Username 'octocat'

        Gets all people that 'octocat' follows.

        .NOTES
        https://docs.github.com/rest/users/followers#list-the-people-the-authenticated-user-follows
        https://docs.github.com/rest/users/followers#list-the-people-a-user-follows

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('login')]
        [string] $Username,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    if ($Username) {
        Get-GitHubUserFollowingUser -Username $Username -PerPage $PerPage
    } else {
        Get-GitHubUserFollowingMe -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [public/Users/Followers/Get-GitHubUserFollowing.ps1] - Done"
#endregion - From public/Users/Followers/Get-GitHubUserFollowing.ps1
#region - From public/Users/Followers/Remove-GitHubUserFollowing.ps1
Write-Verbose "[$scriptName] - [public/Users/Followers/Remove-GitHubUserFollowing.ps1] - Importing"

filter Remove-GitHubUserFollowing {
    <#
        .SYNOPSIS
        Unfollow a user

        .DESCRIPTION
        Unfollowing a user requires the user to be logged in and authenticated with basic auth or OAuth with the `user:follow` scope.

        .EXAMPLE
        Unfollow-GitHubUser -Username 'octocat'

        Unfollows the user with the username 'octocat'.

        .NOTES
        https://docs.github.com/rest/users/followers#unfollow-a-user

    #>

    [OutputType([pscustomobject])]
    [Alias('Unfollow-GitHubUser')]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username
    )

    $inputObject = @{
        APIEndpoint = "/user/following/$Username"
        Method      = 'DELETE'
    }

    $null = (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Followers/Remove-GitHubUserFollowing.ps1] - Done"
#endregion - From public/Users/Followers/Remove-GitHubUserFollowing.ps1
#region - From public/Users/Followers/Test-GitHubUserFollows.ps1
Write-Verbose "[$scriptName] - [public/Users/Followers/Test-GitHubUserFollows.ps1] - Importing"

filter Test-GitHubUserFollows {
    <#
        .SYNOPSIS
        Check if a given user or the authenticated user follows a person

        .DESCRIPTION
        Returns a 204 if the given user or the authenticated user follows another user.
        Returns a 404 if the user is not followed by a given user or the authenticated user.

        .EXAMPLE
        Test-GitHubUserFollows -Follows 'octocat'
        Test-GitHubUserFollows 'octocat'

        Checks if the authenticated user follows the user 'octocat'.

        .EXAMPLE
        Test-GitHubUserFollows -Username 'octocat' -Follows 'ratstallion'

        Checks if the user 'octocat' follows the user 'ratstallion'.

        .NOTES
        https://docs.github.com/rest/users/followers#check-if-a-person-is-followed-by-the-authenticated-user
        https://docs.github.com/rest/users/followers#check-if-a-user-follows-another-user

    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account we want to check if is being followed.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [string] $Follows,

        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username

    )

    if ($Username) {
        Test-GitHubUserFollowedByUser -Username $Username -Follows $Follows
    } else {
        Test-GitHubUserFollowedByMe -Username $Follows
    }

}

Write-Verbose "[$scriptName] - [public/Users/Followers/Test-GitHubUserFollows.ps1] - Done"
#endregion - From public/Users/Followers/Test-GitHubUserFollows.ps1

Write-Verbose "[$scriptName] - [public/Users/Followers] - Done"
#endregion - From public/Users/Followers

#region - From public/Users/GPG-Keys
Write-Verbose "[$scriptName] - [public/Users/GPG-Keys] - Processing folder"

#region - From public/Users/GPG-Keys/Add-GitHubUserGpgKey.ps1
Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Add-GitHubUserGpgKey.ps1] - Importing"

filter Add-GitHubUserGpgKey {
    <#
        .SYNOPSIS
        Create a GPG key for the authenticated user

        .DESCRIPTION
        Adds a GPG key to the authenticated user's GitHub account.
        Requires that you are authenticated via Basic Auth, or OAuth with at least `write:gpg_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).

        .EXAMPLE
        Add-GitHubUserGpgKey -Name 'GPG key for GitHub' -ArmoredPublicKey '-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: GnuPG v1\n\nmQINBFnZ2ZIBEADQ2Z7Z7\n-----END PGP PUBLIC KEY BLOCK-----'

        Adds a GPG key to the authenticated user's GitHub account.

        .NOTES
        https://docs.github.com/rest/users/gpg-keys#create-a-gpg-key-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # A descriptive name for the new key.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [string] $Name,

        # A GPG key in ASCII-armored format.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [Alias('armored_public_key')]
        [string] $ArmoredPublicKey

    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/gpg_keys"
        Method      = 'POST'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Add-GitHubUserGpgKey.ps1] - Done"
#endregion - From public/Users/GPG-Keys/Add-GitHubUserGpgKey.ps1
#region - From public/Users/GPG-Keys/Get-GitHubUserGpgKey.ps1
Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Get-GitHubUserGpgKey.ps1] - Importing"

filter Get-GitHubUserGpgKey {
    <#
        .SYNOPSIS
        List GPG keys for a given user or the authenticated user

        .DESCRIPTION
        Lists a given user's or the current user's GPG keys.

        .EXAMPLE
        Get-GitHubUserGpgKey

        Gets all GPG keys for the authenticated user.

        .EXAMPLE
        Get-GitHubUserGpgKey -ID '1234567'

        Gets the GPG key with ID '1234567' for the authenticated user.

        .EXAMPLE
        Get-GitHubUserGpgKey -Username 'octocat'

        Gets all GPG keys for the 'octocat' user.

        .NOTES
        https://docs.github.com/rest/users/gpg-keys#list-gpg-keys-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            ParameterSetName = 'Username'
        )]
        [string] $Username,

        # The ID of the GPG key.
        [Parameter(
            ParameterSetName = 'Me'
        )]
        [Alias('gpg_key_id')]
        [string] $ID,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    if ($Username) {
        Get-GitHubUserGpgKeyForUser -Username $Username -PerPage $PerPage
    } else {
        if ($ID) {
            Get-GitHubUserMyGpgKeyById -ID $ID
        } else {
            Get-GitHubUserMyGpgKey -PerPage $PerPage
        }
    }
}

Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Get-GitHubUserGpgKey.ps1] - Done"
#endregion - From public/Users/GPG-Keys/Get-GitHubUserGpgKey.ps1
#region - From public/Users/GPG-Keys/Remove-GitHubUserGpgKey.ps1
Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Remove-GitHubUserGpgKey.ps1] - Importing"

filter Remove-GitHubUserGpgKey {
    <#
        .SYNOPSIS
        Delete a GPG key for the authenticated user

        .DESCRIPTION
        Removes a GPG key from the authenticated user's GitHub account.
        Requires that you are authenticated via Basic Auth or via OAuth with at least `admin:gpg_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).

        .EXAMPLE
        Remove-GitHubUserGpgKey -ID '1234567'

        Gets the GPG key with ID '1234567' for the authenticated user.

        .NOTES
        https://docs.github.com/rest/users/gpg-keys#delete-a-gpg-key-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The ID of the GPG key.
        [Parameter(
            Mandatory
        )]
        [Alias('gpg_key_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/user/gpg_keys/$ID"
        Method      = 'DELETE'
    }

    $null = (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/GPG-Keys/Remove-GitHubUserGpgKey.ps1] - Done"
#endregion - From public/Users/GPG-Keys/Remove-GitHubUserGpgKey.ps1

Write-Verbose "[$scriptName] - [public/Users/GPG-Keys] - Done"
#endregion - From public/Users/GPG-Keys

#region - From public/Users/Keys
Write-Verbose "[$scriptName] - [public/Users/Keys] - Processing folder"

#region - From public/Users/Keys/Add-GitHubUserKey.ps1
Write-Verbose "[$scriptName] - [public/Users/Keys/Add-GitHubUserKey.ps1] - Importing"

filter Add-GitHubUserKey {
    <#
        .SYNOPSIS
        Create a public SSH key for the authenticated user

        .DESCRIPTION
        Adds a public SSH key to the authenticated user's GitHub account.
        Requires that you are authenticated via Basic Auth, or OAuth with at least `write:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).

        .EXAMPLE
        Add-GitHubUserKey -Title 'ssh-rsa AAAAB3NzaC1yc2EAAA' -Key '2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234'

        Adds a new public SSH key to the authenticated user's GitHub account.

        .NOTES
        https://docs.github.com/rest/users/keys#create-a-public-ssh-key-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # A descriptive name for the new key.
        [Parameter(
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('name')]
        [string] $Title,

        # The public SSH key to add to your GitHub account.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Key

    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/keys"
        Method      = 'POST'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Keys/Add-GitHubUserKey.ps1] - Done"
#endregion - From public/Users/Keys/Add-GitHubUserKey.ps1
#region - From public/Users/Keys/Get-GitHubUserKey.ps1
Write-Verbose "[$scriptName] - [public/Users/Keys/Get-GitHubUserKey.ps1] - Importing"

filter Get-GitHubUserKey {
    <#
        .SYNOPSIS
        List public SSH keys for a given user or the authenticated user.

        .DESCRIPTION
        Lists a given user's or the current user's public SSH keys.
        For the authenticated users keys, it requires that you are authenticated via Basic Auth or via OAuth with at least `read:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).
        Keys from a given user are accessible by anyone.

        .EXAMPLE
        Get-GitHubUserKey

        Gets all GPG keys for the authenticated user.

        .EXAMPLE
        Get-GitHubUserKey -ID '1234567'

        Gets the public SSH key with the ID '1234567' for the authenticated user.

        .EXAMPLE
        Get-GitHubUserKey -Username 'octocat'

        Gets all GPG keys for the 'octocat' user.

        .NOTES
        https://docs.github.com/rest/users/gpg-keys#list-gpg-keys-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            ParameterSetName = 'Username'
        )]
        [string] $Username,

        # The ID of the GPG key.
        [Parameter(
            ParameterSetName = 'Me'
        )]
        [Alias('gpg_key_id')]
        [string] $ID,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    if ($Username) {
        Get-GitHubUserKeyForUser -Username $Username -PerPage $PerPage
    } else {
        if ($ID) {
            Get-GitHubUserMyKeyById -ID $ID
        } else {
            Get-GitHubUserMyKey -PerPage $PerPage
        }
    }
}

Write-Verbose "[$scriptName] - [public/Users/Keys/Get-GitHubUserKey.ps1] - Done"
#endregion - From public/Users/Keys/Get-GitHubUserKey.ps1
#region - From public/Users/Keys/Remove-GitHubUserKey.ps1
Write-Verbose "[$scriptName] - [public/Users/Keys/Remove-GitHubUserKey.ps1] - Importing"

filter Remove-GitHubUserKey {
    <#
        .SYNOPSIS
        Delete a public SSH key for the authenticated user

        .DESCRIPTION
        Removes a public SSH key from the authenticated user's GitHub account.
        Requires that you are authenticated via Basic Auth or via OAuth with at least `admin:public_key` [scope](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/).

        .EXAMPLE
        Remove-GitHubUserKey -ID '1234567'

        Deletes the public SSH key with ID '1234567' from the authenticated user's GitHub account.

        .NOTES
        https://docs.github.com/rest/users/keys#delete-a-public-ssh-key-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The unique identifier of the key.
        [Parameter(
            Mandatory
        )]
        [Alias('key_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/user/keys/$ID"
        Method      = 'DELETE'
    }

    $null = (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Keys/Remove-GitHubUserKey.ps1] - Done"
#endregion - From public/Users/Keys/Remove-GitHubUserKey.ps1

Write-Verbose "[$scriptName] - [public/Users/Keys] - Done"
#endregion - From public/Users/Keys

#region - From public/Users/Social-Accounts
Write-Verbose "[$scriptName] - [public/Users/Social-Accounts] - Processing folder"

#region - From public/Users/Social-Accounts/Add-GitHubUserSocials.ps1
Write-Verbose "[$scriptName] - [public/Users/Social-Accounts/Add-GitHubUserSocials.ps1] - Importing"

filter Add-GitHubUserSocials {
    <#
        .SYNOPSIS
        Add social accounts for the authenticated user

        .DESCRIPTION
        Add one or more social accounts to the authenticated user's profile. This endpoint is accessible with the `user` scope.

        .EXAMPLE
        Add-GitHubUserSocials -AccountUrls 'https://twitter.com/MyTwitterAccount', 'https://www.linkedin.com/company/MyCompany'

        Adds the Twitter and LinkedIn accounts to the authenticated user's profile.

        .NOTES
        https://docs.github.com/rest/users/social-accounts#add-social-accounts-for-the-authenticated-user
    #>

    [OutputType([void])]
    [CmdletBinding()]
    param (
        # Full URLs for the social media profiles to add.
        [Parameter(Mandatory)]
        [Alias('account_urls')]
        [string[]] $AccountUrls
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/user/social_accounts'
        Body        = $body
        Method      = 'POST'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Social-Accounts/Add-GitHubUserSocials.ps1] - Done"
#endregion - From public/Users/Social-Accounts/Add-GitHubUserSocials.ps1
#region - From public/Users/Social-Accounts/Remove-GitHubUserSocials.ps1
Write-Verbose "[$scriptName] - [public/Users/Social-Accounts/Remove-GitHubUserSocials.ps1] - Importing"

filter Remove-GitHubUserSocials {
    <#
        .SYNOPSIS
        Delete social accounts for the authenticated user

        .DESCRIPTION
        Deletes one or more social accounts from the authenticated user's profile. This endpoint is accessible with the `user` scope.

        .PARAMETER AccountUrls
        Parameter description

        .EXAMPLE
        Remove-GitHubUserSocials -AccountUrls 'https://twitter.com/MyTwitterAccount'

        .NOTES
        https://docs.github.com/rest/users/social-accounts#delete-social-accounts-for-the-authenticated-user
    #>

    [OutputType([void])]
    [CmdletBinding()]
    param (
        # Full URLs for the social media profiles to add.
        [Parameter(Mandatory)]
        [Alias('account_urls')]
        [string[]] $AccountUrls
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/user/social_accounts'
        Body        = $body
        Method      = 'DELETE'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Social-Accounts/Remove-GitHubUserSocials.ps1] - Done"
#endregion - From public/Users/Social-Accounts/Remove-GitHubUserSocials.ps1

Write-Verbose "[$scriptName] - [public/Users/Social-Accounts] - Done"
#endregion - From public/Users/Social-Accounts

#region - From public/Users/SSH-Signing-Keys
Write-Verbose "[$scriptName] - [public/Users/SSH-Signing-Keys] - Processing folder"

#region - From public/Users/SSH-Signing-Keys/Add-GitHubUserSigningKey.ps1
Write-Verbose "[$scriptName] - [public/Users/SSH-Signing-Keys/Add-GitHubUserSigningKey.ps1] - Importing"

filter Add-GitHubUserSigningKey {
    <#
        .SYNOPSIS
        Create a SSH signing key for the authenticated user

        .DESCRIPTION
        Creates an SSH signing key for the authenticated user's GitHub account.
        You must authenticate with Basic Authentication, or you must authenticate with OAuth with at least `write:ssh_signing_key` scope. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/)."

        .EXAMPLE
        Add-GitHubUserSigningKey -Title 'ssh-rsa AAAAB3NzaC1yc2EAAA' -Key '2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234'

        Creates a new SSH signing key for the authenticated user's GitHub account.

        .NOTES
        https://docs.github.com/rest/users/ssh-signing-keys#create-a-ssh-signing-key-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # A descriptive name for the new key.
        [Parameter(
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('name')]
        [string] $Title,

        # The public SSH key to add to your GitHub account. For more information, see [Checking for existing SSH keys](https://docs.github.com/authentication/connecting-to-github-with-ssh/checking-for-existing-ssh-keys)."
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $Key

    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = "/user/ssh_signing_keys"
        Method      = 'POST'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/SSH-Signing-Keys/Add-GitHubUserSigningKey.ps1] - Done"
#endregion - From public/Users/SSH-Signing-Keys/Add-GitHubUserSigningKey.ps1
#region - From public/Users/SSH-Signing-Keys/Get-GitHubUserSigningKey.ps1
Write-Verbose "[$scriptName] - [public/Users/SSH-Signing-Keys/Get-GitHubUserSigningKey.ps1] - Importing"

filter Get-GitHubUserSigningKey {
    <#
        .SYNOPSIS
        List SSH signing keys for a given user or the authenticated user.

        .DESCRIPTION
        Lists a given user's or the current user's SSH signing keys.

        .EXAMPLE
        Get-GitHubUserSigningKey

        Gets all SSH signing keys for the authenticated user.

        .EXAMPLE
        Get-GitHubUserSigningKey -ID '1234567'

        Gets the SSH signing key with the ID '1234567' for the authenticated user.

        .EXAMPLE
        Get-GitHubUserSigningKey -Username 'octocat'

        Gets all SSH signing keys for the 'octocat' user.

        .NOTES
        https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-the-authenticated-user
        https://docs.github.com/rest/users/ssh-signing-keys#get-an-ssh-signing-key-for-the-authenticated-user
        https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-a-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            ParameterSetName = 'Username'
        )]
        [string] $Username,

        # The unique identifier of the SSH signing key.
        [Parameter(
            ParameterSetName = 'Me'
        )]
        [Alias('gpg_key_id')]
        [string] $ID,

        # The number of results per page (max 100).
        [Parameter()]
        [int] $PerPage = 30
    )

    if ($Username) {
        Get-GitHubUserSigningKeyForUser -Username $Username -PerPage $PerPage
    } else {
        if ($ID) {
            Get-GitHubUserMySigningKeyById -ID $ID
        } else {
            Get-GitHubUserMySigningKey -PerPage $PerPage
        }
    }
}

Write-Verbose "[$scriptName] - [public/Users/SSH-Signing-Keys/Get-GitHubUserSigningKey.ps1] - Done"
#endregion - From public/Users/SSH-Signing-Keys/Get-GitHubUserSigningKey.ps1
#region - From public/Users/SSH-Signing-Keys/Remove-GitHubUserSigningKey.ps1
Write-Verbose "[$scriptName] - [public/Users/SSH-Signing-Keys/Remove-GitHubUserSigningKey.ps1] - Importing"

filter Remove-GitHubUserSigningKey {
    <#
        .SYNOPSIS
        Delete an SSH signing key for the authenticated user

        .DESCRIPTION
        Deletes an SSH signing key from the authenticated user's GitHub account.
        You must authenticate with Basic Authentication, or you must authenticate with OAuth with at least `admin:ssh_signing_key` scope. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/)."

        .EXAMPLE
        Remove-GitHubUserSigningKey -ID '1234567'

        Removes the SSH signing key with the ID of `1234567` from the authenticated user's GitHub account.

        .NOTES
        https://docs.github.com/rest/users/ssh-signing-keys#delete-an-ssh-signing-key-for-the-authenticated-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        # The unique identifier of the SSH signing key.
        [Parameter(
            Mandatory
        )]
        [Alias('ssh_signing_key_id')]
        [string] $ID
    )

    $inputObject = @{
        APIEndpoint = "/user/ssh_signing_keys/$ID"
        Method      = 'DELETE'
    }

    $null = (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/SSH-Signing-Keys/Remove-GitHubUserSigningKey.ps1] - Done"
#endregion - From public/Users/SSH-Signing-Keys/Remove-GitHubUserSigningKey.ps1

Write-Verbose "[$scriptName] - [public/Users/SSH-Signing-Keys] - Done"
#endregion - From public/Users/SSH-Signing-Keys

#region - From public/Users/Get-GitHubUser.ps1
Write-Verbose "[$scriptName] - [public/Users/Get-GitHubUser.ps1] - Importing"

filter Get-GitHubUser {
    <#
        .SYNOPSIS
        List user(s)

        .DESCRIPTION
        Get the authenticated user - if no parameters are provided.
        Get a given user - if a username is provided.
        Lists all users, in the order that they signed up on GitHub - if '-All' is provided.

        .EXAMPLE
        Get-GitHubUser

        Get the authenticated user.

        .EXAMPLE
        Get-GitHubUser -Username 'octocat'

        Get the 'octocat' user.

        .EXAMPLE
        Get-GitHubUser -All -Since 17722253

        Get a list of users, starting with the user 'MariusStorhaug'.

        .NOTES
        https://docs.github.com/rest/users/users
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(DefaultParameterSetName = '__DefaultSet')]
    param (
        # The handle for the GitHub user account.
        [Parameter(
            Mandatory,
            ParameterSetName = 'NamedUser',
            ValueFromPipelineByPropertyName
        )]
        [string] $Username,

        # List all users. Use '-Since' to start at a specific user id.
        [Parameter(
            Mandatory,
            ParameterSetName = 'AllUsers'
        )]
        [switch] $All,

        # A user ID. Only return users with an ID greater than this ID.
        [Parameter(ParameterSetName = 'AllUsers')]
        [int] $Since = 0,

        # The number of results per page (max 100).
        [Parameter(ParameterSetName = 'AllUsers')]
        [int] $PerPage = 30
    )

    switch ($PSCmdlet.ParameterSetName) {
        '__DefaultSet' {
            $user = Get-GitHubMyUser
            $social_accounts = Get-GitHubMyUserSocials
            $user | Add-Member -MemberType NoteProperty -Name 'social_accounts' -Value $social_accounts -Force
            $user
        }
        'NamedUser' {
            $user = Get-GitHubUserByName -Username $Username
            $social_accounts = Get-GitHubUserSocialsByName -Username $Username
            $user | Add-Member -MemberType NoteProperty -Name 'social_accounts' -Value $social_accounts -Force
            $user
        }
        'AllUsers' {
            Get-GitHubAllUsers -Since $Since -PerPage $PerPage
        }
    }
}

Write-Verbose "[$scriptName] - [public/Users/Get-GitHubUser.ps1] - Done"
#endregion - From public/Users/Get-GitHubUser.ps1
#region - From public/Users/Get-GitHubUserCard.ps1
Write-Verbose "[$scriptName] - [public/Users/Get-GitHubUserCard.ps1] - Importing"

filter Get-GitHubUserCard {
    <#
        .SYNOPSIS
        Get contextual information for a user

        .DESCRIPTION
        Provides hovercard information when authenticated through basic auth or OAuth with the `repo` scope. You can find out more about someone in relation to their pull requests, issues, repositories, and organizations.

        The `subject_type` and `subject_id` parameters provide context for the person's hovercard, which returns more information than without the parameters. For example, if you wanted to find out more about `octocat` who owns the `Spoon-Knife` repository via cURL, it would look like this:

        ```shell
        curl -u username:token
        https://api.github.com/users/octocat/hovercard?subject_type=repository&subject_id=1300192
        ```

        .EXAMPLE

        .NOTES
        https://docs.github.com/rest/users/users#get-contextual-information-for-a-user

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [string] $Username,
        [Parameter()]
        [ValidateSet('organization', 'repository', 'issue', 'pull_request')]
        [string] $SubjectType,
        [Parameter()]
        [int] $SubjectID = ''
    )

    $body = @{
        subject_type = $SubjectType
        subject_id   = $SubjectID
    }

    $inputObject = @{
        APIEndpoint = "/users/$Username/hovercard"
        Method      = 'GET'
        Body        = $body
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Get-GitHubUserCard.ps1] - Done"
#endregion - From public/Users/Get-GitHubUserCard.ps1
#region - From public/Users/Set-GitHubUser.ps1
Write-Verbose "[$scriptName] - [public/Users/Set-GitHubUser.ps1] - Importing"

filter Set-GitHubUser {
    <#
        .SYNOPSIS
        Update the authenticated user

        .DESCRIPTION
        **Note:** If your email is set to private and you send an `email` parameter as part of this request
        to update your profile, your privacy settings are still enforced: the email address will not be
        displayed on your public profile or via the API.

        .EXAMPLE
        Set-GitHubUser -Name 'octocat'

        Update the authenticated user's name to 'octocat'

        .EXAMPLE
        Set-GitHubUser -Location 'San Francisco'

        Update the authenticated user's location to 'San Francisco'

        .EXAMPLE
        Set-GitHubUser -Hireable $true -Bio 'I love programming'

        Update the authenticated user's hiring availability to 'true' and their biography to 'I love programming'

        .NOTES
        https://docs.github.com/rest/users/users#update-the-authenticated-user
    #>

    [OutputType([void])]
    [Alias('Update-GitHubUser')]
    [CmdletBinding()]
    param (
        # The new name of the user.
        [Parameter()]
        [string] $Name,

        # The publicly visible email address of the user.
        [Parameter()]
        [string] $Email,

        # The new blog URL of the user.
        [Parameter()]
        [string] $Blog,

        # The new Twitter username of the user.
        [Parameter()]
        [string] $TwitterUsername,

        # The new company of the user.
        [Parameter()]
        [string] $Company,

        # The new location of the user.
        [Parameter()]
        [string] $Location,

        # The new hiring availability of the user.
        [Parameter()]
        [boolean] $Hireable,

        # The new short biography of the user.
        [Parameter()]
        [string] $Bio
    )

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case

    $inputObject = @{
        APIEndpoint = '/user'
        Body        = $body
        Method      = 'PATCH'
    }

    (Invoke-GitHubAPI @inputObject).Response

}

Write-Verbose "[$scriptName] - [public/Users/Set-GitHubUser.ps1] - Done"
#endregion - From public/Users/Set-GitHubUser.ps1

Write-Verbose "[$scriptName] - [public/Users] - Done"
#endregion - From public/Users


Write-Verbose "[$scriptName] - [public] - Done"
#endregion - From public

#region - From GitHub.ps1
Write-Verbose "[$scriptName] - [GitHub.ps1] - Importing"

$scriptFilePath = $MyInvocation.MyCommand.Path

Write-Verbose "[$scriptFilePath] - Initializing GitHub module..."

Initialize-SecretVault -Name $script:SecretVault.Name -Type $script:SecretVault.Type

# Autologon if a token is present in environment variables
$envVar = Get-ChildItem -Path 'Env:' | Where-Object Name -In 'GH_TOKEN', 'GITHUB_TOKEN' | Select-Object -First 1
$envVarPresent = $envVar.count -gt 0
if ($envVarPresent) {
    Connect-GitHubAccount
}
Write-Verbose "[$scriptName] - [GitHub.ps1] - Done"
#endregion - From GitHub.ps1

Export-ModuleMember -Function 'Disable-GitHubWorkflow','Enable-GitHubWorkflow','Get-GitHubWorkflow','Get-GitHubWorkflowRun','Get-GitHubWorkflowUsage','Remove-GitHubWorkflowRun','Start-GitHubWorkflow','Start-GitHubWorkflowReRun','Stop-GitHubWorkflowRun','Invoke-GitHubAPI','Connect-GitHubAccount','Disconnect-GitHubAccount','Get-GitHubRepoBranch','Get-GitHubConfig','Set-GitHubConfig','Get-GitHubEnvironment','Get-GitHubEnvironmentSecrets','Update-GitHubEnvironment','Get-GitHubEmojis','Get-GitHubMarkdown','Get-GitHubMarkdownRaw','Get-GitHubApiVersions','Get-GitHubMeta','Get-GitHubOctocat','Get-GitHubRoot','Get-GitHubZen','Get-GitHubOrganization','Get-GitHubOrganizationAppInstallation','Remove-GitHubOrganization','Set-GitHubOrganization','Set-GitHubOrganizationSecurityFeature','Get-GitHubRateLimit','Add-GitHubReleaseAsset','Get-GitHubReleaseAsset','Remove-GitHubReleaseAsset','Set-GitHubReleaseAsset','Get-GitHubRelease','New-GitHubRelease','New-GitHubReleaseNotes','Remove-GitHubRelease','Set-GitHubRelease','Get-GitHubRepository','New-GitHubRepositoryOrg','Get-GitHubScheduledMaintenance','Get-GitHubStatus','Get-GitHubStatusComponents','Get-GitHubStatusIncidents','Get-GitHubRepoTeam','Block-GitHubUser','Get-GitHubBlockedUser','Test-GitHubBlockedUser','Unblock-GitHubUser','Add-GitHubUserEmail','Get-GitHubUserEmail','Remove-GitHubUserEmail','Set-GitHubUserEmailVisibility','Add-GitHubUserFollowing','Get-GitHubUserFollowers','Get-GitHubUserFollowing','Remove-GitHubUserFollowing','Test-GitHubUserFollows','Add-GitHubUserGpgKey','Get-GitHubUserGpgKey','Remove-GitHubUserGpgKey','Add-GitHubUserKey','Get-GitHubUserKey','Remove-GitHubUserKey','Add-GitHubUserSocials','Remove-GitHubUserSocials','Add-GitHubUserSigningKey','Get-GitHubUserSigningKey','Remove-GitHubUserSigningKey','Get-GitHubUser','Get-GitHubUserCard','Set-GitHubUser' -Cmdlet '' -Variable '' -Alias '*'