#!/usr/bin/env bash # Value validation helpers, keyed by @type annotation. # Source this file; do not execute it directly. # Requires colors.sh to be sourced first. # validate_value # Returns 0 if valid, 1 if invalid (prints a message to stderr). validate_value() { local var_name="$1" local value="$2" local type="$3" local required="$4" # Required check if [[ "$required" == "true" && -z "$value" ]]; then printf "${RED} Error: %s is required and cannot be empty.${NC}\n" "$var_name" >&2 return 1 fi # No further validation needed for empty optional values if [[ -z "$value" ]]; then return 0 fi case "$type" in number) if ! [[ "$value" =~ ^-?[0-9]+(\.[0-9]+)?$ ]]; then printf "${RED} Error: Must be a number (got: %s).${NC}\n" "$value" >&2 return 1 fi ;; bool) case "${value,,}" in true|false|yes|no|1|0|y|n) ;; *) printf "${RED} Error: Must be a boolean value (true/false/yes/no).${NC}\n" >&2 return 1 ;; esac ;; url) if ! [[ "$value" =~ ^https?:// ]]; then printf "${YELLOW} Warning: Value doesn't look like a URL (expected http:// or https://).${NC}\n" >&2 # Warn only — allow the user to proceed fi ;; email) if ! [[ "$value" =~ ^[^@[:space:]]+@[^@[:space:]]+\.[^@[:space:]]+$ ]]; then printf "${RED} Error: Must be a valid email address (got: %s).${NC}\n" "$value" >&2 return 1 fi ;; enum:*) local options="${type#enum:}" local valid=false local IFS=',' local opt for opt in $options; do if [[ "$value" == "$opt" ]]; then valid=true break fi done if [[ "$valid" == "false" ]]; then printf "${RED} Error: Must be one of: %s (got: %s).${NC}\n" "$options" "$value" >&2 return 1 fi ;; secret|string|*) # No structural validation for these types ;; esac return 0 } # normalize_bool # Converts a truthy/falsy string to canonical "true" or "false". normalize_bool() { case "${1,,}" in true|yes|1|y) echo "true" ;; false|no|0|n) echo "false" ;; *) echo "$1" ;; # pass-through for validation to catch esac }