ree_lib 1.0.36 → 1.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +9 -2
- data/lib/ree_lib/Packages.schema.json +8 -0
- data/lib/ree_lib/packages/ree_actions/.gitignore +0 -0
- data/lib/ree_lib/packages/ree_actions/.rspec +2 -0
- data/lib/ree_lib/packages/ree_actions/Package.schema.json +20 -0
- data/lib/ree_lib/packages/ree_actions/bin/console +5 -0
- data/lib/ree_lib/packages/ree_actions/package/ree_actions/action.rb +10 -0
- data/lib/ree_lib/packages/ree_actions/package/ree_actions/action_builder.rb +65 -0
- data/lib/ree_lib/packages/ree_actions/package/ree_actions/action_dsl.rb +60 -0
- data/lib/ree_lib/packages/ree_actions/package/ree_actions/dsl.rb +102 -0
- data/lib/ree_lib/packages/ree_actions/package/ree_actions.rb +12 -0
- data/lib/ree_lib/packages/ree_actions/spec/package_schema_spec.rb +14 -0
- data/lib/ree_lib/packages/ree_actions/spec/ree_actions/action_dsl_spec.rb +62 -0
- data/lib/ree_lib/packages/ree_actions/spec/ree_actions/dsl_spec.rb +93 -0
- data/lib/ree_lib/packages/ree_actions/spec/spec_helper.rb +3 -0
- data/lib/ree_lib/packages/ree_roda/.gitignore +0 -0
- data/lib/ree_lib/packages/ree_roda/.rspec +2 -0
- data/lib/ree_lib/packages/ree_roda/Package.schema.json +58 -0
- data/lib/ree_lib/packages/ree_roda/bin/console +5 -0
- data/lib/ree_lib/packages/ree_roda/package/ree_roda/app.rb +46 -0
- data/lib/ree_lib/packages/ree_roda/package/ree_roda/plugins/ree_actions.rb +150 -0
- data/lib/ree_lib/packages/ree_roda/package/ree_roda/plugins/ree_logger.rb +66 -0
- data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/build_action_errors.rb +76 -0
- data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/build_swagger_from_actions.rb +55 -0
- data/lib/ree_lib/packages/ree_roda/package/ree_roda/services/status_from_error.rb +25 -0
- data/lib/ree_lib/packages/ree_roda/package/ree_roda.rb +19 -0
- data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/build_action_errors.schema.json +28 -0
- data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/build_swagger_from_actions.schema.json +63 -0
- data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/status_from_error.schema.json +28 -0
- data/lib/ree_lib/packages/ree_roda/spec/package_schema_spec.rb +14 -0
- data/lib/ree_lib/packages/ree_roda/spec/ree_roda/app_spec.rb +84 -0
- data/lib/ree_lib/packages/ree_roda/spec/spec_helper.rb +3 -0
- data/lib/ree_lib/version.rb +1 -1
- metadata +60 -2
| @@ -0,0 +1,150 @@ | |
| 1 | 
            +
            class Roda
         | 
| 2 | 
            +
              module RodaPlugins
         | 
| 3 | 
            +
                module ReeActions
         | 
| 4 | 
            +
                  def self.load_dependencies(app, opts = {})
         | 
| 5 | 
            +
                    package_require("ree_roda/services/build_swagger_from_actions")
         | 
| 6 | 
            +
                    package_require("ree_json/functions/to_json")
         | 
| 7 | 
            +
                    package_require("ree_hash/functions/transform_values")
         | 
| 8 | 
            +
                    package_require("ree_object/functions/not_blank")
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    app.plugin :all_verbs
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def self.configure(app, opts = {})
         | 
| 14 | 
            +
                    app.opts[:ree_actions_before] = opts[:before] if opts[:before]
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  module ClassMethods
         | 
| 18 | 
            +
                    def ree_actions(actions, swagger_title: "", swagger_description: "",
         | 
| 19 | 
            +
                                    swagger_version: "", swagger_url: "", api_url: "")
         | 
| 20 | 
            +
                      @ree_actions ||= []
         | 
| 21 | 
            +
                      @ree_actions += actions
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                      opts[:ree_actions_swagger_title] = swagger_title
         | 
| 24 | 
            +
                      opts[:ree_actions_swagger_description] = swagger_description
         | 
| 25 | 
            +
                      opts[:ree_actions_swagger_version] = swagger_version
         | 
| 26 | 
            +
                      opts[:ree_actions_swagger_url] = swagger_url
         | 
| 27 | 
            +
                      opts[:ree_actions_api_url] = api_url
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                      opts[:ree_actions_swagger] = ReeRoda::BuildSwaggerFromActions.new.call(
         | 
| 30 | 
            +
                        @ree_actions,
         | 
| 31 | 
            +
                        opts[:ree_actions_swagger_title],
         | 
| 32 | 
            +
                        opts[:ree_actions_swagger_description],
         | 
| 33 | 
            +
                        opts[:ree_actions_swagger_version],
         | 
| 34 | 
            +
                        opts[:ree_actions_api_url]
         | 
| 35 | 
            +
                      )
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                      build_actions_proc
         | 
| 38 | 
            +
                      nil
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    private
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    def build_actions_proc
         | 
| 44 | 
            +
                      list = []
         | 
| 45 | 
            +
                      context = self
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      return list if @ree_actions.nil? || @ree_actions.empty?
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                      if context.opts[:ree_actions_swagger_url]
         | 
| 50 | 
            +
                        list << Proc.new do |r|
         | 
| 51 | 
            +
                          r.get context.opts[:ree_actions_swagger_url] do
         | 
| 52 | 
            +
                            r.json do
         | 
| 53 | 
            +
                              response.status = 200
         | 
| 54 | 
            +
                              ReeJson::ToJson.new.call(context.opts[:ree_actions_swagger])
         | 
| 55 | 
            +
                            end
         | 
| 56 | 
            +
                          end
         | 
| 57 | 
            +
                        end
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                      @ree_actions.each do |action|
         | 
| 61 | 
            +
                        route = []
         | 
| 62 | 
            +
                        route_args = []
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                        action.path.split("/").each do |part|
         | 
| 65 | 
            +
                          if part.start_with?(":")
         | 
| 66 | 
            +
                            route << String
         | 
| 67 | 
            +
                            route_args << part.gsub(":", "")
         | 
| 68 | 
            +
                          else
         | 
| 69 | 
            +
                            route << part
         | 
| 70 | 
            +
                          end
         | 
| 71 | 
            +
                        end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                        list << Proc.new do |r|
         | 
| 74 | 
            +
                          r.send(action.request_method, *route) do |*args|
         | 
| 75 | 
            +
                            r.send(action.respond_to) do
         | 
| 76 | 
            +
                              env["warden"].authenticate!(scope: action.warden_scope)
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                              if context.opts[:ree_actions_before]
         | 
| 79 | 
            +
                                self.instance_exec(@_request, action.warden_scope, &scope.opts[:ree_actions_before])
         | 
| 80 | 
            +
                              end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                              # TODO: implement me when migration to roda DSL happens
         | 
| 83 | 
            +
                              # if action.before; end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                              route_args.each_with_index do |arg, index|
         | 
| 86 | 
            +
                                r.params["#{arg}"] = args[index]
         | 
| 87 | 
            +
                              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                              params = r.params
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                              if r.body
         | 
| 92 | 
            +
                                body = begin
         | 
| 93 | 
            +
                                  JSON.parse(r.body.read)
         | 
| 94 | 
            +
                                rescue => e
         | 
| 95 | 
            +
                                  {}
         | 
| 96 | 
            +
                                end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                                params = params.merge(body)
         | 
| 99 | 
            +
                              end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                              not_blank = ReeObject::NotBlank.new
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                              filtered_params = ReeHash::TransformValues.new.call(params) do |k, v|
         | 
| 104 | 
            +
                                v.is_a?(Array) ? v.select { not_blank.call(_1) } : v
         | 
| 105 | 
            +
                              end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                              accessor = env["warden"].user(action.warden_scope)
         | 
| 108 | 
            +
                              action_result = action.action.klass.new.call(accessor, filtered_params)
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                              if action.serializer
         | 
| 111 | 
            +
                                serialized_result = action.serializer.klass.new.serialize(action_result)
         | 
| 112 | 
            +
                              else
         | 
| 113 | 
            +
                                serialized_result = {}
         | 
| 114 | 
            +
                              end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                              case action.request_method
         | 
| 117 | 
            +
                              when :post
         | 
| 118 | 
            +
                                response.status = 201
         | 
| 119 | 
            +
                                ReeJson::ToJson.new.call(serialized_result)
         | 
| 120 | 
            +
                              when :put, :delete, :patch
         | 
| 121 | 
            +
                                response.status = 204
         | 
| 122 | 
            +
                                ""
         | 
| 123 | 
            +
                              else
         | 
| 124 | 
            +
                                response.status = 200
         | 
| 125 | 
            +
                                ReeJson::ToJson.new.call(serialized_result)
         | 
| 126 | 
            +
                              end
         | 
| 127 | 
            +
                            end
         | 
| 128 | 
            +
                          end
         | 
| 129 | 
            +
                        end
         | 
| 130 | 
            +
                      end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                      opts[:ree_actions_proc]  = list
         | 
| 133 | 
            +
                    end
         | 
| 134 | 
            +
                  end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                  module RequestMethods
         | 
| 137 | 
            +
                    def ree_actions
         | 
| 138 | 
            +
                      if scope.opts[:ree_actions_proc]
         | 
| 139 | 
            +
                        scope.opts[:ree_actions_proc].each do |request_proc|
         | 
| 140 | 
            +
                          self.instance_exec(self, &request_proc)
         | 
| 141 | 
            +
                        end
         | 
| 142 | 
            +
                      end
         | 
| 143 | 
            +
                      nil
         | 
| 144 | 
            +
                    end
         | 
| 145 | 
            +
                  end
         | 
| 146 | 
            +
                end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                register_plugin(:ree_actions, Roda::RodaPlugins::ReeActions)
         | 
| 149 | 
            +
              end
         | 
| 150 | 
            +
            end
         | 
| @@ -0,0 +1,66 @@ | |
| 1 | 
            +
            package_require "ree_logger/beans/logger"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class Roda
         | 
| 4 | 
            +
              module RodaPlugins
         | 
| 5 | 
            +
                # The ree_logger plugin adds ReeLogger support to Roda
         | 
| 6 | 
            +
                #
         | 
| 7 | 
            +
                # Example:
         | 
| 8 | 
            +
                #
         | 
| 9 | 
            +
                #   plugin :ree_logger
         | 
| 10 | 
            +
                #   plugin :ree_logger, log_params: true, filter: -> { request.path.include?("health") }
         | 
| 11 | 
            +
                module ReeLogger
         | 
| 12 | 
            +
                  REE_LOGGER_DEFAULTS = {
         | 
| 13 | 
            +
                    method: :info,
         | 
| 14 | 
            +
                    log_params: true
         | 
| 15 | 
            +
                  }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def self.configure(app, **opts)
         | 
| 18 | 
            +
                    opts = REE_LOGGER_DEFAULTS.merge(opts)
         | 
| 19 | 
            +
                    app.opts[:ree_logger] = ::ReeLogger::Logger.new
         | 
| 20 | 
            +
                    app.opts[:ree_logger_filter] = opts[:filter] if opts[:filter]
         | 
| 21 | 
            +
                    app.opts[:ree_logger_log_params] = !!opts[:log_params]
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  def self.start_timer
         | 
| 25 | 
            +
                    Process.clock_gettime(Process::CLOCK_MONOTONIC)
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  module InstanceMethods
         | 
| 29 | 
            +
                    private
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    # Log request/response information in common log format to logger.
         | 
| 32 | 
            +
                    def _roda_after_90__ree_logger(result)
         | 
| 33 | 
            +
                      return unless result && result[0] && result[1]
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                      if opts[:ree_logger_filter]
         | 
| 36 | 
            +
                        return if self.instance_exec(&opts[:ree_logger_filter])
         | 
| 37 | 
            +
                      end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                      elapsed_time = if timer = @_request_timer
         | 
| 40 | 
            +
                        "%0.4f" % (ReeLogger.start_timer - timer)
         | 
| 41 | 
            +
                      else
         | 
| 42 | 
            +
                        "-"
         | 
| 43 | 
            +
                      end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      env = @_request.env
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                      message = <<~DOC
         | 
| 48 | 
            +
                        Request/Response details:
         | 
| 49 | 
            +
                          Request: #{env["REQUEST_METHOD"]} #{env["QUERY_STRING"] && !env["QUERY_STRING"].empty? ? env["SCRIPT_NAME"].to_s + env["PATH_INFO"] + "?#{env["QUERY_STRING"]}": env["SCRIPT_NAME"].to_s + env["PATH_INFO"]} #{opts[:ree_logger_log_params] ? "\n  Params: " + request.params.inspect : ""}
         | 
| 50 | 
            +
                          Response status: #{response.status || "-"}#{(400..499).include?(response.status) ? "\n  Response body: " + response.body[0] : ""}
         | 
| 51 | 
            +
                          Time Taken: #{elapsed_time}
         | 
| 52 | 
            +
                      DOC
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                      opts[:ree_logger].info(message)
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                    # Create timer instance used for timing
         | 
| 58 | 
            +
                    def _roda_before_05__ree_logger
         | 
| 59 | 
            +
                      @_request_timer = ReeLogger.start_timer
         | 
| 60 | 
            +
                    end
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                register_plugin(:ree_logger, ReeLogger)
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
            end
         | 
| @@ -0,0 +1,76 @@ | |
| 1 | 
            +
            class ReeRoda::BuildActionErrors
         | 
| 2 | 
            +
              include Ree::FnDSL
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              fn :build_action_errors do
         | 
| 5 | 
            +
                link "ree_swagger/dto/error_dto", -> { ErrorDto }
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              contract(ReeActions::Action => ArrayOf[ErrorDto])
         | 
| 9 | 
            +
              def call(action)
         | 
| 10 | 
            +
                ree_object = action.action
         | 
| 11 | 
            +
                errors = recursively_extract_errors(ree_object)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                errors
         | 
| 14 | 
            +
                  .select {
         | 
| 15 | 
            +
                    _1.ancestors.include?(ReeErrors::Error) && status_from_error(_1)
         | 
| 16 | 
            +
                  }
         | 
| 17 | 
            +
                  .map {
         | 
| 18 | 
            +
                    e = _1.new
         | 
| 19 | 
            +
                    description = "type: **#{e.type}**, code: **#{e.code}**, message: **#{e.message}**"
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    ErrorDto.new(
         | 
| 22 | 
            +
                      status: status_from_error(_1),
         | 
| 23 | 
            +
                      description: description
         | 
| 24 | 
            +
                    )
         | 
| 25 | 
            +
                  }
         | 
| 26 | 
            +
                  .uniq { [_1.status, _1.description] }
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              private
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              def recursively_extract_errors(ree_object)
         | 
| 32 | 
            +
                errors = extract_errors(ree_object)
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                ree_object.links.each do |link|
         | 
| 35 | 
            +
                  obj = Ree.container.packages_facade.get_object(
         | 
| 36 | 
            +
                    link.package_name, link.object_name
         | 
| 37 | 
            +
                  )
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  if obj.fn?
         | 
| 40 | 
            +
                    errors += recursively_extract_errors(obj)
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                errors
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
              def extract_errors(ree_object)
         | 
| 48 | 
            +
                klass = ree_object.klass
         | 
| 49 | 
            +
                return [] if ree_object.object?
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                method_decorator = Ree::Contracts.get_method_decorator(
         | 
| 52 | 
            +
                  klass, :call, scope: :instance
         | 
| 53 | 
            +
                )
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                method_decorator&.errors || []
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              def status_from_error(error)
         | 
| 59 | 
            +
                case error.instance_variable_get(:@type)
         | 
| 60 | 
            +
                when :not_found
         | 
| 61 | 
            +
                  404
         | 
| 62 | 
            +
                when :invalid_param
         | 
| 63 | 
            +
                  400
         | 
| 64 | 
            +
                when :conflict
         | 
| 65 | 
            +
                  405
         | 
| 66 | 
            +
                when :auth
         | 
| 67 | 
            +
                  401
         | 
| 68 | 
            +
                when :permission
         | 
| 69 | 
            +
                  403
         | 
| 70 | 
            +
                when :payment
         | 
| 71 | 
            +
                  402
         | 
| 72 | 
            +
                when :validation
         | 
| 73 | 
            +
                  422
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
            end
         | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            class ReeRoda::BuildSwaggerFromActions
         | 
| 2 | 
            +
              include Ree::FnDSL
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              fn :build_swagger_from_actions do
         | 
| 5 | 
            +
                link :build_action_errors
         | 
| 6 | 
            +
                link :build_schema, from: :ree_swagger
         | 
| 7 | 
            +
                link "ree_swagger/dto/endpoint_dto", -> { EndpointDto }
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              contract(ArrayOf[ReeActions::Action], String, String, String, String => Hash)
         | 
| 11 | 
            +
              def call(actions, title, description, version, api_url)
         | 
| 12 | 
            +
                endpoints = actions.map do |action|
         | 
| 13 | 
            +
                  method_decorator = Ree::Contracts.get_method_decorator(
         | 
| 14 | 
            +
                    action.action.klass, :call, scope: :instance
         | 
| 15 | 
            +
                  )
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  response_status = case action.request_method
         | 
| 18 | 
            +
                  when :post
         | 
| 19 | 
            +
                    201
         | 
| 20 | 
            +
                  when :put, :delete, :patch
         | 
| 21 | 
            +
                    204
         | 
| 22 | 
            +
                  else
         | 
| 23 | 
            +
                    200
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  caster = if action.action.klass.const_defined?(:ActionCaster)
         | 
| 27 | 
            +
                    action.action.klass.const_get(:ActionCaster)
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  EndpointDto.new(
         | 
| 31 | 
            +
                    method: action.request_method,
         | 
| 32 | 
            +
                    sections: action.sections,
         | 
| 33 | 
            +
                    respond_to: action.respond_to,
         | 
| 34 | 
            +
                    path: action.path.start_with?("/") ? action.path : "/#{action.path}",
         | 
| 35 | 
            +
                    caster: caster,
         | 
| 36 | 
            +
                    serializer: action.serializer&.klass&.new,
         | 
| 37 | 
            +
                    summary: action.summary,
         | 
| 38 | 
            +
                    authenticate: action.warden_scope != :visitor,
         | 
| 39 | 
            +
                    description: method_decorator&.doc || "",
         | 
| 40 | 
            +
                    response_status: response_status,
         | 
| 41 | 
            +
                    response_description: nil,
         | 
| 42 | 
            +
                    errors: build_action_errors(action)
         | 
| 43 | 
            +
                  )
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                build_schema(
         | 
| 47 | 
            +
                  title: title,
         | 
| 48 | 
            +
                  description: description,
         | 
| 49 | 
            +
                  version: version,
         | 
| 50 | 
            +
                  api_url: api_url,
         | 
| 51 | 
            +
                  endpoints: endpoints
         | 
| 52 | 
            +
                )
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         | 
| 55 | 
            +
             | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            class ReeRoda::StatusFromError
         | 
| 2 | 
            +
              include Ree::FnDSL
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              fn :status_from_error
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              contract(Symbol => Nilor[Integer])
         | 
| 7 | 
            +
              def call(error_type)
         | 
| 8 | 
            +
                case error_type
         | 
| 9 | 
            +
                when :not_found
         | 
| 10 | 
            +
                  404
         | 
| 11 | 
            +
                when :invalid_param
         | 
| 12 | 
            +
                  400
         | 
| 13 | 
            +
                when :conflict
         | 
| 14 | 
            +
                  405
         | 
| 15 | 
            +
                when :auth
         | 
| 16 | 
            +
                  401
         | 
| 17 | 
            +
                when :permission
         | 
| 18 | 
            +
                  403
         | 
| 19 | 
            +
                when :payment
         | 
| 20 | 
            +
                  402
         | 
| 21 | 
            +
                when :validation
         | 
| 22 | 
            +
                  422
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            require "roda"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ReeRoda
         | 
| 4 | 
            +
              include Ree::PackageDSL
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              package do
         | 
| 7 | 
            +
                depends_on :ree_actions
         | 
| 8 | 
            +
                depends_on :ree_logger
         | 
| 9 | 
            +
                depends_on :ree_json
         | 
| 10 | 
            +
                depends_on :ree_hash
         | 
| 11 | 
            +
                depends_on :ree_object
         | 
| 12 | 
            +
                depends_on :ree_swagger
         | 
| 13 | 
            +
                depends_on :ree_errors
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            package_require "ree_roda/plugins/ree_logger"
         | 
| 18 | 
            +
            package_require "ree_roda/plugins/ree_actions"
         | 
| 19 | 
            +
            package_require "ree_roda/app"
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
              "schema_type": "object",
         | 
| 3 | 
            +
              "schema_version": "1.1",
         | 
| 4 | 
            +
              "name": "build_action_errors",
         | 
| 5 | 
            +
              "path": "packages/ree_roda/package/ree_roda/services/build_action_errors.rb",
         | 
| 6 | 
            +
              "mount_as": "fn",
         | 
| 7 | 
            +
              "class": "ReeRoda::BuildActionErrors",
         | 
| 8 | 
            +
              "factory": null,
         | 
| 9 | 
            +
              "methods": [
         | 
| 10 | 
            +
                {
         | 
| 11 | 
            +
                  "doc": "",
         | 
| 12 | 
            +
                  "throws": [
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  ],
         | 
| 15 | 
            +
                  "return": "ArrayOf[ReeSwagger::ErrorDto]",
         | 
| 16 | 
            +
                  "args": [
         | 
| 17 | 
            +
                    {
         | 
| 18 | 
            +
                      "arg": "action",
         | 
| 19 | 
            +
                      "arg_type": "req",
         | 
| 20 | 
            +
                      "type": "ReeActions::Action"
         | 
| 21 | 
            +
                    }
         | 
| 22 | 
            +
                  ]
         | 
| 23 | 
            +
                }
         | 
| 24 | 
            +
              ],
         | 
| 25 | 
            +
              "links": [
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              ]
         | 
| 28 | 
            +
            }
         | 
    
        data/lib/ree_lib/packages/ree_roda/schemas/ree_roda/services/build_swagger_from_actions.schema.json
    ADDED
    
    | @@ -0,0 +1,63 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
              "schema_type": "object",
         | 
| 3 | 
            +
              "schema_version": "1.1",
         | 
| 4 | 
            +
              "name": "build_swagger_from_actions",
         | 
| 5 | 
            +
              "path": "packages/ree_roda/package/ree_roda/services/build_swagger_from_actions.rb",
         | 
| 6 | 
            +
              "mount_as": "fn",
         | 
| 7 | 
            +
              "class": "ReeRoda::BuildSwaggerFromActions",
         | 
| 8 | 
            +
              "factory": null,
         | 
| 9 | 
            +
              "methods": [
         | 
| 10 | 
            +
                {
         | 
| 11 | 
            +
                  "doc": "",
         | 
| 12 | 
            +
                  "throws": [
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  ],
         | 
| 15 | 
            +
                  "return": "Hash",
         | 
| 16 | 
            +
                  "args": [
         | 
| 17 | 
            +
                    {
         | 
| 18 | 
            +
                      "arg": "actions",
         | 
| 19 | 
            +
                      "arg_type": "req",
         | 
| 20 | 
            +
                      "type": "ArrayOf[ReeActions::Action]"
         | 
| 21 | 
            +
                    },
         | 
| 22 | 
            +
                    {
         | 
| 23 | 
            +
                      "arg": "title",
         | 
| 24 | 
            +
                      "arg_type": "req",
         | 
| 25 | 
            +
                      "type": "String"
         | 
| 26 | 
            +
                    },
         | 
| 27 | 
            +
                    {
         | 
| 28 | 
            +
                      "arg": "description",
         | 
| 29 | 
            +
                      "arg_type": "req",
         | 
| 30 | 
            +
                      "type": "String"
         | 
| 31 | 
            +
                    },
         | 
| 32 | 
            +
                    {
         | 
| 33 | 
            +
                      "arg": "version",
         | 
| 34 | 
            +
                      "arg_type": "req",
         | 
| 35 | 
            +
                      "type": "String"
         | 
| 36 | 
            +
                    },
         | 
| 37 | 
            +
                    {
         | 
| 38 | 
            +
                      "arg": "api_url",
         | 
| 39 | 
            +
                      "arg_type": "req",
         | 
| 40 | 
            +
                      "type": "String"
         | 
| 41 | 
            +
                    }
         | 
| 42 | 
            +
                  ]
         | 
| 43 | 
            +
                }
         | 
| 44 | 
            +
              ],
         | 
| 45 | 
            +
              "links": [
         | 
| 46 | 
            +
                {
         | 
| 47 | 
            +
                  "target": "build_action_errors",
         | 
| 48 | 
            +
                  "package_name": "ree_roda",
         | 
| 49 | 
            +
                  "as": "build_action_errors",
         | 
| 50 | 
            +
                  "imports": [
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  ]
         | 
| 53 | 
            +
                },
         | 
| 54 | 
            +
                {
         | 
| 55 | 
            +
                  "target": "build_schema",
         | 
| 56 | 
            +
                  "package_name": "ree_swagger",
         | 
| 57 | 
            +
                  "as": "build_schema",
         | 
| 58 | 
            +
                  "imports": [
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  ]
         | 
| 61 | 
            +
                }
         | 
| 62 | 
            +
              ]
         | 
| 63 | 
            +
            }
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
              "schema_type": "object",
         | 
| 3 | 
            +
              "schema_version": "1.1",
         | 
| 4 | 
            +
              "name": "status_from_error",
         | 
| 5 | 
            +
              "path": "packages/ree_roda/package/ree_roda/services/status_from_error.rb",
         | 
| 6 | 
            +
              "mount_as": "fn",
         | 
| 7 | 
            +
              "class": "ReeRoda::StatusFromError",
         | 
| 8 | 
            +
              "factory": null,
         | 
| 9 | 
            +
              "methods": [
         | 
| 10 | 
            +
                {
         | 
| 11 | 
            +
                  "doc": "",
         | 
| 12 | 
            +
                  "throws": [
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  ],
         | 
| 15 | 
            +
                  "return": "Nilor[Integer]",
         | 
| 16 | 
            +
                  "args": [
         | 
| 17 | 
            +
                    {
         | 
| 18 | 
            +
                      "arg": "error_type",
         | 
| 19 | 
            +
                      "arg_type": "req",
         | 
| 20 | 
            +
                      "type": "Symbol"
         | 
| 21 | 
            +
                    }
         | 
| 22 | 
            +
                  ]
         | 
| 23 | 
            +
                }
         | 
| 24 | 
            +
              ],
         | 
| 25 | 
            +
              "links": [
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              ]
         | 
| 28 | 
            +
            }
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            RSpec.describe "ReeRoda" do
         | 
| 2 | 
            +
              it "generates package schema" do
         | 
| 3 | 
            +
                require "fileutils"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                packages_schema_path = Ree.locate_packages_schema(__dir__)
         | 
| 6 | 
            +
                packages_schema_dir = Pathname.new(packages_schema_path).dirname.to_s
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                FileUtils.cd packages_schema_dir do
         | 
| 9 | 
            +
                  expect(
         | 
| 10 | 
            +
                    system("REE_SKIP_ENV_VARS_CHECK=true bundle exec ree gen.package_json ree_roda --silence")
         | 
| 11 | 
            +
                  ).to eq(true)
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,84 @@ | |
| 1 | 
            +
            require "rack/test"
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            package_require("ree_roda/app")
         | 
| 4 | 
            +
            package_require("ree_actions/dsl")
         | 
| 5 | 
            +
            package_require("ree_roda/plugins/ree_actions")
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            RSpec.describe ReeRoda::App do
         | 
| 8 | 
            +
              include Rack::Test::Methods
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              before :all do
         | 
| 11 | 
            +
                Ree.enable_irb_mode
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                module ReeRodaTest
         | 
| 14 | 
            +
                  include Ree::PackageDSL
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  package
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                class ReeRodaTest::Cmd
         | 
| 20 | 
            +
                  include ReeActions::ActionDSL
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  action :cmd
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  ActionCaster = build_mapper.use(:cast) do
         | 
| 25 | 
            +
                    integer :id
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def call(access, attrs)
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                class ReeRodaTest::TestActions
         | 
| 33 | 
            +
                  include ReeActions::DSL
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  actions :test_actions do
         | 
| 36 | 
            +
                    default_warden_scope :identity
         | 
| 37 | 
            +
                    opts = {from: :ree_roda_test}
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    get "api/action/:id" do
         | 
| 40 | 
            +
                      summary "Some action"
         | 
| 41 | 
            +
                      warden_scope :visitor
         | 
| 42 | 
            +
                      sections "some_action"
         | 
| 43 | 
            +
                      action :cmd, **opts
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                class TestApp < ReeRoda::App
         | 
| 49 | 
            +
                  plugin :ree_actions
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  ree_actions ReeRodaTest::TestActions.new,
         | 
| 52 | 
            +
                    api_url: "http://some.api.url:1337",
         | 
| 53 | 
            +
                    swagger_url: "swagger"
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  route do |r|
         | 
| 56 | 
            +
                    r.get "health" do
         | 
| 57 | 
            +
                      "success"
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    r.ree_actions
         | 
| 61 | 
            +
                  end
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              after :all do
         | 
| 66 | 
            +
                Ree.disable_irb_mode
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              let(:app) { TestApp.app }
         | 
| 70 | 
            +
             | 
| 71 | 
            +
              it {
         | 
| 72 | 
            +
                get "health"
         | 
| 73 | 
            +
                expect(last_response.body).to eq("success")
         | 
| 74 | 
            +
                expect(last_response.status).to eq(200)
         | 
| 75 | 
            +
              }
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              it {
         | 
| 78 | 
            +
                get "swagger"
         | 
| 79 | 
            +
                expect(last_response.status).to eq(200)
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                get "api/v1/swagger"
         | 
| 82 | 
            +
                expect(last_response.status).to eq(404)
         | 
| 83 | 
            +
              }
         | 
| 84 | 
            +
            end
         | 
    
        data/lib/ree_lib/version.rb
    CHANGED