module Sparrow ## # Encapsulates json transform methods. This is basically the core entry point # for all conversions done by the middleware. module Transformable ## # Does the conversion based on the selected strategy and HTTP header # parameters provided def transform_params transform_params_strategy.transform(ensure_json) end def handle transform_query_string end def json_body json = parsable_json_string(transform_params) JSON.parse(json) json rescue JSON::ParserError JSON.generate(ensure_json) end private def json_format if respond_to?(:env) env[Sparrow.configuration.json_format_header(type)] else nil end end # Make sure we are always dealing with a Ruby representation of a JSON # String, i.e. a Hash def ensure_json json_params = if !params.is_a?(Hash) Sparrow::Strategies::JsonFormatStrategy.convert(params) elsif params.is_a?(Hash) && params.values.compact.empty? && params.keys.one? params.keys.first else params end return JSON.parse(json_params) if json_params.is_a?(String) json_params end def parsable_json_string(transformable_params) if [Hash, Array].include? transformable_params.class JSON.generate(transformable_params) else transformable_params end end def transform_params_strategy transform_strategy_options = { camelize_ignore_uppercase_keys: Sparrow.configuration.camelize_ignore_uppercase_keys, camelize_strategy: Sparrow.configuration.camelize_strategy } transform_params = Sparrow::Strategies::TransformParams transform_params.new(transform_strategy, transform_strategy_options) end ## # Usually Query String parameters want to get transformed as well def transform_query_string env_query_hash = Rack::Utils.parse_nested_query(env['QUERY_STRING']) transformed_hash = transform_params_strategy.transform(env_query_hash) env['QUERY_STRING'] = transformed_hash.to_param end def transform_strategy default = Sparrow.configuration.default_json_key_transformation_strategy(type) strategy = json_format || default strategy.to_sym end end end