sinatra-swagger-exposer-ng 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +37 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +118 -0
- data/Rakefile +9 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-configuration-utilities.rb +124 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-parameter.rb +113 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-response.rb +96 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint.rb +101 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-hash-like.rb +45 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-info.rb +73 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-parameter-validation-helper.rb +106 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-response-header.rb +68 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-response-headers.rb +33 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-type-property.rb +83 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-type.rb +128 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-types.rb +35 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-array-value-processor.rb +46 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-base-value-processor.rb +50 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-file-processor-dispatcher.rb +35 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-primitive-value-processor.rb +165 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-processor-dispatcher.rb +69 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-request-processor.rb +128 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-response-processor.rb +47 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-type-value-processor.rb +37 -0
- data/lib/sinatra/swagger-exposer/swagger-content-creator.rb +55 -0
- data/lib/sinatra/swagger-exposer/swagger-exposer.rb +258 -0
- data/lib/sinatra/swagger-exposer/swagger-invalid-exception.rb +16 -0
- data/lib/sinatra/swagger-exposer/swagger-parameter-helper.rb +73 -0
- data/lib/sinatra/swagger-exposer/swagger-request-processor-creator.rb +188 -0
- data/lib/sinatra/swagger-exposer/version.rb +5 -0
- data/sinatra-swagger-exposer.gemspec +30 -0
- metadata +176 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../swagger-parameter-helper'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
|
5
|
+
module SwaggerExposer
|
6
|
+
|
7
|
+
module Processing
|
8
|
+
|
9
|
+
# Fake dispatcher for files
|
10
|
+
class SwaggerFileProcessorDispatcher
|
11
|
+
|
12
|
+
# Initialize
|
13
|
+
# @param name [String] the name
|
14
|
+
# @param required [TrueClass] if the parameter is required
|
15
|
+
def initialize(name, required)
|
16
|
+
@name = name
|
17
|
+
@required = required
|
18
|
+
end
|
19
|
+
|
20
|
+
def useful?
|
21
|
+
@required
|
22
|
+
end
|
23
|
+
|
24
|
+
# Process the value
|
25
|
+
def process(app, parsed_body)
|
26
|
+
if app.params.key?(@name.to_s) && (!app.params[@name.to_s].nil?)
|
27
|
+
elsif @required
|
28
|
+
raise SwaggerInvalidException.new("Mandatory value [#{@name}] is missing")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
require_relative 'swagger-base-value-processor'
|
4
|
+
require_relative '../swagger-parameter-helper'
|
5
|
+
require_relative '../swagger-invalid-exception'
|
6
|
+
|
7
|
+
module Sinatra
|
8
|
+
|
9
|
+
module SwaggerExposer
|
10
|
+
|
11
|
+
module Processing
|
12
|
+
|
13
|
+
# Validate primitive value
|
14
|
+
class SwaggerPrimitiveValueProcessor < SwaggerBaseValueProcessor
|
15
|
+
|
16
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
17
|
+
|
18
|
+
attr_reader :type, :params
|
19
|
+
|
20
|
+
# Initialize
|
21
|
+
# @param name [String] the name
|
22
|
+
# @param required [TrueClass] if the parameter is required
|
23
|
+
# @param type [String] the type name
|
24
|
+
# @param default [Object] the default value
|
25
|
+
# @param params [Hash] parameters
|
26
|
+
def initialize(name, required, type, default, params)
|
27
|
+
super(name, required, default)
|
28
|
+
@type = type
|
29
|
+
@params = params
|
30
|
+
end
|
31
|
+
|
32
|
+
def useful?
|
33
|
+
super ||
|
34
|
+
[TYPE_NUMBER, TYPE_INTEGER, TYPE_BOOLEAN, TYPE_DATE_TIME].include?(@type) || # Must check type
|
35
|
+
(@params.key? PARAMS_MIN_LENGTH) || (@params.key? PARAMS_MAX_LENGTH) # Must check string
|
36
|
+
end
|
37
|
+
|
38
|
+
# Dispatch method
|
39
|
+
def validate_value(value)
|
40
|
+
case @type
|
41
|
+
when TYPE_NUMBER
|
42
|
+
return validate_value_number(value)
|
43
|
+
when TYPE_INTEGER
|
44
|
+
return validate_value_integer(value)
|
45
|
+
when TYPE_BOOLEAN
|
46
|
+
return validate_value_boolean(value)
|
47
|
+
when TYPE_DATE_TIME
|
48
|
+
return validate_value_date_time(value)
|
49
|
+
else
|
50
|
+
return validate_value_string(value)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Validate a boolean
|
55
|
+
def validate_value_boolean(value)
|
56
|
+
if (value == 'true') || value.is_a?(TrueClass)
|
57
|
+
true
|
58
|
+
elsif (value == 'false') || value.is_a?(FalseClass)
|
59
|
+
false
|
60
|
+
else
|
61
|
+
raise SwaggerInvalidException.new("Value [#{name}] should be an boolean but is [#{value}]")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Validate an integer
|
66
|
+
def validate_value_integer(value)
|
67
|
+
begin
|
68
|
+
f = Float(value)
|
69
|
+
i = Integer(value)
|
70
|
+
if f == i
|
71
|
+
i
|
72
|
+
else
|
73
|
+
raise SwaggerInvalidException.new("Value [#{name}] should be an integer but is [#{value}]")
|
74
|
+
end
|
75
|
+
value = Integer(value)
|
76
|
+
validate_numerical_value(value)
|
77
|
+
value
|
78
|
+
rescue ArgumentError
|
79
|
+
raise SwaggerInvalidException.new("Value [#{name}] should be an integer but is [#{value}]")
|
80
|
+
rescue TypeError
|
81
|
+
raise SwaggerInvalidException.new("Value [#{name}] should be an integer but is [#{value}]")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Validate a number value
|
86
|
+
def validate_value_number(value)
|
87
|
+
begin
|
88
|
+
value = Float(value)
|
89
|
+
validate_numerical_value(value)
|
90
|
+
return value
|
91
|
+
rescue ArgumentError
|
92
|
+
raise SwaggerInvalidException.new("Value [#{name}] should be a float but is [#{value}]")
|
93
|
+
rescue TypeError
|
94
|
+
raise SwaggerInvalidException.new("Value [#{name}] should be a float but is [#{value}]")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Validate a numerical value
|
99
|
+
# @param value [Numeric] the value
|
100
|
+
def validate_numerical_value(value)
|
101
|
+
validate_numerical_value_internal(
|
102
|
+
value,
|
103
|
+
PARAMS_MINIMUM,
|
104
|
+
PARAMS_EXCLUSIVE_MINIMUM,
|
105
|
+
'>=',
|
106
|
+
'>')
|
107
|
+
validate_numerical_value_internal(
|
108
|
+
value,
|
109
|
+
PARAMS_MAXIMUM,
|
110
|
+
PARAMS_EXCLUSIVE_MAXIMUM,
|
111
|
+
'<=',
|
112
|
+
'<')
|
113
|
+
end
|
114
|
+
|
115
|
+
# Validate a date time
|
116
|
+
def validate_value_date_time(value)
|
117
|
+
begin
|
118
|
+
DateTime.rfc3339(value)
|
119
|
+
rescue ArgumentError
|
120
|
+
raise SwaggerInvalidException.new("Value [#{name}] should be a date time but is [#{value}]")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Validate a string
|
125
|
+
def validate_value_string(value)
|
126
|
+
if value
|
127
|
+
validate_value_string_length(value, PARAMS_MIN_LENGTH, '>=')
|
128
|
+
validate_value_string_length(value, PARAMS_MAX_LENGTH, '<=')
|
129
|
+
end
|
130
|
+
value
|
131
|
+
end
|
132
|
+
|
133
|
+
# Validate the length of a string
|
134
|
+
# @param value the value to check
|
135
|
+
# @param limit_param_name [Symbol] the param that contain the value to compare to
|
136
|
+
# @param limit_param_method [String] the comparison method to call
|
137
|
+
def validate_value_string_length(value, limit_param_name, limit_param_method)
|
138
|
+
if @params.key? limit_param_name
|
139
|
+
target_value = @params[limit_param_name]
|
140
|
+
unless value.length.send(limit_param_method, target_value)
|
141
|
+
raise SwaggerInvalidException.new("Value [#{name}] length should be #{limit_param_method} than #{target_value} but is #{value.length} for [#{value}]")
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Validate the value of a number
|
147
|
+
# @param value the value to check
|
148
|
+
# @param limit_param_name [Symbol] the param that contain the value to compare to
|
149
|
+
# @param exclusive_limit_param_name [Symbol] the param that indicates if the comparison is absolute
|
150
|
+
# @param limit_param_method [String] the comparison method to call
|
151
|
+
# @param exclusive_limit_param_method [String] the absolute comparison method to call
|
152
|
+
def validate_numerical_value_internal(value, limit_param_name, exclusive_limit_param_name, limit_param_method, exclusive_limit_param_method)
|
153
|
+
if @params.key? limit_param_name
|
154
|
+
target_value = @params[limit_param_name]
|
155
|
+
method_to_call = @params[exclusive_limit_param_name] ? exclusive_limit_param_method : limit_param_method
|
156
|
+
unless value.send(method_to_call, target_value)
|
157
|
+
raise SwaggerInvalidException.new("Value [#{name}] should be #{method_to_call} than [#{target_value}] but is [#{value}]")
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative '../swagger-parameter-helper'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
|
5
|
+
module SwaggerExposer
|
6
|
+
|
7
|
+
module Processing
|
8
|
+
|
9
|
+
# Make headers available as a Hash
|
10
|
+
class HashForHeaders < Hash
|
11
|
+
|
12
|
+
def initialize(app)
|
13
|
+
@app = app
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](name)
|
17
|
+
@app.request.env[key_to_header_key(name)]
|
18
|
+
end
|
19
|
+
|
20
|
+
def key?(name)
|
21
|
+
@app.request.env.key?(key_to_header_key(name))
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# In rack the headers name are transformed
|
27
|
+
def key_to_header_key(key)
|
28
|
+
"HTTP_#{key.gsub(/-/o, '_').upcase}"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
# Dispatch content to a processor
|
34
|
+
class SwaggerProcessorDispatcher
|
35
|
+
|
36
|
+
attr_reader :how_to_pass, :processor
|
37
|
+
|
38
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
39
|
+
|
40
|
+
# Initialize
|
41
|
+
# @param how_to_pass how the value should be passed to the processor
|
42
|
+
# @param processor [Sinatra::SwaggerExposer::Processing::SwaggerBaseValueProcessor] processor for the values
|
43
|
+
def initialize(how_to_pass, processor)
|
44
|
+
@how_to_pass = how_to_pass
|
45
|
+
@processor = processor
|
46
|
+
end
|
47
|
+
|
48
|
+
def useful?
|
49
|
+
(@how_to_pass != HOW_TO_PASS_PATH) && @processor.useful?
|
50
|
+
end
|
51
|
+
|
52
|
+
# Process the value
|
53
|
+
def process(app, parsed_body)
|
54
|
+
case @how_to_pass
|
55
|
+
when HOW_TO_PASS_PATH
|
56
|
+
# can't validate
|
57
|
+
when HOW_TO_PASS_QUERY
|
58
|
+
@processor.process(app.params)
|
59
|
+
when HOW_TO_PASS_HEADER
|
60
|
+
@processor.process(HashForHeaders.new(app))
|
61
|
+
when HOW_TO_PASS_BODY
|
62
|
+
@processor.process(parsed_body || {})
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'mime-types'
|
3
|
+
|
4
|
+
require_relative '../swagger-invalid-exception'
|
5
|
+
|
6
|
+
module Sinatra
|
7
|
+
|
8
|
+
module SwaggerExposer
|
9
|
+
|
10
|
+
module Processing
|
11
|
+
|
12
|
+
# Custom mime types that matches everything when '*' is in list
|
13
|
+
class AllMimesTypes
|
14
|
+
|
15
|
+
def like?(other)
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
# A processor for a request, apply the parameters processors then execute the query code
|
22
|
+
class SwaggerRequestProcessor
|
23
|
+
|
24
|
+
attr_reader :processors_dispatchers, :response_processors, :produces
|
25
|
+
|
26
|
+
# @param produces [Array<String>]
|
27
|
+
def initialize(produces = nil)
|
28
|
+
@processors_dispatchers = []
|
29
|
+
@response_processors = {}
|
30
|
+
@produces = produces
|
31
|
+
if produces
|
32
|
+
@produces_types = produces.collect do |produce|
|
33
|
+
if produce == '*'
|
34
|
+
[Sinatra::SwaggerExposer::Processing::AllMimesTypes.new]
|
35
|
+
else
|
36
|
+
MIME::Types[produce]
|
37
|
+
end
|
38
|
+
end.flatten
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param dispatcher [Sinatra::SwaggerExposer::Processing::SwaggerProcessorDispatcher]
|
43
|
+
def add_dispatcher(dispatcher)
|
44
|
+
@processors_dispatchers << dispatcher
|
45
|
+
end
|
46
|
+
|
47
|
+
# @param response_processor [Sinatra::SwaggerExposer::Processing::SwaggerResponseProcessor]
|
48
|
+
def add_response_processor(code, response_processor)
|
49
|
+
@response_processors[code] = response_processor
|
50
|
+
end
|
51
|
+
|
52
|
+
JSON_CONTENT_TYPE = MIME::Types['application/json'].first
|
53
|
+
HTML_CONTENT_TYPE = MIME::Types['text/html'].first
|
54
|
+
|
55
|
+
# Run the processor the call the route content
|
56
|
+
# @param app the sinatra app being run
|
57
|
+
# @param block_params [Array] the block parameters
|
58
|
+
# @param block the block containing the route content
|
59
|
+
def run(app, block_params, &block)
|
60
|
+
parsed_body = {}
|
61
|
+
if JSON_CONTENT_TYPE.like?(app.env['CONTENT_TYPE'])
|
62
|
+
body = app.request.body.read
|
63
|
+
unless body.empty?
|
64
|
+
begin
|
65
|
+
parsed_body = JSON.parse(body)
|
66
|
+
rescue JSON::ParserError => e
|
67
|
+
return [400, {:code => 400, :message => e.message}.to_json]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
app.params['parsed_body'] = parsed_body
|
72
|
+
unless @processors_dispatchers.empty?
|
73
|
+
@processors_dispatchers.each do |processor_dispatcher|
|
74
|
+
begin
|
75
|
+
processor_dispatcher.process(app, parsed_body)
|
76
|
+
rescue SwaggerInvalidException => e
|
77
|
+
app.content_type :json
|
78
|
+
return [400, {:code => 400, :message => e.message}.to_json]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
if block
|
83
|
+
# Execute the block in the context of the app
|
84
|
+
app.instance_exec(*block_params, &block)
|
85
|
+
else
|
86
|
+
''
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Validate the response
|
91
|
+
# @param response_body [String] the body
|
92
|
+
# @param content_type [String] the content type
|
93
|
+
# @param response_status [Integer] the status
|
94
|
+
def validate_response(response_body, content_type, response_status)
|
95
|
+
validate_response_content_type(content_type, response_status)
|
96
|
+
if @response_processors.key?(response_status)
|
97
|
+
response_processor = response_processors[response_status]
|
98
|
+
if JSON_CONTENT_TYPE.like?(content_type) && response_processor
|
99
|
+
response_processor.validate_response(response_body)
|
100
|
+
end
|
101
|
+
else
|
102
|
+
raise SwaggerInvalidException.new("Status with unknown response status [#{response_status}], known statuses are [#{@response_processors.keys.join(', ')}] response value is #{response_body}")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Validate a response content type
|
107
|
+
# @param content_type [String] the content type to validate
|
108
|
+
# @param response_status [Integer] the status
|
109
|
+
def validate_response_content_type(content_type, response_status)
|
110
|
+
if content_type.nil? && (response_status == 204)
|
111
|
+
# No content and no content type => everything is OK
|
112
|
+
elsif @produces
|
113
|
+
# if there is no content type Sinatra will default to html so we simulate it here
|
114
|
+
if content_type.nil? && @produces_types.any? { |produce| produce.like?(HTML_CONTENT_TYPE) }
|
115
|
+
content_type = HTML_CONTENT_TYPE
|
116
|
+
end
|
117
|
+
unless @produces_types.any? { |produce| produce.like?(content_type) }
|
118
|
+
raise SwaggerInvalidException.new("Undeclared content type [#{content_type}], declared content type are [#{@produces.join(', ')}]")
|
119
|
+
end
|
120
|
+
elsif !JSON_CONTENT_TYPE.like?(content_type)
|
121
|
+
raise SwaggerInvalidException.new("Undeclared content type [#{content_type}], if no declaration for the endpoint you should only return json")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative '../swagger-parameter-helper'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
|
5
|
+
module SwaggerExposer
|
6
|
+
|
7
|
+
module Processing
|
8
|
+
|
9
|
+
# Process a response
|
10
|
+
class SwaggerResponseProcessor
|
11
|
+
|
12
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
13
|
+
|
14
|
+
attr_reader :endpoint_response, :processor
|
15
|
+
|
16
|
+
# Initialize
|
17
|
+
# @param endpoint_response [Sinatra::SwaggerExposer::Configuration::SwaggerEndpointResponse]
|
18
|
+
# @param processor [Sinatra::SwaggerExposer::Processing::SwaggerTypeValueProcessor]
|
19
|
+
def initialize(endpoint_response, processor)
|
20
|
+
@endpoint_response = endpoint_response
|
21
|
+
@processor = processor
|
22
|
+
end
|
23
|
+
|
24
|
+
# Test if the processor is useful
|
25
|
+
# @return [TrueClass]
|
26
|
+
def useful?
|
27
|
+
(@endpoint_response && (@endpoint_response.type != TYPE_FILE)) || @processor
|
28
|
+
end
|
29
|
+
|
30
|
+
# Validate a response
|
31
|
+
# @param response_body [String] the body
|
32
|
+
def validate_response(response_body)
|
33
|
+
parsed_response_body = nil
|
34
|
+
begin
|
35
|
+
parsed_response_body = ::JSON.parse(response_body)
|
36
|
+
rescue ::JSON::ParserError => e
|
37
|
+
raise SwaggerInvalidException.new("Response is not a valid json [#{response_body}]")
|
38
|
+
end
|
39
|
+
if @processor
|
40
|
+
@processor.validate_value(parsed_response_body)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative 'swagger-base-value-processor'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
|
5
|
+
module SwaggerExposer
|
6
|
+
|
7
|
+
module Processing
|
8
|
+
|
9
|
+
# A processor for a type parameter
|
10
|
+
class SwaggerTypeValueProcessor < SwaggerBaseValueProcessor
|
11
|
+
|
12
|
+
attr_reader :attributes_processors
|
13
|
+
|
14
|
+
# Initialize
|
15
|
+
# @param name [String] the name
|
16
|
+
# @param required [TrueClass] if the parameter is required
|
17
|
+
# @param attributes_processors [Array<Sinatra::SwaggerExposer::Processing::SwaggerBaseValueProcessor>] the attributes processors
|
18
|
+
def initialize(name, required, attributes_processors)
|
19
|
+
super(name, required, nil)
|
20
|
+
@attributes_processors = attributes_processors
|
21
|
+
end
|
22
|
+
|
23
|
+
def useful?
|
24
|
+
super || (!(@attributes_processors.empty?))
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate_value(value)
|
28
|
+
@attributes_processors.each do |attribute_processor|
|
29
|
+
attribute_processor.process(value)
|
30
|
+
end
|
31
|
+
value
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Sinatra
|
2
|
+
|
3
|
+
module SwaggerExposer
|
4
|
+
|
5
|
+
# Create the swagger content
|
6
|
+
class SwaggerContentCreator
|
7
|
+
|
8
|
+
def initialize(swagger_info, swagger_types, swagger_endpoints)
|
9
|
+
@swagger_info = swagger_info
|
10
|
+
@swagger_types = swagger_types
|
11
|
+
@swagger_endpoints = swagger_endpoints
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_swagger
|
15
|
+
result = {
|
16
|
+
swagger: '2.0',
|
17
|
+
consumes: ['application/json'],
|
18
|
+
produces: ['application/json'],
|
19
|
+
}
|
20
|
+
if @swagger_info
|
21
|
+
result[:info] = @swagger_info.to_swagger
|
22
|
+
end
|
23
|
+
|
24
|
+
swagger_types_as_swagger = @swagger_types.to_swagger
|
25
|
+
if swagger_types_as_swagger
|
26
|
+
result[:definitions] = swagger_types_as_swagger
|
27
|
+
end
|
28
|
+
|
29
|
+
unless @swagger_endpoints.empty?
|
30
|
+
result_endpoints = {}
|
31
|
+
|
32
|
+
# swagger need the endpoints to be grouped by path
|
33
|
+
endpoints_by_path = @swagger_endpoints.group_by { |endpoint| endpoint.path }
|
34
|
+
endpoints_by_path.keys.sort.each do |path|
|
35
|
+
endpoints = endpoints_by_path[path]
|
36
|
+
|
37
|
+
result_endpoints_for_path = {}
|
38
|
+
endpoints.each do |endpoint|
|
39
|
+
result_endpoints_for_path[endpoint.type] = endpoint.to_swagger
|
40
|
+
end
|
41
|
+
|
42
|
+
result_endpoints[path] = result_endpoints_for_path
|
43
|
+
|
44
|
+
end
|
45
|
+
result[:paths] = result_endpoints
|
46
|
+
end
|
47
|
+
|
48
|
+
result
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|