LemonChannels.Capabilities (lemon_channels v0.1.0)

View Source

Channel capability definitions and registry.

Provides a comprehensive system for defining, validating, and querying channel capabilities including attachments, rich blocks, streaming, threads, and reactions.

Capability Types

  • :attachments - File upload support with size limits and mime types
  • :rich_blocks - Structured UI blocks (markdown, buttons, sections, etc.)
  • :streaming - Real-time message streaming support
  • :threads - Thread/conversation nesting support
  • :reactions - Message reaction support
  • :edit - Message editing support
  • :delete - Message deletion support

Usage

# Define capabilities for a channel
caps = Capabilities.new([
  :attachments,
  {:rich_blocks, [:markdown, :buttons]},
  :threads
])

# Check if capability is supported
Capabilities.supports?(caps, :attachments)
# => true

# Get capability details
Capabilities.get(caps, :attachments)
# => %{max_size: 10_000_000, allowed_mimes: ["image/*", "video/*"]}

# Validate a capability request
Capabilities.validate(caps, :attachments, %{size: 5_000_000, mime_type: "image/png"})
# => :ok

Summary

Types

t()

A capabilities map

Functions

Returns the default capabilities that all channels should have.

Returns an empty capabilities map.

Returns suggested fallback options for unsupported capabilities.

Converts legacy capability format to new format.

Gets a capability by type.

Returns a list of all supported capability types.

Merges two capabilities maps. The second map takes precedence.

Creates a new capabilities map from a list of capability specs.

Creates a capability set for common channel types.

Checks if a capability is supported.

Checks if a capability supports specific features.

Converts new capability format to legacy format.

Validates a capability request against the supported capabilities.

Types

t()

@type t() :: %{required(atom()) => LemonChannels.Capabilities.Capability.t()}

A capabilities map

Functions

default_capabilities()

@spec default_capabilities() :: t()

Returns the default capabilities that all channels should have.

empty()

@spec empty() :: t()

Returns an empty capabilities map.

fallback_for(caps, capability_type)

@spec fallback_for(t(), LemonChannels.Capabilities.Capability.type()) ::
  {:ok, term()} | {:error, :no_fallback}

Returns suggested fallback options for unsupported capabilities.

Examples

caps = Capabilities.new([:threads])  # no rich_blocks
Capabilities.fallback_for(caps, :rich_blocks)
# => {:text, "Fallback to plain text representation"}

from_legacy(legacy)

@spec from_legacy(map()) :: t()

Converts legacy capability format to new format.

get(caps, capability_type)

Gets a capability by type.

Examples

caps = Capabilities.new([{:attachments, max_size: 10_000_000}])
Capabilities.get(caps, :attachments)
# => %Capability{type: :attachments, enabled: true, config: %{max_size: 10000000}}

list(caps)

Returns a list of all supported capability types.

merge(base, override)

@spec merge(t(), t()) :: t()

Merges two capabilities maps. The second map takes precedence.

Examples

base = Capabilities.new([:threads, {:attachments, max_size: 5_000_000}])
override = Capabilities.new([{:attachments, max_size: 10_000_000}, :streaming])
Capabilities.merge(base, override)
# => %{attachments: %{max_size: 10000000}, threads: %{...}, streaming: %{...}}

new(specs)

Creates a new capabilities map from a list of capability specs.

Examples

# Simple boolean capabilities
Capabilities.new([:threads, :reactions, :streaming])

# Capabilities with configuration
Capabilities.new([
  :threads,
  {:attachments, max_size: 10_000_000},
  {:rich_blocks, [:markdown, :buttons, :sections]}
])

set(name)

Creates a capability set for common channel types.

Predefined Sets

  • :messaging - Basic messaging (threads, reactions, edit, delete)
  • :rich_content - Rich content support (attachments, rich_blocks)
  • :realtime - Real-time features (streaming, voice)
  • :full - All capabilities

Examples

Capabilities.set(:messaging)
# => [%Capability{type: :threads}, %Capability{type: :reactions}, ...]

supports?(caps, capability_type)

Checks if a capability is supported.

Examples

caps = Capabilities.new([:threads, :reactions])
Capabilities.supports?(caps, :threads)
# => true
Capabilities.supports?(caps, :streaming)
# => false

supports_feature?(caps, capability_type, feature)

@spec supports_feature?(t(), LemonChannels.Capabilities.Capability.type(), atom()) ::
  boolean()

Checks if a capability supports specific features.

Examples

caps = Capabilities.new([{:rich_blocks, [:markdown, :buttons]}])
Capabilities.supports_feature?(caps, :rich_blocks, :markdown)
# => true
Capabilities.supports_feature?(caps, :rich_blocks, :tables)
# => false

to_legacy(caps)

@spec to_legacy(t()) :: map()

Converts new capability format to legacy format.

This is a temporary function for migration purposes.

validate(caps, capability_type, params)

@spec validate(t(), LemonChannels.Capabilities.Capability.type(), map()) ::
  :ok | {:error, term()}

Validates a capability request against the supported capabilities.

Returns :ok if valid, or {:error, reason} if invalid.

Examples

caps = Capabilities.new([{:attachments, max_size: 10_000_000}])
Capabilities.validate(caps, :attachments, %{size: 5_000_000, mime_type: "image/png"})
# => :ok

Capabilities.validate(caps, :attachments, %{size: 15_000_000, mime_type: "image/png"})
# => {:error, :file_too_large}