# frozen_string_literal: true require 'roda/endpoints/transactions' class Roda module Endpoints # Generic HTTP endpoint abstraction. class Endpoint # Namespacing operations, validations, etc. module Transactions # @return [Endpoints::Transactions] def transactions @transactions ||= Endpoints::Transactions.new(endpoint: self) yield @transaction if block_given? @transactions end def prepare_transactions! return if @transactions_prepared endpoint = self self.class.transactions.each do |(name, block)| transactions.define(name) do instance_exec(endpoint, &block) end end verbs.each do |verb| key = "operations.#{ns}.#{verb}" next if container.key?(key) operation = method(verb) container.register key do |*args| endpoint.instance_exec(*args, &operation) end end @transactions_prepared = true end # @param [Symbol, String] name # @param [Proc] block def step(name, only: [], **kwargs, &block) name = "operations.#{ns}.#{name}" container.register(name, &block) if block_given? verbs = Array(only).flatten verbs.each do |verb| result = transactions[verb].insert(container: container, **kwargs) do step name end @transaction = result end transactions end def before(name, **kwargs, &block) step "before_#{name}", before: name, **kwargs, &block end def after(name, **kwargs, &block) step "after_#{name}", after: name, **kwargs, &block end # @param [Symbol] operation # @param [Array] args # @return [Dry::Monads::Either] def perform(operation, *args, **options) transactions[operation].call(*args, **options) end end end end end