sinatra-swagger-exposer-ng 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|