class OpenUI::Rails::Actions::Registry

The allowlist of actions a model-generated surface may invoke. Only handlers registered here are reachable: there is no reflection from a model-provided name to a Ruby method.

Constants

Definition

Immutable definition stored by the registry and passed to dispatch.

NAME_PATTERN

Pattern accepted for action names sent over the wire.

Public Class Methods

new() click to toggle source

Create an empty action allowlist.

@return [Registry]

# File lib/openui/rails/actions/registry.rb, line 19
def initialize
  @definitions = {}
  @mutex = Mutex.new
end

Public Instance Methods

clear!() click to toggle source

Remove all registered actions.

@return [self]

# File lib/openui/rails/actions/registry.rb, line 95
def clear!
  @mutex.synchronize { @definitions.clear }
  self
end
fetch(name) click to toggle source

Find a registered action or raise when it is not allowlisted.

@param name [String, Symbol]

@return [Definition]

@raise [UnknownActionError] when no action has this name

# File lib/openui/rails/actions/registry.rb, line 67
def fetch(name)
  definition = @mutex.synchronize { @definitions[normalize_name(name)] }
  raise UnknownActionError, "unknown action #{name.inspect}" if definition.nil?

  definition
rescue ConfigurationError => error
  raise InvalidActionError, error.message
end
names() click to toggle source

Return the registered action names.

@return [Array<String>]

# File lib/openui/rails/actions/registry.rb, line 88
def names
  @mutex.synchronize { @definitions.keys }
end
register(name, handler: nil, authorize: nil, schema: nil, confirmation: false, description: nil, &block) click to toggle source

Register a callable action.

@param name [String, Symbol] the wire name the surface emits

@param handler [#call] receives an Invocation, performs the work

@param authorize [#call, nil] receives an Invocation, returns truthy

when allowed. Required at dispatch time (fail closed).

@param schema [Schema, Hash, call, nil] arg validation

@param confirmation [Boolean] require ‘confirmed: true` on the payload

@param description [String, nil] text describing the action

@return [Definition]

# File lib/openui/rails/actions/registry.rb, line 40
def register(name, handler: nil, authorize: nil, schema: nil, confirmation: false, description: nil, &block)
  handler ||= block
  raise ConfigurationError, "handler is required for action #{name.inspect}" unless handler.respond_to?(:call)
  unless authorize.nil? || authorize.respond_to?(:call)
    raise ConfigurationError, "authorize must respond to #call"
  end

  definition = Definition.new(
    name: normalize_name(name).dup.freeze,
    handler: handler,
    authorize: authorize,
    schema: Schema.from(schema),
    confirmation: confirmation ? true : false,
    description: description
  ).freeze

  @mutex.synchronize { @definitions[definition.name] = definition }
  definition
end
registered?(name) click to toggle source

Whether an action name is present in the allowlist.

@param name [String, Symbol]

@return [Boolean]

# File lib/openui/rails/actions/registry.rb, line 81
def registered?(name)
  @mutex.synchronize { @definitions.key?(normalize_name(name)) }
end