require "mountapi/route/parameter" require "json-schema" module Mountapi module Route # The route parameters collection # Top level access to parameters validation and casting class Parameters # @param [Array] # @return [Mountapi::Route::Parameters] # # builder def self.build(parameters = []) return parameters if parameters.is_a?(self) parameters.inject(new) do |params, param| params.add(*param) end end def initialize(parameters = []) @parameters = parameters end # buil and add param to collection def add(*args) @parameters = @parameters << Parameter.build(*args) self end # @param [Hash] inbound_params # # Cast parameter against schema and symbolize keys def cast(inbound_params) @parameters.inject({}) do |acc, param| if inbound_params.key?(param.name) acc.merge(param.name.to_sym => param.cast(inbound_params[param.name])) elsif param.default acc.merge(param.name => param.default) else acc end end end # @param [Request::Params] # @return [Hash] # # Reject request params that does not belongs to specification # Return merge all params from location to root level def filter(request_params) by_location.inject({}) do |hash, (location, params)| request_location = request_params.fetch(location.to_sym, {}) hash.merge(params.each_with_object({}) do |param, hsh| key, val = request_location.find { |k, _v| k.casecmp(param.name).zero? } # Avoid skipping nil param if param key is present and param is nullable hsh[param.name] = val if val || (key && val.nil? && param.json_schema["nullable"]) end) end end # @return [Hash] a json-schema for parameters validation def validation_schema @validation_schema ||= { "type" => "object", "required" => required_params, "properties" => params_schemas } end def by_location @parameters.group_by(&:location) end private def required_params @parameters.select(&:required).map(&:name) end def params_schemas @parameters.inject({}) do |acc, param| acc.merge(param.name => param.json_schema) end end end end end