#!/usr/bin/env nu # [command] # name = "metadata handler" # group = "infrastructure" # tags = ["metadata", "forms", "validation", "interactive"] # version = "1.0.0" # requires = ["traits.nu", "forminquire.nu"] # note = "Command metadata validation and interactive form handling in dispatcher" # ============================================================================ # Metadata Handler for Dispatcher Integration # Version: 1.0.0 # Purpose: Validate commands and execute interactive forms in dispatcher # ============================================================================ use ../lib_provisioning/commands/traits.nu * use ../../forminquire/nulib/forminquire.nu * # Validate command exists and meets requirements def validate-command-execution [ canonical_name: string flags: record = {} ] : nothing -> record { let metadata_result = (get-command-metadata $canonical_name) # If metadata not found, allow command through with default settings # Metadata is optional - commands can still work without it if not $metadata_result.found { return { valid: true error: "" interactive: false form_template: "" } } let req = $metadata_result.metadata.requirements # Check workspace requirement if ($req.requires_workspace and (($env.PROVISIONING_WORKSPACE? | is-empty))) { if not ($flags.workspace? | is-empty) { # Workspace flag provided, will be set by dispatcher } else { return { valid: false error: "Active workspace required. Use --workspace or set PROVISIONING_WORKSPACE" interactive: false form_template: "" } } } # Check confirmation requirement if ($req.requires_confirmation and not ($flags.auto_confirm? | default false)) { # Forms will handle this } # Check auth requirement if ($req.requires_auth) { # Auth will be validated by auth handler, not here } { valid: true error: "" interactive: $req.interactive form_template: ($metadata_result.metadata.form_path? // "") metadata: $metadata_result.metadata } } # Handle interactive command execution def handle-interactive-command [ canonical_name: string form_template: string form_context: record = {} ] : nothing -> record { # Determine which form to run based on command # Use specialized functions from their modules for setup and workspace let form_result = ( match $canonical_name { "setup" => { use ../lib_provisioning/setup/wizard.nu * # For setup, we return a special handling marker # The dispatcher will handle calling the right function { success: true error: "" values: {} _setup_command: true } } "workspace init" => { # For workspace init, same approach { success: true error: "" values: {} _workspace_init_command: true } } "auth login" => { run-form $form_template } "server delete" => { run-form $form_template } _ => { if not (($form_template | is-empty)) { run-form $form_template } else { { success: false error: "No form template defined for interactive command" values: {} } } } } ) if not $form_result.success { return { proceed: false error: $form_result.error form_values: {} } } # Inject form results into environment for command to use $env.FORM_RESULTS = ($form_result.values | to json) { proceed: true error: "" form_values: $form_result.values } } # Print validation errors def show-validation-error [error_msg: string] : nothing -> nothing { print $"(ansi red_bold)✗ Command validation failed(ansi reset)" print $" (ansi yellow)Error:(ansi reset) ($error_msg)" print "" } # Validate and prepare command for execution def prepare-command-execution [ canonical_name: string flags: record = {} ] : nothing -> record { # Validate command let validation = (validate-command-execution $canonical_name $flags) if not $validation.valid { show-validation-error $validation.error return { proceed: false error: $validation.error form_values: {} } } # Handle interactive commands if $validation.interactive { handle-interactive-command $canonical_name $validation.form_template {} } else { { proceed: true error: "" form_values: {} } } } # Check if command should skip if --yes flag provided def should-skip-interactive [flags: record] : nothing -> bool { $flags.auto_confirm? | default false } # Main exported function for dispatcher integration export def validate-and-prepare [ command_str: string flags: record = {} ] : nothing -> record { # If --yes flag provided, skip interactive forms if (should-skip-interactive $flags) { return { proceed: true error: "" form_values: {} } } prepare-command-execution $command_str $flags }