Skip to content

Commit

Permalink
[WIP] Handle parameters from request body.
Browse files Browse the repository at this point in the history
- simple Arrays
  • Loading branch information
LeFnord committed Sep 15, 2023
1 parent 94141e1 commit 6c9126d
Show file tree
Hide file tree
Showing 6 changed files with 4,275 additions and 41 deletions.
2 changes: 1 addition & 1 deletion lib/starter/importer/namespace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class #{@naming.klass_name} < Grape::API
private

def namespace
naming.version_klass ? "'#{naming.origin}'" : ":#{naming.resource.downcase}"
@namespace ||= naming.version_klass ? "'#{naming.origin}'" : ":#{naming.resource.downcase}"
end

def endpoints
Expand Down
70 changes: 67 additions & 3 deletions lib/starter/importer/parameter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,42 @@ def initialize(definition:, components: {})
prepare_attributes(definition:, components:)
end

def to_s
def to_s # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
entry = definition['required'] ? 'requires' : 'optional'
entry << " :#{name}"
entry << ", type: #{definition['schema']['type'].capitalize}"

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

if type == 'Array' && definition.key?('items')
sub = definition.dig('items', 'type').to_s.capitalize
type = "#{type}[#{sub}]"
# TODO: handle object/arrays and its properties
end

entry << ", type: #{type}"

doc = documentation
entry << ", #{doc}" if doc

entry
rescue StandardError => e
print e
end

private

# initialize helper
#
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

def prepare_attributes(definition:, components:)
def prepare_attributes(definition:, components:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
case kind
when :direct
@name = definition['name']
Expand All @@ -45,9 +60,58 @@ def prepare_attributes(definition:, components:)
if (value = @definition.dig('schema', '$ref').presence)
@definition['schema'] = components.dig(*value.split('/')[2..])
end
when :body
definition['in'] = 'body'
schema = definition['content'].values.first['schema']
if schema.key?('$ref')
path = schema['$ref'].split('/')[2..]

@name = path.last
@definition = handle_body(definition:, properties: components.dig(*path))
else
# TODO: make each propery its own Parameter object
@name, @definition = handle_body(definition:, properties: schema)
end
end
end

def handle_body(definition:, properties:)
print "\n - - - \n"
if object?(definition:, properties:) # a nested object -> JSON
# print "\n Objects \n"
# ap definition
# ap properties
# require 'pry'; binding.pry
elsif simple_array?(properties:)
# print "\n simple Array \n"
name = properties['properties'].keys.first
type = properties.dig('properties', name, 'type') || 'array'
subtype = properties.dig('properties', name, 'items', 'type')
final = subtype.nil? ? type : "#{type}[#{subtype}]"

definition['type'] = final
[name, definition]
else # others
# print "\n others \n"
definition.merge(properties)
end
end

# handle_body helper, check/find/define types
#
def object?(definition:, properties:)
definition['content'].keys.first.include?('application/json') ||
properties['type'] == 'object'
end

def simple_array?(properties:)
properties.key?('properties') &&
properties['properties'].length == 1 &&
properties['properties'].values.first['type'] == 'array'
end

# to_s helper
#
def documentation
tmp = {}
tmp['desc'] = definition['description'] if definition.key?('description')
Expand Down
6 changes: 3 additions & 3 deletions lib/starter/importer/specification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def segmentize(path)
[rest.shift, rest.empty? ? '/' : "/#{rest.join('/')}"]
end

def prepare_verbs(spec)
def prepare_verbs(spec) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
path_params = nil
spec.each_with_object({}) do |(verb, content), memo|
if verb == 'parameters'
Expand All @@ -56,9 +56,9 @@ def prepare_verbs(spec)
end

memo[verb] = content
next unless content.key?('parameters') || path_params
next unless content.key?('parameters') || content.key?('requestBody') || path_params

parameters = content['parameters'] || path_params
parameters = ((content['parameters'] || path_params || []) + [content['requestBody']]).compact

memo[verb]['parameters'] = parameters.each_with_object({}) do |definition, para|
parameter = Parameter.new(definition:, components:)
Expand Down
Loading

0 comments on commit 6c9126d

Please sign in to comment.