module ClientApiBuilder::Router::ClassMethods

Constants

REQUIRED_BODY_HTTP_METHODS

Public Instance Methods

add_response_procs(method_name, proc) click to toggle source
# File lib/client_api_builder/router.rb, line 34
def add_response_procs(method_name, proc)
  response_procs = default_options[:response_procs].dup
  response_procs[method_name] = proc
  add_value_to_class_method(:default_options, response_procs: response_procs)
end
base_url(url = nil) click to toggle source
# File lib/client_api_builder/router.rb, line 45
def base_url(url = nil)
  return default_options[:base_url] unless url

  add_value_to_class_method(:default_options, base_url: url)
end
body_builder(builder = nil) click to toggle source
# File lib/client_api_builder/router.rb, line 51
def body_builder(builder = nil)
  return default_options[:body_builder] unless builder

  add_value_to_class_method(:default_options, body_builder: builder)
end
build_body(router, body, options) click to toggle source
# File lib/client_api_builder/router.rb, line 93
def build_body(router, body, options)
  builder = options[:body_builder] || body_builder

  case builder
  when :to_json
    body.to_json
  when :to_query
    body.to_query
  when :query_params
    ClientApiBuilder::QueryParams.to_query(body)
  else
    router.instance_exec(body, &builder)
  end
end
build_query(query) click to toggle source
# File lib/client_api_builder/router.rb, line 108
def build_query(query)
  case query_builder
  when :to_query
    query.to_query
  when :query_params
    ClientApiBuilder::QueryParams.to_query(query)
  else
    query_builder.call(query)
  end
end
connection_option(name, value) click to toggle source
# File lib/client_api_builder/router.rb, line 69
def connection_option(name, value)
  connection_options = default_options[:connection_options].dup
  connection_options[name] = value
  add_value_to_class_method(:default_options, connection_options: connection_options)
end
connection_options() click to toggle source
# File lib/client_api_builder/router.rb, line 85
def connection_options
  default_options[:connection_options]
end
default_options() click to toggle source
# File lib/client_api_builder/router.rb, line 21
def default_options
  {
    base_url: nil,
    body_builder: :to_json,
    connection_options: {},
    headers: {},
    query_builder: Hash.method_defined?(:to_query) ? :to_query : :query_params,
    query_params: {},
    response_procs: {}
  }.freeze
end
generate_route_code(method_name, path, options = {}) click to toggle source
# File lib/client_api_builder/router.rb, line 201
def generate_route_code(method_name, path, options = {})
  http_method = options[:method] || http_method(method_name)

  path = namespaces.join + path

  # instance method
  path.gsub!(/\{([a-z0-9_]+)\}/i) do |_|
    get_instance_method($1)
  end

  path_arguments = []
  path.gsub!(/:([a-z0-9_]+)/i) do |_|
    path_arguments << $1
    "#\{#{$1}\}"
  end

  has_body_param = options[:body].nil? && requires_body?(http_method, options)

  query =
    if options[:query]
      query_arguments = get_arguments(options[:query])
      str = options[:query].inspect
      str.gsub!(/"__\|\|(.+?)\|\|__"/) { $1 }
      str
    else
      query_arguments = []
      'nil'
    end

  body =
    if options[:body]
      has_body_param = false
      body_arguments = get_arguments(options[:body])
      str = options[:body].inspect
      str.gsub!(/"__\|\|(.+?)\|\|__"/) { $1 }
      str
    else
      body_arguments = []
      has_body_param ? 'body' : 'nil'
    end

  query_arguments.map!(&:to_s)
  body_arguments.map!(&:to_s)
  named_arguments = path_arguments + query_arguments + body_arguments
  named_arguments.uniq!

  expected_response_codes =
    if options[:expected_response_codes]
      options[:expected_response_codes]
    elsif options[:expected_response_code]
      [options[:expected_response_code]]
    else
      []
    end
  expected_response_codes.map!(&:to_s)

  stream_param =
    case options[:stream]
    when true,
         :file
      :file
    when :io
      :io
    end

  method_args = named_arguments.map { |arg_name| "#{arg_name}:" }
  method_args += ['body:'] if has_body_param
  method_args += ["#{stream_param}:"] if stream_param
  method_args += ['**__options__', '&block']

  code = "def #{method_name}(" + method_args.join(', ') + ")\n"
  code += "  block ||= self.class.response_proc(#{method_name.inspect})\n"
  code += "  __path__ = \"#{path}\"\n"
  code += "  __query__ = #{query}\n"
  code += "  __body__ = #{body}\n"
  code += "  __expected_response_codes__ = #{expected_response_codes.inspect}\n"
  code += "  __uri__ = build_uri(__path__, __query__, __options__)\n"
  code += "  __body__ = build_body(__body__, __options__)\n"
  code += "  __headers__ = build_headers(__options__)\n"
  code += "  __connection_options__ = build_connection_options(__options__)\n"
  code += "  @request_options = {method: #{http_method.inspect}, uri: __uri__, body: __body__, headers: __headers__, connection_options: __connection_options__}\n"
  code += "  @request_options[:#{stream_param}] = #{stream_param}\n" if stream_param

  case options[:stream]
  when true,
       :file
    code += "  @response = stream_to_file(**@request_options)\n"
  when :io
    code += "  @response = stream_to_io(**@request_options)\n"
  when :block
    code += "  @response = stream(**@request_options, &block)\n"
  else
    code += "  @response = request(**@request_options)\n"
  end

  code += "  expected_response_code!(@response, __expected_response_codes__, __options__)\n"

  if options[:stream] || options[:return] == :response
    code += "  @response\n"
  elsif options[:return] == :body
    code += "  @response.body\n"
  else
    code += "  handle_response(@response, __options__, &block)\n"
  end

  code += "end\n"
  code
end
get_arguments(value) click to toggle source
# File lib/client_api_builder/router.rb, line 175
def get_arguments(value)
  case value
  when Hash
    get_hash_arguments(value)
  when Array
    get_array_arguments(value)
  else
    []
  end
end
get_array_arguments(list) click to toggle source
# File lib/client_api_builder/router.rb, line 157
def get_array_arguments(list)
  arguments = []
  list.each_with_index do |v, idx|
    case v
    when Symbol
      list[idx] = "__||#{v}||__"
      arguments << v
    when Hash
      arguments += get_hash_arguments(v)
    when Array
      arguments += get_array_arguments(v)
    when String
      list[idx] = "__||#{$1}||__" if v =~ /\{([a-z0-9_]+)\}/i
    end
  end
  arguments
end
get_hash_arguments(hsh) click to toggle source
# File lib/client_api_builder/router.rb, line 139
def get_hash_arguments(hsh)
  arguments = []
  hsh.each do |k, v|
    case v
    when Symbol
      hsh[k] = "__||#{v}||__"
      arguments << v
    when Hash
      arguments += get_hash_arguments(v)
    when Array
      arguments += get_array_arguments(v)
    when String
      hsh[k] = "__||#{$1}||__" if v =~ /\{([a-z0-9_]+)\}/i
    end
  end
  arguments
end
get_instance_method(var) click to toggle source
# File lib/client_api_builder/router.rb, line 186
def get_instance_method(var)
   "#\{#{var}\}"
end
header(name, value = nil, &block) click to toggle source
# File lib/client_api_builder/router.rb, line 63
def header(name, value = nil, &block)
  headers = default_options[:headers].dup
  headers[name] = value || block
  add_value_to_class_method(:default_options, headers: headers)
end
headers() click to toggle source
# File lib/client_api_builder/router.rb, line 81
def headers
  default_options[:headers]
end
http_method(method_name) click to toggle source
# File lib/client_api_builder/router.rb, line 119
def http_method(method_name)
  case method_name.to_s
  when /^(?:post|create|add|insert)/i
    :post
  when /^(?:put|update|modify|change)/i
    :put
  when /^(?:delete|remove)/i
    :delete
  else
    :get
  end
end
namespace(name) { || ... } click to toggle source
# File lib/client_api_builder/router.rb, line 195
def namespace(name)
  namespaces << name
  yield
  namespaces.pop
end
namespaces() click to toggle source
# File lib/client_api_builder/router.rb, line 191
def namespaces
  @@namespaces
end
query_builder(builder = nil) click to toggle source
# File lib/client_api_builder/router.rb, line 57
def query_builder(builder = nil)
  return default_options[:query_builder] unless builder

  add_value_to_class_method(:default_options, query_builder: builder)
end
query_param(name, value = nil, &block) click to toggle source
# File lib/client_api_builder/router.rb, line 75
def query_param(name, value = nil, &block)
  query_params = default_options[:query_params].dup
  query_params[name] = value || block
  add_value_to_class_method(:default_options, query_params: query_params)
end
query_params() click to toggle source
# File lib/client_api_builder/router.rb, line 89
def query_params
  default_options[:query_params]
end
requires_body?(http_method, options) click to toggle source
# File lib/client_api_builder/router.rb, line 132
def requires_body?(http_method, options)
  return !options[:no_body] if options.key?(:no_body)
  return options[:has_body] if options.key?(:has_body)

  REQUIRED_BODY_HTTP_METHODS.include?(http_method)
end
response_proc(method_name) click to toggle source
# File lib/client_api_builder/router.rb, line 40
def response_proc(method_name)
  proc = default_options[:response_procs][method_name]
  proc
end
route(method_name, path, options = {}, &block) click to toggle source
# File lib/client_api_builder/router.rb, line 310
def route(method_name, path, options = {}, &block)
  add_response_procs(method_name, block) if block

  self.class_eval generate_route_code(method_name, path, options), __FILE__, __LINE__
end