GitHub.psm1

#region - From classes/Data/Config.ps1
$script:ConfigTemplate = [pscustomobject]@{
    App  = [pscustomobject]@{
        API      = [pscustomobject]@{
            BaseURI = 'https://api.github.com' # $script:ConfigTemplate.App.API.BaseURI
            Version = '2022-11-28'             # $script:ConfigTemplate.App.API.Version
        }
        Defaults = [pscustomobject]@{}         # $script:ConfigTemplate.App.Defaults
    }
}
$script:Config = $script:ConfigTemplate
#endregion - From classes/Data/Config.ps1

#region - From classes/Data/SecretVault.ps1
$script:SecretVault = [pscustomobject]@{
    Name = 'GitHub'                           # $script:SecretVault.Name
    Type = 'Microsoft.PowerShell.SecretStore' # $script:SecretVault.Type
}
$script:Secret = [pscustomobject]@{
    Name = 'Config'                           # $script:Secret.Name
}
#endregion - From classes/Data/SecretVault.ps1

#region - From private/Config/Initialize-SecretVault.ps1
#Requires -Version 7.0
#Requires -Modules Microsoft.PowerShell.SecretManagement
#Requires -Modules Microsoft.PowerShell.SecretStore

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

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

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

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

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

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

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

    $secretVault = Get-SecretVault | Where-Object { $_.ModuleName -eq $Type }
    $secretVaultExists = $secretVault.count -ne 0
    Write-Verbose "A $Name exists: $secretVaultExists"
    if (-not $secretVaultExists) {
        Write-Verbose "Registering [$Name]"

        switch ($Type) {
            'Microsoft.PowerShell.SecretStore' {
                $vaultParameters = @{
                    Authentication  = 'None'
                    PasswordTimeout = -1
                    Interaction     = 'None'
                    Scope           = 'CurrentUser'
                    WarningAction   = 'SilentlyContinue'
                    Confirm         = $false
                    Force           = $true
                }
                Reset-SecretStore @vaultParameters
            }
        }
    }

    $secretStore = Get-SecretVault | Where-Object { $_.Name -eq $Name }
    $secretStoreExists = $secretStore.count -ne 0
    if (-not $secretStoreExists) {
        $secretVault = @{
            Name         = $Name
            ModuleName   = $Type
            DefaultVault = $true
            Description  = 'SecretStore'
        }
        Register-SecretVault @secretVault
    }
}
#endregion - From private/Config/Initialize-SecretVault.ps1

#region - From public/loader.ps1
Initialize-SecretVault -Name $script:SecretVault.Name -Type $script:SecretVault.Type
Restore-GitHubConfig
#endregion - From public/loader.ps1

#region - From public/Config/Get-GitHubConfig.ps1
function Get-GitHubConfig {
    <#
        .SYNOPSIS
        Get the current GitHub configuration.

        .DESCRIPTION
        Get the current GitHub configuration.
        If the Refresh switch is used, the configuration will be refreshed from the configuration file.

        .EXAMPLE
        Get-GitHubConfig

        Returns the current GitHub configuration.

        .EXAMPLE
        Get-GitHubConfig -Refresh

        Refreshes the current GitHub configuration from the configuration store beofre returning it.
    #>

    [Alias('Get-GHConfig')]
    [OutputType([PSCustomObject])]
    [CmdletBinding()]
    param (
        # Refresh the configuration from the configuration store before returning it.
        [Parameter()]
        [switch] $Refresh
    )

    if ($Refresh) {
        Restore-GitHubConfig
    }

    $script:Config
}
#endregion - From public/Config/Get-GitHubConfig.ps1

#region - From public/Config/Reset-GitHubConfig.ps1
function Reset-GitHubConfig {
    <#
        .SYNOPSIS
        Reset the GitHub configuration.

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

        .EXAMPLE
        Reset-GitHubConfig

        Resets the entire GitHub configuration.

        .EXAMPLE
        Reset-GitHubConfig -Scope 'App.API'

        Resets the App.API scope of the GitHub configuration.
    #>

    [Alias('Reset-GHConfig')]
    [OutputType([void])]
    [CmdletBinding()]
    param(
        [Parameter()]
        [ValidateSet('App', 'App.API', 'App.Defaults', 'All')]
        [string] $Scope = 'All'
    )

    switch($Scope) {
        'App' {
            $script:Config.App = $script:ConfigTemplate.App
        }
        'App.API' {
            $script:Config.App.API = $script:ConfigTemplate.App.API
        }
        'App.Defaults' {
            $script:Config.App.Defaults = $script:ConfigTemplate.App.Defaults
        }
        'All' {
            $script:Config = $script:ConfigTemplateDefaults
        }
    }
    Save-GitHubConfig
}
#endregion - From public/Config/Reset-GitHubConfig.ps1

#region - From public/Config/Restore-GitHubConfig.ps1
#Requires -Version 7.0
#Requires -Modules Microsoft.PowerShell.SecretManagement

function Restore-GitHubConfig {
    <#
        .SYNOPSIS
        Restore the GitHub configuration from the configuration store.

        .DESCRIPTION
        Restore the GitHub configuration from the configuration store.

        .EXAMPLE
        Restore-GitHubConfig

        Restores the GitHub configuration from the configuration store.
    #>

    [Alias('Load-GitHubConfig')]
    [Alias('Load-GHConfig')]
    [Alias('Restore-GHConfig')]
    [OutputType([void])]
    [CmdletBinding()]
    param()

    $vault = Get-SecretVault -Name $script:SecretVault.Name
    $vaultExists = $vault.count -eq 1
    if ($vaultExists) {
        $secretExists = Get-SecretInfo -Name $script:Secret.Name -Vault $script:SecretVault.Name
        if ($secretExists) {
            $script:Config = Get-Secret -Name $script:Secret.Name -AsPlainText -Vault $script:SecretVault.Name | ConvertFrom-Json
        } else {
            Write-Warning "Unable to restore configuration."
            Write-Warning "The secret [$($script:Secret.Name)] does not exist in the vault [$($script:SecretVault.Name)]."
        }
    } else {
        Write-Warning "Unable to restore configuration."
        Write-Warning "The vault [$($script:SecretVault.Name)] does not exist."
    }
}
#endregion - From public/Config/Restore-GitHubConfig.ps1

#region - From public/Config/Save-GitHubConfig.ps1
#Requires -Version 7.0
#Requires -Modules Microsoft.PowerShell.SecretManagement

function Save-GitHubConfig {
    <#
        .SYNOPSIS
        Save the GitHub configuration to the configuration store.

        .DESCRIPTION
        Save the GitHub configuration to the configuration store.

        .EXAMPLE
        Save-GitHubConfig

        Saves the GitHub configuration to the configuration store.
    #>

    [Alias('Save-GHConfig')]
    [OutputType([void])]
    [CmdletBinding()]
    param()

    $config = $script:Config | ConvertTo-Json -Depth 100
    Set-Secret -Name $script:Secret.Name -Secret $config -Vault $script:SecretVault.Name
}
#endregion - From public/Config/Save-GitHubConfig.ps1

#region - From public/Config/Set-GitHubConfig.ps1
function Set-GitHubConfig {
    <#
        .SYNOPSIS
        Set the GitHub configuration.

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

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

        Sets the App.API scope of the GitHub configuration.
    #>

    [Alias('Set-GHConfig')]
    [CmdletBinding()]
    param (
        # Set the API Base URI.
        [Parameter()]
        [string] $APIBaseURI,

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

    switch ($PSBoundParameters.Keys) {
        'APIBaseURI' {
            $script:ConfigTemplate.App.API.BaseURI = $APIBaseURI
        }

        'APIVersion' {
            $script:ConfigTemplate.App.API.Version = $APIVersion
        }
    }
    Save-GitHubConfig
}
#endregion - From public/Config/Set-GitHubConfig.ps1

Export-ModuleMember -Function '' -Cmdlet '' -Variable '' -Alias '*'