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,258 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require_relative 'configuration/swagger-endpoint'
|
5
|
+
require_relative 'configuration/swagger-endpoint-parameter'
|
6
|
+
require_relative 'configuration/swagger-endpoint-response'
|
7
|
+
require_relative 'configuration/swagger-response-headers'
|
8
|
+
require_relative 'configuration/swagger-info'
|
9
|
+
require_relative 'configuration/swagger-types'
|
10
|
+
require_relative 'swagger-content-creator'
|
11
|
+
require_relative 'swagger-invalid-exception'
|
12
|
+
require_relative 'swagger-request-processor-creator'
|
13
|
+
|
14
|
+
module Sinatra
|
15
|
+
|
16
|
+
# Expose swagger API from your Sinatra app
|
17
|
+
module SwaggerExposer
|
18
|
+
|
19
|
+
# Called when we register the extension
|
20
|
+
# @param app [Sinatra::Base]
|
21
|
+
def self.registered(app)
|
22
|
+
app.set :result_validation, (ENV['RACK_ENV'] != 'production')
|
23
|
+
app.set :swagger_endpoints, []
|
24
|
+
app.set :swagger_current_endpoint_info, {}
|
25
|
+
app.set :swagger_current_endpoint_parameters, {}
|
26
|
+
app.set :swagger_current_endpoint_responses, {}
|
27
|
+
|
28
|
+
swagger_types = Sinatra::SwaggerExposer::Configuration::SwaggerTypes.new
|
29
|
+
app.set :swagger_types, swagger_types
|
30
|
+
|
31
|
+
response_headers = Sinatra::SwaggerExposer::Configuration::SwaggerResponseHeaders.new
|
32
|
+
app.set :swagger_response_headers, response_headers
|
33
|
+
|
34
|
+
app.set :swagger_processor_creator, Sinatra::SwaggerExposer::SwaggerProcessorCreator.new(swagger_types)
|
35
|
+
declare_swagger_endpoint(app)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Declare the endpoint to serve the swagger content
|
39
|
+
# @param app [Sinatra::Base]
|
40
|
+
def self.declare_swagger_endpoint(app)
|
41
|
+
app.endpoint_summary 'The swagger endpoint'
|
42
|
+
app.endpoint_tags 'swagger'
|
43
|
+
app.endpoint_response 200
|
44
|
+
app.get('/swagger_doc.json') do
|
45
|
+
swagger_content = Sinatra::SwaggerExposer::SwaggerContentCreator.new(
|
46
|
+
settings.respond_to?(:swagger_info) ? settings.swagger_info : nil,
|
47
|
+
settings.swagger_types,
|
48
|
+
settings.swagger_endpoints
|
49
|
+
).to_swagger
|
50
|
+
content_type :json
|
51
|
+
swagger_content.to_json
|
52
|
+
end
|
53
|
+
|
54
|
+
app.endpoint_summary 'Option method for the swagger endpoint, useful for some CORS stuff'
|
55
|
+
app.endpoint_tags 'swagger'
|
56
|
+
app.endpoint_response 200
|
57
|
+
app.endpoint_produces 'text/plain;charset=utf-8'
|
58
|
+
app.options('/swagger_doc.json') do
|
59
|
+
content_type :text
|
60
|
+
200
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Provide a summary for the endpoint
|
65
|
+
# @param summary [String]
|
66
|
+
def endpoint_summary(summary)
|
67
|
+
set_if_type_and_not_exist(summary, :summary, String)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Provide a path
|
71
|
+
# @param path [String]
|
72
|
+
def endpoint_path(path)
|
73
|
+
set_if_type_and_not_exist(path, :path, String)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Provide a description for the endpoint
|
77
|
+
# @param description [String]
|
78
|
+
def endpoint_description(description)
|
79
|
+
set_if_type_and_not_exist(description, :description, String)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Provide tags for the endpoint
|
83
|
+
# @param tags [Array<String>]
|
84
|
+
def endpoint_tags(*tags)
|
85
|
+
set_if_not_exist(tags, :tags)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Provide produces params for the endpoint
|
89
|
+
# @param produces [Array<String>] the response types
|
90
|
+
def endpoint_produces(*produces)
|
91
|
+
set_if_not_exist(produces, :produces)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Define parameter for the endpoint
|
95
|
+
def endpoint_parameter(name, description, how_to_pass, required, type, params = {})
|
96
|
+
parameters = settings.swagger_current_endpoint_parameters
|
97
|
+
check_if_not_duplicate(name, parameters, 'Parameter')
|
98
|
+
parameters[name] = Sinatra::SwaggerExposer::Configuration::SwaggerEndpointParameter.new(
|
99
|
+
name,
|
100
|
+
description,
|
101
|
+
how_to_pass,
|
102
|
+
required,
|
103
|
+
type,
|
104
|
+
params,
|
105
|
+
settings.swagger_types.types_names)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Define fluent endpoint dispatcher
|
109
|
+
# @param params [Hash] the parameters
|
110
|
+
def endpoint(params)
|
111
|
+
params.each_pair do |param_name, param_value|
|
112
|
+
case param_name
|
113
|
+
when :summary
|
114
|
+
endpoint_summary param_value
|
115
|
+
when :description
|
116
|
+
endpoint_description param_value
|
117
|
+
when :tags
|
118
|
+
endpoint_tags *param_value
|
119
|
+
when :produces
|
120
|
+
endpoint_produces *param_value
|
121
|
+
when :path
|
122
|
+
endpoint_path param_value
|
123
|
+
when :parameters
|
124
|
+
param_value.each do |param, args_param|
|
125
|
+
endpoint_parameter param, *args_param
|
126
|
+
end
|
127
|
+
when :responses
|
128
|
+
param_value.each do |code, args_response|
|
129
|
+
endpoint_response code, *args_response
|
130
|
+
end
|
131
|
+
else
|
132
|
+
raise SwaggerInvalidException.new("Invalid endpoint parameter [#{param_name}]")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# General information
|
138
|
+
def general_info(params)
|
139
|
+
set :swagger_info, Sinatra::SwaggerExposer::Configuration::SwaggerInfo.new(params)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Declare a type
|
143
|
+
def type(name, params)
|
144
|
+
settings.swagger_types.add_type(name, params)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Declare a response header
|
148
|
+
def response_header(name, type, description)
|
149
|
+
settings.swagger_response_headers.add_response_header(name, type, description)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Declare a response
|
153
|
+
# @param code [Integer] the response code
|
154
|
+
# @param type the type
|
155
|
+
# @param description [String] the description
|
156
|
+
# @param headers [Array<String>] the headers names
|
157
|
+
def endpoint_response(code, type = nil, description = nil, headers = [])
|
158
|
+
responses = settings.swagger_current_endpoint_responses
|
159
|
+
check_if_not_duplicate(code, responses, 'Response')
|
160
|
+
responses[code] = Sinatra::SwaggerExposer::Configuration::SwaggerEndpointResponse.new(
|
161
|
+
type,
|
162
|
+
description,
|
163
|
+
settings.swagger_types.types_names,
|
164
|
+
headers,
|
165
|
+
settings.swagger_response_headers
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
# Override Sinatra route method
|
170
|
+
def route(verb, path, options = {}, &block)
|
171
|
+
no_swagger = options[:no_swagger]
|
172
|
+
options.delete(:no_swagger)
|
173
|
+
if (verb == 'HEAD') || no_swagger
|
174
|
+
super(verb, path, options, &block)
|
175
|
+
else
|
176
|
+
request_processor = create_request_processor(verb.downcase, path, options)
|
177
|
+
super(verb, path, options) do |*params|
|
178
|
+
response = catch(:halt) do
|
179
|
+
request_processor.run(self, params, &block)
|
180
|
+
end
|
181
|
+
if settings.result_validation
|
182
|
+
begin
|
183
|
+
# Inspired from Sinatra#invoke
|
184
|
+
if (Integer === response) or (String === response)
|
185
|
+
response = [response]
|
186
|
+
end
|
187
|
+
if (Array === response) and (Integer === response.first)
|
188
|
+
response_for_validation = response.dup
|
189
|
+
response_status = response_for_validation.shift
|
190
|
+
response_body = response_for_validation.pop
|
191
|
+
response_headers = (response_for_validation.pop || {}).merge(self.response.header)
|
192
|
+
response_content_type = response_headers['Content-Type']
|
193
|
+
request_processor.validate_response(response_body, response_content_type, response_status)
|
194
|
+
elsif response.respond_to? :each
|
195
|
+
request_processor.validate_response(response.first.dup, self.response.header['Content-Type'], 200)
|
196
|
+
end
|
197
|
+
rescue Sinatra::SwaggerExposer::SwaggerInvalidException => e
|
198
|
+
content_type :json
|
199
|
+
throw :halt, [400, {:code => 400, :message => e.message}.to_json]
|
200
|
+
end
|
201
|
+
end
|
202
|
+
throw :halt, response
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
# Call for each endpoint declaration
|
210
|
+
# @return [Sinatra::SwaggerExposer::Processing::SwaggerRequestProcessor]
|
211
|
+
def create_request_processor(type, path, opts)
|
212
|
+
current_endpoint_info = settings.swagger_current_endpoint_info
|
213
|
+
current_endpoint_parameters = settings.swagger_current_endpoint_parameters
|
214
|
+
current_endpoint_responses = settings.swagger_current_endpoint_responses
|
215
|
+
endpoint = Sinatra::SwaggerExposer::Configuration::SwaggerEndpoint.new(
|
216
|
+
type,
|
217
|
+
path,
|
218
|
+
current_endpoint_parameters.values,
|
219
|
+
current_endpoint_responses.clone,
|
220
|
+
current_endpoint_info[:summary],
|
221
|
+
current_endpoint_info[:description],
|
222
|
+
current_endpoint_info[:tags],
|
223
|
+
current_endpoint_info[:path],
|
224
|
+
current_endpoint_info[:produces])
|
225
|
+
settings.swagger_endpoints << endpoint
|
226
|
+
current_endpoint_info.clear
|
227
|
+
current_endpoint_parameters.clear
|
228
|
+
current_endpoint_responses.clear
|
229
|
+
settings.swagger_processor_creator.create_request_processor(endpoint)
|
230
|
+
end
|
231
|
+
|
232
|
+
def set_if_not_exist(value, name)
|
233
|
+
if settings.swagger_current_endpoint_info.key? name
|
234
|
+
raise SwaggerInvalidException.new("#{name} with value [#{value}] already defined: [#{settings.swagger_current_endpoint_info[name]}]")
|
235
|
+
end
|
236
|
+
settings.swagger_current_endpoint_info[name] = value
|
237
|
+
end
|
238
|
+
|
239
|
+
def set_if_type_and_not_exist(value, name, type)
|
240
|
+
unless value.is_a? type
|
241
|
+
raise SwaggerInvalidException.new("#{name} [#{value}] should be a #{type.to_s.downcase}")
|
242
|
+
end
|
243
|
+
set_if_not_exist(value, name)
|
244
|
+
end
|
245
|
+
|
246
|
+
# Check if a value does not exist in a hash and throw an Exception
|
247
|
+
# @param key the key to validate
|
248
|
+
# @param values [Hash] the existing keys
|
249
|
+
# @param name [String] the valud name for the error message
|
250
|
+
def check_if_not_duplicate(key, values, name)
|
251
|
+
if values.key? key
|
252
|
+
raise SwaggerInvalidException.new("#{name} already exist for #{key} with value [#{values[key]}]")
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Sinatra
|
2
|
+
|
3
|
+
module SwaggerExposer
|
4
|
+
|
5
|
+
# Helper for handling the parameters
|
6
|
+
module SwaggerParameterHelper
|
7
|
+
|
8
|
+
HOW_TO_PASS_BODY = 'body'
|
9
|
+
HOW_TO_PASS_HEADER = 'header'
|
10
|
+
HOW_TO_PASS_PATH = 'path'
|
11
|
+
HOW_TO_PASS_QUERY = 'query'
|
12
|
+
HOW_TO_PASS = [HOW_TO_PASS_PATH, HOW_TO_PASS_QUERY, HOW_TO_PASS_HEADER, 'formData', HOW_TO_PASS_BODY]
|
13
|
+
|
14
|
+
TYPE_BOOLEAN = 'boolean'
|
15
|
+
TYPE_BYTE = 'byte'
|
16
|
+
TYPE_DATE = 'date'
|
17
|
+
TYPE_DOUBLE = 'double'
|
18
|
+
TYPE_DATE_TIME = 'dateTime'
|
19
|
+
TYPE_FLOAT = 'float'
|
20
|
+
TYPE_INTEGER = 'integer'
|
21
|
+
TYPE_LONG = 'long'
|
22
|
+
TYPE_NUMBER = 'number'
|
23
|
+
TYPE_PASSWORD = 'password'
|
24
|
+
TYPE_STRING = 'string'
|
25
|
+
TYPE_ARRAY = 'array'
|
26
|
+
|
27
|
+
PRIMITIVE_TYPES = [
|
28
|
+
TYPE_INTEGER,
|
29
|
+
TYPE_LONG,
|
30
|
+
TYPE_FLOAT,
|
31
|
+
TYPE_DOUBLE,
|
32
|
+
TYPE_STRING,
|
33
|
+
TYPE_BYTE,
|
34
|
+
TYPE_BOOLEAN,
|
35
|
+
TYPE_DATE,
|
36
|
+
TYPE_DATE_TIME,
|
37
|
+
TYPE_PASSWORD,
|
38
|
+
]
|
39
|
+
|
40
|
+
TYPE_FILE = 'file'
|
41
|
+
|
42
|
+
PRIMITIVE_TYPES_FOR_NON_BODY = [TYPE_STRING, TYPE_NUMBER, TYPE_INTEGER, TYPE_BOOLEAN]
|
43
|
+
|
44
|
+
PARAMS_FORMAT = :format
|
45
|
+
PARAMS_DEFAULT = :default
|
46
|
+
PARAMS_EXAMPLE = :example
|
47
|
+
|
48
|
+
# For numbers
|
49
|
+
PARAMS_MINIMUM = :minimum
|
50
|
+
PARAMS_MAXIMUM = :maximum
|
51
|
+
PARAMS_EXCLUSIVE_MINIMUM = :exclusiveMinimum
|
52
|
+
PARAMS_EXCLUSIVE_MAXIMUM = :exclusiveMaximum
|
53
|
+
|
54
|
+
# For strings
|
55
|
+
PARAMS_MIN_LENGTH = :minLength
|
56
|
+
PARAMS_MAX_LENGTH = :maxLength
|
57
|
+
|
58
|
+
PARAMS_LIST = [
|
59
|
+
PARAMS_FORMAT,
|
60
|
+
PARAMS_DEFAULT,
|
61
|
+
PARAMS_EXAMPLE,
|
62
|
+
PARAMS_MINIMUM,
|
63
|
+
PARAMS_MAXIMUM,
|
64
|
+
PARAMS_EXCLUSIVE_MINIMUM,
|
65
|
+
PARAMS_EXCLUSIVE_MAXIMUM,
|
66
|
+
PARAMS_MIN_LENGTH,
|
67
|
+
PARAMS_MAX_LENGTH,
|
68
|
+
]
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require_relative 'swagger-parameter-helper'
|
2
|
+
|
3
|
+
require_relative 'processing/swagger-array-value-processor'
|
4
|
+
require_relative 'processing/swagger-file-processor-dispatcher'
|
5
|
+
require_relative 'processing/swagger-processor-dispatcher'
|
6
|
+
require_relative 'processing/swagger-primitive-value-processor'
|
7
|
+
require_relative 'processing/swagger-request-processor'
|
8
|
+
require_relative 'processing/swagger-response-processor'
|
9
|
+
require_relative 'processing/swagger-type-value-processor'
|
10
|
+
|
11
|
+
module Sinatra
|
12
|
+
|
13
|
+
module SwaggerExposer
|
14
|
+
|
15
|
+
# Create processor from configuration
|
16
|
+
class SwaggerProcessorCreator
|
17
|
+
|
18
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
19
|
+
|
20
|
+
# Initialize
|
21
|
+
# @param types [Sinatra::SwaggerExposer::SwaggerTypes]
|
22
|
+
def initialize(types)
|
23
|
+
@types = types
|
24
|
+
end
|
25
|
+
|
26
|
+
# Create an endpoint processor
|
27
|
+
# @param swagger_endpoint [Sinatra::SwaggerExposer::Configuration::SwaggerEndpoint] the endpoint
|
28
|
+
# @return [Sinatra::SwaggerExposer::Processing::SwaggerRequestProcessor]
|
29
|
+
def create_request_processor(swagger_endpoint)
|
30
|
+
request_processor = Sinatra::SwaggerExposer::Processing::SwaggerRequestProcessor.new(swagger_endpoint.produces)
|
31
|
+
|
32
|
+
swagger_endpoint.parameters.each do |parameter|
|
33
|
+
if TYPE_FILE == parameter.type
|
34
|
+
dispatcher = Sinatra::SwaggerExposer::Processing::SwaggerFileProcessorDispatcher.new(
|
35
|
+
parameter.name,
|
36
|
+
parameter.required
|
37
|
+
)
|
38
|
+
else
|
39
|
+
processor = create_parameter_value_processor(parameter)
|
40
|
+
dispatcher = Sinatra::SwaggerExposer::Processing::SwaggerProcessorDispatcher.new(
|
41
|
+
parameter.how_to_pass,
|
42
|
+
processor
|
43
|
+
)
|
44
|
+
end
|
45
|
+
if dispatcher.useful?
|
46
|
+
request_processor.add_dispatcher(dispatcher)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
swagger_endpoint.responses.each_pair do |code, endpoint_response|
|
51
|
+
response_value_processor = create_response_value_processor(endpoint_response)
|
52
|
+
response_processor = Sinatra::SwaggerExposer::Processing::SwaggerResponseProcessor.new(
|
53
|
+
endpoint_response,
|
54
|
+
response_value_processor
|
55
|
+
)
|
56
|
+
request_processor.add_response_processor(
|
57
|
+
code,
|
58
|
+
response_processor.useful? ? response_processor : nil
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
request_processor
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Create a response processor
|
68
|
+
# @param endpoint_response [Sinatra::SwaggerExposer::Configuration::SwaggerEndpointResponse]
|
69
|
+
# @return [Sinatra::SwaggerExposer::Processing::SwaggerTypeValueProcessor]
|
70
|
+
def create_response_value_processor(endpoint_response)
|
71
|
+
response_type = endpoint_response.type
|
72
|
+
if response_type == TYPE_ARRAY
|
73
|
+
processor_for_values = create_processor_for_type('Response', endpoint_response.items, false)
|
74
|
+
Sinatra::SwaggerExposer::Processing::SwaggerArrayValueProcessor.new('Response', true, processor_for_values)
|
75
|
+
elsif response_type == TYPE_FILE
|
76
|
+
# Don't validate the files' content
|
77
|
+
nil
|
78
|
+
elsif response_type
|
79
|
+
create_processor_for_type('Response', response_type, false)
|
80
|
+
else
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Create a parameter processor for a parameter
|
86
|
+
# @param parameter [Sinatra::SwaggerExposer::Configuration::SwaggerEndpointParameter]
|
87
|
+
# @return [Sinatra::SwaggerExposer::Processing::SwaggerTypeValueProcessor]
|
88
|
+
def create_parameter_value_processor(parameter)
|
89
|
+
type_name = parameter.type
|
90
|
+
if type_name == TYPE_ARRAY
|
91
|
+
if PRIMITIVE_TYPES.include? parameter.items
|
92
|
+
processor_for_values = Sinatra::SwaggerExposer::Processing::SwaggerPrimitiveValueProcessor.new(
|
93
|
+
parameter.name,
|
94
|
+
false,
|
95
|
+
parameter.items,
|
96
|
+
parameter.default,
|
97
|
+
parameter.params
|
98
|
+
)
|
99
|
+
else
|
100
|
+
processor_for_values = create_processor_for_type(parameter.name, parameter.items, false)
|
101
|
+
end
|
102
|
+
Sinatra::SwaggerExposer::Processing::SwaggerArrayValueProcessor.new(
|
103
|
+
parameter.name,
|
104
|
+
parameter.required,
|
105
|
+
processor_for_values
|
106
|
+
)
|
107
|
+
elsif PRIMITIVE_TYPES.include? type_name
|
108
|
+
Sinatra::SwaggerExposer::Processing::SwaggerPrimitiveValueProcessor.new(
|
109
|
+
parameter.name,
|
110
|
+
parameter.required,
|
111
|
+
type_name,
|
112
|
+
parameter.default,
|
113
|
+
parameter.params
|
114
|
+
)
|
115
|
+
else
|
116
|
+
create_processor_for_type(parameter.name, parameter.type, parameter.required)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Create a type parameter processor for a type parameter
|
121
|
+
# @param parameter_name [String] the parameter name
|
122
|
+
# @param parameter_type [String] the parameter type
|
123
|
+
# @param parameter_required [TrueClass] if the parameter is required
|
124
|
+
# @return [Sinatra::SwaggerExposer::Processing::SwaggerTypeValueProcessor]
|
125
|
+
def create_processor_for_type(parameter_name, parameter_type, parameter_required)
|
126
|
+
attributes_processors = create_attributes_processors_for_type(parameter_type)
|
127
|
+
Sinatra::SwaggerExposer::Processing::SwaggerTypeValueProcessor.new(
|
128
|
+
parameter_name,
|
129
|
+
parameter_required,
|
130
|
+
attributes_processors
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Get attributes processor for a type
|
135
|
+
# @param type_name [String] the type name
|
136
|
+
# @return [Array<Sinatra::SwaggerExposer::Processing::SwaggerBaseValueProcessor>]
|
137
|
+
def create_attributes_processors_for_type(type_name)
|
138
|
+
type = @types[type_name]
|
139
|
+
attributes_processors = []
|
140
|
+
type.properties.each_pair do |property_name, property|
|
141
|
+
attributes_processors <<
|
142
|
+
create_processor_for_property(
|
143
|
+
property_name,
|
144
|
+
property,
|
145
|
+
type.required.include?(property.name)
|
146
|
+
)
|
147
|
+
end
|
148
|
+
if type.extends
|
149
|
+
attributes_processors = attributes_processors + create_attributes_processors_for_type(type.extends)
|
150
|
+
end
|
151
|
+
attributes_processors
|
152
|
+
end
|
153
|
+
|
154
|
+
# Create a processor for a type property
|
155
|
+
# @param type_property [Sinatra::SwaggerExposer::Configuration::SwaggerTypeProperty]
|
156
|
+
# @return [Sinatra::SwaggerExposer::Processing::SwaggerBaseValueProcessor]
|
157
|
+
def create_processor_for_property(name, type_property, required)
|
158
|
+
property_type = type_property.type
|
159
|
+
if property_type == TYPE_ARRAY
|
160
|
+
if PRIMITIVE_TYPES.include? type_property.items
|
161
|
+
processor_for_values = Sinatra::SwaggerExposer::Processing::SwaggerPrimitiveValueProcessor.new(
|
162
|
+
name,
|
163
|
+
false,
|
164
|
+
type_property.items,
|
165
|
+
type_property.properties[:default],
|
166
|
+
type_property.properties
|
167
|
+
)
|
168
|
+
else
|
169
|
+
processor_for_values = create_processor_for_type(name, type_property.items, false)
|
170
|
+
end
|
171
|
+
Sinatra::SwaggerExposer::Processing::SwaggerArrayValueProcessor.new(name, required, processor_for_values)
|
172
|
+
elsif PRIMITIVE_TYPES.include? property_type
|
173
|
+
Sinatra::SwaggerExposer::Processing::SwaggerPrimitiveValueProcessor.new(
|
174
|
+
name,
|
175
|
+
required,
|
176
|
+
property_type,
|
177
|
+
type_property.properties[:default],
|
178
|
+
type_property.properties
|
179
|
+
)
|
180
|
+
else
|
181
|
+
create_processor_for_type(name, property_type, required)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sinatra/swagger-exposer/version'
|
5
|
+
|
6
|
+
excluded_patterns = ['test/', 'example/', '.travis.yml', '.gitignore']
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = 'sinatra-swagger-exposer-ng'
|
10
|
+
spec.version = Sinatra::SwaggerExposer::VERSION
|
11
|
+
spec.authors = ['Julien Kirch', 'Camille Paquet']
|
12
|
+
|
13
|
+
spec.summary = %q{Expose swagger API from your Sinatra app}
|
14
|
+
spec.description = %q{This Sinatra extension enable you to add metadata to your code to expose your API as a Swagger endpoint and to validate and enrich the invocation parameters. Fork from Julien Kirch.}
|
15
|
+
spec.homepage = 'https://github.com/ultragreen/sinatra-swagger-exposer'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| excluded_patterns.any? { |ep| f.start_with?(ep) } }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'sinatra', '~> 2.1'
|
22
|
+
spec.add_dependency 'mime-types', '~> 3.4'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler'
|
25
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
26
|
+
spec.add_development_dependency 'minitest', '~> 5.14'
|
27
|
+
spec.add_development_dependency 'rack-test', '~> 1.1'
|
28
|
+
spec.add_development_dependency 'simplecov'
|
29
|
+
|
30
|
+
end
|