Class: Starter::Importer::Parameter

Inherits:
Object
  • Object
show all
Defined in:
lib/starter/importer/parameter.rb

Direct Known Subclasses

NestedParams

Defined Under Namespace

Classes: Error

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(definition:, components: {}) ⇒ Parameter

Returns a new instance of Parameter.



11
12
13
14
15
# File 'lib/starter/importer/parameter.rb', line 11

def initialize(definition:, components: {})
  @nested = []
  @kind = validate_parameters(definition:, components:)
  prepare_attributes(definition:, components:)
end

Instance Attribute Details

#definitionObject

Returns the value of attribute definition.



9
10
11
# File 'lib/starter/importer/parameter.rb', line 9

def definition
  @definition
end

#kindObject

Returns the value of attribute kind.



9
10
11
# File 'lib/starter/importer/parameter.rb', line 9

def kind
  @kind
end

#nameObject

Returns the value of attribute name.



9
10
11
# File 'lib/starter/importer/parameter.rb', line 9

def name
  @name
end

#nestedObject

Returns the value of attribute nested.



9
10
11
# File 'lib/starter/importer/parameter.rb', line 9

def nested
  @nested
end

Instance Method Details

#documentationObject



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/starter/importer/parameter.rb', line 156

def documentation
  @documentation ||= begin
    tmp = {}
    tmp['desc'] = definition['description'] if definition.key?('description')
    if definition.key?('in') && !(definition['type'] == 'File' && definition['format'] == 'binary')
      tmp['in'] = definition['in']
    end

    if definition.key?('format')
      tmp['format'] = definition['format']
      tmp['type'] = 'File' if definition['format'] == 'binary'
    end

    documentation = 'documentation:'
    documentation.tap do |doc|
      doc << ' { '
      content = tmp.map { |k, v| "#{k}: '#{v}'" }
      doc << content.join(', ')
      doc << ' }'
    end
  end
end

#handle_body(definition:, properties:) ⇒ Object

rubocop:disable Metrics/MethodLength



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/starter/importer/parameter.rb', line 65

def handle_body(definition:, properties:) # rubocop:disable Metrics/MethodLength
  if simple_object?(properties:)
    name = properties['properties'].keys.first
    type = properties.dig('properties', name, 'type') || 'array'
    subtype = properties.dig('properties', name, 'items', 'type')
    definition['type'] = subtype.nil? ? type : "#{type}[#{subtype}]"

    properties.dig('properties', name).except('type').each { |k, v| definition[k] = v }
    definition['type'] = 'file' if definition['format'].presence == 'binary'

    [name, definition]
  elsif object?(definition:) # a nested object -> JSON
    definition['type'] = properties['type'].presence || 'JSON'
    return [nil, definition] if properties.nil? || properties['properties'].nil?

    properties['properties'].each do |nested_name, nested_definition|
      nested_definition['required'] = required?(properties, nested_name)
      nested = NestedParams.new(name: nested_name, definition: nested_definition)
      nested.prepare_attributes(definition: nested.definition, components: {})
      nested.name = nested_name
      @nested << nested
    end

    [self.name, definition]
  else # others
    [nil, properties ? definition.merge(properties) : definition]
  end
end

#list_of_object?(properties:) ⇒ Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/starter/importer/parameter.rb', line 106

def list_of_object?(properties:)
  properties&.key?('properties')
end

#nested?Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/starter/importer/parameter.rb', line 23

def nested?
  @nested.present?
end

#object?(definition:) ⇒ Boolean

handle_body helper, check/find/define types

Returns:

  • (Boolean)


96
97
98
99
# File 'lib/starter/importer/parameter.rb', line 96

def object?(definition:)
  definition['type'] == 'object' ||
    definition['content']&.keys&.first&.include?('application/json')
end

#prepare_attributes(definition:, components:) ⇒ Object

rubocop:disable Metrics/MethodLength



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/starter/importer/parameter.rb', line 37

def prepare_attributes(definition:, components:) # rubocop:disable Metrics/MethodLength
  case kind
  when :direct
    @name = definition['name']
    @definition = definition.except('name')
  when :ref
    found = components.dig(*definition['$ref'].split('/')[2..])
    @name = found['name']
    @definition = found.except('name')

    if (value = @definition.dig('schema', '$ref').presence)
      @definition['schema'] = components.dig(*value.split('/')[2..])
    end
  when :body
    definition['in'] = 'body'
    schema = definition['content'] ? definition['content'].values.first['schema'] : definition
    if schema.key?('$ref')
      path = schema['$ref'].split('/')[2..]

      @name, @definition = handle_body(definition:, properties: components.dig(*path))
      @name ||= path.last
    else
      @name, @definition = handle_body(definition:, properties: schema)
      @name = nested.map(&:name).join('_') if @name.nil? && nested?
    end
  end
end

#required?(property, name) ⇒ Boolean

Returns:

  • (Boolean)


110
111
112
113
114
# File 'lib/starter/importer/parameter.rb', line 110

def required?(property, name)
  return false unless property['required']

  property['required'].is_a?(Array) ? property['required'].include?(name) : property['required']
end

#serializedObject



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/starter/importer/parameter.rb', line 136

def serialized
  type = definition['type'] || definition['schema']['type']
  type.scan(/\w+/).each { |x| type.match?('JSON') ? type : type.sub!(x, x.capitalize) }

  if type == 'Array' && definition.key?('items')
    sub = definition.dig('items', 'type').to_s.capitalize
    type = "#{type}[#{sub}]"
  end

  entry = definition['required'] ? 'requires' : 'optional'
  entry << " :#{name}"
  entry << ", type: #{type}"
  entry << ", default: '#{definition['default']}'" if definition.key?('default') && definition['default'].present?
  entry << ", values: #{definition['enum'].map(&:to_s)}" if definition.key?('enum')
  doc = documentation
  entry << ", #{doc}" if doc

  entry
end

#serialized_objectObject

to_s helper



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/starter/importer/parameter.rb', line 118

def serialized_object
  definition.tap do |foo|
    foo['type'] = foo['type'] == 'object' ? 'JSON' : foo['type']
  end

  parent = NestedParams.new(name: name, definition: definition)
  entry = "#{parent} do\n"
  nested.each { |n| entry << "    #{n}\n" }
  entry << '  end'
  if entry.include?("format: 'binary', type: 'File'")
    entry.sub!('type: JSON', 'type: Hash')
    entry.sub!(", documentation: { in: 'body' }", '')
    entry.gsub!(", in: 'body'", '')
  end

  entry
end

#simple_object?(properties:) ⇒ Boolean

Returns:

  • (Boolean)


101
102
103
104
# File 'lib/starter/importer/parameter.rb', line 101

def simple_object?(properties:)
  list_of_object?(properties:) &&
    properties['properties'].length == 1
end

#to_sObject



17
18
19
20
21
# File 'lib/starter/importer/parameter.rb', line 17

def to_s
  return serialized_object if nested?

  serialized
end

#validate_parameters(definition:, components:) ⇒ Object

initialize helper

Raises:



29
30
31
32
33
34
35
# File 'lib/starter/importer/parameter.rb', line 29

def validate_parameters(definition:, components:)
  return :direct if definition.key?('name')
  return :ref if definition.key?('$ref') && components.key?('parameters')
  return :body if definition.key?('content')

  raise Error, 'no valid combination given'
end