class LazyApiDoc::Generator

Attributes

examples[R]

Public Class Methods

new() click to toggle source
# File lib/lazy_api_doc/generator.rb, line 7
def initialize
  @examples = []
end

Public Instance Methods

add(example) click to toggle source
# File lib/lazy_api_doc/generator.rb, line 11
def add(example)
  return if example[:controller] == "anonymous" # don't handle virtual controllers

  @examples << example
end
body_params(route, examples) click to toggle source
# File lib/lazy_api_doc/generator.rb, line 98
def body_params(route, examples)
  first = examples.first
  return unless %w[POST PATCH].include?(first['verb'])

  variants = examples.map { |example| example.params.except("controller", "action", *route[:path_params]) }
  {
    'content' => {
      first.content_type => {
        'schema' => ::LazyApiDoc::VariantsParser.new(variants).result
      }
    }
  }
end
example_group(example, examples, route) click to toggle source
# File lib/lazy_api_doc/generator.rb, line 30
def example_group(example, examples, route) # rubocop:disable Metrics/AbcSize
  {
    example['verb'].downcase => {
      "tags" => [example.controller],
      "description" => example["description"].capitalize,
      "summary" => example.action,
      "parameters" => path_params(route, examples) + query_params(examples),
      "requestBody" => body_params(route, examples),
      "responses" => examples.group_by { |ex| ex.response[:code] }.map do |code, variants|
        [
          code,
          {
            "description" => variants.first["description"].capitalize,
            "content" => {
              example.response[:content_type] => {
                "schema" => ::LazyApiDoc::VariantsParser.new(variants.map { |v| parse_body(v.response) }).result
              }
            }
          }
        ]
      end.to_h # rubocop:disable Style/MultilineBlockChain
    }.reject { |_, v| v.nil? }
  }
end
parse_body(response) click to toggle source
# File lib/lazy_api_doc/generator.rb, line 55
def parse_body(response)
  if response[:content_type].match?("json")
    JSON.parse(response[:body])
  else
    "Not a JSON response"
  end
rescue JSON::ParserError
  response[:body]
end
path_params(route, examples) click to toggle source
# File lib/lazy_api_doc/generator.rb, line 65
def path_params(route, examples)
  path_variants = examples.map { |example| example.params.slice(*route[:path_params]) }
  ::LazyApiDoc::VariantsParser.new(path_variants).result["properties"].map do |param_name, schema|
    {
      'in' => "path",
      'required' => true,
      'name' => param_name,
      'schema' => schema
    }
  end
end
query_params(examples) click to toggle source
# File lib/lazy_api_doc/generator.rb, line 77
def query_params(examples)
  query_variants = examples.map do |example|
    full_path = example.request[:full_path].split('?')
    next {} if full_path.size == 1

    # TODO: simplify it
    full_path.last.split('&').map { |part| part.split('=').map { |each| CGI.unescape(each) } }.group_by(&:first)
             .transform_values { |v| v.map(&:last) }.map { |k, v| [k, k.match?(/\[\]\z/) ? v : v.first] }.to_h
  end

  parsed = ::LazyApiDoc::VariantsParser.new(query_variants).result
  parsed["properties"].map do |param_name, schema|
    {
      'in' => "query",
      'required' => parsed['required'].include?(param_name),
      'name' => param_name,
      'schema' => schema
    }
  end
end
result() click to toggle source
# File lib/lazy_api_doc/generator.rb, line 17
def result
  result = {}
  @examples.map { |example| OpenStruct.new(example) }.sort_by(&:source_location)
           .group_by { |ex| [ex.controller, ex.action] }.map do |_, examples|
    first = examples.first
    route = ::LazyApiDoc::RouteParser.new(first.controller, first.action, first.verb).route
    doc_path = route[:doc_path]
    result[doc_path] ||= {}
    result[doc_path].merge!(example_group(first, examples, route))
  end
  result
end