functions/public/New-KlippyGcodeFolder.ps1

function New-KlippyGcodeFolder {
    <#
    .SYNOPSIS
        Creates a new folder in the Klipper printer's gcodes directory.

    .DESCRIPTION
        Creates a new directory in the printer's gcodes storage.
        Supports creating nested paths (parent directories are created automatically).

    .PARAMETER Id
        The unique identifier of the printer.

    .PARAMETER PrinterName
        The friendly name of the printer.

    .PARAMETER InputObject
        A printer object from pipeline input.

    .PARAMETER Path
        The path of the folder to create (relative to gcodes root).

    .PARAMETER PassThru
        Return the created folder object.

    .EXAMPLE
        New-KlippyGcodeFolder -Path "test_prints"
        Creates a folder named "test_prints" on the default printer.

    .EXAMPLE
        New-KlippyGcodeFolder -PrinterName "voronv2" -Path "projects/benchy"
        Creates nested folder structure.

    .EXAMPLE
        Get-KlippyPrinter | New-KlippyGcodeFolder -Path "backup" -PassThru
        Creates folder on all printers and returns the folder objects.

    .OUTPUTS
        PSCustomObject with folder information (when -PassThru is used).
    #>

    [CmdletBinding(DefaultParameterSetName = 'Default', SupportsShouldProcess = $true)]
    [OutputType([PSCustomObject])]
    param(
        [Parameter(Mandatory = $true, ParameterSetName = 'ById')]
        [ValidateNotNullOrEmpty()]
        [string]$Id,

        [Parameter(Mandatory = $true, ParameterSetName = 'ByName')]
        [ValidateNotNullOrEmpty()]
        [string]$PrinterName,

        [Parameter(Mandatory = $true, ParameterSetName = 'ByObject', ValueFromPipeline = $true)]
        [PSCustomObject]$InputObject,

        [Parameter(Mandatory = $true, Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string]$Path,

        [Parameter()]
        [switch]$PassThru
    )

    process {
        # Resolve printer
        $resolveParams = @{}
        switch ($PSCmdlet.ParameterSetName) {
            'ById' { $resolveParams['Id'] = $Id }
            'ByName' { $resolveParams['PrinterName'] = $PrinterName }
            'ByObject' { $resolveParams['InputObject'] = $InputObject }
        }

        $printer = Resolve-KlippyPrinterTarget @resolveParams

        # Clean path
        $cleanPath = $Path.TrimStart('/').TrimEnd('/')

        if ($PSCmdlet.ShouldProcess("$($printer.PrinterName):gcodes/$cleanPath", "Create folder")) {
            try {
                Write-Verbose "[$($printer.PrinterName)] Creating folder: $cleanPath"

                # Create directory via POST request
                $response = Invoke-KlippyHttpRequest -Printer $printer -Endpoint "server/files/directory" -Method POST -QueryParameters @{
                    path = "gcodes/$cleanPath"
                }

                Write-Verbose "[$($printer.PrinterName)] Folder created successfully"

                if ($PassThru) {
                    # Return folder object
                    [PSCustomObject]@{
                        PSTypeName  = 'KlippyCLI.GcodeFolder'
                        PrinterId   = $printer.Id
                        PrinterName = $printer.PrinterName
                        Path        = $cleanPath
                        Name        = Split-Path $cleanPath -Leaf
                        Modified    = Get-Date
                    }
                }
            }
            catch {
                Write-Error "[$($printer.PrinterName)] Failed to create folder '$cleanPath': $_"
            }
        }
    }
}