require 'rack' module Helios class Backend < Rack::Builder DEFAULT_PATHS = { data: '/' } require 'rails-database-url' if const_defined?(:Rails) def initialize(*args, &block) raise ArgumentError, "Missing block" unless block_given? super(&nil) @services = {} instance_eval(&block) end def call(env) return super(env) unless env["REQUEST_METHOD"] == "OPTIONS" and env["REQUEST_PATH"] == "/" links = [] @services.each do |path, middleware| links << %{<#{path}>; rel="#{middleware}"} end [206, {"Link" => links.join("\n")}, []] end private def service(identifier, options = {}, &block) if identifier.is_a?(Class) middleware = identifier else begin middleware = Helios::Backend.const_get(constantize(identifier)) rescue NameError raise LoadError, "Could not find matching service for #{identifier.inspect} (Helios::Backend::#{constantize(identifier)}). You may need to install an additional gem (such as helios-#{identifier})." end end path = "/#{(options.delete(:root) || DEFAULT_PATHS[identifier] || identifier)}".squeeze("/") map path do instance_eval(&block) if block_given? run middleware.new(self, options) end @services[path] = middleware end def constantize(identifier) identifier.to_s.split(/([[:alpha:]]*)/).select{|c| /[[:alpha:]]/ === c}.map(&:capitalize).join("") end end end require 'helios/backend/data' require 'helios/backend/in-app-purchase' require 'helios/backend/passbook' require 'helios/backend/push-notification' require 'helios/backend/newsstand'