Private/NC-Hlp.CoreMessage.ps1
|
#Requires -Version 5.0 using namespace System.Management.Automation # Nebula.Core: (Private) Custom Write Information =================================================================================================== # Script-scoped color map so it can be overridden at runtime # Foreground and Background are [ConsoleColor] values. # Background can be $null to preserve the current background color. Set-Variable -Name InfoColorMap -Scope Script -Force -Value ([ordered]@{ INFO = @{ Foreground = [ConsoleColor]::Gray; Background = $null } SUCCESS = @{ Foreground = [ConsoleColor]::Green; Background = $null } WARNING = @{ Foreground = [ConsoleColor]::Yellow; Background = $null } ERROR = @{ Foreground = [ConsoleColor]::Red; Background = $null } DEBUG = @{ Foreground = [ConsoleColor]::Cyan; Background = $null } VERBOSE = @{ Foreground = [ConsoleColor]::DarkGray; Background = $null } }) function Add-EmptyLine { <# .SYNOPSIS Inserts an empty row on console. .DESCRIPTION Shows an empty row on the console for better readability. .EXAMPLE Add-EmptyLine #> [CmdletBinding()] param( ) try { Write-Output "" } catch { # Ignore } } function Set-InfoColorMap { <# .SYNOPSIS Overrides one or more level color mappings. .DESCRIPTION Provide a hashtable where keys are levels (INFO, SUCCESS, WARNING, ERROR, DEBUG, VERBOSE) and values are hashtables with Foreground/Background [ConsoleColor] (Background can be $null). .EXAMPLE Set-InfoColorMap @{ WARNING = @{ Foreground = 'DarkYellow'; Background = $null } } #> [CmdletBinding()] param( [Parameter(Mandatory)] [hashtable]$Map ) foreach ($k in $Map.Keys) { if (-not $script:InfoColorMap.Contains($k)) { throw "Unknown level '$k'. Valid levels: $($script:InfoColorMap.Keys -join ', ')." } $entry = $Map[$k] if (-not ($entry -is [hashtable] -and $entry.ContainsKey('Foreground'))) { throw "Map for '$k' must contain at least a 'Foreground' key." } $fg = [ConsoleColor]::Parse([ConsoleColor], "$($entry.Foreground)") $bg = if ($entry.ContainsKey('Background') -and $null -ne $entry.Background) { [ConsoleColor]::Parse([ConsoleColor], "$($entry.Background)") } else { $null } $script:InfoColorMap[$k] = @{ Foreground = $fg; Background = $bg } } } function Write-NCMessage { <# .SYNOPSIS Writes messages to the Information stream with color and level tagging. .DESCRIPTION Honors $InformationPreference. Adds level-based color mapping and tags. If host coloring is not available, falls back to plain Write-Information. .PARAMETER Message Object to write (string or any object). Strings are prefixed with [LEVEL]. .PARAMETER Level One of: INFO, SUCCESS, WARNING, ERROR, DEBUG, VERBOSE. .PARAMETER NoNewline Do not append a newline when writing to host. .PARAMETER ForegroundColor Override level's foreground color. .PARAMETER BackgroundColor Override level's background color (use $null to keep current). .EXAMPLE Write-NCMessage "Processing complete" -Level SUCCESS .EXAMPLE Write-NCMessage "Low disk space" -Level WARNING -NoNewline .EXAMPLE Write-NCMessage "Custom color" -Level INFO -ForegroundColor Magenta #> [CmdletBinding()] param( [Parameter(Mandatory, Position = 0)] [Alias('MessageData')] [object]$Message, [ValidateSet('INFO', 'SUCCESS', 'WARNING', 'ERROR', 'DEBUG', 'VERBOSE')] [string]$Level = 'INFO', [switch]$NoNewline, [Nullable[ConsoleColor]]$ForegroundColor, [Nullable[ConsoleColor]]$BackgroundColor ) # Resolve colors: explicit overrides > map > host defaults $map = $script:InfoColorMap[$Level] $fg = if ($ForegroundColor.HasValue) { $ForegroundColor.Value } elseif ($map -and $map.Foreground) { $map.Foreground } else { $Host.UI.RawUI.ForegroundColor } $bg = if ($BackgroundColor.IsPresent) { $BackgroundColor.Value } elseif ($map -and $map.Background) { $map.Background } else { $Host.UI.RawUI.BackgroundColor } # Prepare message text: add [LEVEL] prefix for strings (keeps objects intact) $msgText = # if ($Message -is [string]) { "[{0}] {1}" -f $Level, $Message } if ($Message -is [string]) { "{0}" -f $Message } else { $Message } # Build HostInformationMessage. If the host doesn't support colors, these fields are ignored. $hostMsg = [HostInformationMessage]@{ Message = $msgText ForegroundColor = $fg BackgroundColor = $bg NoNewline = $NoNewline.IsPresent } # Pass level as a tag for filtering (Receive-Job, transcript parsers, etc.) Write-Information -MessageData $hostMsg -Tags $Level -InformationAction Continue } |