AshCommanded.Commanded.ParameterValidator (AshCommanded v0.1.0)

View Source

Advanced parameter validation for commands.

This module provides comprehensive validation capabilities for command parameters, ensuring they meet specific criteria before being processed by actions.

Validation features include:

  1. Type checking - Ensure values match expected types
  2. Format validation - Validate strings with regular expressions
  3. Range validation - Check numeric values against ranges
  4. Domain validation - Validate values against lists of allowed values
  5. Custom validation functions - Apply arbitrary validation logic
  6. Nested validation - Validate nested maps and collections

These validations complement the more basic validations in ValidationMiddleware.

Example

defmodule MyApp.User do
  use Ash.Resource,
    extensions: [AshCommanded.Commanded.Dsl]
    
  commanded do
    commands do
      command :register_user do
        fields [:id, :name, :email, :age, :roles]
        
        validate_params do
          # Type validation
          validate :id, type: :string
          validate :name, type: :string
          validate :email, type: :string
          validate :age, type: :integer
          validate :roles, type: :list
          
          # Format validation
          validate :email, format: ~r/^[^ ]+@[^ ]+.[^ ]+$/
          
          # Range validation
          validate :age, min: 18, max: 120
          
          # Domain validation
          validate :roles, subset_of: [:user, :admin, :moderator]
          
          # Custom validation
          validate :name, fn value ->
            if String.trim(value) == "" do
              {:error, "Name cannot be blank"}
            else
              :ok
            end
          end
          
          # Multiple validations on one field
          validate :password do
            min_length 8
            format ~r/[A-Z]/
            format ~r/[a-z]/
            format ~r/[0-9]/
            format ~r/[^A-Za-z0-9]/
          end
        end
      end
    end
  end
end

Summary

Functions

Builds a validation specification from a DSL block.

Validates parameters against a validation specification.

Functions

build_validations(validation_specs)

@spec build_validations(list()) :: list()

Builds a validation specification from a DSL block.

This function is used by the DSL to convert validation declarations into a list of validation specifications that can be applied to command parameters.

Parameters

  • validation_block - A keyword list of validation declarations

Returns

A list of validation specifications.

Example

build_validations([
  validate: [:name, [type: :string, min_length: 2]],
  validate: [:email, [type: :string, format: ~r/@.*./]],
  validate: [:age, [type: :integer, min: 18]]
])

validate_params(params, validations)

@spec validate_params(map(), list()) ::
  :ok | {:error, [AshCommanded.Commanded.Error.t()]}

Validates parameters against a validation specification.

Takes a map of parameters and a list of validation rules, and returns :ok or an error tuple with validation failures.

Parameters

  • params - Map of parameters to validate
  • validations - List of validation specifications

Returns

  • :ok - If all validations pass
  • {:error, errors} - If any validations fail, with errors being a list of validation error structs

Example

validate_params(
  %{name: "John", email: "john@example", age: 15},
  [
    {:validate, :name, [type: :string, min_length: 2]},
    {:validate, :email, [type: :string, format: ~r/@.*./]},
    {:validate, :age, [type: :integer, min: 18]}
  ]
)
# => {:error, [%Error{type: :validation_error, message: "does not match required format", field: :email}, 
#              %Error{type: :validation_error, message: "must be at least 18", field: :age}]}