class GovukTechDocs::ApiReference::Renderer

Public Class Methods

new(app, document) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 7
def initialize(app, document)
  @app = app
  @document = document

  # Load template files
  @template_api_full = get_renderer('api_reference_full.html.erb')
  @template_path = get_renderer('path.html.erb')
  @template_schema = get_renderer('schema.html.erb')
  @template_operation = get_renderer('operation.html.erb')
  @template_parameters = get_renderer('parameters.html.erb')
  @template_responses = get_renderer('responses.html.erb')
end

Public Instance Methods

api_full(info, servers) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 20
def api_full(info, servers)
  paths = ''
  paths_data = @document.paths
  paths_data.each do |path_data|
    # For some reason paths.each returns an array of arrays [title, object]
    # instead of an array of objects
    text = path_data[0]
    paths += path(text)
  end
  schemas = ''
  schemas_data = @document.components.schemas
  schemas_data.each do |schema_data|
    text = schema_data[0]
    schemas += schema(text)
  end
  @template_api_full.result(binding)
end
json_output(schema) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 165
def json_output(schema)
  properties =  schema_properties(schema)
  JSON.pretty_generate(properties)
end
json_prettyprint(data) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 170
def json_prettyprint(data)
  JSON.pretty_generate(data)
end
markdown(text) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 159
def markdown(text)
  if text
    Tilt['markdown'].new(context: @app) { text }.render
  end
end
operations(path, path_id) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 133
def operations(path, path_id)
  output = ''
  operations = get_operations(path)
  operations.compact.each do |key, operation|
    id = "#{path_id}-#{key.parameterize}"
    parameters = parameters(operation, id)
    responses = responses(operation, id)
    output += @template_operation.result(binding)
  end
  output
end
parameters(operation, operation_id) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 145
def parameters(operation, operation_id)
  parameters = operation.parameters
  id = "#{operation_id}-parameters"
  output = @template_parameters.result(binding)
  output
end
path(text) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 38
def path(text)
  path = @document.paths[text]
  id = text.parameterize
  operations = operations(path, id)
  @template_path.result(binding)
end
responses(operation, operation_id) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 152
def responses(operation, operation_id)
  responses = operation.responses
  id = "#{operation_id}-responses"
  output = @template_responses.result(binding)
  output
end
schema(text) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 45
def schema(text)
  schemas = ''
  schemas_data = @document.components.schemas
  schemas_data.each do |schema_data|
    all_of = schema_data[1]["allOf"]
    properties = []
    if !all_of.blank?
      all_of.each do |schema_nested|
        schema_nested.properties.each do |property|
          properties.push property
        end
      end
    end

    schema_data[1].properties.each do |property|
      properties.push property
    end

    if schema_data[0] == text
      title = schema_data[0]
      schema = schema_data[1]
      return @template_schema.result(binding)
    end
  end
end
schema_properties(schema_data) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 174
def schema_properties(schema_data)
  properties = Hash.new
  if defined? schema_data.properties
    schema_data.properties.each do |key, property|
      properties[key] = property
    end
  end
  properties.merge! get_all_of_hash(schema_data)
  properties_hash = Hash.new
  properties.each do |pkey, property|
    if property.type == 'object'
      properties_hash[pkey] = Hash.new
      items = property.items
      if !items.blank?
        properties_hash[pkey] = schema_properties(items)
      end
      if !property.properties.blank?
        properties_hash[pkey] = schema_properties(property)
      end
    elsif property.type == 'array'
      properties_hash[pkey] = Array.new
      items = property.items
      if !items.blank?
        properties_hash[pkey].push schema_properties(items)
      end
    else
      properties_hash[pkey] = !property.example.nil? ? property.example : property.type
    end
  end

  properties_hash
end
schemas_from_path(text) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 71
def schemas_from_path(text)
  path = @document.paths[text]
  operations = get_operations(path)
  # Get all referenced schemas
  schemas = []
  operations.compact.each_value do |operation|
    responses = operation.responses
    responses.each do |_rkey, response|
      if response.content['application/json']
        schema = response.content['application/json'].schema
        schema_name = get_schema_name(schema.node_context.source_location.to_s)
        if !schema_name.nil?
          schemas.push schema_name
        end
        schemas.concat(schemas_from_schema(schema))
      end
    end
  end
  # Render all referenced schemas
  output = ''
  schemas.uniq.each do |schema_name|
    output += schema(schema_name)
  end
  if !output.empty?
    output.prepend('<h2 id="schemas">Schemas</h2>')
  end
  output
end
schemas_from_schema(schema) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 100
def schemas_from_schema(schema)
  schemas = []
  properties = []
  schema.properties.each do |property|
    properties.push property[1]
  end
  if schema.type == 'array'
    properties.push schema.items
  end
  all_of = schema["allOf"]
  if !all_of.blank?
    all_of.each do |schema_nested|
      schema_nested.properties.each do |property|
        properties.push property[1]
      end
    end
  end
  properties.each do |property|
    # Must be a schema be referenced by another schema
    # And not a property of a schema
    if property.node_context.referenced_by.to_s.include?('#/components/schemas') &&
        !property.node_context.source_location.to_s.include?('/properties/')
      schema_name = get_schema_name(property.node_context.source_location.to_s)
    end
    if !schema_name.nil?
      schemas.push schema_name
    end
    # Check sub-properties for references
    schemas.concat(schemas_from_schema(property))
  end
  schemas
end

Private Instance Methods

get_all_of_array(schema) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 209
def get_all_of_array(schema)
  properties = Array.new
  if schema.is_a?(Array)
    schema = schema[1]
  end
  if schema["allOf"]
    all_of = schema["allOf"]
  end
  if !all_of.blank?
    all_of.each do |schema_nested|
      schema_nested.properties.each do |property|
        if property.is_a?(Array)
          property = property[1]
        end
        properties.push property
      end
    end
  end
  properties
end
get_all_of_hash(schema) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 230
def get_all_of_hash(schema)
  properties = Hash.new
  if schema["allOf"]
    all_of = schema["allOf"]
  end
  if !all_of.blank?
    all_of.each do |schema_nested|
      schema_nested.properties.each do |key, property|
        properties[key] = property
      end
    end
  end
  properties
end
get_operations(path) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 251
def get_operations(path)
  operations = {}
  operations['get'] = path.get if defined? path.get
  operations['put'] = path.put if defined? path.put
  operations['post'] = path.post if defined? path.post
  operations['delete'] = path.delete if defined? path.delete
  operations['patch'] = path.patch if defined? path.patch
  operations
end
get_renderer(file) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 245
def get_renderer(file)
  template_path = File.join(File.dirname(__FILE__), 'templates/' + file)
  template = File.open(template_path, 'r').read
  ERB.new(template)
end
get_schema_name(text) click to toggle source
# File lib/govuk_tech_docs/api_reference/api_reference_renderer.rb, line 261
def get_schema_name(text)
  unless text.is_a?(String)
    return nil
  end
  # Schema dictates that it's always components['schemas']
  text.gsub(/#\/components\/schemas\//, '')
end