sinatra-swagger-exposer-ng 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +37 -0
  3. data/CODE_OF_CONDUCT.md +13 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +118 -0
  7. data/Rakefile +9 -0
  8. data/lib/sinatra/swagger-exposer/configuration/swagger-configuration-utilities.rb +124 -0
  9. data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-parameter.rb +113 -0
  10. data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-response.rb +96 -0
  11. data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint.rb +101 -0
  12. data/lib/sinatra/swagger-exposer/configuration/swagger-hash-like.rb +45 -0
  13. data/lib/sinatra/swagger-exposer/configuration/swagger-info.rb +73 -0
  14. data/lib/sinatra/swagger-exposer/configuration/swagger-parameter-validation-helper.rb +106 -0
  15. data/lib/sinatra/swagger-exposer/configuration/swagger-response-header.rb +68 -0
  16. data/lib/sinatra/swagger-exposer/configuration/swagger-response-headers.rb +33 -0
  17. data/lib/sinatra/swagger-exposer/configuration/swagger-type-property.rb +83 -0
  18. data/lib/sinatra/swagger-exposer/configuration/swagger-type.rb +128 -0
  19. data/lib/sinatra/swagger-exposer/configuration/swagger-types.rb +35 -0
  20. data/lib/sinatra/swagger-exposer/processing/swagger-array-value-processor.rb +46 -0
  21. data/lib/sinatra/swagger-exposer/processing/swagger-base-value-processor.rb +50 -0
  22. data/lib/sinatra/swagger-exposer/processing/swagger-file-processor-dispatcher.rb +35 -0
  23. data/lib/sinatra/swagger-exposer/processing/swagger-primitive-value-processor.rb +165 -0
  24. data/lib/sinatra/swagger-exposer/processing/swagger-processor-dispatcher.rb +69 -0
  25. data/lib/sinatra/swagger-exposer/processing/swagger-request-processor.rb +128 -0
  26. data/lib/sinatra/swagger-exposer/processing/swagger-response-processor.rb +47 -0
  27. data/lib/sinatra/swagger-exposer/processing/swagger-type-value-processor.rb +37 -0
  28. data/lib/sinatra/swagger-exposer/swagger-content-creator.rb +55 -0
  29. data/lib/sinatra/swagger-exposer/swagger-exposer.rb +258 -0
  30. data/lib/sinatra/swagger-exposer/swagger-invalid-exception.rb +16 -0
  31. data/lib/sinatra/swagger-exposer/swagger-parameter-helper.rb +73 -0
  32. data/lib/sinatra/swagger-exposer/swagger-request-processor-creator.rb +188 -0
  33. data/lib/sinatra/swagger-exposer/version.rb +5 -0
  34. data/sinatra-swagger-exposer.gemspec +30 -0
  35. 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,16 @@
1
+ module Sinatra
2
+
3
+ module SwaggerExposer
4
+
5
+ # When something is wrong
6
+ class SwaggerInvalidException < Exception
7
+
8
+ def initialize(message)
9
+ super(message)
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+
16
+ 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,5 @@
1
+ module Sinatra
2
+ module SwaggerExposer
3
+ VERSION = '0.5.0'
4
+ end
5
+ 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