modules/Core/ConfigurationCommands.psm1
|
# Configuration Commands Module # Provides runtime configuration commands for Spotify CLI live features # Import required modules $SimpleConfigManagerPath = Join-Path $PSScriptRoot "SimpleConfigurationManager.psm1" if (Test-Path $SimpleConfigManagerPath) { Import-Module $SimpleConfigManagerPath -Force -Global } function Initialize-ConfigurationManager { <# .SYNOPSIS Initialize the configuration manager instance #> Initialize-SimpleConfigurationManager } function ConvertTo-Hashtable { <# .SYNOPSIS Convert PSCustomObject to hashtable recursively #> param($InputObject) if ($InputObject -is [PSCustomObject]) { $hashtable = @{} foreach ($property in $InputObject.PSObject.Properties) { if ($property.Value -is [PSCustomObject]) { $hashtable[$property.Name] = ConvertTo-Hashtable -InputObject $property.Value } else { $hashtable[$property.Name] = $property.Value } } return $hashtable } else { return $InputObject } } function Get-LiveFeaturesConfig { <# .SYNOPSIS Get the current live features configuration .DESCRIPTION Retrieves the current configuration for all live features including display, lyrics, and statistics .PARAMETER Section Optional section name to retrieve only specific configuration section .PARAMETER Key Optional key name to retrieve only specific configuration value (requires Section) .EXAMPLE Get-LiveFeaturesConfig Gets the complete configuration .EXAMPLE Get-LiveFeaturesConfig -Section liveDisplay Gets only the live display configuration section .EXAMPLE Get-LiveFeaturesConfig -Section liveDisplay -Key refreshInterval Gets only the refresh interval value from live display section #> [CmdletBinding()] param( [string]$Section, [string]$Key ) Initialize-ConfigurationManager try { if ($Key -and -not $Section) { Write-Error "Key parameter requires Section parameter" return } if ($Key) { # Get specific key value $value = Get-SimpleConfigurationValue -Section $Section -Key $Key if ($null -eq $value) { Write-Warning "Configuration key '$Section.$Key' not found" return } Write-Host "Configuration: $Section.$Key" -ForegroundColor Cyan Write-Host "Value: $value" -ForegroundColor White return $value } elseif ($Section) { # Get specific section $sectionConfig = Get-SimpleConfigurationSection -Section $Section if ($sectionConfig.Count -eq 0) { Write-Warning "Configuration section '$Section' not found" return } Write-Host "Configuration Section: $Section" -ForegroundColor Cyan Write-Host "=" * (20 + $Section.Length) -ForegroundColor Cyan foreach ($key in $sectionConfig.Keys | Sort-Object) { $value = $sectionConfig[$key] $displayValue = if ($value -is [bool]) { if ($value) { "true" } else { "false" } } else { $value } Write-Host " $key : $displayValue" -ForegroundColor White } return $sectionConfig } else { # Get complete configuration $config = Get-SimpleConfiguration Write-Host "Spotify CLI Live Features Configuration" -ForegroundColor Cyan Write-Host "=======================================" -ForegroundColor Cyan Write-Host "" foreach ($sectionName in $config.Keys | Sort-Object) { if ($sectionName -eq '_metadata') { continue } Write-Host "[$sectionName]" -ForegroundColor Yellow foreach ($key in $config[$sectionName].Keys | Sort-Object) { $value = $config[$sectionName][$key] $displayValue = if ($value -is [bool]) { if ($value) { "true" } else { "false" } } else { $value } Write-Host " $key = $displayValue" -ForegroundColor White } Write-Host "" } # Show configuration info $info = Get-SimpleConfigurationInfo Write-Host "Configuration Info:" -ForegroundColor Gray Write-Host " File: $($info.ConfigurationFile)" -ForegroundColor Gray Write-Host " Loaded: $($info.IsLoaded)" -ForegroundColor Gray Write-Host " Has Customizations: $($info.HasCustomizations)" -ForegroundColor Gray if ($info.LastModified) { Write-Host " Last Modified: $($info.LastModified)" -ForegroundColor Gray } return $config } } catch { Write-Error "Failed to get configuration: $($_.Exception.Message)" } } function Set-LiveFeaturesConfig { <# .SYNOPSIS Set live features configuration values .DESCRIPTION Sets configuration values for live features with validation .PARAMETER Section Configuration section name .PARAMETER Key Configuration key name .PARAMETER Value Configuration value to set .PARAMETER SectionConfig Hashtable containing multiple key-value pairs for a section .EXAMPLE Set-LiveFeaturesConfig -Section liveDisplay -Key refreshInterval -Value 2000 Sets the refresh interval to 2000ms .EXAMPLE Set-LiveFeaturesConfig -Section liveDisplay -SectionConfig @{refreshInterval=1500; displayMode="compact"} Sets multiple values in the liveDisplay section #> [CmdletBinding(DefaultParameterSetName = "SingleValue")] param( [Parameter(Mandatory, ParameterSetName = "SingleValue")] [Parameter(Mandatory, ParameterSetName = "SectionConfig")] [string]$Section, [Parameter(Mandatory, ParameterSetName = "SingleValue")] [string]$Key, [Parameter(Mandatory, ParameterSetName = "SingleValue")] $Value, [Parameter(Mandatory, ParameterSetName = "SectionConfig")] [hashtable]$SectionConfig ) Initialize-ConfigurationManager try { if ($PSCmdlet.ParameterSetName -eq "SingleValue") { # Set single value Set-SimpleConfigurationValue -Section $Section -Key $Key -Value $Value Write-Host "✅ Configuration updated: $Section.$Key = $Value" -ForegroundColor Green } else { # Set section configuration foreach ($key in $SectionConfig.Keys) { Set-SimpleConfigurationValue -Section $Section -Key $key -Value $SectionConfig[$key] } Write-Host "✅ Configuration section updated: $Section" -ForegroundColor Green foreach ($key in $SectionConfig.Keys) { Write-Host " $key = $($SectionConfig[$key])" -ForegroundColor White } } } catch { Write-Error "Failed to set configuration: $($_.Exception.Message)" # Show validation help if it's a validation error if ($_.Exception.Message -like "*Invalid value*") { Write-Host "" Write-Host "💡 Use 'Get-LiveFeaturesConfigSchema' to see valid values and ranges" -ForegroundColor Yellow } } } function Reset-LiveFeaturesConfig { <# .SYNOPSIS Reset live features configuration to defaults .DESCRIPTION Resets configuration to default values, either completely or for a specific section .PARAMETER Section Optional section name to reset only specific section .PARAMETER Force Skip confirmation prompt .EXAMPLE Reset-LiveFeaturesConfig Resets all configuration to defaults (with confirmation) .EXAMPLE Reset-LiveFeaturesConfig -Section liveDisplay -Force Resets only live display configuration without confirmation #> [CmdletBinding()] param( [string]$Section, [switch]$Force ) Initialize-ConfigurationManager try { $confirmMessage = if ($Section) { "Reset configuration section '$Section' to defaults?" } else { "Reset ALL configuration to defaults?" } if (-not $Force) { $response = Read-Host "$confirmMessage (y/N)" if ($response -ne 'y' -and $response -ne 'Y') { Write-Host "Configuration reset cancelled" -ForegroundColor Yellow return } } if ($Section) { Reset-SimpleConfiguration -Section $Section Write-Host "✅ Configuration section '$Section' reset to defaults" -ForegroundColor Green } else { Reset-SimpleConfiguration Write-Host "✅ All configuration reset to defaults" -ForegroundColor Green } } catch { Write-Error "Failed to reset configuration: $($_.Exception.Message)" } } function Export-LiveFeaturesConfig { <# .SYNOPSIS Export live features configuration to file or string .DESCRIPTION Exports the current configuration in JSON or YAML format .PARAMETER Path Output file path (optional, outputs to console if not specified) .PARAMETER Format Export format (json or yaml) .EXAMPLE Export-LiveFeaturesConfig Exports configuration to console in JSON format .EXAMPLE Export-LiveFeaturesConfig -Path "config_backup.json" -Format json Exports configuration to file in JSON format #> [CmdletBinding()] param( [string]$Path, [ValidateSet("json", "yaml")] [string]$Format = "json" ) Initialize-ConfigurationManager try { $exportData = Export-SimpleConfiguration if ($Path) { # Export to file $exportData | Set-Content -Path $Path -Encoding UTF8 Write-Host "✅ Configuration exported to: $Path" -ForegroundColor Green } else { # Output to console Write-Host "Current Configuration ($Format format):" -ForegroundColor Cyan Write-Host "=" * 40 -ForegroundColor Cyan Write-Host $exportData } } catch { Write-Error "Failed to export configuration: $($_.Exception.Message)" } } function Import-LiveFeaturesConfig { <# .SYNOPSIS Import live features configuration from file or string .DESCRIPTION Imports configuration from JSON format with validation .PARAMETER Path Input file path .PARAMETER ConfigData Configuration data as string .PARAMETER Format Import format (json) .PARAMETER Force Skip confirmation prompt .EXAMPLE Import-LiveFeaturesConfig -Path "config_backup.json" Imports configuration from JSON file .EXAMPLE Import-LiveFeaturesConfig -ConfigData $jsonString -Format json -Force Imports configuration from JSON string without confirmation #> [CmdletBinding(DefaultParameterSetName = "FromFile")] param( [Parameter(Mandatory, ParameterSetName = "FromFile")] [string]$Path, [Parameter(Mandatory, ParameterSetName = "FromString")] [string]$ConfigData, [ValidateSet("json")] [string]$Format = "json", [switch]$Force ) Initialize-ConfigurationManager try { if ($PSCmdlet.ParameterSetName -eq "FromFile") { if (-not (Test-Path $Path)) { Write-Error "Configuration file not found: $Path" return } $ConfigData = Get-Content -Path $Path -Raw -Encoding UTF8 } if (-not $Force) { Write-Host "This will replace your current configuration." -ForegroundColor Yellow $response = Read-Host "Continue? (y/N)" if ($response -ne 'y' -and $response -ne 'Y') { Write-Host "Configuration import cancelled" -ForegroundColor Yellow return } } # For now, we'll implement a simple JSON import if ($Format -eq "json") { $importedConfig = $ConfigData | ConvertFrom-Json $config = ConvertTo-Hashtable -InputObject $importedConfig # Validate imported configuration $errors = Get-ConfigurationValidationErrors -Config $config if ($errors.Count -gt 0) { throw "Invalid configuration: $($errors -join '; ')" } # Apply the configuration foreach ($section in $config.Keys) { if ($section -eq '_metadata') { continue } foreach ($key in $config[$section].Keys) { Set-SimpleConfigurationValue -Section $section -Key $key -Value $config[$section][$key] } } } else { throw "Unsupported import format: $Format" } Write-Host "✅ Configuration imported successfully" -ForegroundColor Green } catch { Write-Error "Failed to import configuration: $($_.Exception.Message)" } } function Get-LiveFeaturesConfigSchema { <# .SYNOPSIS Get the configuration schema information .DESCRIPTION Shows the available configuration sections, keys, valid values, and ranges .PARAMETER Section Optional section name to show only specific section schema .EXAMPLE Get-LiveFeaturesConfigSchema Shows complete configuration schema .EXAMPLE Get-LiveFeaturesConfigSchema -Section liveDisplay Shows only live display section schema #> [CmdletBinding()] param( [string]$Section ) Initialize-ConfigurationManager # Get the schema from the simple configuration manager $schema = Get-ConfigurationSchema if ($Section) { if (-not $schema.ContainsKey($Section)) { Write-Warning "Configuration section '$Section' not found" return } Write-Host "Configuration Schema: $Section" -ForegroundColor Cyan Write-Host "=" * (22 + $Section.Length) -ForegroundColor Cyan Write-Host "" $sectionSchema = $schema[$Section] foreach ($key in $sectionSchema.Keys | Sort-Object) { $keySchema = $sectionSchema[$key] Write-Host " $key" -ForegroundColor Yellow Write-Host " Type: $($keySchema.Type)" -ForegroundColor White Write-Host " Default: $($keySchema.Default)" -ForegroundColor White if ($keySchema.ContainsKey('ValidValues')) { Write-Host " Valid Values: $($keySchema.ValidValues -join ', ')" -ForegroundColor White } if ($keySchema.ContainsKey('Min') -and $keySchema.ContainsKey('Max')) { Write-Host " Range: $($keySchema.Min) - $($keySchema.Max)" -ForegroundColor White } Write-Host "" } } else { Write-Host "Live Features Configuration Schema" -ForegroundColor Cyan Write-Host "==================================" -ForegroundColor Cyan Write-Host "" foreach ($sectionName in $schema.Keys | Sort-Object) { Write-Host "[$sectionName]" -ForegroundColor Yellow $sectionSchema = $schema[$sectionName] foreach ($key in $sectionSchema.Keys | Sort-Object) { $keySchema = $sectionSchema[$key] Write-Host " $key ($($keySchema.Type))" -ForegroundColor White $details = @() $details += "default: $($keySchema.Default)" if ($keySchema.ContainsKey('ValidValues')) { $details += "values: $($keySchema.ValidValues -join '|')" } if ($keySchema.ContainsKey('Min') -and $keySchema.ContainsKey('Max')) { $details += "range: $($keySchema.Min)-$($keySchema.Max)" } Write-Host " $($details -join ', ')" -ForegroundColor Gray } Write-Host "" } } } function Backup-LiveFeaturesConfig { <# .SYNOPSIS Create a backup of the current configuration .DESCRIPTION Creates a timestamped backup of the current configuration .PARAMETER Path Optional backup directory path (defaults to config directory) .EXAMPLE Backup-LiveFeaturesConfig Creates backup in default location .EXAMPLE Backup-LiveFeaturesConfig -Path "C:\Backups" Creates backup in specified directory #> [CmdletBinding()] param( [string]$Path ) Initialize-ConfigurationManager try { $info = Get-SimpleConfigurationInfo if (-not $Path) { $Path = $info.ConfigurationDirectory } if (-not (Test-Path $Path)) { New-Item -ItemType Directory -Path $Path -Force | Out-Null } $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $backupFile = Join-Path $Path "live_features_config_backup_$timestamp.json" Export-LiveFeaturesConfig -Path $backupFile -Format json Write-Host "✅ Configuration backed up to: $backupFile" -ForegroundColor Green return $backupFile } catch { Write-Error "Failed to backup configuration: $($_.Exception.Message)" } } function Restore-LiveFeaturesConfig { <# .SYNOPSIS Restore configuration from a backup file .DESCRIPTION Restores configuration from a previously created backup file .PARAMETER Path Path to the backup file .PARAMETER Force Skip confirmation prompt .EXAMPLE Restore-LiveFeaturesConfig -Path "live_features_config_backup_20241106_143022.json" Restores configuration from backup file #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Path, [switch]$Force ) if (-not (Test-Path $Path)) { Write-Error "Backup file not found: $Path" return } try { Import-LiveFeaturesConfig -Path $Path -Force:$Force Write-Host "✅ Configuration restored from backup" -ForegroundColor Green } catch { Write-Error "Failed to restore configuration: $($_.Exception.Message)" } } function Test-LiveFeaturesConfig { <# .SYNOPSIS Validate the current configuration .DESCRIPTION Validates the current configuration against the schema and reports any issues .EXAMPLE Test-LiveFeaturesConfig Validates current configuration #> [CmdletBinding()] param() Initialize-ConfigurationManager try { $config = Get-SimpleConfiguration $errors = Get-ConfigurationValidationErrors -Config $config if ($errors.Count -eq 0) { Write-Host "✅ Configuration is valid" -ForegroundColor Green return $true } else { Write-Host "❌ Configuration validation failed:" -ForegroundColor Red foreach ($error in $errors) { Write-Host " • $error" -ForegroundColor Yellow } return $false } } catch { Write-Error "Failed to validate configuration: $($_.Exception.Message)" return $false } } function Update-LiveFeaturesConfig { <# .SYNOPSIS Update configuration to the latest version .DESCRIPTION Migrates configuration from older versions to the current version .PARAMETER Force Skip confirmation prompt .PARAMETER CurrentVersion Current version of the live features (defaults to 1.2) .EXAMPLE Update-LiveFeaturesConfig Updates configuration to latest version with confirmation .EXAMPLE Update-LiveFeaturesConfig -Force -CurrentVersion "1.2" Updates configuration without confirmation #> [CmdletBinding()] param( [switch]$Force, [string]$CurrentVersion = "1.2" ) Initialize-ConfigurationManager try { # For the simple configuration manager, we'll just ensure defaults are merged Write-Host "Updating configuration to latest version..." -ForegroundColor Yellow if (-not $Force) { Write-Host "This will merge your configuration with the latest defaults." -ForegroundColor Cyan $response = Read-Host "Continue? (y/N)" if ($response -ne 'y' -and $response -ne 'Y') { Write-Host "Configuration update cancelled" -ForegroundColor Yellow return } } # Create backup first $backupFile = Backup-LiveFeaturesConfig # Reload configuration to ensure latest defaults are applied Initialize-SimpleConfigurationManager Write-Host "✅ Configuration updated successfully" -ForegroundColor Green Write-Host "💡 Backup created: $backupFile" -ForegroundColor Cyan } catch { Write-Error "Failed to update configuration: $($_.Exception.Message)" } } function Get-LiveFeaturesConfigInfo { <# .SYNOPSIS Get detailed information about the configuration system .DESCRIPTION Shows configuration file location, version, and other metadata .EXAMPLE Get-LiveFeaturesConfigInfo Shows configuration system information #> [CmdletBinding()] param() Initialize-ConfigurationManager try { $info = Get-SimpleConfigurationInfo Write-Host "Live Features Configuration Information" -ForegroundColor Cyan Write-Host "======================================" -ForegroundColor Cyan Write-Host "" Write-Host "Configuration File:" -ForegroundColor Yellow Write-Host " Path: $($info.ConfigurationFile)" -ForegroundColor White Write-Host " Directory: $($info.ConfigurationDirectory)" -ForegroundColor White Write-Host " Exists: $(Test-Path $info.ConfigurationFile)" -ForegroundColor White if ($info.LastModified) { Write-Host " Last Modified: $($info.LastModified)" -ForegroundColor White } Write-Host "" Write-Host "Configuration Status:" -ForegroundColor Yellow Write-Host " Loaded: $($info.IsLoaded)" -ForegroundColor White Write-Host " Has Customizations: $($info.HasCustomizations)" -ForegroundColor White # Show metadata if available $config = Get-SimpleConfiguration if ($config.ContainsKey('_metadata')) { Write-Host "" Write-Host "Migration History:" -ForegroundColor Yellow $metadata = $config['_metadata'] if ($metadata.ContainsKey('migratedFrom')) { Write-Host " Migrated From: $($metadata['migratedFrom'])" -ForegroundColor White } if ($metadata.ContainsKey('migratedAt')) { Write-Host " Migration Date: $($metadata['migratedAt'])" -ForegroundColor White } if ($metadata.ContainsKey('backupFile')) { Write-Host " Backup File: $($metadata['backupFile'])" -ForegroundColor White } } Write-Host "" Write-Host "Available Commands:" -ForegroundColor Yellow Write-Host " config - View configuration" -ForegroundColor White Write-Host " config-set - Modify settings" -ForegroundColor White Write-Host " config-reset - Reset to defaults" -ForegroundColor White Write-Host " config-schema - View valid settings" -ForegroundColor White Write-Host " Get-LiveFeaturesConfig - Full configuration view" -ForegroundColor White Write-Host " Set-LiveFeaturesConfig - Modify configuration" -ForegroundColor White Write-Host " Export-LiveFeaturesConfig - Export/backup config" -ForegroundColor White Write-Host " Import-LiveFeaturesConfig - Import/restore config" -ForegroundColor White return $info } catch { Write-Error "Failed to get configuration info: $($_.Exception.Message)" } } # Export functions Export-ModuleMember -Function @( 'Get-LiveFeaturesConfig', 'Set-LiveFeaturesConfig', 'Reset-LiveFeaturesConfig', 'Export-LiveFeaturesConfig', 'Import-LiveFeaturesConfig', 'Get-LiveFeaturesConfigSchema', 'Backup-LiveFeaturesConfig', 'Restore-LiveFeaturesConfig', 'Test-LiveFeaturesConfig', 'Update-LiveFeaturesConfig', 'Get-LiveFeaturesConfigInfo' ) |