# String Validators # Workspace names, identifiers, and other string validations { # Validate workspace name (alphanumeric, hyphen, underscore, max 64 chars) ValidWorkspaceName = fun name => if name == "" then std.contract.blame_with_message "Workspace name cannot be empty" name else if std.string.length name > 64 then std.contract.blame_with_message "Workspace name must be <= 64 characters" name else if !std.string.matches "^[a-z0-9_-]+$" name then std.contract.blame_with_message "Workspace name must contain only lowercase alphanumeric, hyphen, or underscore" name else name, # Validate service name ValidServiceName = fun name => if name == "" then std.contract.blame_with_message "Service name cannot be empty" name else if std.string.length name > 64 then std.contract.blame_with_message "Service name must be <= 64 characters" name else if !std.string.matches "^[a-z0-9_-]+$" name then std.contract.blame_with_message "Service name must contain only lowercase alphanumeric, hyphen, or underscore" name else name, # Validate filesystem path ValidFilesystemPath = fun path => if path == "" then std.contract.blame_with_message "Path cannot be empty" path else if std.string.length path > 255 then std.contract.blame_with_message "Path must be <= 255 characters" path else if std.string.starts_with path "/" then path else std.contract.blame_with_message "Path must be absolute (start with /)" path, # Validate relative path ValidRelativePath = fun path => if path == "" then std.contract.blame_with_message "Path cannot be empty" path else if std.string.length path > 255 then std.contract.blame_with_message "Path must be <= 255 characters" path else path, # Validate hostname/domain ValidHostname = fun hostname => if hostname == "" then std.contract.blame_with_message "Hostname cannot be empty" hostname else if std.string.length hostname > 253 then std.contract.blame_with_message "Hostname must be <= 253 characters" hostname else if !std.string.matches "^[a-zA-Z0-9.-]+$" hostname then std.contract.blame_with_message "Hostname must contain only alphanumeric, dot, or hyphen" hostname else hostname, # Validate IP address (basic check) ValidIpAddress = fun ip => if ip == "" then std.contract.blame_with_message "IP address cannot be empty" ip else if !std.string.matches "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$|^[0-9a-fA-F:]+$" ip then std.contract.blame_with_message "IP address format invalid (IPv4 or IPv6)" ip else ip, # Validate URL ValidUrl = fun url => if url == "" then std.contract.blame_with_message "URL cannot be empty" url else if !std.string.matches "^https?://" url then std.contract.blame_with_message "URL must start with http:// or https://" url else url, # Validate password minimum length ValidPassword = fun password => if std.string.length password < 8 then std.contract.blame_with_message "Password must be >= 8 characters" password else if std.string.length password > 128 then std.contract.blame_with_message "Password must be <= 128 characters" password else password, # Validate JWT token format ValidJwtToken = fun token => if token == "" then std.contract.blame_with_message "JWT token cannot be empty" token else if !std.string.matches "^[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]+\\.[a-zA-Z0-9_-]+$" token then std.contract.blame_with_message "JWT token format invalid (must be three base64url parts separated by dots)" token else token, # Validate identifier (alphanumeric, underscore, hyphen) ValidIdentifier = fun identifier => if identifier == "" then std.contract.blame_with_message "Identifier cannot be empty" identifier else if !std.string.matches "^[a-z0-9_-]+$" identifier then std.contract.blame_with_message "Identifier must contain only lowercase alphanumeric, underscore, or hyphen" identifier else identifier, # Validate category/tag name ValidCategoryName = fun category => if category == "" then std.contract.blame_with_message "Category cannot be empty" category else if !std.string.matches "^[a-z0-9_]+$" category then std.contract.blame_with_message "Category must contain only lowercase alphanumeric or underscore" category else category, }