GitHub.psm1

[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains long links.')]
[CmdletBinding()]
param()

$scriptName = 'GitHub'
Write-Verbose "[$scriptName] - Importing module"

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

#region - From [classes] - [public] - [GitHubContext]
Write-Verbose "[$scriptName] - [classes] - [public] - [GitHubContext] - Importing"

class GitHubContext {
    # The API base URI.
    # https://api.github.com
    [string] $ApiBaseUri

    # The GitHub API version.
    # 2022-11-28
    [string] $ApiVersion

    # The authentication client ID.
    # Client ID for UAT
    [string] $AuthClientID

    # The authentication type.
    # UAT / PAT / App / IAT
    [string] $AuthType

    # Client ID for GitHub Apps
    [string] $ClientID

    # The device flow type.
    # GitHubApp / OAuthApp
    [string] $DeviceFlowType

    # The API hostname.
    # github.com / msx.ghe.com / github.local
    [string] $HostName

    # User ID / App ID as GraphQL Node ID
    [string] $NodeID

    # The Database ID of the context.
    [string] $DatabaseID

    # The context ID.
    # HostName/Username or HostName/AppSlug
    # Context:PSModule.Github/github.com/Octocat
    [string] $ID

    # The user name.
    [string] $UserName

    # The default value for the Owner parameter.
    [string] $Owner

    # The default value for the Repo parameter.
    [string] $Repo

    # The scope when authenticating with OAuth.
    # 'gist read:org repo workflow'
    [string] $Scope

    # The token type.
    # ghu / gho / ghp / github_pat / PEM / ghs /
    [string] $TokenType

    # The access token.
    [securestring] $Token

    # The token expiration date.
    # 2024-01-01-00:00:00
    [datetime] $TokenExpirationDate

    # The refresh token.
    [securestring] $RefreshToken

    # The refresh token expiration date.
    # 2024-01-01-00:00:00
    [datetime] $RefreshTokenExpirationDate

    GitHubContext([string]$ID) {
        $this.ID = $ID
    }

    GitHubContext([hashtable]$Properties) {
        foreach ($Property in $Properties.Keys) {
            $this.$Property = $Properties.$Property
        }
    }

    GitHubContext([PSCustomObject]$Object) {
        $Object.PSObject.Properties | ForEach-Object {
            $this.($_.Name) = $_.Value
        }
    }
}

Write-Verbose "[$scriptName] - [classes] - [public] - [GitHubContext] - Done"
#endregion - From [classes] - [public] - [GitHubContext]

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

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

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

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

#region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Invoke-GitHubDeviceFlowLogin]
Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Invoke-GitHubDeviceFlowLogin] - 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])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Is the CLI part of the module.')]
    [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 host to connect to.
        [Parameter(Mandatory)]
        [string] $HostName,

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

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

            $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 $HostName in your browser..."
            Start-Process $verificationUri

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

Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Invoke-GitHubDeviceFlowLogin] - Done"
#endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Invoke-GitHubDeviceFlowLogin]
#region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubAccessToken]
Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubAccessToken] - 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 -HostName 'github.com'

        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,

        # The host to connect to.
        [Parameter(Mandatory)]
        [string] $HostName
    )

    $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://$HostName/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] - [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubAccessToken] - Done"
#endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubAccessToken]
#region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubDeviceCode]
Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubDeviceCode] - Importing"

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

        .DESCRIPTION
        Request a GitHub Device Code.

        .EXAMPLE
        Request-GitHubDeviceCode -ClientID $ClientID -Mode $Mode -HostName 'github.com'

        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',

        # The host to connect to.
        [Parameter(Mandatory)]
        [string] $HostName
    )

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

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

    $RESTParams = @{
        Uri     = "https://$HostName/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] - [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubDeviceCode] - Done"
#endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Request-GitHubDeviceCode]
#region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Test-GitHubAccessTokenRefreshRequired]
Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Test-GitHubAccessTokenRefreshRequired] - 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.
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    param(
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    $contextObj = Get-GitHubContext -Context $Context
    $tokenExpirationDate = $contextObj.TokenExpirationDate
    $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] - [functions] - [private] - [Auth] - [DeviceFlow] - [Test-GitHubAccessTokenRefreshRequired] - Done"
#endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Test-GitHubAccessTokenRefreshRequired]
#region - From [functions] - [private] - [Auth] - [DeviceFlow] - [Wait-GitHubAccessToken]
Write-Verbose "[$scriptName] - [functions] - [private] - [Auth] - [DeviceFlow] - [Wait-GitHubAccessToken] - 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 host to connect to.
        [Parameter(Mandatory)]
        [string] $HostName,

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

    do {
        if ($RefreshToken) {
            $response = Request-GitHubAccessToken -ClientID $ClientID -RefreshToken $RefreshToken -HostName $HostName
        } else {
            $response = Request-GitHubAccessToken -ClientID $ClientID -DeviceCode $DeviceCode -HostName $HostName
        }
        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] - [functions] - [private] - [Auth] - [DeviceFlow] - [Wait-GitHubAccessToken] - Done"
#endregion - From [functions] - [private] - [Auth] - [DeviceFlow] - [Wait-GitHubAccessToken]

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


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

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

#region - From [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreByName]
Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreByName] - Importing"

filter Get-GitHubGitignoreByName {
    <#
        .SYNOPSIS
        Get a gitignore template

        .DESCRIPTION
        The API also allows fetching the source of a single template.
        Use the raw [media type](https://docs.github.com/rest/overview/media-types/) to get the raw contents.

        .EXAMPLE
        Get-GitHubGitignoreList

        Get all gitignore templates

        .NOTES
        https://docs.github.com/rest/gitignore/gitignore#get-a-gitignore-template

    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string] $Name
    )

    process {
        $inputObject = @{
            APIEndpoint = "/gitignore/templates/$Name"
            Accept      = 'application/vnd.github.raw+json'
            Method      = 'GET'
        }

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

    }
}

Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreByName] - Done"
#endregion - From [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreByName]
#region - From [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreList]
Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreList] - Importing"

filter Get-GitHubGitignoreList {
    <#
        .SYNOPSIS
        Get all gitignore templates

        .DESCRIPTION
        List all templates available to pass as an option when
        [creating a repository](https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user).

        .EXAMPLE
        Get-GitHubGitignoreList

        Get all gitignore templates

        .NOTES
        https://docs.github.com/rest/gitignore/gitignore#get-all-gitignore-templates

    #>

    [OutputType([string[]])]
    [CmdletBinding()]
    param ()

    $inputObject = @{
        APIEndpoint = '/gitignore/templates'
        Method      = 'GET'
    }

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreList] - Done"
#endregion - From [functions] - [private] - [Gitignore] - [Get-GitHubGitignoreList]

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

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

#region - From [functions] - [private] - [License] - [Get-GitHubLicenseByName]
Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubLicenseByName] - Importing"

filter Get-GitHubLicenseByName {
    <#
        .SYNOPSIS
        Get a license

        .DESCRIPTION
        Gets information about a specific license.
        For more information, see "[Licensing a repository ](https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository)."

        .EXAMPLE
        Get-GitHubGitignoreList

        Get all gitignore templates

        .NOTES
        https://docs.github.com/rest/licenses/licenses#get-a-license

    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [CmdletBinding()]
    param (
        # The license keyword, license name, or license SPDX ID. For example, mit or mpl-2.0.
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [Alias('license')]
        [string] $Name
    )

    process {
        $inputObject = @{
            APIEndpoint = "/licenses/$Name"
            Accept      = 'application/vnd.github+json'
            Method      = 'GET'
        }

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

    }
}

Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubLicenseByName] - Done"
#endregion - From [functions] - [private] - [License] - [Get-GitHubLicenseByName]
#region - From [functions] - [private] - [License] - [Get-GitHubLicenseList]
Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubLicenseList] - Importing"

filter Get-GitHubLicenseList {
    <#
        .SYNOPSIS
        Get all commonly used licenses

        .DESCRIPTION
        Lists the most commonly used licenses on GitHub.
        For more information, see "[Licensing a repository ](https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/licensing-a-repository)."

        .EXAMPLE
        Get-GitHubLicenseList

        Get all commonly used licenses.

        .NOTES
        https://docs.github.com/rest/licenses/licenses#get-all-commonly-used-licenses

    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [OutputType([string[]])]
    [CmdletBinding()]
    param ()

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubLicenseList] - Done"
#endregion - From [functions] - [private] - [License] - [Get-GitHubLicenseList]
#region - From [functions] - [private] - [License] - [Get-GitHubRepositoryLicense]
Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubRepositoryLicense] - Importing"

filter Get-GitHubRepositoryLicense {
    <#
        .SYNOPSIS
        Get the license for a repository

        .DESCRIPTION
        This method returns the contents of the repository's license file, if one is detected.

        Similar to [Get repository content](https://docs.github.com/rest/repos/contents#get-repository-content), this method also supports
        [custom media types](https://docs.github.com/rest/overview/media-types) for retrieving the raw license content or rendered license HTML.

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

        Get the license for the Hello-World repository from the octocat account.

        .NOTES
        https://docs.github.com/rest/licenses/licenses#get-the-license-for-a-repository

    #>

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

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

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/license"
        Accept      = 'application/vnd.github+json'
        Method      = 'GET'
    }

    Invoke-GitHubAPI @inputObject | ForEach-Object {
        $Response = $_.Response
        $rawContent = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Response.content))
        $Response | Add-Member -NotePropertyName 'raw_content' -NotePropertyValue $rawContent -Force
        $Response
    }
}

Write-Verbose "[$scriptName] - [functions] - [private] - [License] - [Get-GitHubRepositoryLicense] - Done"
#endregion - From [functions] - [private] - [License] - [Get-GitHubRepositoryLicense]

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

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

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

#region - From [functions] - [private] - [Organization] - [Blocking] - [Block-GitHubUserByOrganization]
Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Block-GitHubUserByOrganization] - 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] - [functions] - [private] - [Organization] - [Blocking] - [Block-GitHubUserByOrganization] - Done"
#endregion - From [functions] - [private] - [Organization] - [Blocking] - [Block-GitHubUserByOrganization]
#region - From [functions] - [private] - [Organization] - [Blocking] - [Get-GitHubBlockedUserByOrganization]
Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Get-GitHubBlockedUserByOrganization] - 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
        [List users blocked by an organization](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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

    $body = @{
        per_page = $PerPage
    }

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

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

Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Get-GitHubBlockedUserByOrganization] - Done"
#endregion - From [functions] - [private] - [Organization] - [Blocking] - [Get-GitHubBlockedUserByOrganization]
#region - From [functions] - [private] - [Organization] - [Blocking] - [Test-GitHubBlockedUserByOrganization]
Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Test-GitHubBlockedUserByOrganization] - 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] - [functions] - [private] - [Organization] - [Blocking] - [Test-GitHubBlockedUserByOrganization] - Done"
#endregion - From [functions] - [private] - [Organization] - [Blocking] - [Test-GitHubBlockedUserByOrganization]
#region - From [functions] - [private] - [Organization] - [Blocking] - [Unblock-GitHubUserByOrganization]
Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Blocking] - [Unblock-GitHubUserByOrganization] - 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 = "/orgs/$OrganizationName/blocks/$Username"
        Method      = 'DELETE'
    }

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

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

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

#region - From [functions] - [private] - [Organization] - [Get-GitHubAllOrganization]
Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubAllOrganization] - 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])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubAllOrganization] - Done"
#endregion - From [functions] - [private] - [Organization] - [Get-GitHubAllOrganization]
#region - From [functions] - [private] - [Organization] - [Get-GitHubMyOrganization]
Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubMyOrganization] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

    $body = @{
        per_page = $PerPage
    }

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

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

Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubMyOrganization] - Done"
#endregion - From [functions] - [private] - [Organization] - [Get-GitHubMyOrganization]
#region - From [functions] - [private] - [Organization] - [Get-GitHubOrganizationByName]
Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubOrganizationByName] - 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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubOrganizationByName] - Done"
#endregion - From [functions] - [private] - [Organization] - [Get-GitHubOrganizationByName]
#region - From [functions] - [private] - [Organization] - [Get-GitHubUserOrganization]
Write-Verbose "[$scriptName] - [functions] - [private] - [Organization] - [Get-GitHubUserOrganization] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

    $body = @{
        per_page = $PerPage
    }

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

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

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

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

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

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

#region - From [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByID]
Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByID] - 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-GitHubContextSetting -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubContextSetting -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 | ForEach-Object {
        Write-Output $_.Response
    }
}

Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByID] - Done"
#endregion - From [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByID]
#region - From [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByReleaseID]
Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Assets] - [Get-GitHubReleaseAssetByReleaseID] - 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-GitHubContextSetting -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubContextSetting -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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

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

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

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

#region - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseAll]
Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseAll] - 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-GitHubContextSetting -Name Owner),

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

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

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseAll] - Done"
#endregion - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseAll]
#region - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByID]
Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByID] - 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-GitHubContextSetting -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubContextSetting -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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByID] - Done"
#endregion - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByID]
#region - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByTagName]
Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByTagName] - 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-GitHubContextSetting -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubContextSetting -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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByTagName] - Done"
#endregion - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseByTagName]
#region - From [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseLatest]
Write-Verbose "[$scriptName] - [functions] - [private] - [Releases] - [Releases] - [Get-GitHubReleaseLatest] - 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-GitHubContextSetting -Name Owner),

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

    )

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

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

}

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

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


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

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

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

#region - From [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkById]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkById] - Importing"

filter Get-GitHubRepositoryAutolinkById {
    <#
        .SYNOPSIS
        Get an autolink reference of a repository

        .DESCRIPTION
        This returns a single autolink reference by ID that was configured for the given repository.

        Information about autolinks are only available to repository administrators.

        .EXAMPLE
        Get-GitHubRepositoryAutolinkById -Owner 'octocat' -Repo 'Hello-World' -ID 1

        Gets the autolink with the ID 1 for the repository 'Hello-World' owned by 'octocat'.

        .NOTES
        https://docs.github.com/rest/repos/autolinks#get-an-autolink-reference-of-a-repository

    #>

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

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

        # The unique identifier of the autolink.
        [Parameter(Mandatory)]
        [Alias('autolink_id')]
        [Alias('ID')]
        [int] $AutolinkId
    )

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

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

Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkById] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkById]
#region - From [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkList]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkList] - Importing"

filter Get-GitHubRepositoryAutolinkList {
    <#
        .SYNOPSIS
        List all autolinks of a repository

        .DESCRIPTION
        This returns a list of autolinks configured for the given repository.

        Information about autolinks are only available to repository administrators.

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

        Gets all autolinks for the repository 'Hello-World' owned by 'octocat'.

        .NOTES
        https://docs.github.com/rest/repos/autolinks#list-all-autolinks-of-a-repository

    #>

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

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

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

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

Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkList] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolinkList]

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

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

#region - From [functions] - [private] - [Repositories] - [Fork] - [New-GitHubRepositoryAsFork]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Fork] - [New-GitHubRepositoryAsFork] - Importing"

filter New-GitHubRepositoryAsFork {
    <#
        .SYNOPSIS
        Create a fork

        .DESCRIPTION
        Create a fork for the authenticated user.

        **Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects.
        If this takes longer than 5 minutes, be sure to contact [GitHub Support](https://support.github.com/contact?tags=dotcom-rest-api).

        **Note**: Although this endpoint works with GitHub Apps, the GitHub App must be installed on the destination account with access to all
        repositories and on the source account with access to the source repository.

        .EXAMPLE
        New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World'

        Fork the repository `Hello-World` owned by `github` for the authenticated user.
        Repo will be named `Hello-World`, and all branches and tags will be forked.

        .EXAMPLE
        New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' -Name 'Hello-World-2'

        Fork the repository `Hello-World` owned by `github` for the authenticated user, naming the resulting repository `Hello-World-2`.

        .EXAMPLE
        New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' -Organization 'octocat'

        Fork the repository `Hello-World` owned by `github` for the organization `octocat`, naming the resulting repository `Hello-World`.

        .EXAMPLE
        New-GitHubRepositoryAsFork -ForkOwner 'github' -ForkRepo 'Hello-World' -DefaultBranchOnly

        Fork the repository `Hello-World` owned by `github` for the authenticated user, forking only the default branch.

        .NOTES
        https://docs.github.com/rest/repos/forks#create-a-fork

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter(Mandatory)]
        [string] $Owner,

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter(Mandatory)]
        [string] $Repo,

        # The organization or person who will own the new repository.
        # To create a new repository in an organization, the authenticated user must be a member of the specified organization.
        [Parameter()]
        [string] $Organization = (Get-GitHubConfig -Name Owner),

        # The name of the new repository.
        [Parameter()]
        [string] $Name,

        # When forking from an existing repository, fork with only the default branch.
        [Parameter()]
        [Alias('default_branch_only')]
        [switch] $DefaultBranchOnly
    )

    if ([string]::IsNullorEmpty($Name)) {
        $Name = $ForkRepo
    }

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramName = $_.Key
        $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
        $providedValue = $PSBoundParameters[$paramName]
        Write-Verbose "[$paramName]"
        Write-Verbose " - Default: [$paramDefaultValue]"
        Write-Verbose " - Provided: [$providedValue]"
        if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose ' - Using default value'
            $PSBoundParameters[$paramName] = $paramDefaultValue
        } else {
            Write-Verbose ' - Using provided value'
        }
    }

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

    $body['default_branch_only'] = $DefaultBranchOnly

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

    if ($PSCmdlet.ShouldProcess("Repository [$Organization/$Name] as fork of [$Owner/$Repo]", 'Create')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Fork] - [New-GitHubRepositoryAsFork] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Fork] - [New-GitHubRepositoryAsFork]

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

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

#region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubMyRepositories]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubMyRepositories] - 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
        $param = @{
            Visibility = 'public'
            Affiliation = 'owner','collaborator'
            Sort = 'created'
            Direction = 'asc'
            PerPage = 100
            Since = (Get-Date).AddYears(-5)
            Before = (Get-Date).AddDays(-1)
        }
        Get-GitHubMyRepositories @param

        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')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Private function, not exposed to user.')]
    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()]
        [ValidateRange(1, 100)]
        [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 {
        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
    Remove-HashtableEntry -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] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubMyRepositories] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubMyRepositories]
#region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryByName]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryByName] - 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()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

    )

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryByName] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryByName]
#region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByID]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByID] - 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] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByID] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByID]
#region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByOrg]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByOrg] - 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()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubContextSetting -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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

    $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
    Remove-HashtableEntry -Hashtable $body -RemoveNames 'Owner'

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByOrg] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByOrg]
#region - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByUser] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

    $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
    Remove-HashtableEntry -Hashtable $body -RemoveNames 'Username'

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

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

Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByUser] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Repositories] - [Get-GitHubRepositoryListByUser]
#region - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryFromTemplate]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryFromTemplate] - Importing"

filter New-GitHubRepositoryFromTemplate {
    <#
        .SYNOPSIS
        Create a repository using a template

        .DESCRIPTION
        Creates a new repository using a repository template. Use the `template_owner` and `template_repo`
        route parameters to specify the repository to use as the template. If the repository is not public,
        the authenticated user must own or be a member of an organization that owns the repository.
        To check if a repository is available to use as a template, get the repository's information using the
        [Get a repository](https://docs.github.com/rest/repos/repos#get-a-repository) endpoint and check that the `is_template` key is `true`.

        **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 = @{
            TemplateOwner = 'GitHub'
            TemplateRepo = 'octocat'
            Owner = 'PSModule'
            Name = 'MyNewRepo'
            IncludeAllBranches = $true
            Description = 'My new repo'
            Private = $true
        }
        New-GitHubRepositoryFromTemplate @params

        Creates a new private repository named `MyNewRepo` from the `octocat` template repository owned by `GitHub`.

        .NOTES
        https://docs.github.com/rest/repos/repos#create-a-repository-using-a-template

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the template repository. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('template_owner')]
        [string] $TemplateOwner,

        # The name of the template repository without the .git extension. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('template_repo')]
        [string] $TemplateRepo,

        # The organization or person who will own the new repository.
        # To create a new repository in an organization, the authenticated user must be a member of the specified organization.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

        # The name of the new repository.
        [Parameter(Mandatory)]
        [string] $Name,

        # A short description of the new repository.
        [Parameter()]
        [string] $Description,

        # Set to true to include the directory structure and files from all branches in the template repository,
        # and not just the default branch.
        [Parameter()]
        [Alias('include_all_branches')]
        [switch] $IncludeAllBranches,

        # Either true to create a new private repository or false to create a new public one.
        [Parameter()]
        [switch] $Private
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramName = $_.Key
        $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
        $providedValue = $PSBoundParameters[$paramName]
        Write-Verbose "[$paramName]"
        Write-Verbose " - Default: [$paramDefaultValue]"
        Write-Verbose " - Provided: [$providedValue]"
        if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose ' - Using default value'
            $PSBoundParameters[$paramName] = $paramDefaultValue
        } else {
            Write-Verbose ' - Using provided value'
        }
    }

    $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
    Remove-HashtableEntry -Hashtable $body -RemoveNames 'TemplateOwner', 'TemplateRepo' -RemoveTypes 'SwitchParameter'

    $inputObject = @{
        APIEndpoint = "/repos/$TemplateOwner/$TemplateRepo/generate"
        Method      = 'POST'
        Body        = $body
    }

    if ($PSCmdlet.ShouldProcess("Repository [$Owner/$Name] from template [$TemplateOwner/$TemplateRepo]", 'Create')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryFromTemplate] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryFromTemplate]
#region - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryOrg]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryOrg] - Importing"

#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' }

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

        Creates a new public repository named "Hello-World" owned by the organization "PSModule".

        .PARAMETER GitignoreTemplate
        Desired language or platform .gitignore template to apply. Use the name of the template without the extension. For example, "Haskell".

        .PARAMETER LicenseTemplate
        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".

        .NOTES
        https://docs.github.com/rest/repos/repos#create-an-organization-repository

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseDeclaredVarsMoreThanAssignments',
        'GitignoreTemplate',
        Justification = 'Parameter is used in dynamic parameter validation.'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseDeclaredVarsMoreThanAssignments',
        'LicenseTemplate',
        Justification = 'Parameter is used in dynamic parameter validation.'
    )]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -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,

        # The visibility of the repository.
        [Parameter()]
        [ValidateSet('public', 'private')]
        [string] $Visibility = 'public',

        # 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,

        # 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
    )

    dynamicparam {
        $DynamicParamDictionary = New-DynamicParamDictionary

        $dynParam = @{
            Name                   = 'GitignoreTemplate'
            Alias                  = 'gitignore_template'
            Type                   = [string]
            ValidateSet            = Get-GitHubGitignoreList
            DynamicParamDictionary = $DynamicParamDictionary
        }
        New-DynamicParam @dynParam

        $dynParam2 = @{
            Name                   = 'LicenseTemplate'
            Alias                  = 'license_template'
            Type                   = [string]
            ValidateSet            = Get-GitHubLicenseList | Select-Object -ExpandProperty key
            DynamicParamDictionary = $DynamicParamDictionary
        }
        New-DynamicParam @dynParam2

        return $DynamicParamDictionary
    }

    begin {
        $GitignoreTemplate = $PSBoundParameters['GitignoreTemplate']
        $LicenseTemplate = $PSBoundParameters['LicenseTemplate']
    }

    process {
        $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
            $paramName = $_.Key
            $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
            $providedValue = $PSBoundParameters[$paramName]
            Write-Verbose "[$paramName]"
            Write-Verbose " - Default: [$paramDefaultValue]"
            Write-Verbose " - Provided: [$providedValue]"
            if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
                Write-Verbose ' - Using default value'
                $PSBoundParameters[$paramName] = $paramDefaultValue
            } else {
                Write-Verbose ' - Using provided value'
            }
        }

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

        $body['private'] = $Visibility -eq 'private'
        $body['has_issues'] = if ($HasIssues.IsPresent) { $HasIssues } else { $false }
        $body['has_wiki'] = if ($HasWiki.IsPresent) { $HasWiki } else { $false }
        $body['has_projects'] = if ($HasProjects.IsPresent) { $HasProjects } else { $false }
        $body['has_downloads'] = if ($HasDownloads.IsPresent) { $HasDownloads } else { $false }
        $body['is_template'] = if ($IsTemplate.IsPresent) { $IsTemplate } else { $false }
        $body['auto_init'] = if ($AutoInit.IsPresent) { $AutoInit } else { $false }
        $body['allow_squash_merge'] = if ($AllowSquashMerge.IsPresent) { $AllowSquashMerge } else { $false }
        $body['allow_merge_commit'] = if ($AllowMergeCommit.IsPresent) { $AllowMergeCommit } else { $false }
        $body['allow_rebase_merge'] = if ($AllowRebaseMerge.IsPresent) { $AllowRebaseMerge } else { $false }
        $body['allow_auto_merge'] = if ($AllowAutoMerge.IsPresent) { $AllowAutoMerge } else { $false }
        $body['delete_branch_on_merge'] = if ($DeleteBranchOnMerge.IsPresent) { $DeleteBranchOnMerge } else { $false }

        Remove-HashtableEntry -Hashtable $body -NullOrEmptyValues

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

        if ($PSCmdlet.ShouldProcess("Repository in organization $Owner", 'Create')) {
            Invoke-GitHubAPI @inputObject | ForEach-Object {
                Write-Output $_.Response
            }
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryOrg] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryOrg]
#region - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryUser] - Importing"

#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' }

filter New-GitHubRepositoryUser {
    <#
        .SYNOPSIS
        Create a repository for the authenticated user

        .DESCRIPTION
        Creates a new repository for the authenticated user.

        **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 = @{
            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-GitHubRepositoryUser @params

        Creates a new public repository named "Hello-World" owned by the authenticated user.

        .PARAMETER GitignoreTemplate
        The desired language or platform to apply to the .gitignore.

        .PARAMETER LicenseTemplate
        The license keyword of the open source license for this repository.

        .NOTES
        https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user

    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseDeclaredVarsMoreThanAssignments',
        'GitignoreTemplate',
        Justification = 'Parameter is used in dynamic parameter validation.'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseDeclaredVarsMoreThanAssignments',
        'LicenseTemplate',
        Justification = 'Parameter is used in dynamic parameter validation.'
    )]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # 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,

        # The visibility of the repository.
        [Parameter()]
        [ValidateSet('public', 'private')]
        [string] $Visibility = 'public',

        # Whether issues are enabled.
        [Parameter()]
        [Alias('has_issues')]
        [switch] $HasIssues,

        # Whether projects are enabled.
        [Parameter()]
        [Alias('has_projects')]
        [switch] $HasProjects,

        # Whether the wiki is enabled.
        [Parameter()]
        [Alias('has_wiki')]
        [switch] $HasWiki,

        # Whether discussions are enabled.
        [Parameter()]
        [Alias('has_discussions')]
        [switch] $HasDiscussions,

        # Whether downloads are enabled.
        [Parameter()]
        [Alias('has_downloads')]
        [switch] $HasDownloads,

        # Whether this repository acts as a template that can be used to generate new repositories.
        [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,

        # Whether to allow squash merges for pull requests.
        [Parameter()]
        [Alias('allow_squash_merge')]
        [switch] $AllowSquashMerge,

        # Whether to allow merge commits for pull requests.
        [Parameter()]
        [Alias('allow_merge_commit')]
        [switch] $AllowMergeCommit,

        # Whether to allow rebase merges for pull requests.
        [Parameter()]
        [Alias('allow_rebase_merge')]
        [switch] $AllowRebaseMerge,

        # Whether to allow Auto-merge to be used on pull requests.
        [Parameter()]
        [Alias('allow_auto_merge')]
        [switch] $AllowAutoMerge,

        # Whether to delete head branches when pull requests are merged
        [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
    )

    dynamicparam {
        $DynamicParamDictionary = New-DynamicParamDictionary

        $dynParam = @{
            Name                   = 'GitignoreTemplate'
            Alias                  = 'gitignore_template'
            Type                   = [string]
            ValidateSet            = Get-GitHubGitignoreList
            DynamicParamDictionary = $DynamicParamDictionary
        }
        New-DynamicParam @dynParam

        $dynParam2 = @{
            Name                   = 'LicenseTemplate'
            Alias                  = 'license_template'
            Type                   = [string]
            ValidateSet            = Get-GitHubLicenseList | Select-Object -ExpandProperty key
            DynamicParamDictionary = $DynamicParamDictionary
        }
        New-DynamicParam @dynParam2

        return $DynamicParamDictionary
    }

    begin {
        $GitignoreTemplate = $PSBoundParameters['GitignoreTemplate']
        $LicenseTemplate = $PSBoundParameters['LicenseTemplate']
    }

    process {

        $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
            $paramName = $_.Key
            $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
            $providedValue = $PSBoundParameters[$paramName]
            Write-Verbose "[$paramName]"
            Write-Verbose " - Default: [$paramDefaultValue]"
            Write-Verbose " - Provided: [$providedValue]"
            if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
                Write-Verbose ' - Using default value'
                $PSBoundParameters[$paramName] = $paramDefaultValue
            } else {
                Write-Verbose ' - Using provided value'
            }
        }

        $body = $PSBoundParameters | ConvertFrom-HashTable | ConvertTo-HashTable -NameCasingStyle snake_case
        Remove-HashtableEntry -Hashtable $body -RemoveNames 'visibility' -RemoveTypes 'SwitchParameter'

        $body['private'] = $Visibility -eq 'private'
        $body['has_issues'] = if ($HasIssues.IsPresent) { $HasIssues } else { $false }
        $body['has_wiki'] = if ($HasWiki.IsPresent) { $HasWiki } else { $false }
        $body['has_projects'] = if ($HasProjects.IsPresent) { $HasProjects } else { $false }
        $body['has_downloads'] = if ($HasDownloads.IsPresent) { $HasDownloads } else { $false }
        $body['is_template'] = if ($IsTemplate.IsPresent) { $IsTemplate } else { $false }
        $body['auto_init'] = if ($AutoInit.IsPresent) { $AutoInit } else { $false }
        $body['allow_squash_merge'] = if ($AllowSquashMerge.IsPresent) { $AllowSquashMerge } else { $false }
        $body['allow_merge_commit'] = if ($AllowMergeCommit.IsPresent) { $AllowMergeCommit } else { $false }
        $body['allow_rebase_merge'] = if ($AllowRebaseMerge.IsPresent) { $AllowRebaseMerge } else { $false }
        $body['allow_auto_merge'] = if ($AllowAutoMerge.IsPresent) { $AllowAutoMerge } else { $false }
        $body['delete_branch_on_merge'] = if ($DeleteBranchOnMerge.IsPresent) { $DeleteBranchOnMerge } else { $false }

        Remove-HashtableEntry -Hashtable $body -NullOrEmptyValues

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

        if ($PSCmdlet.ShouldProcess('Repository for user', 'Create')) {
            Invoke-GitHubAPI @inputObject | ForEach-Object {
                Write-Output $_.Response
            }
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryUser] - Done"
#endregion - From [functions] - [private] - [Repositories] - [Repositories] - [New-GitHubRepositoryUser]

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


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

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

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

#region - From [functions] - [private] - [Users] - [Blocking] - [Block-GitHubUserByUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Block-GitHubUserByUser] - 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] - [functions] - [private] - [Users] - [Blocking] - [Block-GitHubUserByUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Blocking] - [Block-GitHubUserByUser]
#region - From [functions] - [private] - [Users] - [Blocking] - [Get-GitHubBlockedUserByUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Get-GitHubBlockedUserByUser] - 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
        [List users blocked by the authenticated user](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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Get-GitHubBlockedUserByUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Blocking] - [Get-GitHubBlockedUserByUser]
#region - From [functions] - [private] - [Users] - [Blocking] - [Test-GitHubBlockedUserByUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Test-GitHubBlockedUserByUser] - 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()]
        [ValidateRange(1, 100)]
        [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] - [functions] - [private] - [Users] - [Blocking] - [Test-GitHubBlockedUserByUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Blocking] - [Test-GitHubBlockedUserByUser]
#region - From [functions] - [private] - [Users] - [Blocking] - [Unblock-GitHubUserByUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Blocking] - [Unblock-GitHubUserByUser] - 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] - [functions] - [private] - [Users] - [Blocking] - [Unblock-GitHubUserByUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Blocking] - [Unblock-GitHubUserByUser]

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

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

#region - From [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserAllEmail]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserAllEmail] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserAllEmail] - Done"
#endregion - From [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserAllEmail]
#region - From [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserPublicEmail]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Emails] - [Get-GitHubUserPublicEmail] - 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])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Link to documentation.')]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

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

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

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

#region - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowersOfUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowersOfUser] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowersOfUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowersOfUser]
#region - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingMe]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingMe] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingMe] - Done"
#endregion - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingMe]
#region - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingUser] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserFollowingUser]
#region - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserMyFollowers]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserMyFollowers] - 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])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Private function, not exposed to user.')]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserMyFollowers] - Done"
#endregion - From [functions] - [private] - [Users] - [Followers] - [Get-GitHubUserMyFollowers]
#region - From [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByMe]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByMe] - 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] - [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByMe] - Done"
#endregion - From [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByMe]
#region - From [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByUser] - 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] - [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Followers] - [Test-GitHubUserFollowedByUser]

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

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

#region - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKeyForUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKeyForUser] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKeyForUser] - Done"
#endregion - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKeyForUser]
#region - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKey]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKey] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKey] - Done"
#endregion - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKey]
#region - From [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKeyById]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [GPG-Keys] - [Get-GitHubUserMyGpgKeyById] - 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 | ForEach-Object {
        Write-Output $_.Response
    }

}

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

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

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

#region - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserKeyForUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserKeyForUser] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserKeyForUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserKeyForUser]
#region - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKey]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKey] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKey] - Done"
#endregion - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKey]
#region - From [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKeyById]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Keys] - [Get-GitHubUserMyKeyById] - 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 | ForEach-Object {
        Write-Output $_.Response
    }

}

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

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

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

#region - From [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubMyUserSocials]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubMyUserSocials] - 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])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Private function, not exposed to user.')]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubMyUserSocials] - Done"
#endregion - From [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubMyUserSocials]
#region - From [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubUserSocialsByName]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Social-Accounts] - [Get-GitHubUserSocialsByName] - 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 | ForEach-Object {
        Write-Output $_.Response
    }

}

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

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

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

#region - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKey]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKey] - 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()]
        [ValidateRange(1, 100)]
        [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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKey] - Done"
#endregion - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKey]
#region - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKeyById]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKeyById] - 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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKeyById] - Done"
#endregion - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserMySigningKeyById]
#region - From [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKeyForUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKeyForUser] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

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

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

#region - From [functions] - [private] - [Users] - [Get-GitHubAllUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubAllUser] - 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

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

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubAllUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Get-GitHubAllUser]
#region - From [functions] - [private] - [Users] - [Get-GitHubMyUser]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubMyUser] - 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])]
    [CmdletBinding()]
    param ()

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

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

}

Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubMyUser] - Done"
#endregion - From [functions] - [private] - [Users] - [Get-GitHubMyUser]
#region - From [functions] - [private] - [Users] - [Get-GitHubUserByName]
Write-Verbose "[$scriptName] - [functions] - [private] - [Users] - [Get-GitHubUserByName] - 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])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [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 | ForEach-Object {
        Write-Output $_.Response
    }

}

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

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

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

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

#region - From [functions] - [private] - [Utilities] - [Casing] - [Convert-StringCasingStyle]
Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Casing] - [Convert-StringCasingStyle] - 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] - [functions] - [private] - [Utilities] - [Casing] - [Convert-StringCasingStyle] - Done"
#endregion - From [functions] - [private] - [Utilities] - [Casing] - [Convert-StringCasingStyle]
#region - From [functions] - [private] - [Utilities] - [Casing] - [Get-StringCasingStyle]
Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Casing] - [Get-StringCasingStyle] - 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] - [functions] - [private] - [Utilities] - [Casing] - [Get-StringCasingStyle] - Done"
#endregion - From [functions] - [private] - [Utilities] - [Casing] - [Get-StringCasingStyle]
#region - From [functions] - [private] - [Utilities] - [Casing] - [Split-StringByCasingStyle]
Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Casing] - [Split-StringByCasingStyle] - 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] - [functions] - [private] - [Utilities] - [Casing] - [Split-StringByCasingStyle] - Done"
#endregion - From [functions] - [private] - [Utilities] - [Casing] - [Split-StringByCasingStyle]

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

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

#region - From [functions] - [private] - [Utilities] - [Hashtable] - [ConvertFrom-HashTable]
Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [ConvertFrom-HashTable] - 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
        )]
        [AllowNull()]
        [object] $InputObject
    )
    $InputObject | ConvertTo-Json -Depth 100 | ConvertFrom-Json
}

Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [ConvertFrom-HashTable] - Done"
#endregion - From [functions] - [private] - [Utilities] - [Hashtable] - [ConvertFrom-HashTable]
#region - From [functions] - [private] - [Utilities] - [Hashtable] - [ConvertTo-HashTable]
Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [ConvertTo-HashTable] - 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 = if ($NameCasingStyle) { ($item.Name | Convert-StringCasingStyle -To $NameCasingStyle) } else { $item.Name }
        $hashtable[$name] = $item.Value
    }
    $hashtable
}

Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [ConvertTo-HashTable] - Done"
#endregion - From [functions] - [private] - [Utilities] - [Hashtable] - [ConvertTo-HashTable]
#region - From [functions] - [private] - [Utilities] - [Hashtable] - [Join-Object]
Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [Join-Object] - 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] - [functions] - [private] - [Utilities] - [Hashtable] - [Join-Object] - Done"
#endregion - From [functions] - [private] - [Utilities] - [Hashtable] - [Join-Object]
#region - From [functions] - [private] - [Utilities] - [Hashtable] - [Remove-HashtableEntry]
Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Hashtable] - [Remove-HashtableEntry] - Importing"

filter Remove-HashtableEntry {
    <#
        .SYNOPSIS
        Remove entries from a hashtable.

        .DESCRIPTION
        Remove different types of entries from a hashtable.

        .EXAMPLE
        $Hashtable = @{
            'Key1' = 'Value1'
            'Key2' = 'Value2'
            'Key3' = $null
            'Key4' = 'Value4'
            'Key5' = ''
        }
        $Hashtable | Remove-HashtableEntry -NullOrEmptyValues

        Remove keys with null or empty values
    #>

    [OutputType([void])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions',
        '',
        Justification = 'Function does not change state.'
    )]
    [CmdletBinding()]
    param (
        # The hashtable to remove entries from.
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [hashtable] $Hashtable,

        # Remove keys with null or empty values.
        [Parameter()]
        [switch] $NullOrEmptyValues,

        # Remove keys of type.
        [Parameter()]
        [string[]] $RemoveTypes,

        # Remove keys with a given name.
        [Parameter()]
        [string[]] $RemoveNames,

        # Remove keys NOT of type.
        [Parameter()]
        [string[]] $KeepTypes,

        # Remove keys NOT with a given name.
        [Parameter()]
        [string[]] $KeepNames
    )

    if ($NullOrEmptyValues) {
        Write-Verbose 'Remove keys with null or empty values'
        ($Hashtable.GetEnumerator() | Where-Object { [string]::IsNullOrEmpty($_.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] - [functions] - [private] - [Utilities] - [Hashtable] - [Remove-HashtableEntry] - Done"
#endregion - From [functions] - [private] - [Utilities] - [Hashtable] - [Remove-HashtableEntry]

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

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

#region - From [functions] - [private] - [Utilities] - [Web] - [ConvertTo-QueryString]
Write-Verbose "[$scriptName] - [functions] - [private] - [Utilities] - [Web] - [ConvertTo-QueryString] - 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] - [functions] - [private] - [Utilities] - [Web] - [ConvertTo-QueryString] - Done"
#endregion - From [functions] - [private] - [Utilities] - [Web] - [ConvertTo-QueryString]

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


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


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

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

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

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

filter Disable-GitHubWorkflow {
    <#
        .NOTES
        [Disable a workflow](https://docs.github.com/en/rest/actions/workflows#disable-a-workflow)
    #>

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

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

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

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

    $null = Invoke-GitHubAPI @inputObject

}

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

filter Enable-GitHubWorkflow {
    <#
        .NOTES
        [Enable a workflow](https://docs.github.com/en/rest/actions/workflows#enable-a-workflow)
    #>

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

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

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

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

    $null = Invoke-GitHubAPI @inputObject
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Enable-GitHubWorkflow] - Done"
#endregion - From [functions] - [public] - [Actions] - [Enable-GitHubWorkflow]
#region - From [functions] - [public] - [Actions] - [Get-GitHubWorkflow]
Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Get-GitHubWorkflow] - 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
        [List repository workflows](https://docs.github.com/rest/actions/workflows?apiVersion=2022-11-28#list-repository-workflows)
    #>

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

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

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


    $body = @{
        per_page = $PerPage
    }

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

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

}

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

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

    [CmdletBinding(DefaultParameterSetName = 'Repo')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    param (
        [Parameter()]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

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

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

        # The number of results per page (max 100).
        [Parameter()]
        [ValidateRange(1, 100)]
        [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 | ForEach-Object {
        Write-Output $_.Response.workflow_runs
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Get-GitHubWorkflowRun] - Done"
#endregion - From [functions] - [public] - [Actions] - [Get-GitHubWorkflowRun]
#region - From [functions] - [public] - [Actions] - [Get-GitHubWorkflowUsage]
Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Get-GitHubWorkflowUsage] - 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
        [Get workflow usage](https://docs.github.com/en/rest/actions/workflows#get-workflow-usage)
    #>

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

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

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

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

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

}

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

filter Remove-GitHubWorkflowRun {
    <#
        .SYNOPSIS
        Delete a workflow run

        .DESCRIPTION
        Delete a specific workflow run. Anyone with write 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:write` permission to use
        this endpoint.

        .EXAMPLE
        Remove-GitHubWorkflowRun -Owner 'octocat' -Repo 'Hello-World' -ID 123456789

        Deletes the workflow run with the ID 123456789 from the 'Hello-World' repository owned by 'octocat'

        .NOTES
        [Delete a workflow run](https://docs.github.com/rest/actions/workflow-runs#delete-a-workflow-run)
    #>

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

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

        # The unique identifier of the workflow run.
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [Alias('ID', 'run_id')]
        [string] $RunID
    )

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

    if ($PSCmdlet.ShouldProcess("workflow run with ID [$RunID] in [$Owner/$Repo]", 'Delete')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Remove-GitHubWorkflowRun] - Done"
#endregion - From [functions] - [public] - [Actions] - [Remove-GitHubWorkflowRun]
#region - From [functions] - [public] - [Actions] - [Start-GitHubWorkflow]
Write-Verbose "[$scriptName] - [functions] - [public] - [Actions] - [Start-GitHubWorkflow] - 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
        [Create a workflow dispatch event](https://docs.github.com/en/rest/actions/workflows#create-a-workflow-dispatch-event)
    #>

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

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

        # The ID of the workflow.
        [Alias('workflow_id')]
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $ID,

        # The reference of the workflow run. The reference can be a branch, tag, or a commit SHA.
        [Parameter(
            ValueFromPipelineByPropertyName
        )]
        [Alias('branch', 'tag')]
        [string] $Ref = 'main',

        # Input parameters for the workflow run. You can use the inputs and payload keys to pass custom data to your workflow.
        [Parameter()]
        [hashtable] $Inputs = @{}
    )

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

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

    if ($PSCmdlet.ShouldProcess("workflow with ID [$ID] in [$Owner/$Repo]", 'Start')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

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

filter Start-GitHubWorkflowReRun {
    <#
        .SYNOPSIS
        Re-run a workflow

        .DESCRIPTION
        Re-runs your workflow run using its `run_id`. You can also specify a branch or tag name to re-run a workflow run from a branch

        .EXAMPLE
        Start-GitHubWorkflowReRun -Owner 'octocat' -Repo 'Hello-World' -ID 123456789

        .NOTES
        [Re-run a workflow](https://docs.github.com/en/rest/actions/workflow-runs#re-run-a-workflow)
    #>

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

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

        # The unique identifier of the workflow run.
        [Alias('workflow_id')]
        [Parameter(
            Mandatory,
            ValueFromPipelineByPropertyName
        )]
        [string] $ID
    )

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

    if ($PSCmdlet.ShouldProcess("workflow with ID [$ID] in [$Owner/$Repo]", 'Re-run')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

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

filter Stop-GitHubWorkflowRun {
    <#
        .SYNOPSIS
        Cancel a workflow run

        .DESCRIPTION
        Cancels a workflow run using its `run_id`. You can use this endpoint to cancel a workflow run that is in progress or waiting

        .EXAMPLE
        Stop-GitHubWorkflowRun -Owner 'octocat' -Repo 'Hello-World' -ID 123456789

        Cancels the workflow run with the ID 123456789 from the 'Hello-World' repository owned by 'octocat'

        .NOTES
        [Cancel a workflow run](https://docs.github.com/en/rest/actions/workflow-runs#cancel-a-workflow-run)
    #>

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

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

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


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

    if ($PSCmdlet.ShouldProcess("workflow run with ID [$ID] in [$Owner/$Repo]", 'Cancel/Stop')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

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

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

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

#region - From [functions] - [public] - [API] - [Invoke-GitHubAPI]
Write-Verbose "[$scriptName] - [functions] - [public] - [API] - [Invoke-GitHubAPI] - 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,

        # 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] $Token,

        # 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] $ApiVersion,

        # The context to use for the API call. This is used to retrieve the necessary configuration settings.
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    Write-Verbose 'Invoking GitHub API...'
    $PSBoundParameters.GetEnumerator() | ForEach-Object {
        Write-Verbose " - $($_.Key): $($_.Value)"
    }

    $contextObj = Get-GitHubContext -Name $Context
    Write-Verbose "Using GitHub context: $Context"
    if (-not $contextObj) {
        throw 'Log in using Connect-GitHub before running this command.'
    }

    if ([string]::IsNullOrEmpty($ApiBaseUri)) {
        Write-Verbose 'Using default API base URI from context.'
        Write-Verbose $($contextObj.ApiBaseUri)
        $ApiBaseUri = $contextObj.ApiBaseUri
    }
    Write-Verbose "ApiBaseUri: $ApiBaseUri"

    if ([string]::IsNullOrEmpty($ApiVersion)) {
        Write-Verbose 'Using default API version from context.'
        Write-Verbose $($contextObj.ApiVersion)
        $ApiVersion = $contextObj.ApiVersion
    }
    Write-Verbose "ApiVersion: $ApiVersion"

    if ([string]::IsNullOrEmpty($TokenType)) {
        Write-Verbose 'Using default token type from context.'
        Write-Verbose $($contextObj.TokenType)
        $TokenType = $contextObj.TokenType
    }
    Write-Verbose "TokenType: $TokenType"

    if ([string]::IsNullOrEmpty($Token)) {
        Write-Verbose 'Using default token from context.'
        Write-Verbose $($contextObj.Token)
        $Token = $contextObj.Token
    }
    Write-Verbose "Token: $Token"

    switch ($tokenType) {
        'ghu' {
            if (Test-GitHubAccessTokenRefreshRequired -Context $Context) {
                Connect-GitHubAccount -Silent
                $Token = (Get-GitHubContextSetting -Name 'Token' -Context $Context)
            }
        }
        'PEM' {
            $ClientID = (Get-GitHubContextSetting -Name 'ClientID' -Context $Context)
            $JWT = Get-GitHubAppJSONWebToken -ClientId $ClientID -PrivateKey $Token
            $Token = $JWT.Token
        }
    }

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

    Remove-HashtableEntry -Hashtable $headers -NullOrEmptyValues

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

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

    #If PSversion is higher than 7.1 use HttpVersion
    if ($PSVersionTable.PSVersion -ge [version]'7.3') {
        $APICall['HttpVersion'] = $HttpVersion
    }

    $APICall | Remove-HashtableEntry -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
        }
    }

    try {
        Write-Verbose 'Calling GitHub API with the following parameters:'
        Write-Verbose ($APICall | ConvertFrom-HashTable | Format-List | Out-String)
        Invoke-RestMethod @APICall | ForEach-Object {
            $statusCode = $APICallStatusCode | ConvertTo-Json -Depth 100 | ConvertFrom-Json
            $responseHeaders = $APICallResponseHeaders | ConvertTo-Json -Depth 100 | ConvertFrom-Json
            $verboseMessage = @"

----------------------------------
StatusCode:
$statusCode
----------------------------------
Request:
$($APICall | ConvertFrom-HashTable | Format-List | Out-String)
----------------------------------
ResponseHeaders:
$($responseHeaders.PSObject.Properties | ForEach-Object { $_ | Format-List | Out-String })
----------------------------------

"@

            Write-Verbose $verboseMessage
            [pscustomobject]@{
                Request         = $APICall
                Response        = $_
                StatusCode      = $statusCode
                ResponseHeaders = $responseHeaders
            }
        }
    } catch {
        $failure = $_
        $errorResult = @"

----------------------------------`n`r
Request:
$($APICall | ConvertFrom-HashTable | Format-List | Out-String)
----------------------------------`n`r
Message:
$($failure.Exception.Message | ConvertFrom-HashTable | Format-List | Out-String)
----------------------------------`n`r
Response:
$($failure.Exception.Response | ConvertFrom-HashTable | Format-List | Out-String)
----------------------------------`n`r

"@

        $errorResult.Split([System.Environment]::NewLine) | ForEach-Object { Write-Error $_ }
        throw $failure.Exception.Message
    }
}

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

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

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

#region - From [functions] - [public] - [Apps] - [Get-GitHubApp]
Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubApp] - Importing"

filter Get-GitHubApp {
    <#
        .SYNOPSIS
        Get the authenticated app

        .DESCRIPTION
        Returns the GitHub App associated with the authentication credentials used. To see how many app installations are associated with this
        GitHub App, see the `installations_count` in the response. For more details about your app's installations, see the
        "[List installations for the authenticated app](https://docs.github.com/rest/apps/apps#list-installations-for-the-authenticated-app)"
        endpoint.

        You must use a [JWT](https://docs.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app)
        to access this endpoint.

        .EXAMPLE
        Get-GitHubApp

        Get the authenticated app.

        .NOTES
        [Get the authenticated app | GitHub Docs](https://docs.github.com/rest/apps/apps#get-the-authenticated-app)
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding()]
    param(
        # The context to run the command in.
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    $inputObject = @{
        Context     = $Context
        APIEndpoint = '/app'
        Method      = 'GET'
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubApp] - Done"
#endregion - From [functions] - [public] - [Apps] - [Get-GitHubApp]
#region - From [functions] - [public] - [Apps] - [Get-GitHubAppInstallation]
Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubAppInstallation] - Importing"

filter Get-GitHubAppInstallation {
    <#
        .SYNOPSIS
        List installations for the authenticated app

        .DESCRIPTION
        The permissions the installation has are included under the `permissions` key.

        You must use a [JWT](https://docs.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app)
        to access this endpoint.


        .EXAMPLE
        An example

        .NOTES
        [List installations for the authenticated app](https://docs.github.com/rest/apps/apps#list-installations-for-the-authenticated-app)
    #>

    [CmdletBinding()]
    param()

    $inputObject = @{
        APIEndpoint = '/app/installations'
        Method      = 'GET'
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubAppInstallation] - Done"
#endregion - From [functions] - [public] - [Apps] - [Get-GitHubAppInstallation]
#region - From [functions] - [public] - [Apps] - [Get-GitHubAppJSONWebToken]
Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubAppJSONWebToken] - Importing"

function Get-GitHubAppJSONWebToken {
    <#
        .SYNOPSIS
        Generates a JSON Web Token (JWT) for a GitHub App.

        .DESCRIPTION
        Generates a JSON Web Token (JWT) for a GitHub App.

        .EXAMPLE
        Get-GitHubAppJWT -ClientId 'Iv987654321' -PrivateKeyFilePath '/path/to/private-key.pem'

        Generates a JSON Web Token (JWT) for a GitHub App using the specified client ID and private key file path.

        .EXAMPLE
        Get-GitHubAppJWT -ClientId 'Iv987654321' -PrivateKey '--- BEGIN RSA PRIVATE KEY --- ... --- END RSA PRIVATE KEY ---'

        Generates a JSON Web Token (JWT) for a GitHub App using the specified client ID and private key.

        .OUTPUTS
        System.String

        .NOTES
        [Generating a JSON Web Token (JWT) for a GitHub App | GitHub Docs](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app#example-using-powershell-to-generate-a-jwt)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines',
        '',
        Justification = 'Contains a long link.'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingConvertToSecureStringWithPlainText',
        '',
        Justification = 'Generated JWT is a plaintext string.'
    )]

    [CmdletBinding(DefaultParameterSetName = 'PrivateKey')]
    [Alias('Get-GitHubAppJWT')]
    [OutputType([string])]
    param(
        # The client ID of the GitHub App.
        # Can use the GitHub App ID or the client ID.
        # Example: 'Iv23li8tyK9NUwl7rWlQ'
        # Example: '123456'
        [Parameter(Mandatory)]
        [string] $ClientId,

        # The path to the private key file of the GitHub App.
        # Example: '/path/to/private-key.pem'
        [Parameter(
            Mandatory,
            ParameterSetName = 'FilePath'
        )]
        [string] $PrivateKeyFilePath,

        # The private key of the GitHub App.
        # Example: @'
        # -----BEGIN RSA PRIVATE KEY-----
        # qwe
        # ...
        # -----END RSA PRIVATE KEY-----
        # '@
        [Parameter(
            Mandatory,
            ParameterSetName = 'PrivateKey'
        )]
        [object] $PrivateKey
    )

    if ($PrivateKeyFilePath) {
        if (-not (Test-Path -Path $PrivateKeyFilePath)) {
            throw "The private key path [$PrivateKeyFilePath] does not exist."
        }

        $PrivateKey = Get-Content -Path $PrivateKeyFilePath -Raw
    }

    if ($PrivateKey -is [securestring]) {
        $PrivateKey = $PrivateKey | ConvertFrom-SecureString -AsPlainText
    }

    $header = [Convert]::ToBase64String(
        [System.Text.Encoding]::UTF8.GetBytes(
            (
                ConvertTo-Json -InputObject @{
                    alg = 'RS256'
                    typ = 'JWT'
                }
            )
        )
    ).TrimEnd('=').Replace('+', '-').Replace('/', '_')

    $iat = [System.DateTimeOffset]::UtcNow.AddSeconds(-10).ToUnixTimeSeconds()
    $exp = [System.DateTimeOffset]::UtcNow.AddMinutes(10).ToUnixTimeSeconds()
    $payload = [Convert]::ToBase64String(
        [System.Text.Encoding]::UTF8.GetBytes(
            (
                ConvertTo-Json -InputObject @{
                    iat = $iat
                    exp = $exp
                    iss = $ClientId
                }
            )
        )
    ).TrimEnd('=').Replace('+', '-').Replace('/', '_')

    $rsa = [System.Security.Cryptography.RSA]::Create()
    $rsa.ImportFromPem($PrivateKey)

    $signature = [Convert]::ToBase64String(
        $rsa.SignData(
            [System.Text.Encoding]::UTF8.GetBytes("$header.$payload"),
            [System.Security.Cryptography.HashAlgorithmName]::SHA256,
            [System.Security.Cryptography.RSASignaturePadding]::Pkcs1
        )
    ).TrimEnd('=').Replace('+', '-').Replace('/', '_')
    $jwt = "$header.$payload.$signature"
    [pscustomobject]@{
        Token     = ConvertTo-SecureString -String $jwt -AsPlainText
        IssuedAt  = $iat
        ExpiresAt = $exp
        Issuer    = $ClientId
    }
    Remove-Variable -Name jwt -ErrorAction SilentlyContinue
    Remove-Variable -Name rsa -ErrorAction SilentlyContinue
    Remove-Variable -Name signature -ErrorAction SilentlyContinue
    [System.GC]::Collect()
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [Get-GitHubAppJSONWebToken] - Done"
#endregion - From [functions] - [public] - [Apps] - [Get-GitHubAppJSONWebToken]
#region - From [functions] - [public] - [Apps] - [New-GitHubAppInstallationAccessToken]
Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [New-GitHubAppInstallationAccessToken] - Importing"

filter New-GitHubAppInstallationAccessToken {
    <#
        .SYNOPSIS
        Create an installation access token for an app

        .DESCRIPTION
        Creates an installation access token that enables a GitHub App to make authenticated API requests for the app's installation on an
        organization or individual account. Installation tokens expire one hour from the time you create them. Using an expired token produces a
        status code of `401 - Unauthorized`, and requires creating a new installation token. By default the installation token has access to all
        repositories that the installation can access.

        Optionally, you can use the `repositories` or `repository_ids` body parameters to specify individual repositories that the installation access
        token can access. If you don't use `repositories` or `repository_ids` to grant access to specific repositories, the installation access token
        will have access to all repositories that the installation was granted access to. The installation access token cannot be granted access to
        repositories that the installation was not granted access to. Up to 500 repositories can be listed in this manner.

        Optionally, use the `permissions` body parameter to specify the permissions that the installation access token should have. If `permissions`
        is not specified, the installation access token will have all of the permissions that were granted to the app. The installation access token
        cannot be granted permissions that the app was not granted.

        When using the repository or permission parameters to reduce the access of the token, the complexity of the token is increased due to both the
        number of permissions in the request and the number of repositories the token will have access to. If the complexity is too large, the token
        will fail to be issued. If this occurs, the error message will indicate the maximum number of repositories that should be requested. For the
        average application requesting 8 permissions, this limit is around 5000 repositories. With fewer permissions requested, more repositories are
        supported.

        You must use a [JWT](https://docs.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app)
        to access this endpoint.

        .EXAMPLE
        New-GitHubAppInstallationAccessToken -InstallationID 12345678

        Creates an installation access token for the installation with the ID `12345678`.

        .EXAMPLE
        Connect-GitHub -ClientID $ClientID -PrivateKey $PrivateKey -Verbose
        Get-GitHubAppInstallation | New-GitHubAppInstallationAccessToken

        Gets the GitHub App installations and creates an installation access token for each installation.

        .NOTES
        [Create an installation access token for an app](https://docs.github.com/rest/apps/apps#create-an-installation-access-token-for-an-app)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'No state is changed.'
    )]
    [CmdletBinding()]
    param (
        # The unique identifier of the installation.
        # Example: '12345678'
        [Parameter(
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName
        )]
        [Alias('ID')]
        [int] $InstallationID
    )

    $inputObject = @{
        APIEndpoint = "/app/installations/$InstallationID/access_tokens"
        Method      = 'Post'
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - [New-GitHubAppInstallationAccessToken] - Done"
#endregion - From [functions] - [public] - [Apps] - [New-GitHubAppInstallationAccessToken]

Write-Verbose "[$scriptName] - [functions] - [public] - [Apps] - Done"
#endregion - From [functions] - [public] - [Apps]

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

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

#region - From [functions] - [public] - [Auth] - [Context] - [Get-GitHubContext]
Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Get-GitHubContext] - Importing"

#Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' }

function Get-GitHubContext {
    <#
        .SYNOPSIS
        Get the current GitHub context.

        .DESCRIPTION
        Get the current GitHub context.

        .EXAMPLE
        Get-GitHubContext

        Gets the current GitHub context.
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingConvertToSecureStringWithPlainText', '',
        Justification = 'Encapsulated in a function. Never leaves as a plain text.'
    )]
    [OutputType([GitHubContext])]
    [CmdletBinding(DefaultParameterSetName = 'CurrentContext')]
    param(
        # The name of the context.
        [Parameter(
            Mandatory,
            ParameterSetName = 'NamedContext'
        )]
        [Alias('Name')]
        [string] $Context,

        # List all available contexts.
        [Parameter(
            Mandatory,
            ParameterSetName = 'ListAvailableContexts'
        )]
        [switch] $ListAvailable
    )

    $commandName = $MyInvocation.MyCommand.Name
    Write-Verbose "[$commandName] - Start"

    if ($ListAvailable) {
        $ID = "$($script:Config.Name)/*"
        Write-Verbose "Getting available contexts for [$ID]"
    } elseif ($Context) {
        $ID = "$($script:Config.Name)/$Context"
        Write-Verbose "Getting available contexts for [$ID]"
    } else {
        $config = Get-GitHubConfig
        $defaultContext = $config.DefaultContext
        $ID = "$($script:Config.Name)/$defaultContext"
        if ([string]::IsNullOrEmpty($ID)) {
            throw "No default GitHub context found. Please run 'Set-GitHubDefaultContext' or 'Connect-GitHub' to configure a GitHub context."
        }
        Write-Verbose "Getting the default context: [$ID]"
    }

    Get-Context -ID $ID | ForEach-Object {
        [GitHubContext]$_
    }

    Write-Verbose "[$commandName] - End"
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Get-GitHubContext] - Done"
#endregion - From [functions] - [public] - [Auth] - [Context] - [Get-GitHubContext]
#region - From [functions] - [public] - [Auth] - [Context] - [Remove-GitHubContext]
Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Remove-GitHubContext] - Importing"

#Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' }

filter Remove-GitHubContext {
    <#
        .SYNOPSIS
        Removes a context from the context vault.

        .DESCRIPTION
        This function removes a context from the vault. It supports removing a single context by name,
        multiple contexts using wildcard patterns, and can also accept input from the pipeline.
        If the specified context(s) exist, they will be removed from the vault.

        .EXAMPLE
        Remove-Context

        Removes all contexts from the vault.

        .EXAMPLE
        Remove-Context -ID 'MySecret'

        Removes the context called 'MySecret' from the vault.
    #>

    [OutputType([void])]
    [CmdletBinding(SupportsShouldProcess)]
    param(
        # The name of the context.
        [Parameter(Mandatory)]
        [Alias('Name')]
        [string] $Context
    )

    $commandName = $MyInvocation.MyCommand.Name
    Write-Verbose "[$commandName] - Start"

    $ID = "$($script:Config.Name)/$Context"

    if ($PSCmdlet.ShouldProcess('Remove-Secret', $context.Name)) {
        Remove-Context -ID $ID
    }

    Write-Verbose "[$commandName] - End"
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Remove-GitHubContext] - Done"
#endregion - From [functions] - [public] - [Auth] - [Context] - [Remove-GitHubContext]
#region - From [functions] - [public] - [Auth] - [Context] - [Set-GitHubContext]
Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Set-GitHubContext] - Importing"

#Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' }

function Set-GitHubContext {
    <#
        .SYNOPSIS
        Short description

        .DESCRIPTION
        Long description

        .EXAMPLE
        An example

        .NOTES
        General notes
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The Node ID of the context.
        [Parameter()]
        [string] $NodeID,

        # The Database ID of the context.
        [Parameter()]
        [string] $DatabaseID,

        # Set the access token type.
        [Parameter(Mandatory)]
        [string] $TokenType,

        # Set the client ID.
        [Parameter()]
        [string] $ClientID,

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

        # Set the expiration date of the contexts token.
        [Parameter()]
        [datetime] $TokenExpirationDate,

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

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

        # Set the authentication client ID.
        [Parameter()]
        [string] $AuthClientID,

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

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

        # Set the API hostname.
        [Parameter(Mandatory)]
        [string] $HostName,

        # 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 as the default context.
        [Parameter()]
        [switch] $Default
    )

    begin {
        $commandName = $MyInvocation.MyCommand.Name
        Write-Verbose "[$commandName] - Start"
    }

    process {
        $tempContextName = "$HostName/tempContext"
        $tempContextID = "$($script:Config.Name)/$tempContextName"

        # Set a temporary context.
        $context = @{
            ApiBaseUri                 = $ApiBaseUri                 # https://api.github.com
            ApiVersion                 = $ApiVersion                 # 2022-11-28
            AuthClientID               = $AuthClientID               # Client ID for UAT
            AuthType                   = $AuthType                   # UAT / PAT / App / IAT
            ClientID                   = $ClientID                   # Client ID for GitHub Apps
            DeviceFlowType             = $DeviceFlowType             # GitHubApp / OAuthApp
            HostName                   = $HostName                   # github.com / msx.ghe.com / github.local
            NodeID                     = $NodeID                     # User ID / app ID (GraphQL Node ID)
            DatabaseID                 = $DatabaseID                 # Database ID
            UserName                   = $UserName                   # User name
            Owner                      = $Owner                      # Owner name
            Repo                       = $Repo                       # Repo name
            Scope                      = $Scope                      # 'gist read:org repo workflow'
            #-----------------------------------------------------------------------------------------
            TokenType                  = $TokenType                  # ghu / gho / ghp / github_pat / PEM / ghs /
            Token                      = $Token                      # Access token
            TokenExpirationDate        = $TokenExpirationDate        # 2024-01-01-00:00:00
            RefreshToken               = $RefreshToken               # Refresh token
            RefreshTokenExpirationDate = $RefreshTokenExpirationDate # 2024-01-01-00:00:00
        }

        $context | Remove-HashtableEntry -NullOrEmptyValues

        Set-Context -ID $tempContextID -Context $context

        # Run functions to get info on the temporary context.
        try {
            Write-Verbose 'Getting info on the context.'
            switch -Regex ($context['AuthType']) {
                'PAT|UAT|IAT' {
                    $viewer = Get-GitHubViewer -Context $tempContextName
                    $contextName = "$HostName/$($viewer.login)"
                    $context['Username'] = $viewer.login
                    $context['NodeID'] = $viewer.id
                    $context['DatabaseID'] = ($viewer.databaseId).ToString()
                }
                'App' {
                    $app = Get-GitHubApp -Context $tempContextName
                    $contextName = "$HostName/$($app.slug)"
                    $context['Username'] = $app.slug
                    $context['NodeID'] = $app.node_id
                    $context['DatabaseID'] = $app.id
                }
                default {
                    throw 'Failed to get info on the context. Unknown logon type.'
                }
            }
            Write-Verbose "Found user with username: [$($context['Username'])]"

            if ($PSCmdlet.ShouldProcess('Context', 'Set')) {
                Set-Context -ID "$($script:Config.Name)/$contextName" -Context $context
                if ($Default) {
                    Set-GitHubDefaultContext -Context $contextName
                }
            }
        } catch {
            throw ($_ -join ';')
        } finally {
            Remove-Context -ID $tempContextID
        }
    }

    end {
        Write-Verbose "[$commandName] - End"
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Set-GitHubContext] - Done"
#endregion - From [functions] - [public] - [Auth] - [Context] - [Set-GitHubContext]
#region - From [functions] - [public] - [Auth] - [Context] - [Set-GitHubDefaultContext]
Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Set-GitHubDefaultContext] - Importing"

function Set-GitHubDefaultContext {
    <#
        .SYNOPSIS
        Set the default context.

        .DESCRIPTION
        Set the default context for the GitHub module.

        .EXAMPLE
        Set-GitHubDefaultContext -Context 'github.com/Octocat'
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The context to set as the default.
        [Parameter(Mandatory)]
        [Alias('Name')]
        [string] $Context
    )

    $commandName = $MyInvocation.MyCommand.Name
    Write-Verbose "[$commandName] - Start"

    if ($PSCmdlet.ShouldProcess("$Context", 'Set default context')) {
        Set-GitHubConfig -Name 'DefaultContext' -Value $Context
    }

    Write-Verbose "[$commandName] - End"
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Context] - [Set-GitHubDefaultContext] - Done"
#endregion - From [functions] - [public] - [Auth] - [Context] - [Set-GitHubDefaultContext]

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

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

#region - From [functions] - [public] - [Auth] - [ContextSetting] - [Get-GitHubContextSetting]
Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - [Get-GitHubContextSetting] - Importing"

#Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' }

function Get-GitHubContextSetting {
    <#
        .SYNOPSIS
        Get a module configuration value.

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

        .EXAMPLE
        Get-GitHubContextSetting -Name DefaultUser

        Get the current GitHub configuration for the DefaultUser.
    #>

    [OutputType([object])]
    [CmdletBinding()]
    param(
        # Choose a configuration name to get.
        [Parameter()]
        [string] $Name,

        # The name of the context.
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    $commandName = $MyInvocation.MyCommand.Name
    Write-Verbose "[$commandName] - Start"

    $ID = "$($script:Config.Name)/$Context"

    if (-not $Name) {
        Get-Context -ID $ID
    }

    Get-ContextSetting -Name $Name -ID $ID

    Write-Verbose "[$commandName] - End"
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - [Get-GitHubContextSetting] - Done"
#endregion - From [functions] - [public] - [Auth] - [ContextSetting] - [Get-GitHubContextSetting]
#region - From [functions] - [public] - [Auth] - [ContextSetting] - [Set-GitHubContextSetting]
Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - [Set-GitHubContextSetting] - Importing"

#Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' }

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

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

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

        Sets the App.API scope of the GitHub configuration.

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

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

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

        # The Node ID of the context.
        [Parameter()]
        [string] $NodeID,

        # The Database ID of the context.
        [Parameter()]
        [string] $DatabaseID,

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

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

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

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

        # Set the authentication client ID.
        [Parameter()]
        [string] $AuthClientID,

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

        # Set the client ID.
        [Parameter()]
        [string] $ClientID,

        # 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,

        # The context name to set the configuration for.
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    $commandName = $MyInvocation.MyCommand.Name
    Write-Verbose "[$commandName] - Start"

    $contextID = "$($Script:Config.Name)/$Context"

    if ($PSCmdlet.ShouldProcess('Config', 'Set')) {

        $PSBoundParameters.GetEnumerator() | ForEach-Object {
            $key = $_.Key
            $value = $_.Value
            if ($PSCmdlet.ShouldProcess("Setting [$key]", "to [$value]")) {
                Write-Verbose "Setting [$key] to [$value]"
                Set-ContextSetting -Name $key -Value $value -ID $contextID
            }
        }
    }

    Write-Verbose "[$commandName] - End"
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [ContextSetting] - [Set-GitHubContextSetting] - Done"
#endregion - From [functions] - [public] - [Auth] - [ContextSetting] - [Set-GitHubContextSetting]

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

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

function Connect-GitHubAccount {
    <#
        .SYNOPSIS
        Connects to GitHub.

        .DESCRIPTION
        Connects to GitHub using one of the following logon methods:
        - a personal access token
        - device code login (interactive user login)
        - a system access token (for GitHub Actions)
        - a GitHub App using JWT or installation access token

        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
        $env:GH_TOKEN = '***'
        Connect-GitHubAccount

        Connects to GitHub using the access token from environment variable, assuming unattended mode.

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

        User gets prompted for the access token and stores it in the context.
        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
        [Authenticating to the REST API](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])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links for documentation.')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Is the CLI part of the module.')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'The tokens are recieved as clear text. Mitigating exposure by removing variables and performing garbage collection.')]
    [CmdletBinding(DefaultParameterSetName = 'UAT')]
    param (
        # Choose between authentication methods, either OAuthApp or GitHubApp.
        # For more info about the types of authentication visit:
        # [Differences between GitHub Apps and OAuth apps](https://docs.github.com/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps)
        [Parameter(ParameterSetName = 'UAT')]
        [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:
        # [Scopes for OAuth apps](https://docs.github.com/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)
        [Parameter(ParameterSetName = 'UAT')]
        [string] $Scope = 'gist read:org repo workflow',


        # The user will be prompted to enter the token.
        [Parameter(
            Mandatory,
            ParameterSetName = 'PAT'
        )]
        [switch] $UseAccessToken,

        # An access token to use for authentication. Can be both a string or a SecureString.
        # Supports both personal access tokens (PAT) and GitHub App installation access tokens (IAT).
        # Example: 'ghp_1234567890abcdef'
        # Example: 'ghs_1234567890abcdef'
        [Parameter(
            Mandatory,
            ParameterSetName = 'Token'
        )]
        [object] $Token,

        # The client ID for the GitHub App to use for authentication.
        [Parameter(ParameterSetName = 'UAT')]
        [Parameter(
            Mandatory,
            ParameterSetName = 'App'
        )]
        [string] $ClientID,

        # The private key for the GitHub App when authenticating as a GitHub App.
        [Parameter(
            Mandatory,
            ParameterSetName = 'App'
        )]
        [string] $PrivateKey,

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

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

        # API version used for API requests.
        [Parameter()]
        [string] $ApiVersion = '2022-11-28',

        # The host to connect to. Can use $env:GITHUB_SERVER_URL to set the host, as the protocol is removed automatically.
        # Example: github.com, github.enterprise.com, msx.ghe.com
        [Parameter()]
        [Alias('Host')]
        [Alias('Server')]
        [string] $HostName = $env:GITHUB_SERVER_URL ?? 'github.com',

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

    $commandName = $MyInvocation.MyCommand.Name
    Write-Verbose "[$commandName] - Start"

    try {
        if ($Token -is [System.Security.SecureString]) {
            $Token = ConvertFrom-SecureString $Token -AsPlainText
        }

        $HostName = $HostName -replace '^https?://'
        $ApiBaseUri = "https://api.$HostName"
        $authType = $PSCmdlet.ParameterSetName
        $tokenPrefixPattern = '(?<=^(ghu|gho|ghs|github_pat|ghp)).*'

        # If running on GitHub Actions and no access token is provided, use the GitHub token.
        if (($env:GITHUB_ACTIONS -eq 'true') -and $PSCmdlet.ParameterSetName -ne 'App') {
            $tokenNotProvided = [string]::IsNullOrEmpty($Token)
            $gitHubToken = $env:GH_TOKEN ?? $env:GITHUB_TOKEN
            $gitHubTokenPresent = -not [string]::IsNullOrEmpty($gitHubToken)
            Write-Verbose "Token not provided: [$tokenNotProvided]"
            Write-Verbose "GitHub token present: [$gitHubTokenPresent]"
            if ($tokenNotProvided -and $gitHubTokenPresent) {
                $authType = 'Token'
                $Token = $gitHubToken
            }
        }

        $context = @{
            ApiBaseUri = $ApiBaseUri
            ApiVersion = $ApiVersion
            HostName   = $HostName
            AuthType   = $authType
            Owner      = $Owner
            Repo       = $Repo
        }

        $gitHubConfig = Get-GitHubConfig
        $defaultContextID = $gitHubConfig.DefaultContext
        if ($defaultContextID) {
            $defaultContext = Get-GitHubContext -Context $defaultContextID
        }

        Write-Verbose "AuthType: [$authType]"
        switch ($authType) {
            'UAT' {
                Write-Verbose 'Logging in using device flow...'
                if (-not [string]::IsNullOrEmpty($ClientID)) {
                    Write-Verbose "Using provided ClientID: [$ClientID]"
                    $authClientID = $ClientID
                } elseif (-not [string]::IsNullOrEmpty($($defaultContext.AuthClientID))) {
                    Write-Verbose "Reusing previously stored ClientID: [$($defaultContext.AuthClientID)]"
                    $authClientID = $defaultContext.AuthClientID
                } else {
                    Write-Verbose "Using default ClientID: [$($script:Auth.$Mode.ClientID)]"
                    $authClientID = $script:Auth.$Mode.ClientID
                }
                if ($Mode -ne ($defaultContext.DeviceFlowType)) {
                    Write-Verbose "Using $Mode authentication..."
                    $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $authClientID -Scope $Scope -HostName $HostName
                } else {
                    $accessTokenValidity = [datetime]($defaultContext.TokenExpirationDate) - (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 ..."
                            }
                            return
                        } else {
                            if (-not $Silent) {
                                Write-Host 'âš  ' -ForegroundColor Yellow -NoNewline
                                Write-Host "Access token remaining validity $accessTokenValidityText. Refreshing access token..."
                            }
                            $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $authClientID -RefreshToken ($defaultContext.RefreshToken) -HostName $HostName
                        }
                    } else {
                        $refreshTokenValidity = [datetime]($defaultContext.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 $authClientID -RefreshToken ($defaultContext.RefreshToken) -HostName $HostName
                        } else {
                            Write-Verbose "Using $Mode authentication..."
                            $tokenResponse = Invoke-GitHubDeviceFlowLogin -ClientID $authClientID -Scope $Scope -HostName $HostName
                        }
                    }
                }
                switch ($Mode) {
                    'GitHubApp' {
                        $context += @{
                            Token                      = ConvertTo-SecureString -AsPlainText $tokenResponse.access_token
                            TokenExpirationDate        = (Get-Date).AddSeconds($tokenResponse.expires_in)
                            TokenType                  = $tokenResponse.access_token -replace $tokenPrefixPattern
                            AuthClientID               = $authClientID
                            DeviceFlowType             = $Mode
                            RefreshToken               = ConvertTo-SecureString -AsPlainText $tokenResponse.refresh_token
                            RefreshTokenExpirationDate = (Get-Date).AddSeconds($tokenResponse.refresh_token_expires_in)
                            Scope                      = $tokenResponse.scope
                        }
                    }
                    'OAuthApp' {
                        $context += @{
                            Token          = ConvertTo-SecureString -AsPlainText $tokenResponse.access_token
                            TokenType      = $tokenResponse.access_token -replace $tokenPrefixPattern
                            AuthClientID   = $authClientID
                            DeviceFlowType = $Mode
                            Scope          = $tokenResponse.scope
                        }
                    }
                    default {
                        Write-Host 'âš  ' -ForegroundColor Yellow -NoNewline
                        Write-Host "Unexpected authentication mode: $Mode"
                        return
                    }
                }
            }
            'App' {
                Write-Verbose 'Logging in as a GitHub App...'
                $context += @{
                    Token     = ConvertTo-SecureString -AsPlainText $PrivateKey
                    TokenType = 'PEM'
                    ClientID  = $ClientID
                }
            }
            'PAT' {
                Write-Debug "UseAccessToken is set to [$UseAccessToken]. Using provided access token..."
                Write-Verbose 'Logging in using personal access token...'
                Write-Host '! ' -ForegroundColor DarkYellow -NoNewline
                Start-Process "https://$HostName/settings/tokens"
                $accessTokenValue = Read-Host -Prompt 'Enter your personal access token' -AsSecureString
                $Token = ConvertFrom-SecureString $accessTokenValue -AsPlainText
                $tokenType = $Token -replace $tokenPrefixPattern
                $context += @{
                    Token     = ConvertTo-SecureString -AsPlainText $Token
                    TokenType = $tokenType
                }
            }
            'Token' {
                $tokenType = $Token -replace $tokenPrefixPattern
                switch -Regex ($tokenType) {
                    'ghp|github_pat' {
                        $context += @{
                            Token     = ConvertTo-SecureString -AsPlainText $Token
                            TokenType = $tokenType
                        }
                        $context['AuthType'] = 'PAT'
                    }
                    'ghs' {
                        Write-Verbose 'Logging in using an installation access token...'
                        $context += @{
                            Token     = ConvertTo-SecureString -AsPlainText $Token
                            TokenType = $tokenType
                        }
                        $context['AuthType'] = 'IAT'
                    }
                    default {
                        Write-Host 'âš  ' -ForegroundColor Yellow -NoNewline
                        Write-Host "Unexpected token type: $tokenType"
                        throw "Unexpected token type: $tokenType"
                    }
                }
            }
        }
        Set-GitHubContext @context -Default
        $context = Get-GitHubContext
        Write-Verbose ($context | Format-List | Out-String)
        if (-not $Silent) {
            $name = $context.Username
            Write-Host '✓ ' -ForegroundColor Green -NoNewline
            Write-Host "Logged in as $name!"
        }
    } catch {
        Write-Error $_
        Write-Error (Get-PSCallStack | Format-Table | Out-String)
        throw 'Failed to connect to GitHub.'
    } finally {
        Remove-Variable -Name tokenResponse -ErrorAction SilentlyContinue
        Remove-Variable -Name context -ErrorAction SilentlyContinue
        [System.GC]::Collect()
    }
    Write-Verbose "[$commandName] - End"
}

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

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

        .DESCRIPTION
        Disconnects from GitHub and removes the GitHub context.

        .EXAMPLE
        Disconnect-GitHubAccount

        Disconnects from GitHub and removes the default GitHub context.

        .EXAMPLE
        Disconnect-GithubAccount -Context 'github.com/Octocat'

        Disconnects from GitHub and removes the context 'github.com/Octocat'.
    #>

    [Alias(
        'Disconnect-GHAccount',
        'Disconnect-GitHub',
        'Disconnect-GH',
        'Logout-GitHubAccount',
        'Logout-GHAccount',
        'Logout-GitHub',
        'Logout-GH',
        'Logoff-GitHubAccount',
        'Logoff-GHAccount',
        'Logoff-GitHub',
        'Logoff-GH'
    )]
    [OutputType([void])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Is the CLI part of the module.')]
    [CmdletBinding()]
    param(
        # The context to log out of.
        [Parameter()]
        [Alias('Name')]
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext'),

        # Silently disconnects from GitHub.
        [Parameter()]
        [switch] $Silent
    )

    $commandName = $MyInvocation.MyCommand.Name
    Write-Verbose "[$commandName] - Start"

    Remove-GitHubContext -Context $Context
    $isDefaultContext = $Context -eq (Get-GitHubConfig -Name 'DefaultContext')
    if ($isDefaultContext) {
        Remove-GitHubConfig -Name 'DefaultContext'
    }

    if (-not $Silent) {
        Write-Host '✓ ' -ForegroundColor Green -NoNewline
        Write-Host "Logged out of GitHub! [$Context]"
    }

    Write-Verbose "[$commandName] - End"
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Disconnect-GitHubAccount] - Done"
#endregion - From [functions] - [public] - [Auth] - [Disconnect-GitHubAccount]
#region - From [functions] - [public] - [Auth] - [Get-GitHubViewer]
Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Get-GitHubViewer] - Importing"

function Get-GitHubViewer {
    <#
        .SYNOPSIS
        Gets the currently authenticated user.

        .DESCRIPTION
        Gets the currently authenticated user.

        .EXAMPLE
        Get-GithubViewer

        Gets the currently authenticated user.

        .NOTES
        [GraphQL API - Queries - Viewer](https://docs.github.com/en/graphql/reference/queries#viewer)
    #>

    [CmdletBinding()]
    param(
        # The fields to return.
        [string[]] $Fields = @('login', 'id', 'databaseId'),

        # Context to run the command in.
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    begin {
        $commandName = $MyInvocation.MyCommand.Name
        Write-Verbose "[$commandName] - Start"
    }

    process {
        $query = @"
query {
  viewer {
    $($Fields -join "`n")
  }
}
"@

        $results = Invoke-GitHubGraphQLQuery -Query $query -Context $Context

        return $results.data.viewer
    }

    end {
        Write-Verbose "[$commandName] - End"
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Auth] - [Get-GitHubViewer] - Done"
#endregion - From [functions] - [public] - [Auth] - [Get-GitHubViewer]

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

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

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

filter Get-GitHubRepoBranch {
    <#
        .SYNOPSIS
        List branches

        .DESCRIPTION
        Lists all branches from a repository

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

        Gets all the branches from the 'Hello-World' repository owned by 'octocat'

        .NOTES
        [List branches](https://docs.github.com/rest/branches/branches#list-branches)
    #>

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

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

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

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

}

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

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

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

#region - From [functions] - [public] - [Commands] - [Add-GitHubMask]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Add-GitHubMask] - Importing"

filter Add-GitHubMask {
    <#
        .SYNOPSIS
        Masks a value in a log

        .DESCRIPTION
        Masking a value prevents a string or variable from being printed in the log. Each masked word separated by whitespace is
        replaced with the * character. You can use an environment variable or string for the mask's value. When you mask a value,
        it is treated as a secret and will be redacted on the runner. For example, after you mask a value, you won't be able to
        set that value as an output.

        .EXAMPLE
        Add-Mask $SecretValue

        Masks the value of $SecretValue so that its printed like ***.

        .EXAMPLE
        $SecretValue1, $SecretValue2 | Mask

        Masks the value of $SecretValue1 and $SecretValue2 so that its printed like ***, using the pipeline

        .NOTES
        [Masking a value in a log](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#masking-a-value-in-a-log)
    #>

    [Alias('Mask', 'Add-Mask')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long documentation URL'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Does not change state'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingWriteHost', '', Scope = 'Function',
        Justification = 'Intended for logging in Github Runners which does support Write-Host'
    )]
    [CmdletBinding()]
    param(
        # The value to mask
        [Parameter(
            Mandatory,
            ValueFromPipeline
        )]
        [AllowNull()]
        [string[]] $Value
    )

    foreach ($item in $Value) {
        Write-Host "::add-mask::$item"
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Add-GitHubMask] - Done"
#endregion - From [functions] - [public] - [Commands] - [Add-GitHubMask]
#region - From [functions] - [public] - [Commands] - [Add-GitHubSystemPath]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Add-GitHubSystemPath] - Importing"

function Add-GitHubSystemPath {
    <#
        .SYNOPSIS
        Adds a system path to the GitHub Actions environment

        .DESCRIPTION
        Prepends a directory to the system PATH variable and automatically makes it available to all subsequent actions in the current job;
        the currently running action cannot access the updated path variable. To see the currently defined paths for your job, you can use
        echo "$env:PATH" in a step or an action.

        .EXAMPLE
        Add-GitHubSystemPath -Path '$HOME/.local/bin'

        .NOTES
        [Adding a system path](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#adding-a-system-path)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long documentation URL'
    )]
    [OutputType([void])]
    [CmdletBinding()]
    param (
        [string]$Path
    )

    Write-Verbose "Current PATH: $env:PATH"
    Write-Verbose "Adding system path: $Path"

    $Path | Out-File -FilePath $env:GITHUB_PATH -Append
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Add-GitHubSystemPath] - Done"
#endregion - From [functions] - [public] - [Commands] - [Add-GitHubSystemPath]
#region - From [functions] - [public] - [Commands] - [Disable-GitHubCommand]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Disable-GitHubCommand] - Importing"

function Disable-GitHubCommand {
    <#
        .SYNOPSIS
        Stops workflow commands

        .DESCRIPTION
        Stops processing any workflow commands. This special command allows you to log anything without accidentally running a workflow command.
        For example, you could stop logging to output an entire script that has comments.

        To stop the processing of workflow commands, pass a unique string to the function. To resume processing workflow commands, pass the same string
        that you used to stop workflow commands to the Enable-GitHubCommand.

        .EXAMPLE
        Disable-GitHubCommand "123"

        Stops processing any workflow commands.

        .NOTES
        [Stopping and starting workflow commands](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#stopping-and-starting-workflow-commands)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingWriteHost', '', Scope = 'Function',
        Justification = 'Intended for logging in Github Runners which does support Write-Host'
    )]
    [OutputType([void])]
    [CmdletBinding()]
    param (
        # The unique string to stop the processing of workflow commands
        [Parameter(Mandatory)]
        [string] $String
    )

    $String = $String.ToLower()

    if ($env:GITHUB_ACTIONS -eq 'true') {
        Write-Host "::stop-commands::$String"
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Disable-GitHubCommand] - Done"
#endregion - From [functions] - [public] - [Commands] - [Disable-GitHubCommand]
#region - From [functions] - [public] - [Commands] - [Enable-GitHubCommand]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Enable-GitHubCommand] - Importing"

function Enable-GitHubCommand {
    <#
        .SYNOPSIS
        Resumes workflow commands

        .DESCRIPTION
        Resumes processing any workflow commands.

        To stop the processing of workflow commands, pass a unique string to the function. To resume processing workflow commands, pass the same string
        that you used to stop workflow commands to the Enable-GitHubCommand.

        .EXAMPLE
        Enable-GitHubCommand "123"

        Resumes processing any workflow commands.

        .NOTES
        [Stopping and starting workflow commands](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#stopping-and-starting-workflow-commands)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingWriteHost', '', Scope = 'Function',
        Justification = 'Intended for logging in Github Runners which does support Write-Host'
    )]
    [OutputType([void])]
    [CmdletBinding()]
    param (
        # The unique string to resume the processing of workflow commands
        [Parameter(Mandatory)]
        [string] $String
    )

    $String = $String.ToLower()

    if ($env:GITHUB_ACTIONS -eq 'true') {
        Write-Host "::$String::"
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Enable-GitHubCommand] - Done"
#endregion - From [functions] - [public] - [Commands] - [Enable-GitHubCommand]
#region - From [functions] - [public] - [Commands] - [Set-GitHubEnvironmentVariable]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubEnvironmentVariable] - Importing"

function Set-GitHubEnvironmentVariable {
    <#
        .SYNOPSIS
        Setting an environment variable

        .DESCRIPTION
        Set a GitHub environment variable

        .EXAMPLE
        Set-GitHubEnv -Name 'MyVariable' -Value 'MyValue'

        .NOTES
        [Setting an environment variable](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-an-environment-variable)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Does not change system state significantly'
    )]
    [OutputType([void])]
    [Alias('Set-GitHubEnv')]
    [CmdletBinding()]
    param (
        # Name of the variable
        [Parameter(Mandatory)]
        [string] $Name,

        # Value of the variable
        [Parameter(Mandatory)]
        [AllowNull()]
        [string] $Value
    )

    Write-Verbose "Env: [$Name] = [$Value]"

    $Value = $Value.Split([System.Environment]::NewLine)
    $guid = [guid]::NewGuid().Guid
    "$Name<<$guid" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
    $Value | ForEach-Object {
        $_ | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
    }
    "$guid" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubEnvironmentVariable] - Done"
#endregion - From [functions] - [public] - [Commands] - [Set-GitHubEnvironmentVariable]
#region - From [functions] - [public] - [Commands] - [Set-GitHubLogGroup]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubLogGroup] - Importing"

function Set-GitHubLogGroup {
    <#
        .SYNOPSIS
        Encapsulates commands with a log group in GitHub Actions

        .DESCRIPTION
        DSL approach for GitHub Action commands.
        Allows for colapsing of code in IDE for code that belong together.

        .EXAMPLE
        Set-GitHubLogGroup -Name 'MyGroup' -ScriptBlock {
            Write-Host 'Hello, World!'
        }

        Creates a new log group named 'MyGroup' and writes 'Hello, World!' to the output.

        .EXAMPLE
        LogGroup 'MyGroup' {
            Write-Host 'Hello, World!'
        }

        Uses the alias 'LogGroup' to create a new log group named 'MyGroup' and writes 'Hello, World!' to the output.

        .NOTES
        [GitHub - Grouping log lines](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines)
    #>

    [Alias('LogGroup')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Does not change state'
    )]
    [CmdletBinding()]
    param(
        # The name of the log group
        [Parameter(Mandatory)]
        [string] $Name,

        # The script block to execute
        [Parameter(Mandatory)]
        [scriptblock] $ScriptBlock
    )

    Start-GitHubLogGroup -Name $Name
    . $ScriptBlock
    Stop-GitHubLogGroup
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubLogGroup] - Done"
#endregion - From [functions] - [public] - [Commands] - [Set-GitHubLogGroup]
#region - From [functions] - [public] - [Commands] - [Set-GitHubNoCommandGroup]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubNoCommandGroup] - Importing"

function Set-GitHubNoCommandGroup {
    <#
        .SYNOPSIS
        Disables workflow commands for a block of code.

        .DESCRIPTION
        DSL approach for GitHub Action commands.
        Allows for colapsing of code in IDE for code that belong together.

        .EXAMPLE
        Set-GitHubNoCommandGroup {
            Write-Host 'Hello, World!'
            Write-GithubError 'This is an error'
        }

        Groups commands where no workflow commands are run.

        .EXAMPLE
        NoLogGroup 'MyGroup' {
            Write-Host 'Hello, World!'
            Write-GithubError 'This is an error'
        }

        Groups commands where no workflow commands are run, using an alias and DSL approach.

        .NOTES
        [Stopping and starting workflow commands](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#stopping-and-starting-workflow-commands)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Does not change state'
    )]
    [CmdletBinding()]
    [Alias('NoLogGroup')]
    param(
        # The script block to execute
        [Parameter(Mandatory)]
        [scriptblock] $ScriptBlock
    )

    $guid = [string][guid]::NewGuid().Guid

    Disable-GitHubCommand -String $guid
    . $ScriptBlock
    Enable-GitHubCommand -String $guid
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubNoCommandGroup] - Done"
#endregion - From [functions] - [public] - [Commands] - [Set-GitHubNoCommandGroup]
#region - From [functions] - [public] - [Commands] - [Set-GitHubOutput]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubOutput] - Importing"

function Set-GitHubOutput {
    <#
        .SYNOPSIS
        Set a output variable in GitHub Actions

        .DESCRIPTION
        Supports SecureString and multiline strings.

        .EXAMPLE
        Set-GitHubOutput -Name 'MyOutput' -Value 'Hello, World!'

        Creates a new output variable named 'MyOutput' with the value 'Hello, World!'.

        .NOTES
        [Setting an output parameter](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-an-output-parameter)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Does not change system state significantly'
    )]
    [OutputType([void])]
    [Alias('Output')]
    [CmdletBinding()]
    param (
        # Name of the variable
        [Parameter(Mandatory)]
        [string] $Name,

        # Value of the variable
        [Parameter(Mandatory)]
        [AllowNull()]
        [object] $Value
    )

    if ($Value -Is [securestring]) {
        $Value = $Value | ConvertFrom-SecureString -AsPlainText -Force
        Add-Mask -Value $Value
    }

    if ([string]::IsNullOrEmpty($env:GITHUB_ACTION)) {
        Write-Warning 'Cannot create output as the step has no ID.'
    }

    Write-Verbose "Output: [$Name] = [$Value]"

    $Value = $Value.Split([System.Environment]::NewLine)
    $guid = [guid]::NewGuid().Guid
    "$Name<<$guid" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
    $Value | ForEach-Object {
        $_ | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
    }
    "$guid" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append

    Write-Verbose "Output: [$Name] avaiable as `${{ steps.$env:GITHUB_ACTION.outputs.$Name }}'"
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubOutput] - Done"
#endregion - From [functions] - [public] - [Commands] - [Set-GitHubOutput]
#region - From [functions] - [public] - [Commands] - [Set-GitHubStepSummary]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubStepSummary] - Importing"

function Set-GitHubStepSummary {
    <#
        .SYNOPSIS
        Set a summary for the step in GitHub Actions

        .DESCRIPTION
        You can set some custom Markdown for each job so that it will be displayed on the summary page of a workflow run.
        You can use job summaries to display and group unique content, such as test result summaries, so that someone viewing
        the result of a workflow run doesn't need to go into the logs to see important information related to the run, such as failures.

        Job summaries support GitHub flavored Markdown, and you can add your Markdown content for a step to the `GITHUB_STEP_SUMMARY`
        environment file. `GITHUB_STEP_SUMMARY` is unique for each step in a job. For more information about the per-step file that
        `GITHUB_STEP_SUMMARY` references, see [Environment files](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions?utm_source=chatgpt.com#environment-files).

        When a job finishes, the summaries for all steps in a job are grouped together into a single job summary and are shown on the
        workflow run summary page. If multiple jobs generate summaries, the job summaries are ordered by job completion time.

        .EXAMPLE
        Set-GitHubStepSummary -Summary 'Hello, World!'

        .NOTES
        [Adding a job summary](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions?utm_source=chatgpt.com#adding-a-job-summary)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Does not change system state significantly'
    )]
    [OutputType([void])]
    [Alias('Summary')]
    [CmdletBinding()]
    param (
        # Summary of the step
        [Parameter(Mandatory)]
        [AllowNull()]
        [string] $Summary,

        # Whether to overwrite the existing summary
        [switch] $Overwrite
    )

    Write-Verbose "Step summary:"
    Write-Verbose $Summary

    $Append = -not $Overwrite

    $Summary = $Summary.Split([System.Environment]::NewLine)
    $Summary | ForEach-Object {
        $_ | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append:$Append
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Set-GitHubStepSummary] - Done"
#endregion - From [functions] - [public] - [Commands] - [Set-GitHubStepSummary]
#region - From [functions] - [public] - [Commands] - [Start-GitHubLogGroup]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Start-GitHubLogGroup] - Importing"

function Start-GitHubLogGroup {
    <#
        .SYNOPSIS
        Starts a log group in GitHub Actions

        .EXAMPLE
        New-LogGroup 'MyGroup'

        Starts a new log group named 'MyGroup'

        .NOTES
        [GitHub - Grouping log lines](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Does not change state'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingWriteHost', '', Scope = 'Function',
        Justification = 'Intended for logging in Github Runners which does support Write-Host'
    )]
    [CmdletBinding()]
    [Alias('Start-LogGroup')]
    param(
        # The name of the log group
        [Parameter(Mandatory)]
        [string] $Name
    )

    Write-Host "::group::$Name"
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Start-GitHubLogGroup] - Done"
#endregion - From [functions] - [public] - [Commands] - [Start-GitHubLogGroup]
#region - From [functions] - [public] - [Commands] - [Stop-GitHubLogGroup]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Stop-GitHubLogGroup] - Importing"

function Stop-GitHubLogGroup {
    <#
        .SYNOPSIS
        Stops the current log group in GitHub Actions

        .EXAMPLE
        Stop-LogGroup

        Starts a new log group named 'MyGroup'

        .NOTES
        [GitHub - Grouping log lines](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#grouping-log-lines)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Does not change state'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingWriteHost', '', Scope = 'Function',
        Justification = 'Intended for logging in Github Runners'
    )]
    [CmdletBinding()]
    [Alias('Stop-LogGroup')]
    param()

    Write-Host '::endgroup::'
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Stop-GitHubLogGroup] - Done"
#endregion - From [functions] - [public] - [Commands] - [Stop-GitHubLogGroup]
#region - From [functions] - [public] - [Commands] - [Write-GitHubDebug]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubDebug] - Importing"

function Write-GitHubDebug {
    <#
        .SYNOPSIS
        Write a debug message in GitHub Actions

        .DESCRIPTION
        Write a debug message in GitHub Actions. The message will only be displayed if the action is running in debug mode.
        To run in debug mode, you must create a secret or variable named ACTIONS_STEP_DEBUG with the value `true` to see the debug messages set by
        this command in the log. For more information, see [Enabling debug logging](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/troubleshooting-workflows/enabling-debug-logging).

        If both the secret and variable are set, the value of the secret takes precedence over the variable.

        .EXAMPLE
        Write-GitHubDebug -Message 'Hello, World!'

        Writes a debug message 'Hello, World!'.

        .NOTES
        [Enabling debug logging](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-a-debug-message)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingWriteHost', '', Scope = 'Function',
        Justification = 'Intended for logging in Github Runners'
    )]
    [OutputType([void])]
    [Alias('Debug')]
    [CmdletBinding()]
    param (
        # Message to write
        [Parameter(Mandatory)]
        [string] $Message
    )

    if ($env:GITHUB_ACTIONS -eq 'true') {
        Write-Host "::debug::$Message"
    } else {
        Write-Debug "$Message"
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubDebug] - Done"
#endregion - From [functions] - [public] - [Commands] - [Write-GitHubDebug]
#region - From [functions] - [public] - [Commands] - [Write-GitHubError]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubError] - Importing"

function Write-GitHubError {
    <#
        .SYNOPSIS
        Write a error message in GitHub Actions

        .DESCRIPTION
        Write a error message in GitHub Actions. The message will be displayed in the GitHub Actions log.

        .EXAMPLE
        Write-GitHubError -Message 'Hello, World!'

        Writes a error message 'Hello, World!'.

        .NOTES
        [Enabling debug logging](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-an-error-message)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingWriteHost', '', Scope = 'Function',
        Justification = 'Intended for logging in Github Runners'
    )]
    [OutputType([void])]
    [Alias('Error')]
    [CmdletBinding()]
    param (
        # Message to write
        [Parameter(Mandatory)]
        [string] $Message,

        # The name of the file that this error is related to
        [Parameter()]
        [string] $Name,

        # The line number that this error is related to
        [Parameter()]
        [int] $Line,

        # The column number that this error is related to
        [Parameter()]
        [int] $Column,

        # The end column number that this error is related to
        [Parameter()]
        [int] $EndColumn,

        # The end line number that this error is related to
        [Parameter()]
        [int] $EndLine,

        # The title of the error
        [Parameter()]
        [string] $Title
    )

    if ($env:GITHUB_ACTIONS -eq 'true') {
        Write-Host "::error file=$Name,line=$Line,col=$Column,endColumn=$EndColumn,endLine=$EndLine,title=$Title::$Message"
    } else {
        Write-Error $Message
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubError] - Done"
#endregion - From [functions] - [public] - [Commands] - [Write-GitHubError]
#region - From [functions] - [public] - [Commands] - [Write-GitHubNotice]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubNotice] - Importing"

function Write-GitHubNotice {
    <#
        .SYNOPSIS
        Write a notice message in GitHub Actions

        .DESCRIPTION
        Write a notice message in GitHub Actions. The message will be displayed in the GitHub Actions log.

        .EXAMPLE
        Write-GitHubNotice -Message 'Hello, World!'

        Writes a notice message 'Hello, World!'.

        .NOTES
        [Enabling debug logging](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/troubleshooting-workflows/enabling-debug-logging)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingWriteHost', '', Scope = 'Function',
        Justification = 'Intended for logging in Github Runners'
    )]
    [OutputType([void])]
    [Alias('Notice')]
    [CmdletBinding()]
    param (
        # Message to write
        [Parameter(Mandatory)]
        [string] $Message,

        # The name of the file that this notice is related to
        [Parameter()]
        [string] $Name,

        # The line number that this notice is related to
        [Parameter()]
        [int] $Line,

        # The column number that this notice is related to
        [Parameter()]
        [int] $Column,

        # The end column number that this notice is related to
        [Parameter()]
        [int] $EndColumn,

        # The end line number that this notice is related to
        [Parameter()]
        [int] $EndLine,

        # The title of the notice
        [Parameter()]
        [string] $Title
    )

    if ($env:GITHUB_ACTIONS -eq 'true') {
        Write-Host "::notice file=$Name,line=$Line,col=$Column,endColumn=$EndColumn,endLine=$EndLine,title=$Title::$Message"
    } else {
        Write-Host $Message
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubNotice] - Done"
#endregion - From [functions] - [public] - [Commands] - [Write-GitHubNotice]
#region - From [functions] - [public] - [Commands] - [Write-GitHubWarning]
Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubWarning] - Importing"

function Write-GitHubWarning {
    <#
        .SYNOPSIS
        Write a warning message in GitHub Actions

        .DESCRIPTION
        Write a warning message in GitHub Actions. The message will be displayed in the GitHub Actions log.

        .EXAMPLE
        Write-GitHubWarning -Message 'Hello, World!'

        Writes a warning message 'Hello, World!'.

        .NOTES
        [Enabling debug logging](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/troubleshooting-workflows/enabling-debug-logging)
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidLongLines', '', Scope = 'Function',
        Justification = 'Long doc links'
    )]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidUsingWriteHost', '', Scope = 'Function',
        Justification = 'Intended for logging in Github Runners'
    )]
    [OutputType([void])]
    [Alias('Warning')]
    [CmdletBinding()]
    param (
        # Message to write
        [Parameter(Mandatory)]
        [string] $Message,

        # The name of the file that this warning is related to
        [Parameter()]
        [string] $Name,

        # The line number that this warning is related to
        [Parameter()]
        [int] $Line,

        # The column number that this warning is related to
        [Parameter()]
        [int] $Column,

        # The end column number that this warning is related to
        [Parameter()]
        [int] $EndColumn,

        # The end line number that this warning is related to
        [Parameter()]
        [int] $EndLine,

        # The title of the warning
        [Parameter()]
        [string] $Title
    )

    if ($env:GITHUB_ACTIONS -eq 'true') {
        Write-Host "::warning file=$Name,line=$Line,col=$Column,endColumn=$EndColumn,endLine=$EndLine,title=$Title::$Message"
    } else {
        Write-Warning $Message
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - [Write-GitHubWarning] - Done"
#endregion - From [functions] - [public] - [Commands] - [Write-GitHubWarning]

Write-Verbose "[$scriptName] - [functions] - [public] - [Commands] - Done"
#endregion - From [functions] - [public] - [Commands]

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

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

#Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' }

function Get-GitHubConfig {
    <#
        .SYNOPSIS
        Get a GitHub module configuration.

        .DESCRIPTION
        Get a GitHub module configuration.

        .EXAMPLE
        Get-GitHubConfig -Name DefaultUser

        Get the DefaultUser value from the GitHub module configuration.
    #>

    [OutputType([void])]
    [CmdletBinding()]
    param (
        # The name of the configuration to get.
        [Parameter()]
        [string] $Name
    )

    begin {
        $commandName = $MyInvocation.MyCommand.Name
        Write-Verbose "[$commandName] - Start"
    }

    process {
        if (-not $Name) {
            return Get-Context -ID $script:Config.Name
        }

        Get-ContextSetting -Name $Name -ID $script:Config.Name
    }

    end {
        Write-Verbose "[$commandName] - End"
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Get-GitHubConfig] - Done"
#endregion - From [functions] - [public] - [Config] - [Get-GitHubConfig]
#region - From [functions] - [public] - [Config] - [Remove-GitHubConfig]
Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Remove-GitHubConfig] - Importing"

#Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' }

function Remove-GitHubConfig {
    <#
        .SYNOPSIS
        Remove a GitHub module configuration.

        .DESCRIPTION
        Remove a GitHub module configuration.

        .EXAMPLE
        Remove-GitHubConfig -Name DefaultUser

        Removes the 'DefaultUser' item in the GitHub module configuration.
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        # Set the access token type.
        [Parameter()]
        [string] $Name
    )

    $commandName = $MyInvocation.MyCommand.Name
    Write-Verbose "[$commandName] - Start"

    try {
        if ($PSCmdlet.ShouldProcess('ContextSetting', 'Remove')) {
            Remove-ContextSetting -Name $Name -ID $script:Config.Name
        }
    } catch {
        Write-Error $_
        Write-Error (Get-PSCallStack | Format-Table | Out-String)
        throw 'Failed to connect to GitHub.'
    }

    Write-Verbose "[$commandName] - End"
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Remove-GitHubConfig] - Done"
#endregion - From [functions] - [public] - [Config] - [Remove-GitHubConfig]
#region - From [functions] - [public] - [Config] - [Set-GitHubConfig]
Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Set-GitHubConfig] - Importing"

#Requires -Modules @{ ModuleName = 'Context'; RequiredVersion = '4.0.0' }

function Set-GitHubConfig {
    <#
        .SYNOPSIS
        Set a GitHub module configuration.

        .DESCRIPTION
        Set a GitHub module configuration.

        .EXAMPLE
        Set-GitHubConfig -Name DefaultUser -Value 'Octocat'

        Sets the value of DefaultUser to 'Octocat' in the GitHub module configuration.
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        # Set the access token type.
        [Parameter()]
        [string] $Name,

        # Set the access token type.
        [Parameter()]
        [string] $Value
    )

    if ($PSCmdlet.ShouldProcess('ContextSetting', 'Set')) {
        Set-ContextSetting -Name $Name -Value $Value -ID $script:Config.Name
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - [Set-GitHubConfig] - Done"
#endregion - From [functions] - [public] - [Config] - [Set-GitHubConfig]

Write-Verbose "[$scriptName] - [functions] - [public] - [Config] - Done"
#endregion - From [functions] - [public] - [Config]

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

#region - From [functions] - [public] - [Emojis] - [Get-GitHubEmoji]
Write-Verbose "[$scriptName] - [functions] - [public] - [Emojis] - [Get-GitHubEmoji] - Importing"

filter Get-GitHubEmoji {
    <#
        .SYNOPSIS
        Get emojis

        .DESCRIPTION
        Lists all the emojis available to use on GitHub.
        If you pass the `Destination` parameter, the emojis will be downloaded to the specified destination.

        .EXAMPLE
        Get-GitHubEmoji

        Gets all the emojis available to use on GitHub.

        .EXAMPLE
        Get-GitHubEmoji -Destination 'C:\Users\user\Documents\GitHub\Emojis'

        Downloads all the emojis available to use on GitHub to the specified destination.

        .NOTES
        [Get emojis](https://docs.github.com/rest/reference/emojis#get-emojis)
    #>

    [CmdletBinding()]
    param (
        # The path to the directory where the emojis will be downloaded.
        [Parameter()]
        [string] $Destination
    )

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

    $response = Invoke-GitHubAPI @inputObject | ForEach-Object {
        Write-Output $_.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] - [functions] - [public] - [Emojis] - [Get-GitHubEmoji] - Done"
#endregion - From [functions] - [public] - [Emojis] - [Get-GitHubEmoji]

Write-Verbose "[$scriptName] - [functions] - [public] - [Emojis] - Done"
#endregion - From [functions] - [public] - [Emojis]

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

#region - From [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseInstallableOrganization]
Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseInstallableOrganization] - Importing"

function Get-GitHubEnterpriseInstallableOrganization {
    <#
        .SYNOPSIS
        Get enterprise-owned organizations that can have GitHub Apps installed

        .DESCRIPTION
        List of organizations owned by the enterprise on which the authenticated GitHub App installation may install other GitHub Apps.

        The authenticated GitHub App must be installed on the enterprise and be granted the Enterprise/enterprise_organization_installations
        (read) permission.

        .EXAMPLE
        Get-GitHubEnterpriseInstallableOrganization -Enterprise 'msx'
    #>

    [CmdletBinding()]
    param(
        # The enterprise slug or ID.
        [Parameter(Mandatory)]
        [string] $Enterprise
    )
    $inputObject = @{
        APIEndpoint = "/enterprises/$Enterprise/apps/installable_organizations"
        Method      = 'GET'
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseInstallableOrganization] - Done"
#endregion - From [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseInstallableOrganization]
#region - From [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseOrganization]
Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseOrganization] - Importing"

function Get-GitHubEnterpriseOrganization {
    <#
        .SYNOPSIS
        Get the list of organizations in a GitHub Enterprise instance.

        .DESCRIPTION
        Use this function to retrieve the list of organizations in a GitHub Enterprise instance.

        .EXAMPLE
        Get-GitHubEnterpriseOrganization -EnterpriseSlug 'msx'
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string] $EnterpriseSlug
    )

    # Define GraphQL query
    $query = @"
query(`$enterpriseSlug: String!, `$first: Int = 100, `$after: String) {
  enterprise(slug: `$enterpriseSlug) {
    organizations(first: `$first, after: `$after) {
      edges {
        node {
          name
          login
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
    }
  }
}
"@


    # Initialize pagination variables
    $variables = @{
        'enterpriseSlug' = $EnterpriseSlug
        'first'          = 100
        'after'          = $null
    }
    $allOrgs = @()

    # Loop through pages to retrieve all organizations
    do {
        $response = Invoke-GitHubGraphQLQuery -Query $query -Variables $variables
        # Check for errors
        if ($response.errors) {
            Write-Error "Error: $($response.errors[0].message)"
            break
        }

        # Extract organization names and add to the list
        foreach ($org in $response.data.enterprise.organizations.edges) {
            $allOrgs += $org.node.name
        }

        # Update pagination cursor
        $pageInfo = $response.data.enterprise.organizations.pageInfo
        $variables.after = $pageInfo.endCursor

    } while ($pageInfo.hasNextPage -eq $true)

    # Output the list of organization names
    $allOrgs | ForEach-Object { Write-Output $_ }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseOrganization] - Done"
#endregion - From [functions] - [public] - [Enterprise] - [Get-GitHubEnterpriseOrganization]
#region - From [functions] - [public] - [Enterprise] - [Install-GitHubAppOnEnterpriseOrganization]
Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Install-GitHubAppOnEnterpriseOrganization] - Importing"

function Install-GitHubAppOnEnterpriseOrganization {
    <#
        .SYNOPSIS
        Install an app on an Enterprise-owned organization

        .DESCRIPTION
        Installs the provided GitHub App on the specified organization owned by the enterprise.

        The authenticated GitHub App must be installed on the enterprise and be granted the Enterprise/organization_installations (write) permission.

        .EXAMPLE
        Install-GitHubAppOnEnterpriseOrganization -Enterprise 'msx' -Organization 'org' -ClientID '123456'
    #>

    [CmdletBinding()]
    param(
        # The enterprise slug or ID.
        [Parameter(Mandatory)]
        [string] $Enterprise,

        # The organization name. The name is not case sensitive.
        [Parameter(Mandatory)]
        [string] $Organization,

        # The client ID of the GitHub App to install.
        [Parameter(Mandatory)]
        [string] $ClientID,

        # The repository selection for the GitHub App. Can be one of:
        # - all - all repositories that the authenticated GitHub App installation can access.
        # - selected - select specific repositories.
        [Parameter()]
        [ValidateSet('all', 'selected')]
        [string] $RepositorySelection = 'all',

        # The names of the repositories to which the installation will be granted access.
        [Parameter()]
        [string[]] $Repositories
    )

    $body = @{
        client_id            = $ClientID
        repository_selection = $RepositorySelection
        repositories         = $Repositories
    }
    $body | Remove-HashtableEntry -NullOrEmptyValues

    $inputObject = @{
        APIEndpoint = "/enterprises/$Enterprise/apps/organizations/$Organization/installations"
        Method      = 'Post'
        Body        = $body
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - [Install-GitHubAppOnEnterpriseOrganization] - Done"
#endregion - From [functions] - [public] - [Enterprise] - [Install-GitHubAppOnEnterpriseOrganization]

Write-Verbose "[$scriptName] - [functions] - [public] - [Enterprise] - Done"
#endregion - From [functions] - [public] - [Enterprise]

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

#region - From [functions] - [public] - [Gitignore] - [Get-GitHubGitignore]
Write-Verbose "[$scriptName] - [functions] - [public] - [Gitignore] - [Get-GitHubGitignore] - Importing"

#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' }

filter Get-GitHubGitignore {
    <#
        .SYNOPSIS
        Get a gitignore template or list of all gitignore templates names

        .DESCRIPTION
        If no parameters are specified, the function will return a list of all gitignore templates names.
        If the Name parameter is specified, the function will return the gitignore template for the specified name.

        .EXAMPLE
        Get-GitHubGitignoreList

        Get all gitignore templates

        .EXAMPLE
        Get-GitHubGitignore -Name 'VisualStudio'

        Get a gitignore template for VisualStudio

        .NOTES
        [Get a gitignore template](https://docs.github.com/rest/gitignore/gitignore#get-a-gitignore-template)
        [Get all gitignore templates](https://docs.github.com/rest/gitignore/gitignore#get-all-gitignore-templates)

    #>

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

    dynamicparam {
        $DynamicParamDictionary = New-DynamicParamDictionary

        $dynParam = @{
            Name                   = 'Name'
            ParameterSetName       = 'Name'
            Type                   = [string]
            Mandatory              = $true
            ValidateSet            = Get-GitHubGitignoreList
            DynamicParamDictionary = $DynamicParamDictionary
        }
        New-DynamicParam @dynParam

        return $DynamicParamDictionary
    }

    process {
        $Name = $PSBoundParameters['Name']
        switch ($PSCmdlet.ParameterSetName) {
            'List' {
                Get-GitHubGitignoreList
            }
            'Name' {
                Get-GitHubGitignoreByName -Name $Name
            }
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Gitignore] - [Get-GitHubGitignore] - Done"
#endregion - From [functions] - [public] - [Gitignore] - [Get-GitHubGitignore]

Write-Verbose "[$scriptName] - [functions] - [public] - [Gitignore] - Done"
#endregion - From [functions] - [public] - [Gitignore]

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

#region - From [functions] - [public] - [GraphQL] - [Invoke-GitHubGraphQLQuery]
Write-Verbose "[$scriptName] - [functions] - [public] - [GraphQL] - [Invoke-GitHubGraphQLQuery] - Importing"

function Invoke-GitHubGraphQLQuery {
    <#
        .SYNOPSIS
        Invoke a GraphQL query against the GitHub GraphQL API

        .DESCRIPTION
        Use this function to invoke a GraphQL query against the GitHub GraphQL API.

        .EXAMPLE
        Invoke-GitHubGraphQLQuery -Query $query -Variables $Variables

        .NOTES
        [GitHub GraphQL API documentation](https://docs.github.com/graphql)
    #>

    param (
        # The GraphQL query to execute.
        [string] $Query,

        # The variables to pass to the query.
        [hashtable] $Variables,

        # The context to run the command in.
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    $inputObject = @{
        Context     = $Context
        APIEndpoint = '/graphql'
        Method      = 'Post'
        Body        = @{
            'query'     = $query
            'variables' = $variables
        } | ConvertTo-Json
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [GraphQL] - [Invoke-GitHubGraphQLQuery] - Done"
#endregion - From [functions] - [public] - [GraphQL] - [Invoke-GitHubGraphQLQuery]

Write-Verbose "[$scriptName] - [functions] - [public] - [GraphQL] - Done"
#endregion - From [functions] - [public] - [GraphQL]

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

#region - From [functions] - [public] - [License] - [Get-GitHubLicense]
Write-Verbose "[$scriptName] - [functions] - [public] - [License] - [Get-GitHubLicense] - Importing"

#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' }

filter Get-GitHubLicense {
    <#
        .SYNOPSIS
        Get a license template, list of all popular license templates or a license for a repository

        .DESCRIPTION
        If no parameters are specified, the function will return a list of all license templates.
        If the Name parameter is specified, the function will return the license template for the specified name.
        If the Owner and Repo parameters are specified, the function will return the license for the specified repository.

        .EXAMPLE
        Get-GitHubLicense

        Get all license templates

        .EXAMPLE
        Get-GitHubLicense -Name mit

        Get the mit license template

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

        Get the license for the Hello-World repository from the octocat account.

        .PARAMETER Name
        The license keyword, license name, or license SPDX ID. For example, mit or mpl-2.0.

        .NOTES
        [Get a license](https://docs.github.com/rest/licenses/licenses#get-a-license)
        [Get all commonly used licenses](https://docs.github.com/rest/licenses/licenses#get-all-commonly-used-licenses)
        [Get the license for a repository](https://docs.github.com/rest/licenses/licenses#get-the-license-for-a-repository)

    #>

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

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

    dynamicparam {
        $DynamicParamDictionary = New-DynamicParamDictionary

        $dynParam = @{
            Name                   = 'Name'
            ParameterSetName       = 'Name'
            Type                   = [string]
            Mandatory              = $true
            ValidateSet            = Get-GitHubLicenseList | Select-Object -ExpandProperty Name
            DynamicParamDictionary = $DynamicParamDictionary
        }
        New-DynamicParam @dynParam

        return $DynamicParamDictionary
    }

    process {
        $Name = $PSBoundParameters['Name']
        switch ($PSCmdlet.ParameterSetName) {
            'List' {
                Get-GitHubLicenseList
            }
            'Name' {
                Get-GitHubLicenseByName -Name $Name
            }
            'Repository' {
                Get-GitHubRepositoryLicense -Owner $Owner -Repo $Repo
            }
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [License] - [Get-GitHubLicense] - Done"
#endregion - From [functions] - [public] - [License] - [Get-GitHubLicense]

Write-Verbose "[$scriptName] - [functions] - [public] - [License] - Done"
#endregion - From [functions] - [public] - [License]

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

#region - From [functions] - [public] - [Markdown] - [Get-GitHubMarkdown]
Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - [Get-GitHubMarkdown] - Importing"

filter Get-GitHubMarkdown {
    <#
        .NOTES
        [Render a Markdown document](https://docs.github.com/en/rest/markdown/markdown#render-a-markdown-document)
    #>

    [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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - [Get-GitHubMarkdown] - Done"
#endregion - From [functions] - [public] - [Markdown] - [Get-GitHubMarkdown]
#region - From [functions] - [public] - [Markdown] - [Get-GitHubMarkdownRaw]
Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - [Get-GitHubMarkdownRaw] - Importing"

filter Get-GitHubMarkdownRaw {
    <#
        .NOTES
        [Render a Markdown document in raw mode](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 | ForEach-Object {
        Write-Output $_.Response
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - [Get-GitHubMarkdownRaw] - Done"
#endregion - From [functions] - [public] - [Markdown] - [Get-GitHubMarkdownRaw]

Write-Verbose "[$scriptName] - [functions] - [public] - [Markdown] - Done"
#endregion - From [functions] - [public] - [Markdown]

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

#region - From [functions] - [public] - [Meta] - [Get-GitHubApiVersion]
Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubApiVersion] - Importing"

filter Get-GitHubApiVersion {
    <#
        .SYNOPSIS
        Get all API versions.

        .DESCRIPTION
        Get all supported GitHub API versions.

        .EXAMPLE
        Get-GitHubApiVersion

        Get all supported GitHub API versions.

        .NOTES
        [Get all API versions](https://docs.github.com/rest/meta/meta#get-all-api-versions)
    #>

    [OutputType([string[]])]
    [CmdletBinding()]
    param ()

    $inputObject = @{
        ApiEndpoint = '/versions'
        Method      = 'GET'
    }

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

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubApiVersion] - Done"
#endregion - From [functions] - [public] - [Meta] - [Get-GitHubApiVersion]
#region - From [functions] - [public] - [Meta] - [Get-GitHubMeta]
Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubMeta] - 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
        [Get GitHub meta information](https://docs.github.com/rest/meta/meta#get-apiname-meta-information)
    #>

    [OutputType([object])]
    [CmdletBinding()]
    param ()

    $inputObject = @{
        ApiEndpoint = '/meta'
        Method      = 'GET'
    }

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

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubMeta] - Done"
#endregion - From [functions] - [public] - [Meta] - [Get-GitHubMeta]
#region - From [functions] - [public] - [Meta] - [Get-GitHubOctocat]
Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubOctocat] - 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
        [Get Octocat](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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubOctocat] - Done"
#endregion - From [functions] - [public] - [Meta] - [Get-GitHubOctocat]
#region - From [functions] - [public] - [Meta] - [Get-GitHubRoot]
Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubRoot] - 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
        [GitHub API Root](https://docs.github.com/rest/meta/meta#github-api-root)
    #>

    [CmdletBinding()]
    param ()

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

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

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubRoot] - Done"
#endregion - From [functions] - [public] - [Meta] - [Get-GitHubRoot]
#region - From [functions] - [public] - [Meta] - [Get-GitHubZen]
Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubZen] - 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
        [Get the Zen of GitHub](https://docs.github.com/rest/meta/meta#get-the-zen-of-github)
    #>

    [CmdletBinding()]
    param ()

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

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

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - [Get-GitHubZen] - Done"
#endregion - From [functions] - [public] - [Meta] - [Get-GitHubZen]

Write-Verbose "[$scriptName] - [functions] - [public] - [Meta] - Done"
#endregion - From [functions] - [public] - [Meta]

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

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

#region - From [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationMember]
Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationMember] - Importing"

function Get-GitHubOrganizationMember {
    <#
        .SYNOPSIS
        List organization members

        .DESCRIPTION
        List all users who are members of an organization.
        If the authenticated user is also a member of this organization then both concealed and public members will be returned.

        .NOTES
        [List organization members](https://docs.github.com/en/rest/orgs/members?apiVersion=2022-11-28#list-organization-members)
    #>

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

        # Filter members returned in the list.
        # `2fa_disabled` means that only members without two-factor authentication enabled will be returned.
        # This options is only available for organization owners.
        [Parameter()]
        [ValidateSet('2fa_disabled', 'all')]
        [string] $Filter = 'all',

        # Filter members returned by their role.
        [Parameter()]
        [ValidateSet('all', 'admin', 'member')]
        [string] $Role = 'all',

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

        # The context to run the command in
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    $body = @{
        filter   = $Filter
        role     = $Role
        per_page = $PerPage
    }

    $inputObject = @{
        Context     = $Context
        Body        = $body
        Method      = 'Get'
        APIEndpoint = "/orgs/$Organization/members"
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationMember] - Done"
#endregion - From [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationMember]
#region - From [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationPendingInvitation]
Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationPendingInvitation] - Importing"

function Get-GitHubOrganizationPendingInvitation {
    <#
        .SYNOPSIS
        List pending organization invitations

        .DESCRIPTION
        The return hash contains a `role` field which refers to the Organization
        Invitation role and will be one of the following values: `direct_member`, `admin`,
        `billing_manager`, or `hiring_manager`. If the invitee is not a GitHub
        member, the `login` field in the return hash will be `null`.

        .NOTES
        [List pending organization invitations](https://docs.github.com/rest/orgs/members#list-pending-organization-invitations)
    #>

    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('Org')]
        [string] $Organization,

        # Filter invitations by their member role.
        [Parameter()]
        [ValidateSet('all', 'admin', 'direct_member', 'billing_manager', 'hiring_manager')]
        [string] $Role = 'all',

        # Filter invitations by their invitation source.
        [Parameter()]
        [ValidateSet('all', 'member', 'scim')]
        [string] $InvitationSource = 'all',

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

        # The context to run the command in
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    $body = @{
        role              = $Role
        invitation_source = $InvitationSource
        per_page          = $PerPage
    }

    $inputObject = @{
        Context     = $Context
        Body        = $body
        Method      = 'Get'
        APIEndpoint = "/orgs/$Organization/invitations"
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationPendingInvitation] - Done"
#endregion - From [functions] - [public] - [Organization] - [Members] - [Get-GitHubOrganizationPendingInvitation]
#region - From [functions] - [public] - [Organization] - [Members] - [New-GitHubOrganizationInvitation]
Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [New-GitHubOrganizationInvitation] - Importing"

function New-GitHubOrganizationInvitation {
    <#
        .SYNOPSIS
        Create an organization invitation

        .DESCRIPTION
        Invite people to an organization by using their GitHub user ID or their email address. In order to create invitations in an organization,
        the authenticated user must be an organization owner.

        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. For more information, see
        "[Rate limits for the API](https://docs.github.com/rest/using-the-rest-api/rate-limits-for-the-rest-api#about-secondary-rate-limits)"
        and "[Best practices for using the REST API](https://docs.github.com/rest/guides/best-practices-for-using-the-rest-api)."

        .NOTES
        [Create an organization invitation](https://docs.github.com/rest/orgs/members#list-pending-organization-invitations)
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('Org')]
        [string] $Organization,

        # GitHub user ID for the person you are inviting.
        [Parameter(
            Mandatory,
            ParameterSetName = 'UserID'
        )]
        [Alias('invitee_id', 'user_id')]
        [int] $InviteeID,

        # Email address of the person you are inviting, which can be an existing GitHub user.
        [Parameter(
            Mandatory,
            ParameterSetName = 'Email'
        )]
        [string] $Email,

        # The role for the new member.
        #
        # - `admin` - Organization owners with full administrative rights to the organization and complete access to all repositories and teams.
        # - `direct_member` - Non-owner organization members with ability to see other members and join teams by invitation.
        # - `billing_manager` - Non-owner organization members with ability to manage the billing settings of your organization.
        # - `reinstate` - The previous role assigned to the invitee before they were removed from your organization.
        # Can be one of the roles listed above.
        # Only works if the invitee was previously part of your organization.
        [Parameter()]
        [ValidateSet('admin', 'direct_member', 'billing_manager', 'reinstate')]
        [string] $Role = 'direct_member',

        # Specify IDs for the teams you want to invite new members to.
        [Parameter()]
        [int[]] $TeamIDs,

        # The context to run the command in
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name 'DefaultContext')
    )

    $body = @{
        invitee_id = $InviteeID
        email      = $Email
        role       = $Role
        team_ids   = $TeamIDs
    }

    $body | Remove-HashtableEntry -NullOrEmptyValues

    $inputObject = @{
        Context     = $Context
        Body        = $body
        Method      = 'post'
        APIEndpoint = "/orgs/$Organization/invitations"
    }

    if ($PSCmdlet.ShouldProcess("$InviteeID$Email to organization $Organization", 'Invite')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - [New-GitHubOrganizationInvitation] - Done"
#endregion - From [functions] - [public] - [Organization] - [Members] - [New-GitHubOrganizationInvitation]

Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Members] - Done"
#endregion - From [functions] - [public] - [Organization] - [Members]

#region - From [functions] - [public] - [Organization] - [Get-GitHubOrganization]
Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Get-GitHubOrganization] - 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
        [List organizations](https://docs.github.com/rest/orgs/orgs)
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(DefaultParameterSetName = '__DefaultSet')]
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'All', Justification = 'Required for parameter set')]
    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')]
        [ValidateRange(1, 100)]
        [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] - [functions] - [public] - [Organization] - [Get-GitHubOrganization] - Done"
#endregion - From [functions] - [public] - [Organization] - [Get-GitHubOrganization]
#region - From [functions] - [public] - [Organization] - [Get-GitHubOrganizationAppInstallation]
Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Get-GitHubOrganizationAppInstallation] - 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
        [List app installations for an organization](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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

    $body = @{
        per_page = $PerPage
    }

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

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

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Get-GitHubOrganizationAppInstallation] - Done"
#endregion - From [functions] - [public] - [Organization] - [Get-GitHubOrganizationAppInstallation]
#region - From [functions] - [public] - [Organization] - [Remove-GitHubOrganization]
Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Remove-GitHubOrganization] - 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 [GitHub Terms of Service](https://docs.github.com/site-policy/github-terms/github-terms-of-service)
        regarding account deletion before using this endpoint.

        .EXAMPLE
        Remove-GitHubOrganization -OrganizationName 'GitHub'

        Deletes the organization 'GitHub' and all its repositories.

        .NOTES
        [Delete an organization](https://docs.github.com/rest/orgs/orgs#delete-an-organization)
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(SupportsShouldProcess)]
    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'
    }

    if ($PSCmdlet.ShouldProcess("organization [$OrganizationName]", 'Delete')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Remove-GitHubOrganization] - Done"
#endregion - From [functions] - [public] - [Organization] - [Remove-GitHubOrganization]
#region - From [functions] - [public] - [Organization] - [Set-GitHubOrganization]
Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Set-GitHubOrganization] - 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
        [Update an organization](https://docs.github.com/rest/orgs/orgs#update-an-organization)

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(SupportsShouldProcess)]
    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-HashtableEntry -Hashtable $body -RemoveNames 'organization_name'

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

    if ($PSCmdlet.ShouldProcess("organization [$OrganizationName]", 'Set')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Set-GitHubOrganization] - Done"
#endregion - From [functions] - [public] - [Organization] - [Set-GitHubOrganization]
#region - From [functions] - [public] - [Organization] - [Set-GitHubOrganizationSecurityFeature]
Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Set-GitHubOrganizationSecurityFeature] - 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
        [Enable or disable a security feature for an organization](https://docs.github.com/rest/orgs/orgs#enable-or-disable-a-security-feature-for-an-organization)
    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long link in notes.')]
    [CmdletBinding(SupportsShouldProcess)]
    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
    }

    if ($PSCmdlet.ShouldProcess("security feature [$SecurityProduct] on organization [$OrganizationName]", 'Set')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - [Set-GitHubOrganizationSecurityFeature] - Done"
#endregion - From [functions] - [public] - [Organization] - [Set-GitHubOrganizationSecurityFeature]

Write-Verbose "[$scriptName] - [functions] - [public] - [Organization] - Done"
#endregion - From [functions] - [public] - [Organization]

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

#region - From [functions] - [public] - [Rate-Limit] - [Get-GitHubRateLimit]
Write-Verbose "[$scriptName] - [functions] - [public] - [Rate-Limit] - [Get-GitHubRateLimit] - 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
        [Get rate limit status for the authenticated user](https://docs.github.com/rest/rate-limit/rate-limit#get-rate-limit-status-for-the-authenticated-user)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [CmdletBinding()]
    param ()

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

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

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Rate-Limit] - [Get-GitHubRateLimit] - Done"
#endregion - From [functions] - [public] - [Rate-Limit] - [Get-GitHubRateLimit]

Write-Verbose "[$scriptName] - [functions] - [public] - [Rate-Limit] - Done"
#endregion - From [functions] - [public] - [Rate-Limit]

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

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

#region - From [functions] - [public] - [Releases] - [Assets] - [Add-GitHubReleaseAsset]
Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Add-GitHubReleaseAsset] - 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
        [Upload a release asset](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-GitHubContextSetting -Name Owner),

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

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

        #The name of the file 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 name of the file
    if (!$Name) {
        $Name = (Get-Item $FilePath).Name
    }

    # If label is not provided, use the name of the file
    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-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo', 'ID', 'FilePath'

    $body['name'] = $Name
    $body['label'] = $Label

    Remove-HashtableEntry -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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Add-GitHubReleaseAsset] - Done"
#endregion - From [functions] - [public] - [Releases] - [Assets] - [Add-GitHubReleaseAsset]
#region - From [functions] - [public] - [Releases] - [Assets] - [Get-GitHubReleaseAsset]
Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Get-GitHubReleaseAsset] - 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
        [Get a release asset](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-GitHubContextSetting -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubContextSetting -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] - [functions] - [public] - [Releases] - [Assets] - [Get-GitHubReleaseAsset] - Done"
#endregion - From [functions] - [public] - [Releases] - [Assets] - [Get-GitHubReleaseAsset]
#region - From [functions] - [public] - [Releases] - [Assets] - [Remove-GitHubReleaseAsset]
Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Remove-GitHubReleaseAsset] - 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
        [Delete a release asset](https://docs.github.com/rest/releases/assets#delete-a-release-asset)

    #>

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

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubContextSetting -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'
    }

    if ($PSCmdlet.ShouldProcess("Asset with ID [$ID] in [$Owner/$Repo]", 'Delete')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Remove-GitHubReleaseAsset] - Done"
#endregion - From [functions] - [public] - [Releases] - [Assets] - [Remove-GitHubReleaseAsset]
#region - From [functions] - [public] - [Releases] - [Assets] - [Set-GitHubReleaseAsset]
Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Set-GitHubReleaseAsset] - 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
        [Update a release asset](https://docs.github.com/rest/releases/assets#update-a-release-asset)
    #>

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

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

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

        #The name of the file 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-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo', 'ID'

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

    if ($PSCmdlet.ShouldProcess("assets for release with ID [$ID] in [$Owner/$Repo]", 'Set')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - [Set-GitHubReleaseAsset] - Done"
#endregion - From [functions] - [public] - [Releases] - [Assets] - [Set-GitHubReleaseAsset]

Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Assets] - Done"
#endregion - From [functions] - [public] - [Releases] - [Assets]

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

#region - From [functions] - [public] - [Releases] - [Releases] - [Get-GitHubRelease]
Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Get-GitHubRelease] - 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
        [List releases](https://docs.github.com/rest/releases/releases#list-releases)
        [Get the latest release](https://docs.github.com/rest/releases/releases#get-the-latest-release)

    #>

    [CmdletBinding(DefaultParameterSetName = 'All')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Latest', Justification = 'Required for parameter set')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

        # The number of results per page (max 100).
        [Parameter(ParameterSetName = 'All')]
        [ValidateRange(1, 100)]
        [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] - [functions] - [public] - [Releases] - [Releases] - [Get-GitHubRelease] - Done"
#endregion - From [functions] - [public] - [Releases] - [Releases] - [Get-GitHubRelease]
#region - From [functions] - [public] - [Releases] - [Releases] - [New-GitHubRelease]
Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [New-GitHubRelease] - 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
        [Create a release](https://docs.github.com/rest/releases/releases#create-a-release)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubContextSetting -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-HashtableEntry -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-HashtableEntry -Hashtable $requestBody -NullOrEmptyValues

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

    if ($PSCmdlet.ShouldProcess("$Owner/$Repo", 'Create a release')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [New-GitHubRelease] - Done"
#endregion - From [functions] - [public] - [Releases] - [Releases] - [New-GitHubRelease]
#region - From [functions] - [public] - [Releases] - [Releases] - [New-GitHubReleaseNote]
Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [New-GitHubReleaseNote] - Importing"

filter New-GitHubReleaseNote {
    <#
        .SYNOPSIS
        List releases

        .DESCRIPTION
        Generate a name and body describing a [release](https://docs.github.com/en/rest/releases/releases#get-a-release).
        The body content will be Markdown formatted and contain information like
        the changes since last release and users who contributed. The generated release notes are not saved anywhere. They are
        intended to be generated and used when creating a new release.

        .EXAMPLE
        $params = @{
            Owner = 'octocat'
            Repo = 'hello-world'
            TagName = 'v1.0.0'
        }
        New-GitHubReleaseNote @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-GitHubReleaseNote @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-GitHubReleaseNote @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
        [Generate release notes content for a release](https://docs.github.com/rest/releases/releases#list-releases)

    #>

    [OutputType([pscustomobject])]
    [Alias('Generate-GitHubReleaseNotes')]
    [Alias('New-GitHubReleaseNotes')]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubContextSetting -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-HashtableEntry -Hashtable $body -RemoveNames 'Owner', 'Repo'

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/releases/generate-notes"
        Method      = 'POST'
        Body        = $body
    }

    if ($PSCmdlet.ShouldProcess("$Owner/$Repo", 'Create release notes')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [New-GitHubReleaseNote] - Done"
#endregion - From [functions] - [public] - [Releases] - [Releases] - [New-GitHubReleaseNote]
#region - From [functions] - [public] - [Releases] - [Releases] - [Remove-GitHubRelease]
Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Remove-GitHubRelease] - 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
        [Delete a release](https://docs.github.com/rest/releases/releases#delete-a-release)

    #>

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

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

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

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

    if ($PSCmdlet.ShouldProcess("Release with ID [$ID] in [$Owner/$Repo]", 'Delete')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Remove-GitHubRelease] - Done"
#endregion - From [functions] - [public] - [Releases] - [Releases] - [Remove-GitHubRelease]
#region - From [functions] - [public] - [Releases] - [Releases] - [Set-GitHubRelease]
Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Set-GitHubRelease] - 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
        [Update a release](https://docs.github.com/rest/releases/releases#update-a-release)
    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter()]
        [string] $Repo = (Get-GitHubContextSetting -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-HashtableEntry -Hashtable $requestBody -RemoveNames 'Owner', 'Repo', 'Draft', 'Prerelease'
    $requestBody = Join-Object -AsHashtable -Main $requestBody -Overrides @{
        draft      = if ($Draft.IsPresent) { $Draft } else { $false }
        prerelease = if ($Prerelease.IsPresent) { $Prerelease } else { $false }
    }

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

    if ($PSCmdlet.ShouldProcess("release with ID [$ID] in [$Owner/$Repo]", 'Update')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - [Set-GitHubRelease] - Done"
#endregion - From [functions] - [public] - [Releases] - [Releases] - [Set-GitHubRelease]

Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - [Releases] - Done"
#endregion - From [functions] - [public] - [Releases] - [Releases]


Write-Verbose "[$scriptName] - [functions] - [public] - [Releases] - Done"
#endregion - From [functions] - [public] - [Releases]

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

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

#region - From [functions] - [public] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolink]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolink] - Importing"

filter Get-GitHubRepositoryAutolink {
    <#
        .SYNOPSIS
        List all autolinks of a repository

        .DESCRIPTION
        This returns a list of autolinks configured for the given repository.

        Information about autolinks are only available to repository administrators.

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

        Gets all autolinks for the repository 'Hello-World' owned by 'octocat'.

        .EXAMPLE
        Get-GitHubRepositoryAutolink -Owner 'octocat' -Repo 'Hello-World' -ID 1

        Gets the autolink with the ID 1 for the repository 'Hello-World' owned by 'octocat'.

        .NOTES
        [Get all autolinks of a repository](https://docs.github.com/rest/repos/autolinks#list-all-autolinks-of-a-repository)

    #>

    [Alias('Get-GitHubRepositoryAutolinks')]
    [CmdletBinding(DefaultParameterSetName = 'Default')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

        # The unique identifier of the autolink.
        [Parameter(
            Mandatory,
            ParameterSetName = 'ById'
        )]
        [Alias('autolink_id')]
        [Alias('ID')]
        [int] $AutolinkId
    )

    switch ($PSCmdlet.ParameterSetName) {
        'ById' {
            Get-GitHubRepositoryAutolinkById -Owner $Owner -Repo $Repo -ID $AutolinkId
        }
        default {
            Get-GitHubRepositoryAutolinkList -Owner $Owner -Repo $Repo
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolink] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Autolinks] - [Get-GitHubRepositoryAutolink]
#region - From [functions] - [public] - [Repositories] - [Autolinks] - [New-GitHubRepositoryAutolink]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [New-GitHubRepositoryAutolink] - Importing"

filter New-GitHubRepositoryAutolink {
    <#
        .SYNOPSIS
        Create an autolink reference for a repository

        .DESCRIPTION
        Users with admin access to the repository can create an autolink.

        .EXAMPLE
        New-GitHubRepositoryAutolink -Owner 'octocat' -Repo 'Hello-World' -KeyPrefix 'GH-' -UrlTemplate 'https://www.example.com/issue/<num>'

        Creates an autolink for the repository 'Hello-World' owned by 'octocat' that links to <https://www.example.com/issue/123>
        when the prefix 'GH-' is found in an issue, pull request, or commit.

        .NOTES
        [Create an autolink reference for a repository](https://docs.github.com/rest/repos/autolinks#create-an-autolink-reference-for-a-repository)

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter(Mandatory)]
        [string] $Owner,

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter(Mandatory)]
        [string] $Repo,

        # This prefix appended by certain characters will generate a link any time it is found in an issue, pull request, or commit.
        [Parameter(Mandatory)]
        [Alias('key_prefix')]
        [string] $KeyPrefix,

        # The URL must contain <num> for the reference number. <num> matches different characters depending on the value of is_alphanumeric.
        [Parameter(Mandatory)]
        [Alias('url_template')]
        [string] $UrlTemplate,

        # Whether this autolink reference matches alphanumeric characters. If true, the <num> parameter of the url_template matches alphanumeric
        # characters A-Z (case insensitive), 0-9, and -. If false, this autolink reference only matches numeric characters.
        [Parameter()]
        [Alias('is_alphanumeric')]
        [bool] $IsAlphanumeric = $true
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramName = $_.Key
        $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
        $providedValue = $PSBoundParameters[$paramName]
        Write-Verbose "[$paramName]"
        Write-Verbose " - Default: [$paramDefaultValue]"
        Write-Verbose " - Provided: [$providedValue]"
        if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose ' - Using default value'
            $PSBoundParameters[$paramName] = $paramDefaultValue
        } else {
            Write-Verbose ' - Using provided value'
        }
    }

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

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

    if ($PSCmdlet.ShouldProcess("Autolink for repository [$Owner/$Repo]", 'Create')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [New-GitHubRepositoryAutolink] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Autolinks] - [New-GitHubRepositoryAutolink]
#region - From [functions] - [public] - [Repositories] - [Autolinks] - [Remove-GitHubRepositoryAutolink]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [Remove-GitHubRepositoryAutolink] - Importing"

filter Remove-GitHubRepositoryAutolink {
    <#
        .SYNOPSIS
        Delete an autolink reference from a repository

        .DESCRIPTION
        This deletes a single autolink reference by ID that was configured for the given repository.

        Information about autolinks are only available to repository administrators.

        .EXAMPLE
        Remove-GitHubRepositoryAutolink -Owner 'octocat' -Repo 'Hello-World' -AutolinkId 1

        Deletes the autolink with ID 1 for the repository 'Hello-World' owned by 'octocat'.

        .NOTES
        [Delete an autolink reference from a repository](https://docs.github.com/rest/repos/autolinks#delete-an-autolink-reference-from-a-repository)

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter(Mandatory)]
        [string] $Owner,

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter(Mandatory)]
        [string] $Repo,

        # The unique identifier of the autolink.
        [Parameter(Mandatory)]
        [Alias('autolink_id')]
        [Alias('ID')]
        [int] $AutolinkId
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/autolinks/$AutolinkId"
        Method      = 'DELETE'
        Body        = $body
    }

    if ($PSCmdlet.ShouldProcess("Autolink with ID [$AutolinkId] for repository [$Owner/$Repo]", 'Delete')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - [Remove-GitHubRepositoryAutolink] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Autolinks] - [Remove-GitHubRepositoryAutolink]

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Autolinks] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Autolinks]

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

#region - From [functions] - [public] - [Repositories] - [CustomProperties] - [Get-GitHubRepositoryCustomProperty]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [CustomProperties] - [Get-GitHubRepositoryCustomProperty] - Importing"

filter Get-GitHubRepositoryCustomProperty {
    <#
        .SYNOPSIS
        Get all custom property values for a repository

        .DESCRIPTION
        Gets all custom property values that are set for a repository.
        Users with read access to the repository can use this endpoint.

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

        Gets all custom property values that are set for the 'hello-world' repository.

        .NOTES
        [Get all custom property values for a repository](https://docs.github.com/rest/repos/custom-properties#get-all-custom-property-values-for-a-repository)

    #>

    [Alias('Get-GitHubRepositoryCustomProperties')]
    [CmdletBinding()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [OutputType([pscustomobject])]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [CustomProperties] - [Get-GitHubRepositoryCustomProperty] - Done"
#endregion - From [functions] - [public] - [Repositories] - [CustomProperties] - [Get-GitHubRepositoryCustomProperty]

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [CustomProperties] - Done"
#endregion - From [functions] - [public] - [Repositories] - [CustomProperties]

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

#region - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryPrivateVulnerabilityReporting]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryPrivateVulnerabilityReporting] - Importing"

filter Disable-GitHubRepositoryPrivateVulnerabilityReporting {
    <#
        .SYNOPSIS
        Disable private vulnerability reporting for a repository

        .DESCRIPTION
        Disables private vulnerability reporting for a repository. The authenticated user must have admin access
        to the repository. For more information, see
        "[Privately reporting a security vulnerability](https://docs.github.com/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability)".

        .EXAMPLE
        Disable-GitHubRepositoryPrivateVulnerabilityReporting -Owner 'PSModule' -Repo 'GitHub'

        Disables private vulnerability reporting for the PSModule/GitHub repository.

        .NOTES
        [Disable private vulnerability reporting for a repository](https://docs.github.com/rest/repos/repos#disable-private-vulnerability-reporting-for-a-repository)

    #>

    [CmdletBinding(SupportsShouldProcess)]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/private-vulnerability-reporting"
        Method      = 'DELETE'
    }

    if ($PSCmdlet.ShouldProcess("Private Vulnerability Reporting for [$Owner/$Repo]", 'Disable')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryPrivateVulnerabilityReporting] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryPrivateVulnerabilityReporting]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositorySecurityFix]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositorySecurityFix] - Importing"

filter Disable-GitHubRepositorySecurityFix {
    <#
        .SYNOPSIS
        Disable automated security fixes

        .DESCRIPTION
        Disables automated security fixes for a repository. The authenticated user must have admin access to the repository.
        For more information, see
        "[Configuring automated security fixes](https://docs.github.com/articles/configuring-automated-security-fixes)".

        .EXAMPLE
        Disable-GitHubRepositorySecurityFix -Owner 'PSModule' -Repo 'GitHub'

        Disables automated security fixes for the repository.

        .NOTES
        [Disable automated security fixes](https://docs.github.com/rest/repos/repos#disable-automated-security-fixes)

    #>

    [CmdletBinding(SupportsShouldProcess)]
    [Alias('Disable-GitHubRepositorySecurityFixes')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/automated-security-fixes"
        Method      = 'DELETE'
    }

    if ($PSCmdlet.ShouldProcess("Security Fixes for [$Owner/$Repo]", 'Disable')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositorySecurityFix] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositorySecurityFix]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryVulnerabilityAlert]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryVulnerabilityAlert] - Importing"

filter Disable-GitHubRepositoryVulnerabilityAlert {
    <#
        .SYNOPSIS
        Disable vulnerability alerts

        .DESCRIPTION
        Disables dependency alerts and the dependency graph for a repository.
        The authenticated user must have admin access to the repository. For more information, see
        "[About security alerts for vulnerable dependencies](https://docs.github.com/articles/about-security-alerts-for-vulnerable-dependencies)".

        .EXAMPLE
        Disable-GitHubRepositoryVulnerabilityAlert -Owner 'octocat' -Repo 'hello-world'

        Disables vulnerability alerts for the 'octocat/hello-world' repository.

        .NOTES
        [Disable vulnerability alerts](https://docs.github.com/rest/repos/repos#disable-vulnerability-alerts)
    #>

    [CmdletBinding(SupportsShouldProcess)]
    [Alias('Disable-GitHubRepositoryVulnerabilityAlerts')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/vulnerability-alerts"
        Method      = 'DELETE'
    }

    if ($PSCmdlet.ShouldProcess("Vulnerability Alerts for [$Owner/$Repo]", 'Disable')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryVulnerabilityAlert] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Disable-GitHubRepositoryVulnerabilityAlert]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryPrivateVulnerabilityReporting]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryPrivateVulnerabilityReporting] - Importing"

filter Enable-GitHubRepositoryPrivateVulnerabilityReporting {
    <#
        .SYNOPSIS
        Enable private vulnerability reporting for a repository

        .DESCRIPTION
        Enables private vulnerability reporting for a repository. The authenticated user must have admin access
        to the repository. For more information, see
        "[Privately reporting a security vulnerability](https://docs.github.com/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability)."

        .EXAMPLE
        Enable-GitHubRepositoryPrivateVulnerabilityReporting -Owner 'PSModule' -Repo 'GitHub'

        Enables private vulnerability reporting for the PSModule/GitHub repository.

        .NOTES
        [Enable private vulnerability reporting for a repository](https://docs.github.com/rest/repos/repos#enable-private-vulnerability-reporting-for-a-repository)

    #>

    [CmdletBinding(SupportsShouldProcess)]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/private-vulnerability-reporting"
        Method      = 'PUT'
    }

    if ($PSCmdlet.ShouldProcess("Private Vulnerability Reporting for [$Owner/$Repo]", 'Enable')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryPrivateVulnerabilityReporting] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryPrivateVulnerabilityReporting]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositorySecurityFix]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositorySecurityFix] - Importing"

filter Enable-GitHubRepositorySecurityFix {
    <#
        .SYNOPSIS
        Enable automated security fixes

        .DESCRIPTION
        Enables automated security fixes for a repository. The authenticated user must have admin access to the repository.
        For more information, see
        "[Configuring automated security fixes](https://docs.github.com/articles/configuring-automated-security-fixes)".

        .EXAMPLE
        Enable-GitHubRepositorySecurityFix -Owner 'PSModule' -Repo 'GitHub'

        Enables automated security fixes for the repository.

        .NOTES
        [Enable automated security fixes](https://docs.github.com/rest/repos/repos#enable-automated-security-fixes)

    #>

    [CmdletBinding(SupportsShouldProcess)]
    [Alias('Enable-GitHubRepositorySecurityFixes')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/automated-security-fixes"
        Method      = 'PUT'
    }

    if ($PSCmdlet.ShouldProcess("Security Fixes for [$Owner/$Repo]", 'Enable')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositorySecurityFix] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositorySecurityFix]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryVulnerabilityAlert]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryVulnerabilityAlert] - Importing"

filter Enable-GitHubRepositoryVulnerabilityAlert {
    <#
        .SYNOPSIS
        Enable vulnerability alerts

        .DESCRIPTION
        Enables dependency alerts and the dependency graph for a repository.
        The authenticated user must have admin access to the repository.
        For more information, see
        "[About security alerts for vulnerable dependencies](https://docs.github.com/articles/about-security-alerts-for-vulnerable-dependencies)".

        .EXAMPLE
        Enable-GitHubRepositoryVulnerabilityAlert -Owner 'octocat' -Repo 'hello-world'

        Enables vulnerability alerts for the 'octocat/hello-world' repository.

        .NOTES
        [Enable vulnerability alerts](https://docs.github.com/rest/repos/repos#enable-vulnerability-alerts)
    #>

    [CmdletBinding(SupportsShouldProcess)]
    [Alias('Enable-GitHubRepositoryVulnerabilityAlerts')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/vulnerability-alerts"
        Method      = 'PUT'
    }

    if ($PSCmdlet.ShouldProcess("Vulnerability Alerts for [$Owner/$Repo]", "Enable")) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryVulnerabilityAlert] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Enable-GitHubRepositoryVulnerabilityAlert]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepository]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepository] - Importing"

#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' }

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
        [List repositories for the authenticated user](https://docs.github.com/rest/repos/repos#list-repositories-for-the-authenticated-user)
        [Get a repository](https://docs.github.com/rest/repos/repos#get-a-repository)
        [List public repositories](https://docs.github.com/rest/repos/repos#list-public-repositories)
        [List organization repositories](https://docs.github.com/rest/repos/repos#list-organization-repositories)
        [List repositories for a user](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-GitHubContextSetting -Name Owner),

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ParameterSetName = 'ByName'
        )]
        [string] $Repo = (Get-GitHubContextSetting -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')]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30

    )

    dynamicparam {
        $DynamicParamDictionary = New-DynamicParamDictionary

        if ($PSCmdlet.ParameterSetName -in 'MyRepos_Type', 'ListByOrg', 'ListByUser') {

            switch ($PSCmdlet.ParameterSetName) {
                'MyRepos_Type' {
                    $ValidateSet = 'all', 'owner', 'public', 'private', 'member'
                }
                'ListByOrg' {
                    $ValidateSet = 'all', 'public', 'private', 'forks', 'sources', 'member'
                }
                'ListByUser' {
                    $ValidateSet = 'all', 'owner', 'member'
                }
            }

            $dynParam = @{
                Name                   = 'Type'
                ParameterSetName       = $PSCmdlet.ParameterSetName
                Type                   = [string]
                Mandatory              = $false
                ValidateSet            = $ValidateSet
                DynamicParamDictionary = $DynamicParamDictionary
            }
            New-DynamicParam @dynParam
        }

        return $DynamicParamDictionary
    }

    begin {
        $Type = $PSBoundParameters['Type']
    }

    process {
        switch ($PSCmdlet.ParameterSetName) {
            'MyRepos_Type' {
                $params = @{
                    Type      = $Type
                    Sort      = $Sort
                    Direction = $Direction
                    PerPage   = $PerPage
                    Since     = $Since
                    Before    = $Before
                }
                Remove-HashtableEntry -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-HashtableEntry -Hashtable $params -NullOrEmptyValues
                Get-GitHubMyRepositories @params
            }
            'ByName' {
                $params = @{
                    Owner = $Owner
                    Repo  = $Repo
                }
                Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues
                Get-GitHubRepositoryByName @params
            }
            'ListByID' {
                $params = @{
                    Since = $SinceID
                }
                Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues
                Get-GitHubRepositoryListByID @params
            }
            'ListByOrg' {
                $params = @{
                    Owner     = $Owner
                    Type      = $Type
                    Sort      = $Sort
                    Direction = $Direction
                    PerPage   = $PerPage
                }
                Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues
                Get-GitHubRepositoryListByOrg @params
            }
            'ListByUser' {
                $params = @{
                    Username  = $Username
                    Type      = $Type
                    Sort      = $Sort
                    Direction = $Direction
                    PerPage   = $PerPage
                }
                Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues
                Get-GitHubRepositoryListByUser @params
            }
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepository] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepository]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryActivity]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryActivity] - Importing"

filter Get-GitHubRepositoryActivity {
    <#
        .SYNOPSIS
        List repository activities

        .DESCRIPTION
        Lists a detailed history of changes to a repository, such as pushes, merges, force pushes, and branch changes,
        and associates these changes with commits and users.

        For more information about viewing repository activity,
        see "[Viewing activity and data for your repository](https://docs.github.com/repositories/viewing-activity-and-data-for-your-repository)."

        .EXAMPLE
        Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub'

        .EXAMPLE
        Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -Direction 'asc'

        .EXAMPLE
        Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -PerPage 100

        .EXAMPLE
        Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -Before '2021-01-01T00:00:00Z'

        .EXAMPLE
        Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -After '2021-01-01T00:00:00Z'

        .EXAMPLE
        Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -Ref 'refs/heads/main'

        .EXAMPLE
        Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -Actor 'octocat'

        .EXAMPLE
        $params = @{
            Owner = 'PSModule'
            Repo = 'GitHub'
            TimePeriod = 'day'
        }
        Get-GitHubRepositoryActivity @params |
            Select-Object -Property @{n='actor';e={$_.actor.login}},activity_type,ref,timestamp

        Gets the activity for the past 24 hours and selects the actor, activity type, ref, and timestamp.

        .EXAMPLE
        Get-GitHubRepositoryActivity -Owner 'PSModule' -Repo 'GitHub' -ActivityType 'push','force_push'

        .NOTES
        [List repository activities](https://docs.github.com/rest/repos/repos#list-repository-activities)

    #>

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

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

        # The direction to sort the results by.
        [Parameter()]
        [ValidateSet('asc', 'desc')]
        [string] $Direction = 'desc',

        # The number of results per page (max 100).
        # Default: 30
        [Parameter()]
        [ValidateRange(1, 100)]
        [Alias('per_page')]
        [int] $PerPage = 30,

        # A cursor, as given in the Link header. If specified, the query only searches for results before this cursor.
        [Parameter(ParameterSetName = 'BeforeAfter')]
        [string] $Before,

        # A cursor, as given in the Link header. If specified, the query only searches for results after this cursor.
        [Parameter(ParameterSetName = 'BeforeAfter')]
        [string] $After,

        # The Git reference for the activities you want to list.
        # The ref for a branch can be formatted either as refs/heads/BRANCH_NAME or BRANCH_NAME, where BRANCH_NAME is the name of your branch.
        [Parameter()]
        [string] $Ref,

        # The GitHub username to use to filter by the actor who performed the activity.
        [Parameter()]
        [string] $Actor,

        # The time period to filter by.
        # For example,day will filter for activity that occurred in the past 24 hours,
        # and week will filter for activity that occurred in the past 7 days (168 hours).
        [Parameter()]
        [ValidateSet('day', 'week', 'month', 'quarter', 'year')]
        [Alias('time_period')]
        [string] $TimePeriod,

        # The activity type to filter by.
        # For example,you can choose to filter by 'force_push', to see all force pushes to the repository.
        [Parameter()]
        [ValidateSet('push', 'force_push', 'branch_creation', 'branch_deletion', 'pr_merge', 'merge_queue_merge')]
        [Alias('activity_type')]
        [string] $ActivityType
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramName = $_.Key
        $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
        $providedValue = $PSBoundParameters[$paramName]
        Write-Verbose "[$paramName]"
        Write-Verbose " - Default: [$paramDefaultValue]"
        Write-Verbose " - Provided: [$providedValue]"
        if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose ' - Using default value'
            $PSBoundParameters[$paramName] = $paramDefaultValue
        } else {
            Write-Verbose ' - Using provided value'
        }
    }

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryActivity] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryActivity]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryCodeownersError]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryCodeownersError] - Importing"

filter Get-GitHubRepositoryCodeownersError {
    <#
        .SYNOPSIS
        List CODEOWNERS errors

        .DESCRIPTION
        List any syntax errors that are detected in the CODEOWNERS file.

        For more information about the correct CODEOWNERS syntax,
        see "[About code owners](https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners)."

        .EXAMPLE
        Get-GitHubRepositoryCodeownersError -Owner 'PSModule' -Repo 'GitHub'

        Gets the CODEOWNERS errors for the repository.

        .NOTES
        [List CODEOWNERS errors](https://docs.github.com/rest/repos/repos#list-codeowners-errors)

    #>

    [CmdletBinding()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

        # A branch, tag or commit name used to determine which version of the CODEOWNERS file to use.
        # Default: the repository's default branch (e.g. main)
        [Parameter()]
        [string] $Ref
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramName = $_.Key
        $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
        $providedValue = $PSBoundParameters[$paramName]
        Write-Verbose "[$paramName]"
        Write-Verbose " - Default: [$paramDefaultValue]"
        Write-Verbose " - Provided: [$providedValue]"
        if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose ' - Using default value'
            $PSBoundParameters[$paramName] = $paramDefaultValue
        } else {
            Write-Verbose ' - Using provided value'
        }
    }

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryCodeownersError] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryCodeownersError]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryContributor]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryContributor] - Importing"

filter Get-GitHubRepositoryContributor {
    <#
        .SYNOPSIS
        List repository contributors

        .DESCRIPTION
        Lists contributors to the specified repository and sorts them by the number of commits per contributor in descending order.
        This endpoint may return information that is a few hours old because the GitHub REST API caches contributor data to improve performance.

        GitHub identifies contributors by author email address. This endpoint groups contribution counts by GitHub user,
        which includes all associated email addresses. To improve performance, only the first 500 author email addresses
        in the repository link to GitHub users. The rest will appear as anonymous contributors without associated GitHub user information.

        .EXAMPLE
        Get-GitHubRepositoryContributor -Owner 'PSModule' -Repo 'GitHub'

        Gets all contributors to the GitHub repository.

        .NOTES
        [List repository contributors](https://docs.github.com/rest/repos/repos#list-repository-contributors)

    #>

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

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

        # Wether to include anonymous contributors in results.
        [Parameter()]
        [switch] $Anon,

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

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryContributor] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryContributor]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryFork]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryFork] - Importing"

filter Get-GitHubRepositoryFork {
    <#
        .SYNOPSIS
        List forks

        .DESCRIPTION
        List forks of a named repository.

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

        List forks of the 'Hello-World' repository owned by 'octocat'.

        .NOTES
        [List forks](https://docs.github.com/rest/repos/forks#list-forks)

    #>

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

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

        # The direction to sort the results by.
        [Parameter()]
        [ValidateSet('newest', 'oldest', 'stargazers', 'watchers')]
        [string] $Sort = 'newest',

        # The number of results per page.
        [Parameter()]
        [ValidateRange(1, 100)]
        [Alias('per_page')]
        [int] $PerPage = 30
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramName = $_.Key
        $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
        $providedValue = $PSBoundParameters[$paramName]
        Write-Verbose "[$paramName]"
        Write-Verbose " - Default: [$paramDefaultValue]"
        Write-Verbose " - Provided: [$providedValue]"
        if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose ' - Using default value'
            $PSBoundParameters[$paramName] = $paramDefaultValue
        } else {
            Write-Verbose ' - Using provided value'
        }
    }

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryFork] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryFork]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryLanguage]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryLanguage] - Importing"

filter Get-GitHubRepositoryLanguage {
    <#
        .SYNOPSIS
        List repository languages

        .DESCRIPTION
        Lists languages for the specified repository. The value shown for each language is the number of
        bytes of code written in that language.

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

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

        .NOTES
        [List repository languages](https://docs.github.com/rest/repos/repos#list-repository-languages)

    #>

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

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryLanguage] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryLanguage]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositorySecurityFix]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositorySecurityFix] - Importing"

filter Get-GitHubRepositorySecurityFix {
    <#
        .SYNOPSIS
        Check if automated security fixes are enabled for a repository

        .DESCRIPTION
        Shows whether automated security fixes are enabled, disabled or paused for a repository.
        The authenticated user must have admin read access to the repository. For more information, see
        "[Configuring automated security fixes](https://docs.github.com/articles/configuring-automated-security-fixes)".

        .EXAMPLE
        Get-GitHubRepositorySecurityFix -Owner 'PSModule' -Repo 'GitHub'

        Gets the automated security fixes status for the GitHub repository.

        .NOTES
        [Check if automated security fixes are enabled for a repository](https://docs.github.com/rest/repos/repos#check-if-automated-security-fixes-are-enabled-for-a-repository)

    #>

    [Alias('Get-GitHubRepoSecurityFixes')]
    [CmdletBinding()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/automated-security-fixes"
        Method      = 'GET'
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositorySecurityFix] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositorySecurityFix]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTag]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTag] - Importing"

filter Get-GitHubRepositoryTag {
    <#
        .SYNOPSIS
        List repository tags

        .DESCRIPTION
        List repository tags

        .EXAMPLE
        Get-GitHubRepositoryTag -Owner 'PSModule' -Repo 'GitHub'

        Gets all tags of the GitHub repository.

        .NOTES
        [List repository tags](https://docs.github.com/rest/repos/repos#list-repository-tags)

    #>

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

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

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

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTag] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTag]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTeam]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTeam] - Importing"

filter Get-GitHubRepositoryTeam {
    <#
        .SYNOPSIS
        List repository teams

        .DESCRIPTION
        Lists the teams that have access to the specified repository and that are also visible to the authenticated user.

        For a public repository, a team is listed only if that team added the public repository explicitly.

        Personal access tokens require the following scopes:
        * `public_repo` to call this endpoint on a public repository
        * `repo` to call this endpoint on a private repository (this scope also includes public repositories)

        This endpoint is not compatible with fine-grained personal access tokens.

        .EXAMPLE
        Get-GitHubRepositoryTeam -Owner 'PSModule' -Repo 'GitHub'

        Lists the teams that have access to the specified repository and that are also visible to the authenticated user.

        .NOTES
        [List repository teams](https://docs.github.com/rest/repos/repos#list-repository-teams)

    #>

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

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

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

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTeam] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTeam]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTopic]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTopic] - Importing"

filter Get-GitHubRepositoryTopic {
    <#
        .SYNOPSIS
        Get all repository topics

        .DESCRIPTION
        Get all repository topics

        .EXAMPLE

        .NOTES
        [Get all repository topics](https://docs.github.com/rest/repos/repos#get-all-repository-topics)

    #>

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

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

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

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTopic] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Get-GitHubRepositoryTopic]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Move-GitHubRepository]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Move-GitHubRepository] - Importing"

filter Move-GitHubRepository {
    <#
        .SYNOPSIS
        Transfer a repository

        .DESCRIPTION
        A transfer request will need to be accepted by the new owner when transferring a personal repository to another user.
        The response will contain the original `owner`, and the transfer will continue asynchronously. For more details on
        the requirements to transfer personal and organization-owned repositories, see
        [about repository transfers](https://docs.github.com/articles/about-repository-transfers/).
        You must use a personal access token (classic) or an OAuth token for this endpoint. An installation access token or
        a fine-grained personal access token cannot be used because they are only granted access to a single account.

        .EXAMPLE
        Move-GitHubRepository -Owner 'PSModule' -Repo 'GitHub' -NewOwner 'GitHub' -NewName 'PowerShell'

        Moves the GitHub repository to the PSModule organization and renames it to GitHub.

        .NOTES
        [Transfer a repository](https://docs.github.com/rest/repos/repos#transfer-a-repository)

    #>

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

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

        # The username or organization name the repository will be transferred to.
        [Parameter(Mandatory)]
        [Alias('new_owner')]
        [string] $NewOwner,

        # The new name to be given to the repository.
        [Parameter()]
        [Alias('new_name')]
        [string] $NewName,

        # ID of the team or teams to add to the repository. Teams can only be added to organization-owned repositories.
        [Parameter()]
        [Alias('team_ids')]
        [int[]] $TeamIds
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramName = $_.Key
        $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
        $providedValue = $PSBoundParameters[$paramName]
        Write-Verbose "[$paramName]"
        Write-Verbose " - Default: [$paramDefaultValue]"
        Write-Verbose " - Provided: [$providedValue]"
        if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose ' - Using default value'
            $PSBoundParameters[$paramName] = $paramDefaultValue
        } else {
            Write-Verbose ' - Using provided value'
        }
    }

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Move-GitHubRepository] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Move-GitHubRepository]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [New-GitHubRepository]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [New-GitHubRepository] - Importing"

#Requires -Modules @{ ModuleName = 'DynamicParams'; RequiredVersion = '1.1.8' }

filter New-GitHubRepository {
    <#
        .SYNOPSIS
        Create a repository for a user or an organization.

        .DESCRIPTION
        Creates a new repository for a user or in a specified 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 = @{
            Name = 'Hello-World'
            Description = 'This is your first repository'
            Homepage = 'https://github.com'
            HasIssues = $true
            HasProjects = $true
            HasWiki = $true
            HasDiscussions = $true
            HasDownloads = $true
            IsTemplate = $true
            AutoInit = $true
            AllowSquashMerge = $true
            AllowAutoMerge = $true
            DeleteBranchOnMerge = $true
            SquashMergeCommitTitle = 'PR_TITLE'
            SquashMergeCommitMessage = 'PR_BODY'
        }
        New-GitHubRepository @params

        Creates a new public repository named "Hello-World" owned by the authenticated user.

        .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-GitHubRepository @params

        Creates a new public repository named "Hello-World" owned by the organization "PSModule".

        .EXAMPLE
        $params = @{
            TemplateOwner = 'GitHub'
            TemplateRepo = 'octocat'
            Owner = 'PSModule'
            Name = 'MyNewRepo'
            IncludeAllBranches = $true
            Description = 'My new repo'
            Private = $true
        }
        New-GitHubRepository @params

        Creates a new private repository named `MyNewRepo` from the `octocat` template repository owned by `GitHub`.

        .EXAMPLE
        $params = @{
            ForkOwner = 'octocat'
            ForkRepo = 'Hello-World'
            Owner = 'PSModule'
            Name = 'MyNewRepo'
            DefaultBranchOnly = $true
        }
        New-GitHubRepository @params

        Creates a new repository named `MyNewRepo` as a fork of `Hello-World` owned by `octocat`.
        Only the default branch will be forked.

        .NOTES
        https://docs.github.com/rest/repos/repos#create-a-repository-using-a-template


        .PARAMETER GitignoreTemplate
        Desired language or platform .gitignore template to apply. Use the name of the template without the extension. For example, "Haskell".

        .PARAMETER LicenseTemplate
        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".

        .NOTES
        [Create a repository for the authenticated user](https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user)
        [Create an organization repository](https://docs.github.com/rest/repos/repos#create-an-organization-repository)

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(
        SupportsShouldProcess,
        DefaultParameterSetName = 'user'
    )]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter(ParameterSetName = 'org')]
        [Parameter(ParameterSetName = 'fork')]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

        # The name of the repository.
        [Parameter(ParameterSetName = 'fork')]
        [Parameter(Mandatory, ParameterSetName = 'user')]
        [Parameter(Mandatory, ParameterSetName = 'org')]
        [Parameter(Mandatory, ParameterSetName = 'template')]
        [string] $Name,

        # The account owner of the template repository. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ParameterSetName = 'template'
        )]
        [Alias('template_owner')]
        [string] $TemplateOwner,

        # The name of the template repository without the .git extension. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ParameterSetName = 'template'
        )]
        [Alias('template_repo')]
        [string] $TemplateRepo,

        # The account owner of the repository. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ParameterSetName = 'fork'
        )]
        [string] $ForkOwner,

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter(
            Mandatory,
            ParameterSetName = 'fork'
        )]
        [string] $ForkRepo,

        # When forking from an existing repository, fork with only the default branch.
        [Parameter(ParameterSetName = 'fork')]
        [Alias('default_branch_only')]
        [switch] $DefaultBranchOnly,

        # A short description of the new repository.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Parameter(ParameterSetName = 'template')]
        [string] $Description,

        # Set to true to include the directory structure and files from all branches in the template repository,
        # and not just the default branch.
        [Parameter(ParameterSetName = 'template')]
        [Alias('include_all_branches')]
        [switch] $IncludeAllBranches,

        # A URL with more information about the repository.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [ValidateNotNullOrEmpty()]
        [uri] $Homepage,

        # The visibility of the repository.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Parameter(ParameterSetName = 'template')]
        [ValidateSet('public', 'private')]
        [string] $Visibility = 'public',

        # Whether issues are enabled.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('has_issues')]
        [switch] $HasIssues,

        # Whether projects are enabled.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('has_projects')]
        [switch] $HasProjects,

        # Whether the wiki is enabled.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('has_wiki')]
        [switch] $HasWiki,

        # Whether discussions are enabled.
        [Parameter(ParameterSetName = 'user')]
        [Alias('has_discussions')]
        [switch] $HasDiscussions,

        # Whether downloads are enabled.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('has_downloads')]
        [switch] $HasDownloads,

        # Whether this repository acts as a template that can be used to generate new repositories.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [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(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('team_id')]
        [int] $TeamId,

        # Pass true to create an initial commit with empty README.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('auto_init')]
        [switch] $AutoInit,

        # Whether to allow squash merges for pull requests.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('allow_squash_merge')]
        [switch] $AllowSquashMerge,

        # Whether to allow merge commits for pull requests.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('allow_merge_commit')]
        [switch] $AllowMergeCommit,

        # Whether to allow rebase merges for pull requests.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('allow_rebase_merge')]
        [switch] $AllowRebaseMerge,

        # Whether to allow Auto-merge to be used on pull requests.
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [Alias('allow_auto_merge')]
        [switch] $AllowAutoMerge,

        # Whether to delete head branches when pull requests are merged
        [Parameter(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [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(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [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(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [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(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [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(ParameterSetName = 'user')]
        [Parameter(ParameterSetName = 'org')]
        [ValidateSet('PR_BODY', 'PR_TITLE', 'BLANK')]
        [Alias('merge_commit_message')]
        [string] $MergeCommitMessage
    )

    dynamicparam {
        $DynamicParamDictionary = New-DynamicParamDictionary

        $dynParam = @{
            Name                   = 'GitignoreTemplate'
            Alias                  = 'gitignore_template'
            Type                   = [string]
            ValidateSet            = Get-GitHubGitignoreList
            DynamicParamDictionary = $DynamicParamDictionary
        }
        New-DynamicParam @dynParam

        $dynParam2 = @{
            Name                   = 'LicenseTemplate'
            Alias                  = 'license_template'
            Type                   = [string]
            ValidateSet            = Get-GitHubLicenseList | Select-Object -ExpandProperty key
            DynamicParamDictionary = $DynamicParamDictionary
        }
        New-DynamicParam @dynParam2

        return $DynamicParamDictionary
    }

    begin {
        $GitignoreTemplate = $PSBoundParameters['GitignoreTemplate']
        $LicenseTemplate = $PSBoundParameters['LicenseTemplate']
    }

    process {
        if ($PSCmdlet.ParameterSetName -in 'user', 'org') {
            $params = @{
                Owner                    = $Owner
                Name                     = $Name
                Description              = $Description
                Homepage                 = $Homepage
                Visibility               = $Visibility
                HasIssues                = $HasIssues
                HasProjects              = $HasProjects
                HasWiki                  = $HasWiki
                HasDiscussions           = $HasDiscussions
                HasDownloads             = $HasDownloads
                IsTemplate               = $IsTemplate
                TeamId                   = $TeamId
                AutoInit                 = $AutoInit
                AllowSquashMerge         = $AllowSquashMerge
                AllowMergeCommit         = $AllowMergeCommit
                AllowRebaseMerge         = $AllowRebaseMerge
                AllowAutoMerge           = $AllowAutoMerge
                DeleteBranchOnMerge      = $DeleteBranchOnMerge
                SquashMergeCommitTitle   = $SquashMergeCommitTitle
                SquashMergeCommitMessage = $SquashMergeCommitMessage
                MergeCommitTitle         = $MergeCommitTitle
                MergeCommitMessage       = $MergeCommitMessage
                GitignoreTemplate        = $GitignoreTemplate
                LicenseTemplate          = $LicenseTemplate
            }
            Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues
        }

        switch ($PSCmdlet.ParameterSetName) {
            'user' {
                if ($PSCmdlet.ShouldProcess("repository for user [$Name]", 'Create')) {
                    New-GitHubRepositoryUser @params
                }
            }
            'org' {
                if ($PSCmdlet.ShouldProcess("repository for organization [$Owner/$Name]", 'Create')) {
                    New-GitHubRepositoryOrg @params
                }
            }
            'template' {
                if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] from template [$TemplateOwner/$TemplateRepo]", 'Create')) {
                    $params = @{
                        TemplateOwner      = $TemplateOwner
                        TemplateRepo       = $TemplateRepo
                        Owner              = $Owner
                        Name               = $Name
                        IncludeAllBranches = $IncludeAllBranches
                        Description        = $Description
                        Private            = $Visibility -eq 'private'
                    }
                    Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues
                    New-GitHubRepositoryFromTemplate @params
                }
            }
            'fork' {
                if ([string]::IsNullorEmpty($Name)) {
                    $Name = $ForkRepo
                }
                if ($PSCmdlet.ShouldProcess("repository [$Owner/$Name] as fork from [$ForkOwner/$ForkRepo]", 'Create')) {
                    $params = @{
                        Owner             = $ForkOwner
                        Repo              = $ForkRepo
                        Organization      = $Owner
                        Name              = $Name
                        DefaultBranchOnly = $DefaultBranchOnly
                    }
                    Remove-HashtableEntry -Hashtable $params -NullOrEmptyValues
                    New-GitHubRepositoryAsFork @params
                }
            }
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [New-GitHubRepository] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [New-GitHubRepository]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Remove-GitHubRepository]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Remove-GitHubRepository] - Importing"

filter Remove-GitHubRepository {
    <#
        .SYNOPSIS
        Delete a repository

        .DESCRIPTION
        Deleting a repository requires admin access. If OAuth is used, the `delete_repo` scope is required.

        If an organization owner has configured the organization to prevent members from deleting organization-owned
        repositories, you will get a `403 Forbidden` response.

        .EXAMPLE
        Remove-GitHubRepository -Owner 'PSModule' -Repo 'Hello-World'

        Deletes the repository `Hello-World` in the `PSModule` organization.

        .NOTES
        [Delete a repository](https://docs.github.com/rest/repos/repos#delete-a-repository)
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('org')]
        [Alias('login')]
        [string] $Owner,

        # The name of the repository without the .git extension. The name is not case sensitive.
        [Parameter(Mandatory)]
        [string] $Repo
    )

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

    if ($PSCmdlet.ShouldProcess("repo [$Owner/$Repo]", 'Delete')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Remove-GitHubRepository] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Remove-GitHubRepository]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Set-GitHubRepositoryTopic]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Set-GitHubRepositoryTopic] - Importing"

filter Set-GitHubRepositoryTopic {
    <#
        .SYNOPSIS
        Replace all repository topics

        .DESCRIPTION
        Replace all repository topics

        .EXAMPLE
        Set-GitHubRepositoryTopic -Owner 'octocat' -Repo 'hello-world' -Names 'octocat', 'octo', 'octocat/hello-world'

        Replaces all topics for the repository 'octocat/hello-world' with the topics 'octocat', 'octo', 'octocat/hello-world'.

        .NOTES
        [Replace all repository topics](https://docs.github.com/rest/repos/repos#replace-all-repository-topics)
    #>

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

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

        # The number of results per page (max 100).
        [Parameter()]
        [Alias('Topics')]
        [string[]] $Names = @()
    )

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

    $body.names = $body.names | ForEach-Object { $_.ToLower() }

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

    if ($PSCmdlet.ShouldProcess("topics for repo [$Owner/$Repo]", 'Set')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response.names
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Set-GitHubRepositoryTopic] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Set-GitHubRepositoryTopic]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Start-GitHubRepositoryEvent]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Start-GitHubRepositoryEvent] - Importing"

filter Start-GitHubRepositoryEvent {
    <#
        .SYNOPSIS
        Create a repository dispatch event

        .DESCRIPTION
        You can use this endpoint to trigger a webhook event called `repository_dispatch` when you want activity
        that happens outside of GitHub to trigger a GitHub Actions workflow or GitHub App webhook. You must configure
        your GitHub Actions workflow or GitHub App to run when the `repository_dispatch`
        event occurs. For an example `repository_dispatch` webhook payload, see
        "[RepositoryDispatchEvent](https://docs.github.com/webhooks/event-payloads/#repository_dispatch)."

        The `client_payload` parameter is available for any extra information that your workflow might need.
        This parameter is a JSON payload that will be passed on when the webhook event is dispatched. For example,
        the `client_payload` can include a message that a user would like to send using a GitHub Actions workflow.
        Or the `client_payload` can be used as a test to debug your workflow.

        This endpoint requires write access to the repository by providing either:

        - Personal access tokens with `repo` scope. For more information, see
        "[Creating a personal access token for the command line](https://docs.github.com/articles/creating-a-personal-access-token-for-the-command-line)"
        in the GitHub Help documentation.
        - GitHub Apps with both `metadata:read` and `contents:read&write` permissions.

        This input example shows how you can use the `client_payload` as a test to debug your workflow.

        .EXAMPLE
        $params = @{
            EventType = 'on-demand-test'
            ClientPayload = @{
                unit = false
                integration = true
            }
        }
        Start-GitHubRepositoryEvent @params

        Starts a repository event with the name `on-demand-test` and a `client_payload` that includes `unit` and `integration`.

        .NOTES
        [Create a repository dispatch event](https://docs.github.com/rest/repos/repos#create-a-repository-dispatch-event)

    #>

    [CmdletBinding(SupportsShouldProcess)]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

        # A custom webhook event name. Must be 100 characters or fewer.
        [Parameter(Mandatory)]
        [Alias('event_type')]
        [string] $EventType,

        # JSON payload with extra information about the webhook event that your action or workflow may use.
        # The maximum number of top-level properties is 10.
        [Parameter()]
        [Alias('client_payload')]
        [object] $ClientPayload
    )

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramName = $_.Key
        $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
        $providedValue = $PSBoundParameters[$paramName]
        Write-Verbose "[$paramName]"
        Write-Verbose " - Default: [$paramDefaultValue]"
        Write-Verbose " - Provided: [$providedValue]"
        if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose ' - Using default value'
            $PSBoundParameters[$paramName] = $paramDefaultValue
        } else {
            Write-Verbose ' - Using provided value'
        }
    }

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Start-GitHubRepositoryEvent] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Start-GitHubRepositoryEvent]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Test-GitHubRepositoryVulnerabilityAlert]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Test-GitHubRepositoryVulnerabilityAlert] - Importing"

filter Test-GitHubRepositoryVulnerabilityAlert {
    <#
        .SYNOPSIS
        Check if vulnerability alerts are enabled for a repository

        .DESCRIPTION
        Shows whether dependency alerts are enabled or disabled for a repository.
        The authenticated user must have admin read access to the repository.
        For more information, see
        "[About security alerts for vulnerable dependencies](https://docs.github.com/articles/about-security-alerts-for-vulnerable-dependencies)".

        .EXAMPLE
        Test-GitHubRepositoryVulnerabilityAlert -Owner 'PSModule' -Repo 'GitHub'

        Checks if vulnerability alerts are enabled for the PSModule/GitHub repository.

        .NOTES
        [Check if vulnerability alerts are enabled for a repository](https://docs.github.com/rest/repos/repos#list-repository-tags)
    #>

    [OutputType([bool])]
    [CmdletBinding()]
    [Alias('Test-GitHubRepositoryVulnerabilityAlerts')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Test-GitHubRepositoryVulnerabilityAlert] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Test-GitHubRepositoryVulnerabilityAlert]
#region - From [functions] - [public] - [Repositories] - [Repositories] - [Update-GitHubRepository]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Update-GitHubRepository] - Importing"

filter Update-GitHubRepository {
    <#
        .SYNOPSIS
        Update a repository

        .DESCRIPTION
        **Note**: To edit a repository's topics, use the
        [Replace all repository topics](https://docs.github.com/rest/repos/repos#replace-all-repository-topics) endpoint.

        .EXAMPLE
        Update-GitHubRepository -Name 'octocat' -Description 'Hello-World' -Homepage 'https://github.com'

        .EXAMPLE
        $params = @{
            Owner = 'octocat'
            Repo = 'Hello-World'
            name = 'Hello-World-Repo
            description = 'This is your first repository'
            homepage = 'https://github.com'
        }
        Update-GitHubRepository @params

        .NOTES
        [Update a repository](https://docs.github.com/rest/repos/repos#update-a-repository)
    #>

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

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

        # The name of the repository.
        [Parameter()]
        [string] $Name,

        # A short description of the repository.
        [Parameter()]
        [string] $Description,

        # A URL with more information about the repository.
        [Parameter()]
        [uri] $Homepage,

        # The visibility of the repository.
        [Parameter()]
        [ValidateSet('public', 'private')]
        [string] $Visibility,

        # Use the status property to enable or disable GitHub Advanced Security for this repository.
        # For more information, see "About GitHub Advanced Security."
        [Parameter()]
        [switch] $EnableAdvancedSecurity,

        # Use the status property to enable or disable secret scanning for this repository.
        # For more information, see "About secret scanning."
        [Parameter()]
        [switch] $EnableSecretScanning,

        # Use the status property to enable or disable secret scanning push protection for this repository.
        # For more information, see "Protecting pushes with secret scanning."
        [Parameter()]
        [switch] $EnableSecretScanningPushProtection,

        # Whether issues are enabled.
        [Parameter()]
        [Alias('has_issues')]
        [switch] $HasIssues,

        # Whether projects are enabled.
        [Parameter()]
        [Alias('has_projects')]
        [switch] $HasProjects,

        # Whether the wiki is enabled.
        [Parameter()]
        [Alias('has_wiki')]
        [switch] $HasWiki,

        # Whether this repository acts as a template that can be used to generate new repositories.
        [Parameter()]
        [Alias('is_template')]
        [switch] $IsTemplate,

        # Updates the default branch for this repository.
        [Parameter()]
        [Alias('default_branch')]
        [string] $DefaultBranch,

        # Whether to allow squash merges for pull requests.
        [Parameter()]
        [Alias('allow_squash_merge')]
        [switch] $AllowSquashMerge,

        # Whether to allow merge commits for pull requests.
        [Parameter()]
        [Alias('allow_merge_commit')]
        [switch] $AllowMergeCommit,

        # Whether to allow rebase merges for pull requests.
        [Parameter()]
        [Alias('allow_rebase_merge')]
        [switch] $AllowRebaseMerge,

        # Whether to allow Auto-merge to be used on pull requests.
        [Parameter()]
        [Alias('allow_auto_merge')]
        [switch] $AllowAutoMerge,

        # Whether to delete head branches when pull requests are merged
        [Parameter()]
        [Alias('delete_branch_on_merge')]
        [switch] $DeleteBranchOnMerge,

        # Either true to always allow a pull request head branch that is behind its base branch
        # to be updated even if it is not required to be up to date before merging, or false otherwise.
        [Parameter()]
        [Alias('allow_update_branch')]
        [switch] $AllowUpdateMerge,

        # 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,

        # Whether to archive this repository. false will unarchive a previously archived repository.
        [Parameter()]
        [switch] $Archived,

        # Either true to allow private forks, or false to prevent private forks.
        [Parameter()]
        [Alias('allow_forking')]
        [switch] $AllowForking,

        # Either true to require contributors to sign off on web-based commits,
        # or false to not require contributors to sign off on web-based commits.
        [Parameter()]
        [Alias('web_commit_signoff_required')]
        [switch] $WebCommitSignoffRequired
    )

    $body = @{
        name                            = $Name
        description                     = $Description
        homepage                        = $Homepage
        visibility                      = $Visibility
        private                         = $Visibility -eq 'private'
        default_branch                  = $DefaultBranch
        squash_merge_commit_title       = $SquashMergeCommitTitle
        squash_merge_commit_message     = $SquashMergeCommitMessage
        merge_commit_title              = $MergeCommitTitle
        merge_commit_message            = $MergeCommitMessage

        advanced_security               = if ($EnableAdvancedSecurity.IsPresent) {
            @{
                status = if ($EnableAdvancedSecurity) { 'enabled' } else { 'disabled' }
            }
        } else { $null }
        secret_scanning                 = if ($EnableSecretScanning.IsPresent) {
            @{
                status = if ($EnableSecretScanning) { 'enabled' } else { 'disabled' }
            }
        } else { $null }
        secret_scanning_push_protection = if ($EnableSecretScanningPushProtection.IsPresent) {
            @{
                status = if ($EnableSecretScanningPushProtection) { 'enabled' } else { 'disabled' }
            }
        } else { $null }
        has_issues                      = if ($HasIssues.IsPresent) { $HasIssues } else { $null }
        has_projects                    = if ($HasProjects.IsPresent) { $HasProjects } else { $null }
        has_wiki                        = if ($HasWiki.IsPresent) { $HasWiki } else { $null }
        is_template                     = if ($IsTemplate.IsPresent) { $IsTemplate } else { $null }
        allow_squash_merge              = if ($AllowSquashMerge.IsPresent) { $AllowSquashMerge } else { $null }
        allow_merge_commit              = if ($AllowMergeCommit.IsPresent) { $AllowMergeCommit } else { $null }
        allow_rebase_merge              = if ($AllowRebaseMerge.IsPresent) { $AllowRebaseMerge } else { $null }
        allow_auto_merge                = if ($AllowAutoMerge.IsPresent) { $AllowAutoMerge } else { $null }
        allow_update_branch             = if ($AllowUpdateMerge.IsPresent) { $AllowUpdateMerge } else { $null }
        delete_branch_on_merge          = if ($DeleteBranchOnMerge.IsPresent) { $DeleteBranchOnMerge } else { $null }
        archived                        = if ($Archived.IsPresent) { $Archived } else { $null }
        allow_forking                   = if ($AllowForking.IsPresent) { $AllowForking } else { $null }
        web_commit_signoff_required     = if ($WebCommitSignoffRequired.IsPresent) { $WebCommitSignoffRequired } else { $null }
    }

    Remove-HashtableEntry -Hashtable $body -NullOrEmptyValues

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

    if ($PSCmdlet.ShouldProcess("Repository [$Owner/$Repo]", 'Update')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - [Update-GitHubRepository] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories] - [Update-GitHubRepository]

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Repositories] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Repositories]

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

#region - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuite]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuite] - Importing"

filter Get-GitHubRepositoryRuleSuite {
    <#
        .SYNOPSIS
        List repository rule suites or a rule suite by ID.

        .DESCRIPTION
        Lists suites of rule evaluations at the repository level.
        If an ID is specified, gets information about a suite of rule evaluations from within a repository.
        For more information, see"[Managing rulesets for a repository](https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/managing-rulesets-for-a-repository#viewing-insights-for-rulesets)."

        .EXAMPLE
        $params = @{
            Owner = 'octocat'
            Repo = 'hello-world'
            Ref = 'main'
            TimePeriod = 'day'
            ActorName = 'octocat'
            RuleSuiteResult = 'all'
        }
        Get-GitHubRepositoryRuleSuite @params

        Gets a list of rule suites for the main branch of the hello-world repository owned by octocat.

        .EXAMPLE
        Get-GitHubRepositoryRuleSuite -Owner 'octocat' -Repo 'hello-world' -RuleSuiteId 123456789

        Gets information about a suite of rule evaluations with ID 123456789 from within the octocat/hello-world repository.

        .NOTES
        [List repository rule suites](https://docs.github.com/rest/repos/rule-suites#list-repository-rule-suites)
        [Get a repository rule suite](https://docs.github.com/rest/repos/rule-suites#get-a-repository-rule-suite)
    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')]
    [CmdletBinding(DefaultParameterSetName = 'Default')]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

        # The name of the ref. Cannot contain wildcard characters.
        # When specified, only rule evaluations triggered for this ref will be returned.
        [Parameter()]
        [string] $Ref,

        # The time period to filter by.
        # For example,day will filter for rule suites that occurred in the past 24 hours,
        # and week will filter for insights that occurred in the past 7 days (168 hours).
        [Parameter()]
        [ValidateSet('hour', 'day', 'week', 'month')]
        [string] $TimePeriod = 'day',

        # The handle for the GitHub user account to filter on. When specified, only rule evaluations triggered by this actor will be returned.
        [Parameter()]
        [string] $ActorName,

        # The rule results to filter on. When specified, only suites with this result will be returned.
        [Parameter()]
        [ValidateSet('pass', 'fail', 'bypass', 'all')]
        [string] $RuleSuiteResult = 'all',

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

        # The unique identifier of the rule suite result. To get this ID, you can use GET /repos/ { owner }/ { repo }/rulesets/rule-suites for repositories and GET /orgs/ { org }/rulesets/rule-suites for organizations.
        [Parameter(
            Mandatory,
            ParameterSetName = 'ById'
        )]
        [int] $RuleSuiteId
    )

    switch ($PSCmdlet.ParameterSetName) {
        'Default' {
            $params = @{
                Owner           = $Owner
                Repo            = $Repo
                Ref             = $Ref
                TimePeriod      = $TimePeriod
                ActorName       = $ActorName
                RuleSuiteResult = $RuleSuiteResult
                PerPage         = $PerPage
            }
            Get-GitHubRepositoryRuleSuiteList @params
        }
        'ById' {
            $params = @{
                Owner       = $Owner
                Repo        = $Repo
                RuleSuiteId = $RuleSuiteId
            }
            Get-GitHubRepositoryRuleSuiteById @params
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuite] - Done"
#endregion - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuite]
#region - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteById]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteById] - Importing"

filter Get-GitHubRepositoryRuleSuiteById {
    <#
        .SYNOPSIS
        Get a repository rule suite

        .DESCRIPTION
        Gets information about a suite of rule evaluations from within a repository.
        For more information, see "[Managing rulesets for a repository](https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/managing-rulesets-for-a-repository#viewing-insights-for-rulesets)."

        .EXAMPLE
        Get-GitHubRepositoryRuleSuiteById -Owner 'octocat' -Repo 'hello-world' -RuleSuiteId 123456789

        Gets information about a suite of rule evaluations with ID 123456789 from within the octocat/hello-world repository.

        .NOTES
        [Get a repository rule suite](https://docs.github.com/rest/repos/rule-suites#get-a-repository-rule-suite)
    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')]
    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

        # The unique identifier of the rule suite result. To get this ID, you can use GET /repos/ { owner }/ { repo }/rulesets/rule-suites for repositories and GET /orgs/ { org }/rulesets/rule-suites for organizations.
        [Parameter(Mandatory)]
        [int] $RuleSuiteId

    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/rulesets/rule-suites/$RuleSuiteId"
        Method      = 'GET'
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteById] - Done"
#endregion - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteById]
#region - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteList]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteList] - Importing"

filter Get-GitHubRepositoryRuleSuiteList {
    <#
        .SYNOPSIS
        List repository rule suites

        .DESCRIPTION
        Lists suites of rule evaluations at the repository level.
        For more information, see"[Managing rulesets for a repository](https://docs.github.com/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/managing-rulesets-for-a-repository#viewing-insights-for-rulesets)."

        .EXAMPLE
        $params = @{
            Owner = 'octocat'
            Repo = 'hello-world'
            Ref = 'main'
            TimePeriod = 'day'
            ActorName = 'octocat'
            RuleSuiteResult = 'all'
        }
        Get-GitHubRepositoryRuleSuiteList @params

        Gets a list of rule suites for the main branch of the hello-world repository owned by octocat.

        .NOTES
        [List repository rule suites](https://docs.github.com/rest/repos/rule-suites#list-repository-rule-suites)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links')]
    [CmdletBinding()]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

        # The name of the ref. Cannot contain wildcard characters.
        # When specified, only rule evaluations triggered for this ref will be returned.
        [Parameter()]
        [string] $Ref,

        # The time period to filter by.
        # For example,day will filter for rule suites that occurred in the past 24 hours,
        # and week will filter for insights that occurred in the past 7 days (168 hours).
        [Parameter()]
        [ValidateSet('hour', 'day', 'week', 'month')]
        [string] $TimePeriod = 'day',

        # The handle for the GitHub user account to filter on. When specified, only rule evaluations triggered by this actor will be returned.
        [Parameter()]
        [string] $ActorName,

        # The rule results to filter on. When specified, only suites with this result will be returned.
        [Parameter()]
        [ValidateSet('pass', 'fail', 'bypass', 'all')]
        [string] $RuleSuiteResult = 'all',

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

    $PSCmdlet.MyInvocation.MyCommand.Parameters.GetEnumerator() | ForEach-Object {
        $paramName = $_.Key
        $paramDefaultValue = Get-Variable -Name $paramName -ValueOnly -ErrorAction SilentlyContinue
        $providedValue = $PSBoundParameters[$paramName]
        Write-Verbose "[$paramName]"
        Write-Verbose " - Default: [$paramDefaultValue]"
        Write-Verbose " - Provided: [$providedValue]"
        if (-not $PSBoundParameters.ContainsKey($paramName) -and ($null -ne $paramDefaultValue)) {
            Write-Verbose ' - Using default value'
            $PSBoundParameters[$paramName] = $paramDefaultValue
        } else {
            Write-Verbose ' - Using provided value'
        }
    }

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


    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/rulesets/rule-suites"
        Method      = 'GET'
        Body        = $body
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteList] - Done"
#endregion - From [functions] - [public] - [Repositories] - [RuleSuite] - [Get-GitHubRepositoryRuleSuiteList]

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [RuleSuite] - Done"
#endregion - From [functions] - [public] - [Repositories] - [RuleSuite]

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

#region - From [functions] - [public] - [Repositories] - [Tags] - [Get-GitHubRepositoryTagProtection]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [Get-GitHubRepositoryTagProtection] - Importing"

filter Get-GitHubRepositoryTagProtection {
    <#
        .SYNOPSIS
        List tag protection states for a repository

        .DESCRIPTION
        This returns the tag protection states of a repository.

        This information is only available to repository administrators.

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

        Gets the tag protection states of the 'hello-world' repository.

        .NOTES
        [List tag protection states for a repository](https://docs.github.com/rest/repos/tags#list-tag-protection-states-for-a-repository)

    #>

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

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [Get-GitHubRepositoryTagProtection] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Tags] - [Get-GitHubRepositoryTagProtection]
#region - From [functions] - [public] - [Repositories] - [Tags] - [New-GitHubRepositoryTagProtection]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [New-GitHubRepositoryTagProtection] - Importing"

filter New-GitHubRepositoryTagProtection {
    <#
        .SYNOPSIS
        Create a tag protection state for a repository

        .DESCRIPTION
        This creates a tag protection state for a repository.
        This endpoint is only available to repository administrators.

        .EXAMPLE
        New-GitHubRepositoryTagProtection -Owner 'octocat' -Repo 'hello-world' -Pattern 'v1.*'

        Creates a tag protection state for the 'hello-world' repository with the pattern 'v1.*'.

        .NOTES
        [Create a tag protection state for a repository](https://docs.github.com/rest/repos/tags#create-a-tag-protection-state-for-a-repository)
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

        # An optional glob pattern to match against when enforcing tag protection.
        [Parameter(Mandatory)]
        [string] $Pattern
    )

    $body['pattern'] = $Pattern

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/tags/protection"
        Method      = 'POST'
        Body        = $body
    }

    if ($PSCmdlet.ShouldProcess("tag protection state on pattern [$Pattern] for repository [$Owner/$Repo]", 'Create')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [New-GitHubRepositoryTagProtection] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Tags] - [New-GitHubRepositoryTagProtection]
#region - From [functions] - [public] - [Repositories] - [Tags] - [Remove-GitHubRepositoryTagProtection]
Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [Remove-GitHubRepositoryTagProtection] - Importing"

filter Remove-GitHubRepositoryTagProtection {
    <#
        .SYNOPSIS
        Delete a tag protection state for a repository

        .DESCRIPTION
        This deletes a tag protection state for a repository.
        This endpoint is only available to repository administrators.

        .EXAMPLE
        Remove-GitHubRepositoryTagProtection -Owner 'octocat' -Repo 'hello-world' -TagProtectionId 1

        Deletes the tag protection state with the ID 1 for the 'hello-world' repository.

        .NOTES
        [Delete a tag protection state for a repository](https://docs.github.com/rest/repos/tags#delete-a-tag-protection-state-for-a-repository)

    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The account owner of the repository. The name is not case sensitive.
        [Parameter()]
        [Alias('org')]
        [string] $Owner = (Get-GitHubContextSetting -Name Owner),

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

        # The unique identifier of the tag protection.
        [Parameter(Mandatory)]
        [int] $TagProtectionId
    )

    $inputObject = @{
        APIEndpoint = "/repos/$Owner/$Repo/tags/protection/$TagProtectionId"
        Method      = 'DELETE'
    }

    if ($PSCmdlet.ShouldProcess("tag protection state with ID [$TagProtectionId] for repository [$Owner/$Repo]", 'Delete')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - [Remove-GitHubRepositoryTagProtection] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Tags] - [Remove-GitHubRepositoryTagProtection]

Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - [Tags] - Done"
#endregion - From [functions] - [public] - [Repositories] - [Tags]


Write-Verbose "[$scriptName] - [functions] - [public] - [Repositories] - Done"
#endregion - From [functions] - [public] - [Repositories]

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

#region - From [functions] - [public] - [Status] - [Get-GitHubScheduledMaintenance]
Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubScheduledMaintenance] - 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
        [Scheduled maintenances](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] - [functions] - [public] - [Status] - [Get-GitHubScheduledMaintenance] - Done"
#endregion - From [functions] - [public] - [Status] - [Get-GitHubScheduledMaintenance]
#region - From [functions] - [public] - [Status] - [Get-GitHubStatus]
Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubStatus] - 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
        [Summary](https://www.githubstatus.com/api#summary)
        [Status](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] - [functions] - [public] - [Status] - [Get-GitHubStatus] - Done"
#endregion - From [functions] - [public] - [Status] - [Get-GitHubStatus]
#region - From [functions] - [public] - [Status] - [Get-GitHubStatusComponent]
Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubStatusComponent] - Importing"

function Get-GitHubStatusComponent {
    <#
        .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-GitHubStatusComponent

        Gets the status of GitHub components

        .NOTES
        [Components](https://www.githubstatus.com/api#components)
    #>

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

    $APIURI = 'https://www.githubstatus.com/api/v2/components.json'
    $response = Invoke-RestMethod -Uri $APIURI -Method Get
    $response.components
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubStatusComponent] - Done"
#endregion - From [functions] - [public] - [Status] - [Get-GitHubStatusComponent]
#region - From [functions] - [public] - [Status] - [Get-GitHubStatusIncident]
Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - [Get-GitHubStatusIncident] - Importing"

function Get-GitHubStatusIncident {
    <#
        .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-GitHubStatusIncident

        Gets the status of GitHub incidents

        .EXAMPLE
        Get-GitHubStatusIncident -Unresolved

        Gets the status of GitHub incidents that are unresolved

        .NOTES
        [Incidents](https://www.githubstatus.com/api#incidents)
    #>

    [OutputType([pscustomobject[]])]
    [Alias('Get-GitHubStatusIncidents')]
    [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] - [functions] - [public] - [Status] - [Get-GitHubStatusIncident] - Done"
#endregion - From [functions] - [public] - [Status] - [Get-GitHubStatusIncident]

Write-Verbose "[$scriptName] - [functions] - [public] - [Status] - Done"
#endregion - From [functions] - [public] - [Status]

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

#region - From [functions] - [public] - [Teams] - [Get-GitHubRepoTeam]
Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubRepoTeam] - Importing"

filter Get-GitHubRepoTeam {
    <#
        .NOTES
        [List repository teams](https://docs.github.com/rest/reference/repos#get-a-repository)
    #>

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

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

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

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubRepoTeam] - Done"
#endregion - From [functions] - [public] - [Teams] - [Get-GitHubRepoTeam]
#region - From [functions] - [public] - [Teams] - [Get-GitHubTeamByName]
Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubTeamByName] - Importing"

function Get-GitHubTeamByName {
    <#
        .SYNOPSIS
        Get a team by name

        .DESCRIPTION
        Gets a team using the team's slug. To create the slug, GitHub replaces special characters in the name string, changes all words to lowercase,
        and replaces spaces with a - separator. For example, "My TEam Näme" would become my-team-name.

        .EXAMPLE
        Get-GitHubTeamByName -Organization 'github' -Name 'my-team-name'

        .NOTES
        [Get team by name](https://docs.github.com/en/rest/teams/teams#get-a-team-by-name)
    #>

    [OutputType([void])]
    [CmdletBinding()]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('Org')]
        [string] $Organization,

        # The slug of the team name.
        [Parameter(Mandatory)]
        [Alias('Team', 'TeamName', 'slug', 'team_slug')]
        [string] $Name,

        # The context to run the command in
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name DefaultContext)
    )

    $inputObject = @{
        Context     = $Context
        Method      = 'Get'
        APIEndpoint = "/orgs/$Organization/teams/$Name"
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubTeamByName] - Done"
#endregion - From [functions] - [public] - [Teams] - [Get-GitHubTeamByName]
#region - From [functions] - [public] - [Teams] - [Get-GitHubTeamListByOrg]
Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubTeamListByOrg] - Importing"

function Get-GitHubTeamListByOrg {
    <#
        .SYNOPSIS
        List teams

        .DESCRIPTION
        Lists all teams in an organization that are visible to the authenticated user.

        .EXAMPLE
        Get-GitHubTeamListByOrg -Organization 'github'

        .NOTES
        [List teams](https://docs.github.com/rest/teams/teams#list-teams)
    #>

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

        # The context to run the command in
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name DefaultContext)
    )

    $inputObject = @{
        Context     = $Context
        Method      = 'Get'
        APIEndpoint = "/orgs/$Organization/teams"
    }

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

Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Get-GitHubTeamListByOrg] - Done"
#endregion - From [functions] - [public] - [Teams] - [Get-GitHubTeamListByOrg]
#region - From [functions] - [public] - [Teams] - [New-GitHubTeam]
Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [New-GitHubTeam] - Importing"

function New-GitHubTeam {
    <#
        .SYNOPSIS
        Create a team

        .DESCRIPTION
        To create a team, the authenticated user must be a member or owner of `{org}`. By default, organization members can create teams.
        Organization owners can limit team creation to organization owners. For more information, see
        "[Setting team creation permissions](https://docs.github.com/articles/setting-team-creation-permissions-in-your-organization)."

        When you create a new team, you automatically become a team maintainer without explicitly adding yourself to the optional array of
        `maintainers`. For more information, see
        "[About teams](https://docs.github.com/github/setting-up-and-managing-organizations-and-teams/about-teams)".

        .EXAMPLE
        $params = @{
            Organization = 'github'
            Name = 'team-name'
            Description = 'A new team'
            Maintainers = 'octocat'
            RepoNames = 'github/octocat'
            Privacy = 'closed'
            Permission = 'pull'
        }
        New-GitHubTeam @params

        .NOTES
        [Create a team](https://docs.github.com/rest/teams/teams#create-a-team)
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param(
        # The organization name. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('Org')]
        [string] $Organization,

        # The name of the team.
        [Parameter(Mandatory)]
        [string] $Name,

        # The description of the team.
        [Parameter()]
        [string] $Description,

        # List GitHub IDs for organization members who will become team maintainers.
        [Parameter()]
        [string[]] $Maintainers,

        # The full name (e.g., "organization-name/repository-name") of repositories to add the team to.
        [Parameter()]
        [string[]] $RepoNames,

        # The level of privacy this team should have. The options are:
        # For a non-nested team:
        # - secret - only visible to organization owners and members of this team.
        # - closed - visible to all members of this organization.
        # Default: secret
        # For a parent or child team:
        # - closed - visible to all members of this organization.
        # Default for child team: closed
        [Parameter()]
        [ValidateSet('secret', 'closed')]
        [string] $Privacy = 'closed',

        # The notification setting the team has chosen. The options are:
        # notifications_enabled - team members receive notifications when the team is @mentioned.
        # notifications_disabled - no one receives notifications.
        # Default: notifications_enabled
        [Parameter()]
        [ValidateSet('notifications_enabled', 'notifications_disabled')]
        [string] $NotificationSetting,

        # Closing down notice. The permission that new repositories will be added to the team with when none is specified.
        [Parameter()]
        [ValidateSet('pull', 'push')]
        [string] $Permission = 'pull',

        # The ID of a team to set as the parent team.
        [Parameter()]
        [int] $ParentTeamID,

        # The context to run the command in
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name DefaultContext)
    )

    $body = @{
        name                 = $Name
        description          = $Description
        maintainers          = $Maintainers
        repo_names           = $RepoNames
        privacy              = $Privacy
        notification_setting = $NotificationSetting
        permission           = $Permission
        parent_team_id       = $ParentTeamID
    }

    $body | Remove-HashtableEntry -NullOrEmptyValues

    $inputObject = @{
        Context     = $Context
        Method      = 'POST'
        Body        = $body
        APIEndpoint = "/orgs/$Organization/teams"
    }

    if ($PSCmdlet.ShouldProcess("'$Name' in '$Organization'", 'Create team')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [New-GitHubTeam] - Done"
#endregion - From [functions] - [public] - [Teams] - [New-GitHubTeam]
#region - From [functions] - [public] - [Teams] - [Remove-GitHubTeam]
Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Remove-GitHubTeam] - Importing"

function Remove-GitHubTeam {
    <#
        .SYNOPSIS
        Delete a team

        .DESCRIPTION
        To delete a team, the authenticated user must be an organization owner or team maintainer.
        If you are an organization owner, deleting a parent team will delete all of its child teams as well.

        .EXAMPLE
        Remove-GitHubTeam -Organization 'github' -Name 'team-name'

        .NOTES
        [Delete a team](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#delete-a-team)
    #>

    [OutputType([void])]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('Org')]
        [string] $Organization,

        # The slug of the team name.
        [Parameter(Mandatory)]
        [Alias('Team', 'TeamName', 'slug', 'team_slug')]
        [string] $Name,

        # The context to run the command in
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name DefaultContext)
    )

    $inputObject = @{
        Context     = $Context
        Method      = 'Delete'
        APIEndpoint = "/orgs/$Organization/teams/$Name"
    }

    if ($PSCmdlet.ShouldProcess("$Organization/$Name", 'Delete')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Remove-GitHubTeam] - Done"
#endregion - From [functions] - [public] - [Teams] - [Remove-GitHubTeam]
#region - From [functions] - [public] - [Teams] - [Update-GitHubTeam]
Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Update-GitHubTeam] - Importing"

function Update-GitHubTeam {
    <#
        .SYNOPSIS
        Update a team

        .DESCRIPTION
        To edit a team, the authenticated user must either be an organization owner or a team maintainer.

        .EXAMPLE
        $params = @{
            Organization = 'github'
            Name = 'team-name'
            NewName = 'new-team-name'
            Description = 'A new team'
            Privacy = 'closed'
            NotificationSetting = 'notifications_enabled'
            Permission = 'pull'
            ParentTeamID = 123456
        }
        Update-GitHubTeam @params

        .NOTES
        [Update a team](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#update-a-team)
    #>

    [OutputType([pscustomobject])]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The organization name. The name is not case sensitive.
        [Parameter(Mandatory)]
        [Alias('Org')]
        [string] $Organization,

        # The slug of the team name.
        [Parameter(Mandatory)]
        [Alias('Team', 'TeamName', 'slug', 'team_slug')]
        [string] $Name,

        # The new team name.
        [Parameter()]
        [Alias()]
        [string] $NewName,

        # The description of the team.
        [Parameter()]
        [string] $Description,

        # The level of privacy this team should have. The options are:
        # For a non-nested team:
        # - secret - only visible to organization owners and members of this team.
        # - closed - visible to all members of this organization.
        # Default: secret
        # For a parent or child team:
        # - closed - visible to all members of this organization.
        # Default for child team: closed
        [Parameter()]
        [ValidateSet('secret', 'closed')]
        [string] $Privacy = 'closed',

        # The notification setting the team has chosen. The options are:
        # notifications_enabled - team members receive notifications when the team is @mentioned.
        # notifications_disabled - no one receives notifications.
        # Default: notifications_enabled
        [Parameter()]
        [ValidateSet('notifications_enabled', 'notifications_disabled')]
        [string] $NotificationSetting,

        # Closing down notice. The permission that new repositories will be added to the team with when none is specified.
        [Parameter()]
        [ValidateSet('pull', 'push')]
        [string] $Permission = 'pull',

        # The ID of a team to set as the parent team.
        [Parameter()]
        [int] $ParentTeamID,

        # The context to run the command in
        [Parameter()]
        [string] $Context = (Get-GitHubConfig -Name DefaultContext)
    )

    $body = @{
        name                 = $NewName
        description          = $Description
        privacy              = $Privacy
        notification_setting = $NotificationSetting
        permission           = $Permission
        parent_team_id       = $ParentTeamID
    }

    $body | Remove-HashtableEntry -NullOrEmptyValues

    $inputObject = @{
        Context     = $Context
        Method      = 'Patch'
        APIEndpoint = "/orgs/$Organization/teams/$Name"
        Body        = $body
    }

    if ($PSCmdlet.ShouldProcess("$Organization/$Name", 'Update')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - [Update-GitHubTeam] - Done"
#endregion - From [functions] - [public] - [Teams] - [Update-GitHubTeam]

Write-Verbose "[$scriptName] - [functions] - [public] - [Teams] - Done"
#endregion - From [functions] - [public] - [Teams]

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

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

#region - From [functions] - [public] - [Users] - [Blocking] - [Block-GitHubUser]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Block-GitHubUser] - 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
        [Block a user](https://docs.github.com/rest/users/blocking#block-a-user)
        [Block a user from an organization](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')]
        [string] $OrganizationName
    )

    if ($OrganizationName) {
        Block-GitHubUserByOrganization -OrganizationName $OrganizationName -Username $Username
    } else {
        Block-GitHubUserByUser -Username $Username
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Block-GitHubUser] - Done"
#endregion - From [functions] - [public] - [Users] - [Blocking] - [Block-GitHubUser]
#region - From [functions] - [public] - [Users] - [Blocking] - [Get-GitHubBlockedUser]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Get-GitHubBlockedUser] - 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
        [List users blocked by the authenticated user](https://docs.github.com/rest/users/blocking#list-users-blocked-by-the-authenticated-user)
        [List users blocked by an organization](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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

    if ($OrganizationName) {
        Get-GitHubBlockedUserByOrganization -OrganizationName $OrganizationName -PerPage $PerPage
    } else {
        Get-GitHubBlockedUserByUser -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Get-GitHubBlockedUser] - Done"
#endregion - From [functions] - [public] - [Users] - [Blocking] - [Get-GitHubBlockedUser]
#region - From [functions] - [public] - [Users] - [Blocking] - [Test-GitHubBlockedUser]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Test-GitHubBlockedUser] - 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
        [Check if a user is blocked by the authenticated user](https://docs.github.com/rest/users/blocking#check-if-a-user-is-blocked-by-the-authenticated-user)
        [Check if a user is blocked by an organization](https://docs.github.com/rest/orgs/blocking#check-if-a-user-is-blocked-by-an-organization)
    #>

    [OutputType([bool])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [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')]
        [string] $OrganizationName,

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

    if ($OrganizationName) {
        Test-GitHubBlockedUserByOrganization -OrganizationName $OrganizationName -Username $Username -PerPage $PerPage
    } else {
        Test-GitHubBlockedUserByUser -Username $Username -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Test-GitHubBlockedUser] - Done"
#endregion - From [functions] - [public] - [Users] - [Blocking] - [Test-GitHubBlockedUser]
#region - From [functions] - [public] - [Users] - [Blocking] - [Unblock-GitHubUser]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Unblock-GitHubUser] - 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
        [Unblock a user](https://docs.github.com/rest/users/blocking#unblock-a-user)
        [Unblock a user from an organization](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')]
        [string] $OrganizationName
    )

    if ($OrganizationName) {
        Unblock-GitHubUserByOrganization -OrganizationName $OrganizationName -Username $Username
    } else {
        Unblock-GitHubUserByUser -Username $Username
    }
}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - [Unblock-GitHubUser] - Done"
#endregion - From [functions] - [public] - [Users] - [Blocking] - [Unblock-GitHubUser]

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Blocking] - Done"
#endregion - From [functions] - [public] - [Users] - [Blocking]

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

#region - From [functions] - [public] - [Users] - [Emails] - [Add-GitHubUserEmail]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Add-GitHubUserEmail] - 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
        [Add an email address for the authenticated user](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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Add-GitHubUserEmail] - Done"
#endregion - From [functions] - [public] - [Users] - [Emails] - [Add-GitHubUserEmail]
#region - From [functions] - [public] - [Users] - [Emails] - [Get-GitHubUserEmail]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Get-GitHubUserEmail] - 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
        [List email addresses for the authenticated user](https://docs.github.com/rest/users/emails#list-email-addresses-for-the-authenticated-user)
        [List public email addresses for the authenticated user](https://docs.github.com/en/rest/users/emails#list-public-email-addresses-for-the-authenticated-user)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [CmdletBinding()]
    param (
        # The number of results per page (max 100).
        [Parameter()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30,

        [Parameter()]
        [switch] $Public
    )

    if ($Public) {
        Get-GitHubUserPublicEmail -PerPage $PerPage
    } else {
        Get-GitHubUserAllEmail -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Get-GitHubUserEmail] - Done"
#endregion - From [functions] - [public] - [Users] - [Emails] - [Get-GitHubUserEmail]
#region - From [functions] - [public] - [Users] - [Emails] - [Remove-GitHubUserEmail]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Remove-GitHubUserEmail] - 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
        [Delete an email address for the authenticated user](https://docs.github.com/rest/users/emails#delete-an-email-address-for-the-authenticated-user)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [CmdletBinding(SupportsShouldProcess)]
    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
    }

    if ($PSCmdlet.ShouldProcess("Email addresses [$($Emails -join ', ')]", 'Delete')) {
        $null = Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Remove-GitHubUserEmail] - Done"
#endregion - From [functions] - [public] - [Users] - [Emails] - [Remove-GitHubUserEmail]
#region - From [functions] - [public] - [Users] - [Emails] - [Set-GitHubUserEmailVisibility]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Set-GitHubUserEmailVisibility] - 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
        [Set primary email visibility for the authenticated user](https://docs.github.com/rest/users/emails#set-primary-email-visibility-for-the-authenticated-user)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [CmdletBinding(SupportsShouldProcess)]
    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
    }

    if ($PSCmdlet.ShouldProcess("Email visibility [$Visibility]", 'Set')) {
        $null = Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - [Set-GitHubUserEmailVisibility] - Done"
#endregion - From [functions] - [public] - [Users] - [Emails] - [Set-GitHubUserEmailVisibility]

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Emails] - Done"
#endregion - From [functions] - [public] - [Users] - [Emails]

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

#region - From [functions] - [public] - [Users] - [Followers] - [Add-GitHubUserFollowing]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Add-GitHubUserFollowing] - 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
        [Follow a user](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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Add-GitHubUserFollowing] - Done"
#endregion - From [functions] - [public] - [Users] - [Followers] - [Add-GitHubUserFollowing]
#region - From [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollower]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollower] - Importing"

filter Get-GitHubUserFollower {
    <#
        .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-GitHubUserFollower

        Gets all followers of the authenticated user.

        .EXAMPLE
        Get-GitHubUserFollower -Username 'octocat'

        Gets all followers of the user 'octocat'.

        .NOTES
        [List followers of the authenticated user](https://docs.github.com/rest/users/followers#list-followers-of-the-authenticated-user)
    #>

    [OutputType([pscustomobject])]
    [Alias('Get-GitHubUserMyFollowers')]
    [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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

    if ($Username) {
        Get-GitHubUserFollowersOfUser -Username $Username -PerPage $PerPage
    } else {
        Get-GitHubUserMyFollowers -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollower] - Done"
#endregion - From [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollower]
#region - From [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollowing]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollowing] - 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
        [List the people the authenticated user follows](https://docs.github.com/rest/users/followers#list-the-people-the-authenticated-user-follows)
        [List the people a 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()]
        [ValidateRange(1, 100)]
        [int] $PerPage = 30
    )

    if ($Username) {
        Get-GitHubUserFollowingUser -Username $Username -PerPage $PerPage
    } else {
        Get-GitHubUserFollowingMe -PerPage $PerPage
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollowing] - Done"
#endregion - From [functions] - [public] - [Users] - [Followers] - [Get-GitHubUserFollowing]
#region - From [functions] - [public] - [Users] - [Followers] - [Remove-GitHubUserFollowing]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Remove-GitHubUserFollowing] - 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
        [Unfollow a user](https://docs.github.com/rest/users/followers#unfollow-a-user)
    #>

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

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

    if ($PSCmdlet.ShouldProcess("User [$Username]", 'Unfollow')) {
        $null = Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Remove-GitHubUserFollowing] - Done"
#endregion - From [functions] - [public] - [Users] - [Followers] - [Remove-GitHubUserFollowing]
#region - From [functions] - [public] - [Users] - [Followers] - [Test-GitHubUserFollowing]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - [Test-GitHubUserFollowing] - Importing"

filter Test-GitHubUserFollowing {
    <#
        .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-GitHubUserFollowing -Follows 'octocat'
        Test-GitHubUserFollowing 'octocat'

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

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

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

        .NOTES
        [Check if a person is followed by the authenticated user](https://docs.github.com/rest/users/followers#check-if-a-person-is-followed-by-the-authenticated-user)
        [Check if a user follows another user](https://docs.github.com/rest/users/followers#check-if-a-user-follows-another-user)

    #>

    [OutputType([bool])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [Alias('Test-GitHubUserFollows')]
    [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] - [functions] - [public] - [Users] - [Followers] - [Test-GitHubUserFollowing] - Done"
#endregion - From [functions] - [public] - [Users] - [Followers] - [Test-GitHubUserFollowing]

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Followers] - Done"
#endregion - From [functions] - [public] - [Users] - [Followers]

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

#region - From [functions] - [public] - [Users] - [GPG-Keys] - [Add-GitHubUserGpgKey]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Add-GitHubUserGpgKey] - 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-----
        Version: GnuPG v1

        mQINBFnZ2ZIBEADQ2Z7Z7
        -----END PGP PUBLIC KEY BLOCK-----
        '@

        Adds a GPG key to the authenticated user's GitHub account.

        .NOTES
        [Create a GPG key for the authenticated user](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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Add-GitHubUserGpgKey] - Done"
#endregion - From [functions] - [public] - [Users] - [GPG-Keys] - [Add-GitHubUserGpgKey]
#region - From [functions] - [public] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKey]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKey] - 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
        [List GPG keys for the authenticated user](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()]
        [ValidateRange(1, 100)]
        [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] - [functions] - [public] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKey] - Done"
#endregion - From [functions] - [public] - [Users] - [GPG-Keys] - [Get-GitHubUserGpgKey]
#region - From [functions] - [public] - [Users] - [GPG-Keys] - [Remove-GitHubUserGpgKey]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Remove-GitHubUserGpgKey] - 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
        [Delete a GPG key for the authenticated user](https://docs.github.com/rest/users/gpg-keys#delete-a-gpg-key-for-the-authenticated-user)

    #>

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

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

    if ($PSCmdlet.ShouldProcess("GPG key with ID [$ID]", 'Delete')) {
        $null = Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - [Remove-GitHubUserGpgKey] - Done"
#endregion - From [functions] - [public] - [Users] - [GPG-Keys] - [Remove-GitHubUserGpgKey]

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [GPG-Keys] - Done"
#endregion - From [functions] - [public] - [Users] - [GPG-Keys]

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

#region - From [functions] - [public] - [Users] - [Keys] - [Add-GitHubUserKey]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Add-GitHubUserKey] - 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
        [Create a public SSH key for the authenticated user](https://docs.github.com/rest/users/keys#create-a-public-ssh-key-for-the-authenticated-user)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links for documentation.')]
    [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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Add-GitHubUserKey] - Done"
#endregion - From [functions] - [public] - [Users] - [Keys] - [Add-GitHubUserKey]
#region - From [functions] - [public] - [Users] - [Keys] - [Get-GitHubUserKey]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Get-GitHubUserKey] - 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
        [List GPG keys for the authenticated user](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()]
        [ValidateRange(1, 100)]
        [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] - [functions] - [public] - [Users] - [Keys] - [Get-GitHubUserKey] - Done"
#endregion - From [functions] - [public] - [Users] - [Keys] - [Get-GitHubUserKey]
#region - From [functions] - [public] - [Users] - [Keys] - [Remove-GitHubUserKey]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Remove-GitHubUserKey] - 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
        [Delete a public SSH key for the authenticated user](https://docs.github.com/rest/users/keys#delete-a-public-ssh-key-for-the-authenticated-user)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [CmdletBinding(SupportsShouldProcess)]
    param (
        # The unique identifier of the key.
        [Parameter(
            Mandatory
        )]
        [Alias('key_id')]
        [string] $ID
    )

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

    if ($PSCmdlet.ShouldProcess("Key with ID [$ID]", 'Delete')) {
        $null = Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - [Remove-GitHubUserKey] - Done"
#endregion - From [functions] - [public] - [Users] - [Keys] - [Remove-GitHubUserKey]

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Keys] - Done"
#endregion - From [functions] - [public] - [Users] - [Keys]

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

#region - From [functions] - [public] - [Users] - [Social-Accounts] - [Add-GitHubUserSocial]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - [Add-GitHubUserSocial] - Importing"

filter Add-GitHubUserSocial {
    <#
        .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-GitHubUserSocial -AccountUrls 'https://twitter.com/MyTwitterAccount', 'https://www.linkedin.com/company/MyCompany'

        Adds the Twitter and LinkedIn accounts to the authenticated user's profile.

        .NOTES
        [Add social accounts for the authenticated user](https://docs.github.com/rest/users/social-accounts#add-social-accounts-for-the-authenticated-user)
    #>

    [OutputType([void])]
    [Alias('Add-GitHubUserSocials')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links for documentation.')]
    [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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - [Add-GitHubUserSocial] - Done"
#endregion - From [functions] - [public] - [Users] - [Social-Accounts] - [Add-GitHubUserSocial]
#region - From [functions] - [public] - [Users] - [Social-Accounts] - [Remove-GitHubUserSocial]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - [Remove-GitHubUserSocial] - Importing"

filter Remove-GitHubUserSocial {
    <#
        .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-GitHubUserSocial -AccountUrls 'https://twitter.com/MyTwitterAccount'

        .NOTES
        [Delete social accounts for the authenticated user](https://docs.github.com/rest/users/social-accounts#delete-social-accounts-for-the-authenticated-user)
    #>

    [OutputType([void])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [Alias('Remove-GitHubUserSocials')]
    [CmdletBinding(SupportsShouldProcess)]
    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'
    }

    if ($PSCmdlet.ShouldProcess("Social accounts [$($AccountUrls -join ', ')]", 'Delete')) {
        $null = Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - [Remove-GitHubUserSocial] - Done"
#endregion - From [functions] - [public] - [Users] - [Social-Accounts] - [Remove-GitHubUserSocial]

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Social-Accounts] - Done"
#endregion - From [functions] - [public] - [Users] - [Social-Accounts]

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

#region - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Add-GitHubUserSigningKey]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Add-GitHubUserSigningKey] - 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
        [Create a SSH signing key for the authenticated user](https://docs.github.com/rest/users/ssh-signing-keys#create-a-ssh-signing-key-for-the-authenticated-user)

    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Long links for documentation.')]
    [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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Add-GitHubUserSigningKey] - Done"
#endregion - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Add-GitHubUserSigningKey]
#region - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKey]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKey] - 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
        [List SSH signing keys for the authenticated user](https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-the-authenticated-user)
        [Get an SSH signing key for the authenticated user](https://docs.github.com/rest/users/ssh-signing-keys#get-an-ssh-signing-key-for-the-authenticated-user)
        [List SSH signing keys for a user](https://docs.github.com/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-a-user)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [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()]
        [ValidateRange(1, 100)]
        [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] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKey] - Done"
#endregion - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Get-GitHubUserSigningKey]
#region - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Remove-GitHubUserSigningKey]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Remove-GitHubUserSigningKey] - 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
        [Delete an SSH signing key for the authenticated user](https://docs.github.com/rest/users/ssh-signing-keys#delete-an-ssh-signing-key-for-the-authenticated-user)

    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidLongLines', '', Justification = 'Contains a long link.')]
    [CmdletBinding(SupportsShouldProcess)]
    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'
    }

    if ($PSCmdlet.ShouldProcess("SSH signing key with ID [$ID]", 'Delete')) {
        $null = Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Remove-GitHubUserSigningKey] - Done"
#endregion - From [functions] - [public] - [Users] - [SSH-Signing-Keys] - [Remove-GitHubUserSigningKey]

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

#region - From [functions] - [public] - [Users] - [Get-GitHubUser]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Get-GitHubUser] - 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
        [Get the authenticated user](https://docs.github.com/rest/users/users)
    #>

    [OutputType([pscustomobject])]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSReviewUnusedParameter',
        'All',
        Justification = 'Parameter is used in dynamic parameter validation.'
    )]
    [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')]
        [ValidateRange(1, 100)]
        [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] - [functions] - [public] - [Users] - [Get-GitHubUser] - Done"
#endregion - From [functions] - [public] - [Users] - [Get-GitHubUser]
#region - From [functions] - [public] - [Users] - [Get-GitHubUserCard]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Get-GitHubUserCard] - 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
        [Get contextual information for a user](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 | ForEach-Object {
        Write-Output $_.Response
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Get-GitHubUserCard] - Done"
#endregion - From [functions] - [public] - [Users] - [Get-GitHubUserCard]
#region - From [functions] - [public] - [Users] - [Set-GitHubUser]
Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Set-GitHubUser] - 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
        [Update the authenticated user](https://docs.github.com/rest/users/users#update-the-authenticated-user)
    #>

    [OutputType([void])]
    [Alias('Update-GitHubUser')]
    [CmdletBinding(SupportsShouldProcess)]
    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'
    }

    if ($PSCmdlet.ShouldProcess('authenticated user', 'Set')) {
        Invoke-GitHubAPI @inputObject | ForEach-Object {
            Write-Output $_.Response
        }
    }

}

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - [Set-GitHubUser] - Done"
#endregion - From [functions] - [public] - [Users] - [Set-GitHubUser]

Write-Verbose "[$scriptName] - [functions] - [public] - [Users] - Done"
#endregion - From [functions] - [public] - [Users]


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

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

#region - From [variables] - [private] - [Auth]
Write-Verbose "[$scriptName] - [variables] - [private] - [Auth] - Importing"

$script:Auth = @{
    GitHubApp                     = @{
        ClientID = 'Iv1.f26b61bc99e69405' # $script:Auth.GitHubApp.ClientID #gitleaks:allow
    }
    OAuthApp                      = @{
        ClientID = '7204ae9b0580f2cb8288' # $script:Auth.OAuthApp.ClientID #gitleaks:allow
    }
    AccessTokenGracePeriodInHours = 4
}

Write-Verbose "[$scriptName] - [variables] - [private] - [Auth] - Done"
#endregion - From [variables] - [private] - [Auth]
#region - From [variables] - [private] - [Config]
Write-Verbose "[$scriptName] - [variables] - [private] - [Config] - Importing"

$script:Config = @{
    Name = 'PSModule.GitHub' # $script:Config.Name
}

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

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

#region - From [completers]
Write-Verbose "[$scriptName] - [completers] - Importing"

Register-ArgumentCompleter -ParameterName Context -ScriptBlock {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
    $null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter

    $contexts = Get-GitHubContext -ListAvailable -Verbose:$false | Where-Object { "$($_.HostName)/$($_.UserName)" -like "$wordToComplete*" }

    $contexts | ForEach-Object {
        $contextID = "$($_.HostName)/$($_.UserName)"
        [System.Management.Automation.CompletionResult]::new($contextID, $contextID, 'ParameterValue', $contextID)
    }
}
Write-Verbose "[$scriptName] - [completers] - Done"
#endregion - From [completers]

#region - From [loader]
Write-Verbose "[$scriptName] - [loader] - Importing"

$scriptFilePath = $MyInvocation.MyCommand.Path
Write-Verbose "Initializing GitHub PowerShell module..."
Write-Verbose "Path: $scriptFilePath"

if ($env:GITHUB_ACTIONS -eq 'true') {
    Write-Verbose 'Detected running on a GitHub Actions runner, preparing environment...'
    $env:GITHUB_REPOSITORY_NAME = $env:GITHUB_REPOSITORY -replace '.+/'
    Set-GitHubEnv -Name 'GITHUB_REPOSITORY_NAME' -Value $env:GITHUB_REPOSITORY_NAME
}

### This is the context for this module
# Get current module context
$context = (Get-Context -ID $script:Config.Name)
if (-not $context) {
    Write-Verbose 'No context found, creating a new context...'
    Set-Context -ID $script:Config.Name -Context @{ Name = 'GitHub' }
}
Write-Verbose "[$scriptName] - [loader] - Done"
#endregion - From [loader]

# Get the internal TypeAccelerators class to use its static methods.
$TypeAcceleratorsClass = [psobject].Assembly.GetType(
    'System.Management.Automation.TypeAccelerators'
)
# Ensure none of the types would clobber an existing type accelerator.
# If a type accelerator with the same name exists, throw an exception.
$ExistingTypeAccelerators = $TypeAcceleratorsClass::Get
# Define the types to export with type accelerators.
$ExportableEnums = @(
)
$ExportableEnums | Foreach-Object { Write-Verbose "Exporting enum '$($_.FullName)'." }
foreach ($Type in $ExportableEnums) {
    if ($Type.FullName -in $ExistingTypeAccelerators.Keys) {
        Write-Warning "Enum already exists [$($Type.FullName)]. Skipping."
    } else {
        Write-Verbose "Importing enum '$Type'."
        $TypeAcceleratorsClass::Add($Type.FullName, $Type)
    }
}
$ExportableClasses = @(
    [GitHubContext]
)
$ExportableClasses | Foreach-Object { Write-Verbose "Exporting class '$($_.FullName)'." }
foreach ($Type in $ExportableClasses) {
    if ($Type.FullName -in $ExistingTypeAccelerators.Keys) {
        Write-Warning "Class already exists [$($Type.FullName)]. Skipping."
    } else {
        Write-Verbose "Importing class '$Type'."
        $TypeAcceleratorsClass::Add($Type.FullName, $Type)
    }
}

# Remove type accelerators when the module is removed.
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
    foreach ($Type in ($ExportableEnums + $ExportableClasses)) {
        $TypeAcceleratorsClass::Remove($Type.FullName)
    }
}.GetNewClosure()
$exports = @{
    Alias    = '*'
    Cmdlet   = ''
    Function = @(
        'Disable-GitHubWorkflow'
        'Enable-GitHubWorkflow'
        'Get-GitHubWorkflow'
        'Get-GitHubWorkflowRun'
        'Get-GitHubWorkflowUsage'
        'Remove-GitHubWorkflowRun'
        'Start-GitHubWorkflow'
        'Start-GitHubWorkflowReRun'
        'Stop-GitHubWorkflowRun'
        'Invoke-GitHubAPI'
        'Get-GitHubApp'
        'Get-GitHubAppInstallation'
        'Get-GitHubAppJSONWebToken'
        'New-GitHubAppInstallationAccessToken'
        'Get-GitHubContext'
        'Remove-GitHubContext'
        'Set-GitHubContext'
        'Set-GitHubDefaultContext'
        'Get-GitHubContextSetting'
        'Set-GitHubContextSetting'
        'Connect-GitHubAccount'
        'Disconnect-GitHubAccount'
        'Get-GitHubViewer'
        'Get-GitHubRepoBranch'
        'Add-GitHubMask'
        'Add-GitHubSystemPath'
        'Disable-GitHubCommand'
        'Enable-GitHubCommand'
        'Set-GitHubEnvironmentVariable'
        'Set-GitHubLogGroup'
        'Set-GitHubNoCommandGroup'
        'Set-GitHubOutput'
        'Set-GitHubStepSummary'
        'Start-GitHubLogGroup'
        'Stop-GitHubLogGroup'
        'Write-GitHubDebug'
        'Write-GitHubError'
        'Write-GitHubNotice'
        'Write-GitHubWarning'
        'Get-GitHubConfig'
        'Remove-GitHubConfig'
        'Set-GitHubConfig'
        'Get-GitHubEmoji'
        'Get-GitHubEnterpriseInstallableOrganization'
        'Get-GitHubEnterpriseOrganization'
        'Install-GitHubAppOnEnterpriseOrganization'
        'Get-GitHubGitignore'
        'Invoke-GitHubGraphQLQuery'
        'Get-GitHubLicense'
        'Get-GitHubMarkdown'
        'Get-GitHubMarkdownRaw'
        'Get-GitHubApiVersion'
        'Get-GitHubMeta'
        'Get-GitHubOctocat'
        'Get-GitHubRoot'
        'Get-GitHubZen'
        'Get-GitHubOrganizationMember'
        'Get-GitHubOrganizationPendingInvitation'
        'New-GitHubOrganizationInvitation'
        '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-GitHubReleaseNote'
        'Remove-GitHubRelease'
        'Set-GitHubRelease'
        'Get-GitHubRepositoryAutolink'
        'New-GitHubRepositoryAutolink'
        'Remove-GitHubRepositoryAutolink'
        'Get-GitHubRepositoryCustomProperty'
        'Disable-GitHubRepositoryPrivateVulnerabilityReporting'
        'Disable-GitHubRepositorySecurityFix'
        'Disable-GitHubRepositoryVulnerabilityAlert'
        'Enable-GitHubRepositoryPrivateVulnerabilityReporting'
        'Enable-GitHubRepositorySecurityFix'
        'Enable-GitHubRepositoryVulnerabilityAlert'
        'Get-GitHubRepository'
        'Get-GitHubRepositoryActivity'
        'Get-GitHubRepositoryCodeownersError'
        'Get-GitHubRepositoryContributor'
        'Get-GitHubRepositoryFork'
        'Get-GitHubRepositoryLanguage'
        'Get-GitHubRepositorySecurityFix'
        'Get-GitHubRepositoryTag'
        'Get-GitHubRepositoryTeam'
        'Get-GitHubRepositoryTopic'
        'Move-GitHubRepository'
        'New-GitHubRepository'
        'Remove-GitHubRepository'
        'Set-GitHubRepositoryTopic'
        'Start-GitHubRepositoryEvent'
        'Test-GitHubRepositoryVulnerabilityAlert'
        'Update-GitHubRepository'
        'Get-GitHubRepositoryRuleSuite'
        'Get-GitHubRepositoryRuleSuiteById'
        'Get-GitHubRepositoryRuleSuiteList'
        'Get-GitHubRepositoryTagProtection'
        'New-GitHubRepositoryTagProtection'
        'Remove-GitHubRepositoryTagProtection'
        'Get-GitHubScheduledMaintenance'
        'Get-GitHubStatus'
        'Get-GitHubStatusComponent'
        'Get-GitHubStatusIncident'
        'Get-GitHubRepoTeam'
        'Get-GitHubTeamByName'
        'Get-GitHubTeamListByOrg'
        'New-GitHubTeam'
        'Remove-GitHubTeam'
        'Update-GitHubTeam'
        'Block-GitHubUser'
        'Get-GitHubBlockedUser'
        'Test-GitHubBlockedUser'
        'Unblock-GitHubUser'
        'Add-GitHubUserEmail'
        'Get-GitHubUserEmail'
        'Remove-GitHubUserEmail'
        'Set-GitHubUserEmailVisibility'
        'Add-GitHubUserFollowing'
        'Get-GitHubUserFollower'
        'Get-GitHubUserFollowing'
        'Remove-GitHubUserFollowing'
        'Test-GitHubUserFollowing'
        'Add-GitHubUserGpgKey'
        'Get-GitHubUserGpgKey'
        'Remove-GitHubUserGpgKey'
        'Add-GitHubUserKey'
        'Get-GitHubUserKey'
        'Remove-GitHubUserKey'
        'Add-GitHubUserSocial'
        'Remove-GitHubUserSocial'
        'Add-GitHubUserSigningKey'
        'Get-GitHubUserSigningKey'
        'Remove-GitHubUserSigningKey'
        'Get-GitHubUser'
        'Get-GitHubUserCard'
        'Set-GitHubUser'
    )
}
Export-ModuleMember @exports