Module: Apia::OpenApi::Helpers

Instance Method Summary collapse

Instance Method Details

#add_to_components_schemas(definition, id, **schema_opts) ⇒ Object

A component schema is a re-usable schema that can be referenced by other parts of the spec e.g. { “$ref”: “#/components/schemas/PaginationObject” }



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/apia/open_api/helpers.rb', line 10

def add_to_components_schemas(definition, id, **schema_opts)
  return true unless @spec.dig(:components, :schemas, id).nil?

  component_schema = {}
  @spec[:components][:schemas][id] = component_schema
  Objects::Schema.new(
    spec: @spec,
    definition: definition,
    schema: component_schema,
    id: id,
    **schema_opts
  ).add_to_spec

  return true if component_schema.present?

  @spec[:components][:schemas].delete(id)
  false
end

#convert_type_to_open_api_data_type(type) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/apia/open_api/helpers.rb', line 29

def convert_type_to_open_api_data_type(type)
  case type.klass.to_s
  when "Apia::Scalars::String", "Apia::Scalars::Base64", "Apia::Scalars::Date"
    "string"
  when "Apia::Scalars::Integer", "Apia::Scalars::UnixTime"
    "integer"
  when "Apia::Scalars::Decimal"
    "number"
  when "Apia::Scalars::Boolean"
    "boolean"
  else
    raise "Unknown Apia type #{type.klass} mapping to OpenAPI type"
  end
end

#formatted_description(description) ⇒ Object



93
94
95
96
97
# File 'lib/apia/open_api/helpers.rb', line 93

def formatted_description(description)
  return description if description.end_with?(".")

  "#{description}."
end

#generate_array_schema(definition) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/apia/open_api/helpers.rb', line 55

def generate_array_schema(definition)
  type = definition.type
  schema = {
    type: "array",
    items: {
      type: convert_type_to_open_api_data_type(type)
    }
  }
  schema[:description] = definition.description if definition.description.present?
  schema[:items][:format] = "float" if type.klass == Apia::Scalars::Decimal
  schema[:items][:format] = "date" if type.klass == Apia::Scalars::Date
  schema
end

#generate_id_from_definition(definition) ⇒ Object

Converts the definition id to a short version: e.g. CoreAPI/Objects/TimeZone => TimeZone



89
90
91
# File 'lib/apia/open_api/helpers.rb', line 89

def generate_id_from_definition(definition)
  definition.id.split("/").last
end

#generate_scalar_schema(definition) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/apia/open_api/helpers.rb', line 44

def generate_scalar_schema(definition)
  type = definition.type
  schema = {
    type: convert_type_to_open_api_data_type(type)
  }
  schema[:description] = definition.description if definition.description.present?
  schema[:format] = "float" if type.klass == Apia::Scalars::Decimal
  schema[:format] = "date" if type.klass == Apia::Scalars::Date
  schema
end

#generate_schema_ref(definition, id: nil, sibling_props: false, **schema_opts) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/apia/open_api/helpers.rb', line 69

def generate_schema_ref(definition, id: nil, sibling_props: false, **schema_opts)
  id ||= generate_id_from_definition(definition.type.klass.definition)
  success = add_to_components_schemas(definition, id, **schema_opts)

  # sibling_props indicates we want to allow sibling properties (typically setting nullable: true)
  # In OpenAPI 3.0 sibling properties are not allowed for $refs (but are allowed in 3.1)
  # Using allOf is a workaround to allow us to set a ref as `nullable` in OpenAPI 3.0
  if success && sibling_props
    {
      allOf: [{ "$ref": "#/components/schemas/#{id}" }]
    }
  elsif success
    { "$ref": "#/components/schemas/#{id}" }
  else # no properties were defined, so just declare an object with unknown properties
    { type: "object" }
  end
end