Sodium.psm1

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


if ($PSVersionTable.PSVersion -lt '6.0') {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSAvoidAssignmentToAutomaticVariable', '', Justification = 'Compatibility with PowerShell 6.0 and newer.'
    )]
    $IsWindows = [System.Environment]::OSVersion.Platform -eq 'Win32NT'
}

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

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

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

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

#region - From [init] - [initializer]
Write-Verbose "[$scriptName] - [init] - [initializer] - Importing"

Write-Verbose '-------------------------------'
Write-Verbose '--- THIS IS AN INITIALIZER ---'
Write-Verbose '-------------------------------'

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

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

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

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

class Function {
    $Name
    $Version

    PSModule ([string] $Name, [string] $Version) {
        $this.Name = $Name
        $this.Version = $Version
    }
}

Write-Verbose "[$scriptName] - [classes] - [Function] - Done"
#endregion - From [classes] - [Function]
#region - From [classes] - [PSModule]
Write-Verbose "[$scriptName] - [classes] - [PSModule] - Importing"

class PSModule {
    $Name
    $Version
    $Functions

    PSModule ([string] $Name, [string] $Version, [hashtable] $Functions) {
        $this.Name = $Name
        $this.Version = $Version
        $this.Functions = $Functions
    }
}

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

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

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

#region - From [private] - [Get-InternalPSModule]
Write-Verbose "[$scriptName] - [private] - [Get-InternalPSModule] - Importing"

function Get-InternalPSModule {
    <#
        .SYNOPSIS
        Performs tests on a module.

        .EXAMPLE
        Get-InternalPSModule -Name 'World'

        "Hello, World!"
    #>

    [CmdletBinding()]
    param (
        # Name of the person to greet.
        [Parameter(Mandatory)]
        [string] $Name
    )
    Write-Output "Hello, $Name!"
}

Write-Verbose "[$scriptName] - [private] - [Get-InternalPSModule] - Done"
#endregion - From [private] - [Get-InternalPSModule]
#region - From [private] - [Set-InternalPSModule]
Write-Verbose "[$scriptName] - [private] - [Set-InternalPSModule] - Importing"

function Set-InternalPSModule {
    <#
        .SYNOPSIS
        Performs tests on a module.

        .EXAMPLE
        Set-InternalPSModule -Name 'World'

        "Hello, World!"
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Reason for suppressing'
    )]
    [CmdletBinding()]
    param (
        # Name of the person to greet.
        [Parameter(Mandatory)]
        [string] $Name
    )
    Write-Output "Hello, $Name!"
}

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

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

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

#region - From [public] - [Get-PSModuleTemplate]
Write-Verbose "[$scriptName] - [public] - [Get-PSModuleTemplate] - Importing"

function Get-PSModuleTemplate {
    <#
        .SYNOPSIS
        Performs tests on a module.

        .EXAMPLE
        Get-PSModuleTemplate -Name 'World'

        "Hello, World!"
    #>

    [CmdletBinding()]
    param (
        # Name of the person to greet.
        [Parameter(Mandatory)]
        [string] $Name
    )
    Write-Output "Hello, $Name!"
}

Write-Verbose "[$scriptName] - [public] - [Get-PSModuleTemplate] - Done"
#endregion - From [public] - [Get-PSModuleTemplate]
#region - From [public] - [New-PSModuleTemplate]
Write-Verbose "[$scriptName] - [public] - [New-PSModuleTemplate] - Importing"

function New-PSModuleTemplate {
    <#
        .SYNOPSIS
        Performs tests on a module.

        .EXAMPLE
        New-PSModuleTemplate -Name 'World'

        "Hello, World!"
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Reason for suppressing'
    )]
    [CmdletBinding()]
    param (
        # Name of the person to greet.
        [Parameter(Mandatory)]
        [string] $Name
    )
    Write-Output "Hello, $Name!"
}

Write-Verbose "[$scriptName] - [public] - [New-PSModuleTemplate] - Done"
#endregion - From [public] - [New-PSModuleTemplate]
#region - From [public] - [Set-PSModuleTemplate]
Write-Verbose "[$scriptName] - [public] - [Set-PSModuleTemplate] - Importing"

function Set-PSModuleTemplate {
    <#
        .SYNOPSIS
        Performs tests on a module.

        .EXAMPLE
        Set-PSModuleTemplate -Name 'World'

        "Hello, World!"
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute(
        'PSUseShouldProcessForStateChangingFunctions', '', Scope = 'Function',
        Justification = 'Reason for suppressing'
    )]
    [CmdletBinding()]
    param (
        # Name of the person to greet.
        [Parameter(Mandatory)]
        [string] $Name
    )
    Write-Output "Hello, $Name!"
}

Write-Verbose "[$scriptName] - [public] - [Set-PSModuleTemplate] - Done"
#endregion - From [public] - [Set-PSModuleTemplate]
#region - From [public] - [Test-PSModuleTemplate]
Write-Verbose "[$scriptName] - [public] - [Test-PSModuleTemplate] - Importing"

function Test-PSModuleTemplate {
    <#
        .SYNOPSIS
        Performs tests on a module.

        .EXAMPLE
        Test-PSModuleTemplate -Name 'World'

        "Hello, World!"
    #>

    [CmdletBinding()]
    param (
        # Name of the person to greet.
        [Parameter(Mandatory)]
        [string] $Name
    )
    Write-Output "Hello, $Name!"
}

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

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

#region - From [finally]
Write-Verbose "[$scriptName] - [finally] - Importing"

Write-Verbose '------------------------------'
Write-Verbose '--- THIS IS A LAST LOADER ---'
Write-Verbose '------------------------------'
Write-Verbose "[$scriptName] - [finally] - Done"
#endregion - From [finally]

# 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 = @(
    [Function]
    [PSModule]
)
$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 = @(
        'Get-PSModuleTemplate'
        'New-PSModuleTemplate'
        'Set-PSModuleTemplate'
        'Test-PSModuleTemplate'
    )
    Variable = ''
}
Export-ModuleMember @exports