Public/New-PstFunction.ps1

function New-PstFunction {
    <#
.SYNOPSIS
    Creates a new PowerShell function from a template with configurable complexity levels.
.DESCRIPTION
    This function takes an approved verb and noun, copies a function template based on the specified
    complexity level, and renames the file and function block to the specified verb-noun combination.

    Complexity Levels:
    - Basic: Simple function with minimal structure (no error handling, basic parameters)
    - Moderate: Function with parameter validation, basic error handling, and help documentation
    - Complex: Full cmdlet features including begin/process/end blocks, pipeline support, ShouldProcess
.PARAMETER Verb
    (Required) The approved verb for the function name.
.PARAMETER Noun
    (Required) The noun for the function name.
.PARAMETER ComplexityLevel
    (Optional) The complexity level of the function template. Valid values: Basic, Moderate, Complex.
    Defaults to Complex for backward compatibility.
.PARAMETER Force
    (Optional) Forces creation even if file exists, useful in automation scenarios.
.EXAMPLE
    New-PstFunction -Verb Get -Noun Item
    Creates a new complex function file named Get-Item.ps1 with full cmdlet features.
.EXAMPLE
    New-PstFunction -Verb Get -Noun Item -ComplexityLevel Basic
    Creates a simple function with minimal structure for basic automation tasks.
.EXAMPLE
    New-PstFunction -Verb Set -Noun Configuration -ComplexityLevel Moderate
    Creates a moderately complex function with parameter validation and error handling.
.NOTES
    Ensure that the appropriate template files exist in the Resources/Samples directory.
    Template files: Function-Basic.ps1, Function-Moderate.ps1, Function-Complex.ps1
.LINK
    For more information on approved verbs, visit: https://docs.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands
#>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter(Mandatory = $true, Position = 0,
            HelpMessage = "The approved verb for the function name.")]
        [ValidateSet("Add", "Approve", "Assert", "Backup", "Block", "Checkpoint", "Clear", "Close", "Compare", "Complete", "Compress", "Confirm", "Connect", "Convert", "ConvertFrom", "ConvertTo", "Copy", "Debug", "Deny", "Disable", "Disconnect", "Dismount", "Edit", "Enable", "Enter", "Exit", "Expand", "Export", "Find", "Format", "Get", "Grant", "Group", "Hide", "Import", "Initialize", "Install", "Invoke", "Join", "Limit", "Lock", "Measure", "Merge", "Mount", "Move", "New", "Open", "Optimize", "Out", "Ping", "Pop", "Protect", "Publish", "Push", "Read", "Receive", "Redo", "Register", "Remove", "Rename", "Repair", "Request", "Reset", "Resize", "Resolve", "Restart", "Restore", "Resume", "Revoke", "Save", "Search", "Select", "Send", "Set", "Show", "Skip", "Split", "Start", "Step", "Stop", "Submit", "Suspend", "Switch", "Sync", "Test", "Trace", "Unblock", "Undo", "Uninstall", "Unlock", "Unprotect", "Unpublish", "Unregister", "Update", "Use", "Wait", "Watch", "Write")]
        [string]$Verb,

        [Parameter(Mandatory = $true, Position = 1,
            HelpMessage = "The noun for the function name.")]
        [ValidatePattern('^[A-Za-z][A-Za-z0-9]*$')]
        [string]$Noun,

        [Parameter(Mandatory = $false)]
        [ValidateSet("Basic", "Moderate", "Complex")]
        [string]$ComplexityLevel = "Complex",

        [Parameter(Mandatory = $false)]
        [switch]$Force
    )
    begin {
        Write-Debug -Message "Begin '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'"

        # Select template based on complexity level
        $templateFileName = switch ($ComplexityLevel) {
            "Basic"     { "Function-Basic.ps1" }
            "Moderate"  { "Function-Moderate.ps1" }
            "Complex"   { "Function-Complex.ps1" }
            default     { "Function-Complex.ps1" }  # Fallback to Complex
        }

        $templatePath = $Samples[$templateFileName]
        $newFunctionName = "$Verb-$Noun"
        $newFilePath = "$newFunctionName.ps1"

        Write-Verbose "Using complexity level: $ComplexityLevel"
        Write-Verbose "Selected template: $templateFileName"

        if (-not $templatePath) {
            throw "Template '$templateFileName' not found in Samples hashtable. Available templates: $($Samples.Keys -join ', ')"
        }
        if (-not (Test-Path $templatePath)) {
            throw "Template file not found: $templatePath"
        } else {
            Write-Verbose "Template file found: $templatePath"
        }
    }
    process {
        try {
            # Check if we're in automation mode - inline check to avoid scope issues
            $isAutomationMode = $Force -or
            ($Global:PstAutomationMode -eq $true) -or
            ($env:CI -eq 'true') -or
            ($env:GITHUB_ACTIONS -eq 'true') -or
            ($Host.Name -eq 'ServerRemoteHost') -or
            (-not [Environment]::UserInteractive) -or
            ($global:ConfirmPreference -eq 'None')
            # Check if file already exists
            if ((Test-Path $newFilePath) -and -not $isAutomationMode) {
                if (-not $PSCmdlet.ShouldProcess($newFilePath, "Overwrite existing function file")) {
                    Write-Warning "Operation cancelled by user."
                    return
                }
            }
            elseif ((Test-Path $newFilePath) -and $isAutomationMode -and -not $Force) {
                Write-Warning "File '$newFilePath' already exists. Use -Force to overwrite in automation mode."
                return
            }
            # Proceed with file creation - skip ShouldProcess in automation mode
            if ($isAutomationMode -or $PSCmdlet.ShouldProcess($newFilePath, "Create new function file")) {
                Write-Verbose "Getting file content from '$($templatePath)'"
                $templateContent = (Get-Content -Path $templatePath) -join "`n"
                Write-Verbose "Replacing '""Function Verb-Noun"" with ""Function $($newFunctionName)""' "
                $newContent = $templateContent -replace "Function Verb-Noun", "Function $newFunctionName"
                Write-Verbose "Set-Content to path '$($newFilePath)'"
                $newContent | Set-Content -Path $newFilePath
                Write-Output "New function file created: $newFilePath"
            }
            else {
                Write-Verbose "Operation cancelled or skipped."
            }
        }
        catch {
            if ($_.Exception -and $_.Exception.Message) {
                Write-Error "An error occurred: $($_.Exception.Message)"
            } else {
                Write-Error "An error occurred, but no additional information is available."
            }
        }
    }
    end {
        if ($?) {
            Write-Debug -Message "End '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'"
        }
    }
}