sinatra-swagger-exposer 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile +0 -1
- data/README.md +1 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-configuration-utilities.rb +124 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-parameter.rb +15 -20
- data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-response.rb +39 -7
- data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint.rb +21 -8
- data/lib/sinatra/swagger-exposer/configuration/swagger-hash-like.rb +45 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-info.rb +9 -8
- 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 +7 -6
- data/lib/sinatra/swagger-exposer/configuration/swagger-type.rb +10 -9
- data/lib/sinatra/swagger-exposer/configuration/swagger-types.rb +4 -20
- data/lib/sinatra/swagger-exposer/processing/swagger-array-value-processor.rb +46 -0
- data/lib/sinatra/swagger-exposer/processing/{swagger-base-value-preprocessor.rb → swagger-base-value-processor.rb} +9 -7
- data/lib/sinatra/swagger-exposer/processing/{swagger-parameter-preprocessor.rb → swagger-parameter-processor.rb} +9 -9
- data/lib/sinatra/swagger-exposer/processing/{swagger-primitive-value-preprocessor.rb → swagger-primitive-value-processor.rb} +46 -46
- data/lib/sinatra/swagger-exposer/processing/{swagger-preprocessor-dispatcher.rb → swagger-processor-dispatcher.rb} +11 -11
- data/lib/sinatra/swagger-exposer/processing/swagger-request-processor.rb +123 -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 +3 -7
- data/lib/sinatra/swagger-exposer/swagger-exposer.rb +99 -33
- data/lib/sinatra/swagger-exposer/swagger-parameter-helper.rb +19 -19
- data/lib/sinatra/swagger-exposer/swagger-request-processor-creator.rb +180 -0
- data/lib/sinatra/swagger-exposer/version.rb +1 -1
- data/sinatra-swagger-exposer.gemspec +9 -8
- metadata +29 -11
- data/lib/sinatra/swagger-exposer/processing/swagger-array-value-preprocessor.rb +0 -46
- data/lib/sinatra/swagger-exposer/processing/swagger-request-preprocessor.rb +0 -64
- data/lib/sinatra/swagger-exposer/processing/swagger-type-value-preprocessor.rb +0 -37
- data/lib/sinatra/swagger-exposer/swagger-preprocessor-creator.rb +0 -137
- data/lib/sinatra/swagger-exposer/swagger-utilities.rb +0 -108
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99783f615757c81a5f32093c96bc4e6c8daca8ca
|
4
|
+
data.tar.gz: 48bfb098f71405d8d75c800dba55108fa453db29
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef40b1896dc2f5f12ba702620d469868698b427d29d4600014a5804eb1dca682aa197e0f14287fde1d9f2b962dce7acfd3ef5b0b6596b0a46c35f2a5147bd37d
|
7
|
+
data.tar.gz: a5a48f8e4a46fece4af4a015fe87e77c9ca12bedc4822f32a306247c323dfe9a4c0f3e6491fb755058fcf741cfe89d876c3741699cafcaa093570b918285c848
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,7 @@ This Sinatra extension enable you to add metadata to your code to
|
|
10
10
|
|
11
11
|
- expose your API as a [Swagger](http://swagger.io) endpoint.
|
12
12
|
- validate and enrich the invocation parameters
|
13
|
+
- validate the responses during test dans development
|
13
14
|
|
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.
|
15
16
|
|
@@ -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.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
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require_relative '../swagger-invalid-exception'
|
2
|
-
|
2
|
+
|
3
3
|
require_relative 'swagger-parameter-validation-helper'
|
4
4
|
require_relative 'swagger-type-property'
|
5
|
+
require_relative 'swagger-configuration-utilities'
|
5
6
|
|
6
7
|
module Sinatra
|
7
8
|
|
@@ -11,7 +12,7 @@ module Sinatra
|
|
11
12
|
|
12
13
|
class SwaggerEndpointParameter
|
13
14
|
|
14
|
-
include
|
15
|
+
include SwaggerConfigurationUtilities
|
15
16
|
include SwaggerParameterValidationHelper
|
16
17
|
|
17
18
|
attr_reader :type, :name, :required, :default, :params, :items, :how_to_pass
|
@@ -23,15 +24,9 @@ module Sinatra
|
|
23
24
|
# @param required [TrueClass] if the parameter is required
|
24
25
|
# @param type [String] the type name
|
25
26
|
# @param params [Hash] parameters
|
26
|
-
# @param known_types [String]
|
27
|
+
# @param known_types [Array<String>] known custom types names
|
27
28
|
def initialize(name, description, how_to_pass, required, type, params, known_types)
|
28
|
-
|
29
|
-
raise SwaggerInvalidException.new("Name [#{name}] should be a string or a symbol")
|
30
|
-
end
|
31
|
-
name = name.to_s
|
32
|
-
if name.empty?
|
33
|
-
raise SwaggerInvalidException.new('Name should not be empty')
|
34
|
-
end
|
29
|
+
check_name(name)
|
35
30
|
@name = name
|
36
31
|
|
37
32
|
if description
|
@@ -66,9 +61,9 @@ module Sinatra
|
|
66
61
|
# @return [Hash]
|
67
62
|
def to_swagger
|
68
63
|
result = {
|
69
|
-
|
70
|
-
|
71
|
-
|
64
|
+
:name => @name,
|
65
|
+
:in => @how_to_pass,
|
66
|
+
:required => @required
|
72
67
|
}
|
73
68
|
|
74
69
|
if @type
|
@@ -102,13 +97,13 @@ module Sinatra
|
|
102
97
|
|
103
98
|
def to_s
|
104
99
|
{
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
100
|
+
:name => @name,
|
101
|
+
:in => @how_to_pass,
|
102
|
+
:required => @required,
|
103
|
+
:type => @type,
|
104
|
+
:items => @items,
|
105
|
+
:description => @description,
|
106
|
+
:params => @params,
|
112
107
|
}.to_json
|
113
108
|
end
|
114
109
|
|
@@ -1,6 +1,7 @@
|
|
1
|
-
require_relative '../swagger-utilities'
|
2
1
|
require_relative '../swagger-invalid-exception'
|
3
2
|
|
3
|
+
require_relative 'swagger-configuration-utilities'
|
4
|
+
|
4
5
|
module Sinatra
|
5
6
|
|
6
7
|
module SwaggerExposer
|
@@ -9,15 +10,38 @@ module Sinatra
|
|
9
10
|
|
10
11
|
class SwaggerEndpointResponse
|
11
12
|
|
12
|
-
include
|
13
|
+
include SwaggerConfigurationUtilities
|
14
|
+
|
15
|
+
attr_reader :type, :items
|
13
16
|
|
14
17
|
RESPONSE_PRIMITIVES_FILES = PRIMITIVE_TYPES + [TYPE_FILE]
|
15
18
|
|
16
|
-
|
17
|
-
|
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
|
+
|
18
29
|
if description
|
19
30
|
@description = description
|
20
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
|
+
|
21
45
|
end
|
22
46
|
|
23
47
|
def to_swagger
|
@@ -47,14 +71,22 @@ module Sinatra
|
|
47
71
|
result[:description] = @description
|
48
72
|
end
|
49
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
|
+
|
50
82
|
result
|
51
83
|
end
|
52
84
|
|
53
85
|
def to_s
|
54
86
|
{
|
55
|
-
|
56
|
-
|
57
|
-
|
87
|
+
:type => @type,
|
88
|
+
:items => @items,
|
89
|
+
:description => @description,
|
58
90
|
}.to_json
|
59
91
|
end
|
60
92
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative '../swagger-invalid-exception'
|
2
|
-
|
2
|
+
|
3
|
+
require_relative 'swagger-configuration-utilities'
|
3
4
|
|
4
5
|
module Sinatra
|
5
6
|
|
@@ -10,16 +11,26 @@ module Sinatra
|
|
10
11
|
# An endpoint
|
11
12
|
class SwaggerEndpoint
|
12
13
|
|
13
|
-
include
|
14
|
+
include SwaggerConfigurationUtilities
|
14
15
|
|
15
|
-
attr_reader :path, :type, :parameters
|
16
|
+
attr_reader :path, :type, :parameters, :responses, :produces
|
16
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
|
17
27
|
def initialize(type, sinatra_path, parameters, responses, summary, description, tags, explicit_path, produces)
|
18
28
|
@type = type
|
19
29
|
@path = swagger_path(sinatra_path, explicit_path)
|
20
30
|
|
21
31
|
@parameters = parameters
|
22
32
|
@responses = responses
|
33
|
+
@produces = produces
|
23
34
|
|
24
35
|
@attributes = {}
|
25
36
|
if summary
|
@@ -36,6 +47,8 @@ module Sinatra
|
|
36
47
|
end
|
37
48
|
end
|
38
49
|
|
50
|
+
# Return a swagger version
|
51
|
+
# @return [Hash]
|
39
52
|
def to_swagger
|
40
53
|
result = @attributes.clone
|
41
54
|
|
@@ -74,11 +87,11 @@ module Sinatra
|
|
74
87
|
|
75
88
|
def to_s
|
76
89
|
{
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
90
|
+
:type => @type,
|
91
|
+
:path => @path,
|
92
|
+
:attributes => @attributes,
|
93
|
+
:parameters => @parameters,
|
94
|
+
:responses => @responses,
|
82
95
|
}.to_json
|
83
96
|
end
|
84
97
|
|
@@ -0,0 +1,45 @@
|
|
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
|
+
# A hash-like for groups of things
|
12
|
+
class SwaggerHashLike
|
13
|
+
|
14
|
+
include SwaggerConfigurationUtilities
|
15
|
+
|
16
|
+
def initialize(things)
|
17
|
+
@things = things
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](name)
|
21
|
+
@things[name]
|
22
|
+
end
|
23
|
+
|
24
|
+
def key?(name)
|
25
|
+
@things.key? name
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_duplicate(name, type_name)
|
29
|
+
if key?(name)
|
30
|
+
raise SwaggerInvalidException.new("#{type_name} [#{name}] already exist with value #{@things[name]}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_swagger
|
35
|
+
if @things.empty?
|
36
|
+
nil
|
37
|
+
else
|
38
|
+
hash_to_swagger(@things)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative '../swagger-invalid-exception'
|
2
|
-
|
2
|
+
|
3
|
+
require_relative 'swagger-configuration-utilities'
|
3
4
|
|
4
5
|
module Sinatra
|
5
6
|
|
@@ -10,7 +11,7 @@ module Sinatra
|
|
10
11
|
# The info declaration
|
11
12
|
class SwaggerInfo
|
12
13
|
|
13
|
-
include
|
14
|
+
include SwaggerConfigurationUtilities
|
14
15
|
|
15
16
|
def initialize(values)
|
16
17
|
@values = process(values, 'info', INFO_FIELDS, values)
|
@@ -18,12 +19,12 @@ module Sinatra
|
|
18
19
|
|
19
20
|
# Known fields for the info field
|
20
21
|
INFO_FIELDS = {
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
:version => String,
|
23
|
+
:title => String,
|
24
|
+
:description => String,
|
25
|
+
:termsOfService => String,
|
26
|
+
:contact => {:name => String, :email => String, :url => String},
|
27
|
+
:license => {:name => String, :url => String},
|
27
28
|
}
|
28
29
|
|
29
30
|
# Recursive function
|