Commands/PSAdapter/New-PSAdapter.ps1

function New-PSAdapter {
    <#
    .SYNOPSIS
        Creates a new PowerShell Adapter
    .DESCRIPTION
        Creates a new PowerShell Adapter.

        Adapters allow you to adapt anything into a PowerShell command.
    #>
    
    param(
    # The template name, or a command.
    [Parameter(ValueFromPipelineByPropertyName)]
    [ArgumentCompleter({
        param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) 
        $typeData = Get-TypeData -TypeName "PSAdapter.[ct]*"
        return $typeData.Members.Keys -match "$([Regex]::Escape($wordToComplete))"
    })]
    [PSObject]
    $Template = "DotNetAdapter",
    
    # Any arguments to pass to the template
    [Parameter(ValueFromPipelineByPropertyName)]
    [Alias('TemplateArguments','TemplateArgs')]
    [PSObject[]]
    $TemplateArgument = @(),

    # Any parameters to pass to the template
    [Parameter(ValueFromPipelineByPropertyName)]
    [Alias('TemplateParameters')]
    [Collections.IDictionary]
    $TemplateParameter = @{},

    # The namespace for the adapter.
    # If this is not provided, it will use the name of the current repository.
    [Parameter(ValueFromPipelineByPropertyName)]
    [string]
    $Namespace,

    # The output path for the adapter.
    [Parameter(ValueFromPipelineByPropertyName)]
    [string]
    $OutputPath
    )

    process {

        $templateSource = $null
        $foundTemplateCommands = @(
            if ($template -is [Management.Automation.CommandInfo] -or
                $template -is [ScriptBlock]) {
                $Template
            } else {
                $escapedName = [Regex]::Escape("$Template")

                foreach ($typeData in Get-TypeData -TypeName "PSAdapter.Template", "PSAdapter.Class") {
                    foreach ($foundKey in $typeData.Members.Keys -match "^$escapedName") {
                        if ($typeData.Members[$foundKey].RefeferencedMemberName) {
                            $foundKey = $typeData.Members[$foundKey].RefeferencedMemberName
                        }
        
                        if ($typeData.Members[$foundKey].Script) {
                            $typeData.Members[$foundKey].Script
                        }
                        elseif ($typeData.Members[$foundKey].GetterScript) {
                            $typeData.Members[$foundKey].GetterScript
                        } elseif ($typeData.Members[$foundKey].Value) {
                            $typeData.Members[$foundKey].Value
                        } else {
                            continue
                        }                        
                    }
                }
    
                $ExecutionContext.SessionState.InvokeCommand.GetCommands('*Template*','Function,Alias', $true) -match 'Adapter'
            }                        
        )

        if (-not $Namespace) {
            if ($env:GITHUB_REPOSITORY) {
                $Namespace = $env:GITHUB_REPOSITORY -replace '/', '.'
            } else {
                $Namespace = 'PSAdapter'
            }
        }

        $templateOutput = 
            foreach ($foundTemplateCommand in $foundTemplateCommands) {
                if ($foundTemplateCommand -is [string]) {
                    $foundTemplateCommand
                    continue
                }
                if ($TemplateParameter) {
                    if ($TemplateArgument) {
                        & $foundTemplateCommand @TemplateArgument @TemplateParameter
                    } else {
                        & $foundTemplateCommand @TemplateParameter
                    }
                }
                elseif ($TemplateArgument) {
                    & $foundTemplateCommand @TemplateArgument
                }
                else {
                    $foundTemplateCommand
                }
            }
                        
        $templateOutputAsScriptBlock = 
            try {
                if ($templateOutput -is [scriptblock]) {
                    $templateOutput
                } else {
                    [scriptblock]::Create($templateOutput)
                }
            } catch {
                $ex = $_                
                $null
            }

        $templateString = $templateOutput -join [Environment]::NewLine
        
        if ($templateOutputAsScriptBlock) {
            $foundTemplateClasses = $templateOutputAsScriptBlock.Ast.FindAll({param($ast) $ast -is [Management.Automation.Language.TypeDefinitionAst]}, $true)
            if ($foundTemplateClasses) {
                $templateString =
                    $foundTemplateClasses.Extent -as [string[]] -replace 
                        'PSAdapter', ($Namespace -replace '\.', '_') -join
                            [Environment]::NewLine
            }
        }
        
        $findCurrentNamespace = [Regex]::new("(?<!using\s+)(?<=namespace\s+)(?<Namespace>\S+)")

        $templateResult =
            if ($templateString -as [xml]) {
                $templateXml -as [xml]
            } else {                
                $templateString -replace $findCurrentNamespace, $Namespace
            }
        
        if ($OutputPath) {
            if ($templateResult -is [xml]) {
                $templateResult.Save($OutputPath)
                if ($?) {
                    Get-Item -Path $outputPath
                }
            } else {
                New-Item -Path $filePath -Force -Value $templateResult
            }            
        } else {
            $templateResult
        }
    }
}