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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4fcf6c8efdac0057fcb228a1c7f1c5baaeb1ea7e5a5852dcc706622b4aec6627
4
+ data.tar.gz: 311b3f769095d3e17f3010eaff435e4947a6ccb3d8263a1f08ff86bcfe9757b0
5
+ SHA512:
6
+ metadata.gz: 29a5246b5ce296df3a5e6854df5ca1da37545ee3e3f6368d2843f458218f6be73230fd31b200402c30415200a9a91666f8ba59eebcc042a2c1eeb08656e62aa4
7
+ data.tar.gz: 1cabaa25bd0e87c9dd9d6f05a5ae947a9eb5edbb52e8919f181db0dcfd2216d09ffee354780c85b3f438c466290bc6548628f17734850508b196f253ea8c4a2e
data/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ # 0.6.0
2
+
3
+ - Fix when an html content is expected and no content type is specified
4
+ - Prevents conflicts with Sinatra::Json library, fix by Grant McLendon
5
+
6
+ # 0.5.0
7
+
8
+ - Fix for header parameters
9
+ - Accept file parameter
10
+
11
+ # 0.4.0
12
+
13
+ - Validate responses
14
+ - No validation when the parameter is null
15
+ - Accept :no_swagger param in declaration
16
+
17
+ # 0.3.0
18
+
19
+ - Can now accept types as parameters
20
+ - Accept json utf-8 content type
21
+
22
+ # 0.2.0
23
+
24
+ - Fix empty value returned from validation when a parameter is a String
25
+ - Added maxLength and minLength validations
26
+ - Add produces parameter
27
+ - Add fluent syntax
28
+
29
+ # 0.1.0
30
+
31
+ - Added verification and enrichment form params
32
+ - Added type extends
33
+ - Added validation for min and max value for numbers
34
+
35
+ # 0.0.1
36
+
37
+ - First version
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'codeclimate-test-reporter', group: :test, require: nil
6
+ gem 'coveralls', require: false
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Julien Kirch
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # Sinatra::SwaggerExposer
2
+
3
+ [![Code Climate](https://codeclimate.com/github/archiloque/sinatra-swagger-exposer/badges/gpa.svg)](https://codeclimate.com/github/archiloque/sinatra-swagger-exposer)
4
+ [![Build Status](https://travis-ci.org/archiloque/sinatra-swagger-exposer.svg?branch=master)](https://travis-ci.org/archiloque/sinatra-swagger-exposer)
5
+ [![Coverage Status](https://coveralls.io/repos/archiloque/sinatra-swagger-exposer/badge.svg?branch=master)](https://coveralls.io/r/archiloque/sinatra-swagger-exposer?branch=master)
6
+
7
+ Create Swagger endpoint for your Sinatra application.
8
+
9
+ This Sinatra extension enable you to add metadata to your code to
10
+
11
+ - expose your API as a [Swagger](http://swagger.io) endpoint.
12
+ - validate and enrich the invocation parameters
13
+ - validate the responses during test and development
14
+
15
+ I'm adding features as I need them and it currently doesn't use all the Swagger options, so if you need one that is missing please open an issue.
16
+
17
+ ## Design choices
18
+
19
+ - All the declarations are validated when the server is started
20
+ - The declarations are defined to look as ruby-ish as possible
21
+ - Declarations are used for parameters validation and enrichment
22
+
23
+ ## Usage
24
+
25
+ Bring in the 'sinatra-swagger-exposer' gem from [rubygems](https://rubygems.org/gems/sinatra-swagger-exposer).
26
+
27
+ To use it in your app :
28
+
29
+ ```ruby
30
+ require 'sinatra/swagger-exposer/swagger-exposer'
31
+
32
+ class MyApp < Sinatra::Base
33
+
34
+ register Sinatra::SwaggerExposer
35
+
36
+ general_info(
37
+ {
38
+ version: '0.0.1',
39
+ title: 'My app',
40
+ description: 'My wonderful app',
41
+ license: {
42
+ name: 'MIT',
43
+ url: 'http://opensource.org/licenses/MIT'
44
+ }
45
+ }
46
+ )
47
+
48
+ type 'Status',
49
+ {
50
+ :properties => {
51
+ :status => {
52
+ :type => String,
53
+ :example => 'OK',
54
+ },
55
+ },
56
+ :required => [:status]
57
+ }
58
+
59
+ endpoint_description 'Base method to ping'
60
+ endpoint_response 200, 'Status', 'Standard response'
61
+ endpoint_tags 'Ping'
62
+ get '/' do
63
+ json({'status' => 'OK'})
64
+ end
65
+
66
+ end
67
+ ```
68
+
69
+ The swagger json endpoint will be exposed at `/swagger_doc.json`.
70
+
71
+ You can also use a more fluent variant by providing a hash to the `endpoint` method
72
+
73
+
74
+ ```ruby
75
+ endpoint :description => 'Base method to ping',
76
+ :responses { 200 => ['Status', 'Standard response']}
77
+ :tags 'Ping'
78
+ get '/' do
79
+ json({'status' => 'OK'})
80
+ end
81
+ ```
82
+
83
+ The hash should contains the key `description`, `summary`, `path`, `tags`, `responses` and `params`.
84
+ Note both `responses` and `params` takes a hash as argument `hash(param_name =>param_details)` and `hash(status_code=>res_param)`
85
+
86
+ If the equivalent methods have more than one param, theses are wrapped in an array.
87
+
88
+
89
+ ## Detailed example
90
+
91
+ A more complete example is available [here](https://github.com/archiloque/sinatra-swagger-exposer/tree/master/example).
92
+
93
+ ## About swagger-ui
94
+
95
+ - If you to use [swagger-ui](https://github.com/swagger-api/swagger-ui) with your app you will need to add croo-origin setup.
96
+ The easiest way is to use the [sinatra-cross_origin](https://github.com/britg/sinatra-cross_origin) gem. Fro a simple sample you can have a look at [example application](https://github.com/archiloque/sinatra-swagger-exposer/tree/master/example).
97
+ - Swagger-ui doesn't work with all the swagger features
98
+ - Some of them like parameters maximum and minimum values are ignored
99
+ - Some of them like extending types make the endpoint unusable
100
+
101
+ ## Changes
102
+
103
+ Changelog is [here](https://github.com/archiloque/sinatra-swagger-exposer/blob/master/CHANGELOG.md).
104
+
105
+ ## Resources
106
+
107
+ - [Swagger RESTful API Documentation Specification](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md).
108
+ - [Swagger json examples](https://github.com/swagger-api/swagger-spec/tree/master/examples/v2.0/json).
109
+ - [The swagger json schema](https://raw.githubusercontent.com/swagger-api/swagger-spec/master/schemas/v2.0/schema.json).
110
+
111
+ ## Todo
112
+
113
+ - More parameters taken into account
114
+ - More validations where possible
115
+
116
+ ## License
117
+
118
+ This software is released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.pattern = 'test/**/test-*.rb'
7
+ end
8
+
9
+ task :default => :test
@@ -0,0 +1,124 @@
1
+ require_relative '../swagger-invalid-exception'
2
+ require_relative '../swagger-parameter-helper'
3
+
4
+ module Sinatra
5
+
6
+ module SwaggerExposer
7
+
8
+ module Configuration
9
+
10
+ module SwaggerConfigurationUtilities
11
+
12
+ include ::Sinatra::SwaggerExposer::SwaggerParameterHelper
13
+
14
+ def ref_to_type(type)
15
+ {'$ref' => "#/definitions/#{type}"}
16
+ end
17
+
18
+ def hash_to_swagger(hash)
19
+ result = {}
20
+ hash.each_pair do |key, value|
21
+ result[key] = value.to_swagger
22
+ end
23
+ result
24
+ end
25
+
26
+ # Transform a type into a String
27
+ # @return [String]
28
+ def type_to_s(value)
29
+ if [TrueClass, FalseClass].include? value
30
+ TYPE_BOOLEAN
31
+ elsif value == DateTime
32
+ TYPE_DATE_TIME
33
+ elsif value.is_a? Class
34
+ value.to_s.downcase
35
+ else
36
+ value
37
+ end
38
+ end
39
+
40
+ def get_type(type, possible_values)
41
+ @type = type
42
+ if type.nil?
43
+ raise SwaggerInvalidException.new('Type is nil')
44
+ elsif type.is_a?(String) || @type.is_a?(Class)
45
+ @type = type_to_s(@type)
46
+ check_type(@type, possible_values)
47
+ elsif @type.is_a? Array
48
+ @items = type_to_s(get_array_type(@type))
49
+ check_type(@items, possible_values)
50
+ @type = TYPE_ARRAY
51
+ else
52
+ raise SwaggerInvalidException.new("Type [#{@type}] of has an unknown type, should be a class, a string or an array")
53
+ end
54
+ end
55
+
56
+ # Validate if a parameter is in a list of available values
57
+ # @param params [Hash] the parameters
58
+ # @param allowed_values [Enumerable, #include?] the allowed values
59
+ # @param ignored_values [Enumerable, #include?] values to ignore
60
+ # @return [Hash] the filtered hash
61
+ def white_list_params(params, allowed_values, ignored_values = [])
62
+ result = {}
63
+ params.each_pair do |key, value|
64
+ if allowed_values.include? key
65
+ result[key] = value
66
+ elsif !ignored_values.include?(key)
67
+ raise SwaggerInvalidException.new("Unknown property [#{key}] with value [#{value}]#{list_or_none(allowed_values, 'properties')}")
68
+ end
69
+ end
70
+ result
71
+ end
72
+
73
+ def list_or_none(list, name)
74
+ if list.empty?
75
+ ", no available #{name}"
76
+ else
77
+ ", possible #{name} are #{list.sort.join(', ')}"
78
+ end
79
+ end
80
+
81
+ # Validate if a value is suitable for a name
82
+ # @param name [String] the name
83
+ # @return [NilClass]
84
+ def check_name(name)
85
+ unless name.is_a?(String) || name.is_a?(Symbol)
86
+ raise SwaggerInvalidException.new("Name [#{name}] should be a string or a symbol")
87
+ end
88
+ name = name.to_s
89
+ if name.empty?
90
+ raise SwaggerInvalidException.new('Name should not be empty')
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def get_array_type(array)
97
+ if array.empty?
98
+ raise SwaggerInvalidException.new('Type is an empty array, you should specify a type as the array content')
99
+ elsif array.length > 1
100
+ raise SwaggerInvalidException.new("Type [#{array}] has more than one entry, it should only have one")
101
+ else
102
+ type_to_s(array[0])
103
+ end
104
+ end
105
+
106
+ # Validate if a type is in a list of available values
107
+ # @param type [String] the parameter
108
+ # @param allowed_values [Enumerable, #include?] the allowed values
109
+ # @return [NilClass]
110
+ def check_type(type, allowed_values)
111
+ if allowed_values.empty?
112
+ raise SwaggerInvalidException.new("Unknown type [#{type}], no available type")
113
+ elsif !allowed_values.include?(type)
114
+ raise SwaggerInvalidException.new("Unknown type [#{type}]#{list_or_none(allowed_values, 'types')}")
115
+ end
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,113 @@
1
+ require_relative '../swagger-invalid-exception'
2
+
3
+ require_relative 'swagger-parameter-validation-helper'
4
+ require_relative 'swagger-type-property'
5
+ require_relative 'swagger-configuration-utilities'
6
+
7
+ module Sinatra
8
+
9
+ module SwaggerExposer
10
+
11
+ module Configuration
12
+
13
+ class SwaggerEndpointParameter
14
+
15
+ include SwaggerConfigurationUtilities
16
+ include SwaggerParameterValidationHelper
17
+
18
+ attr_reader :type, :name, :required, :default, :params, :items, :how_to_pass
19
+
20
+ # Create a new instance
21
+ # @param name [String] the name
22
+ # @param description [String] the description
23
+ # @param how_to_pass [String] how to pass the parameter
24
+ # @param required [TrueClass] if the parameter is required
25
+ # @param type [String] the type name
26
+ # @param params [Hash] parameters
27
+ # @param known_types [Array<String>] known custom types names
28
+ def initialize(name, description, how_to_pass, required, type, params, known_types)
29
+ check_name(name)
30
+ @name = name
31
+
32
+ if description
33
+ @description = description
34
+ end
35
+
36
+ how_to_pass = how_to_pass.to_s
37
+ unless HOW_TO_PASS.include? how_to_pass
38
+ raise SwaggerInvalidException.new("Unknown how to pass value [#{how_to_pass}]#{list_or_none(HOW_TO_PASS, 'registered types')}")
39
+ end
40
+ @how_to_pass = how_to_pass
41
+
42
+ if @how_to_pass == HOW_TO_PASS_BODY
43
+ get_type(type, PRIMITIVE_TYPES + known_types + [TYPE_FILE])
44
+ else
45
+ get_type(type, PRIMITIVE_TYPES_FOR_NON_BODY)
46
+ end
47
+
48
+ unless [true, false].include? required
49
+ raise SwaggerInvalidException.new("Required should be a boolean instead of [#{required}]")
50
+ end
51
+ @required = required
52
+
53
+ params = white_list_params(params, PARAMS_LIST, SwaggerTypeProperty::PROPERTIES)
54
+ validate_params(@type == TYPE_ARRAY ? @items : @type, params)
55
+ @default = params[PARAMS_DEFAULT]
56
+ @params = params
57
+ end
58
+
59
+
60
+ # Return the swagger version
61
+ # @return [Hash]
62
+ def to_swagger
63
+ result = {
64
+ :name => @name,
65
+ :in => @how_to_pass,
66
+ :required => @required
67
+ }
68
+
69
+ if @type
70
+ if @type == TYPE_ARRAY
71
+ result[:type] = TYPE_ARRAY
72
+ if @items
73
+ if PRIMITIVE_TYPES.include? @items
74
+ result[:items] = {:type => @items}
75
+ else
76
+ result[:schema] = ref_to_type(@items)
77
+ end
78
+ end
79
+ else
80
+ if PRIMITIVE_TYPES.include? @type
81
+ result[:type] = @type
82
+ else
83
+ result[:schema] = ref_to_type(@type)
84
+ end
85
+ end
86
+ end
87
+
88
+ if @description
89
+ result[:description] = @description
90
+ end
91
+ unless @params.empty?
92
+ result.merge!(@params)
93
+ end
94
+
95
+ result
96
+ end
97
+
98
+ def to_s
99
+ {
100
+ :name => @name,
101
+ :in => @how_to_pass,
102
+ :required => @required,
103
+ :type => @type,
104
+ :items => @items,
105
+ :description => @description,
106
+ :params => @params,
107
+ }.to_json
108
+ end
109
+
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,96 @@
1
+ require_relative '../swagger-invalid-exception'
2
+
3
+ require_relative 'swagger-configuration-utilities'
4
+
5
+ module Sinatra
6
+
7
+ module SwaggerExposer
8
+
9
+ module Configuration
10
+
11
+ class SwaggerEndpointResponse
12
+
13
+ include SwaggerConfigurationUtilities
14
+
15
+ attr_reader :type, :items
16
+
17
+ RESPONSE_PRIMITIVES_FILES = PRIMITIVE_TYPES + [TYPE_FILE]
18
+
19
+ # @param type the type
20
+ # @param description [String] the description
21
+ # @param known_types [Array<String>] known custom types names
22
+ # @param headers [Array<String] the headers names
23
+ # @param known_headers [Sinatra::SwaggerExposer::Configuration::SwaggerResponseHeaders] the known headers
24
+ def initialize(type, description, known_types, headers, known_headers)
25
+ if type
26
+ get_type(type, known_types + RESPONSE_PRIMITIVES_FILES)
27
+ end
28
+
29
+ if description
30
+ @description = description
31
+ end
32
+
33
+ @headers = {}
34
+ headers.each do |header_name|
35
+ header_name = header_name.to_s
36
+ if @headers.key? header_name
37
+ raise SwaggerInvalidException.new("Duplicated header_name [#{header_name}]")
38
+ end
39
+ unless known_headers.key? header_name
40
+ raise SwaggerInvalidException.new("Unknown header_name [#{header_name}]")
41
+ end
42
+ @headers[header_name] = known_headers[header_name]
43
+ end
44
+
45
+ end
46
+
47
+ def to_swagger
48
+ result = {}
49
+
50
+ if @type
51
+ if @type == TYPE_ARRAY
52
+ schema = {:type => TYPE_ARRAY}
53
+ if @items
54
+ if RESPONSE_PRIMITIVES_FILES.include? @items
55
+ schema[:items] = {:type => @items}
56
+ else
57
+ schema[:items] = ref_to_type(@items)
58
+ end
59
+ end
60
+ result[:schema] = schema
61
+ else
62
+ if RESPONSE_PRIMITIVES_FILES.include? @type
63
+ result[:schema] = {:type => @type}
64
+ else
65
+ result[:schema] = ref_to_type(@type)
66
+ end
67
+ end
68
+ end
69
+
70
+ if @description
71
+ result[:description] = @description
72
+ end
73
+
74
+ unless @headers.empty?
75
+ swagged_headers = {}
76
+ @headers.each_pair do |name, value|
77
+ swagged_headers[name] = value.to_swagger
78
+ end
79
+ result[:headers] = swagged_headers
80
+ end
81
+
82
+ result
83
+ end
84
+
85
+ def to_s
86
+ {
87
+ :type => @type,
88
+ :items => @items,
89
+ :description => @description,
90
+ }.to_json
91
+ end
92
+
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,101 @@
1
+ require_relative '../swagger-invalid-exception'
2
+
3
+ require_relative 'swagger-configuration-utilities'
4
+
5
+ module Sinatra
6
+
7
+ module SwaggerExposer
8
+
9
+ module Configuration
10
+
11
+ # An endpoint
12
+ class SwaggerEndpoint
13
+
14
+ include SwaggerConfigurationUtilities
15
+
16
+ attr_reader :path, :type, :parameters, :responses, :produces
17
+
18
+ # @param type [String] the http verb
19
+ # @param sinatra_path [String] the sinatra path
20
+ # @param parameters [Array<Sinatra::SwaggerExposer::Configuration::SwaggerEndpoint>] the endpoint parameters
21
+ # @param responses [Hash<Integer, Sinatra::SwaggerExposer::Configuration::SwaggerEndpointResponse>] the endpoint possible responses
22
+ # @param summary [String] a summary for the endpoint
23
+ # @param description [String] a description for the endpoint
24
+ # @param tags [Array<String>] a list of tags
25
+ # @param explicit_path [String] an explicit path if the sinatra path is a regex
26
+ # @param produces [Array<String>] the result types
27
+ def initialize(type, sinatra_path, parameters, responses, summary, description, tags, explicit_path, produces)
28
+ @type = type
29
+ @path = swagger_path(sinatra_path, explicit_path)
30
+
31
+ @parameters = parameters
32
+ @responses = responses
33
+ @produces = produces
34
+
35
+ @attributes = {}
36
+ if summary
37
+ @attributes[:summary] = summary
38
+ end
39
+ if description
40
+ @attributes[:description] = description
41
+ end
42
+ if tags
43
+ @attributes[:tags] = tags
44
+ end
45
+ if produces
46
+ @attributes[:produces] = produces
47
+ end
48
+ end
49
+
50
+ # Return a swagger version
51
+ # @return [Hash]
52
+ def to_swagger
53
+ result = @attributes.clone
54
+
55
+ unless @parameters.empty?
56
+ result[:parameters] = @parameters.collect { |parameter| parameter.to_swagger }
57
+ end
58
+
59
+ unless @responses.empty?
60
+ result[:responses] = hash_to_swagger(@responses)
61
+ end
62
+
63
+ result
64
+ end
65
+
66
+ REGEX_PATH_PARAM_MIDDLE = /\A(.*\/)\:([a-z]+)\/(.+)\z/
67
+ REGEX_PATH_PARAM_END = /\A(.*)\/:([a-z]+)\z/
68
+
69
+ # Get the endpoint swagger path
70
+ # @param sinatra_path the path declared in the sinatra app
71
+ # @param explicit_path an explicit path the user can specify
72
+ def swagger_path(sinatra_path, explicit_path)
73
+ if explicit_path
74
+ explicit_path
75
+ elsif sinatra_path.is_a? String
76
+ while (m = REGEX_PATH_PARAM_MIDDLE.match(sinatra_path))
77
+ sinatra_path = "#{m[1]}{#{m[2]}}/#{m[3]}"
78
+ end
79
+ if (m = REGEX_PATH_PARAM_END.match(sinatra_path))
80
+ sinatra_path = "#{m[1]}/{#{m[2]}}"
81
+ end
82
+ sinatra_path
83
+ else
84
+ raise SwaggerInvalidException.new("You need to specify a path when using a non-string path [#{sinatra_path}]")
85
+ end
86
+ end
87
+
88
+ def to_s
89
+ {
90
+ :type => @type,
91
+ :path => @path,
92
+ :attributes => @attributes,
93
+ :parameters => @parameters,
94
+ :responses => @responses,
95
+ }.to_json
96
+ end
97
+
98
+ end
99
+ end
100
+ end
101
+ end