%-
def extract_attributes(schema, properties)
attributes = []
_, properties = schema.dereference(properties)
properties.each do |key, value|
# found a reference to another element:
_, value = schema.dereference(value)
# include top level reference to nested things, when top level is nullable
if value.has_key?('type') && value['type'].include?('null') && (value.has_key?('items') || value.has_key?('properties'))
attributes << build_attribute(schema, key, value)
end
if value.has_key?('anyOf')
descriptions = []
examples = []
anyof = value['anyOf']
anyof.each do |ref|
_, nested_field = schema.dereference(ref)
descriptions << nested_field['description'] if nested_field['description']
examples << nested_field['example'] if nested_field['example']
end
# avoid repetition :}
description = if descriptions.size > 1
descriptions.first.gsub!(/ of (this )?.*/, "")
descriptions[1..-1].map { |d| d.gsub!(/unique /, "") }
[descriptions[0...-1].join(", "), descriptions.last].join(" or ")
else
description = descriptions.last
end
example = [*examples].map { |e| "`#{e.to_json}`" }.join(" or ")
attributes << [key, "string", description, example]
# found a nested object
elsif value['properties']
nested = extract_attributes(schema, value['properties'])
nested.each do |attribute|
attribute[0] = "#{key}:#{attribute[0]}"
end
attributes.concat(nested)
# found an array with nested objects
elsif value['items'] && value['items']['properties']
nested = extract_attributes(schema, value['items']['properties'])
nested.each do |attribute|
attribute[0] = "#{key}/#{attribute[0]}"
end
attributes.concat(nested)
# just a regular attribute
else
attributes << build_attribute(schema, key, value)
end
end
return attributes
end
def build_attribute(schema, key, value)
description = value['description'] || ""
if value['default']
description += "
**default:** `#{value['default'].to_json}`"
end
if value['minimum'] || value['maximum']
description += "
**Range:** `"
if value['minimum']
comparator = value['exclusiveMinimum'] ? "<" : "<="
description += "#{value['minimum'].to_json} #{comparator} "
end
description += "value"
if value['maximum']
comparator = value['exclusiveMaximum'] ? "<" : "<="
description += " #{comparator} #{value['maximum'].to_json}"
end
description += "`"
end
if value['enum']
description += '
**one of:**' + [*value['enum']].map { |e| "`#{e.to_json}`" }.join(" or ")
end
if value['pattern']
description += "
**pattern:** #{value['pattern'].gsub /\|/, '|'}
"
end
if value['minLength'] || value['maxLength']
description += "
**Length:** `"
if value['minLength']
description += "#{value['minLength'].to_json}"
end
unless value['minLength'] == value['maxLength']
if value['maxLength']
unless value['minLength']
description += "0"
end
description += "..#{value['maxLength'].to_json}"
else
description += "..∞"
end
end
description += "`"
end
if value.has_key?('example')
example = if value['example'].is_a?(Hash) && value['example'].has_key?('oneOf')
value['example']['oneOf'].map { |e| "`#{e.to_json}`" }.join(" or ")
else
"`#{value['example'].to_json}`"
end
elsif value['type'] == ['array'] && value.has_key?('items')
example = "`#{schema.schema_value_example(value)}`"
elsif value['type'].include?('null')
example = "`null`"
end
type = if value['type'].include?('null')
'nullable '
else
''
end
type += (value['format'] || (value['type'] - ['null']).first)
[key, type, description, example]
end
def build_link_path(schema, link)
link['href'].gsub(%r|(\{\([^\)]+\)\})|) do |ref|
ref = ref.gsub('%2F', '/').gsub('%23', '#').gsub(%r|[\{\(\)\}]|, '')
ref_resource = ref.split('#/definitions/').last.split('/').first.gsub('-','_')
identity_key, identity_value = schema.dereference(ref)
if identity_value.has_key?('anyOf')
'{' + ref_resource + '_' + identity_value['anyOf'].map {|r| r['$ref'].split('/').last}.join('_or_') + '}'
else
'{' + ref_resource + '_' + identity_key.split('/').last + '}'
end
end
end
%>