sinatra-swagger-exposer 0.2.0 → 0.3.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 +4 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-parameter.rb +118 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-response.rb +64 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint.rb +88 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-info.rb +72 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-parameter-validation-helper.rb +106 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-type-property.rb +82 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-type.rb +127 -0
- data/lib/sinatra/swagger-exposer/configuration/swagger-types.rb +51 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-array-value-preprocessor.rb +46 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-base-value-preprocessor.rb +48 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-parameter-preprocessor.rb +47 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-preprocessor-dispatcher.rb +45 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-primitive-value-preprocessor.rb +165 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-request-preprocessor.rb +64 -0
- data/lib/sinatra/swagger-exposer/processing/swagger-type-value-preprocessor.rb +37 -0
- data/lib/sinatra/swagger-exposer/swagger-content-creator.rb +3 -2
- data/lib/sinatra/swagger-exposer/swagger-exposer.rb +18 -20
- data/lib/sinatra/swagger-exposer/swagger-parameter-helper.rb +1 -1
- data/lib/sinatra/swagger-exposer/swagger-preprocessor-creator.rb +137 -0
- data/lib/sinatra/swagger-exposer/swagger-utilities.rb +1 -1
- data/lib/sinatra/swagger-exposer/version.rb +1 -1
- metadata +18 -10
- data/lib/sinatra/swagger-exposer/swagger-endpoint-parameter.rb +0 -197
- data/lib/sinatra/swagger-exposer/swagger-endpoint-response.rb +0 -63
- data/lib/sinatra/swagger-exposer/swagger-endpoint.rb +0 -94
- data/lib/sinatra/swagger-exposer/swagger-info.rb +0 -70
- data/lib/sinatra/swagger-exposer/swagger-parameter-preprocessor.rb +0 -187
- data/lib/sinatra/swagger-exposer/swagger-request-preprocessor.rb +0 -56
- data/lib/sinatra/swagger-exposer/swagger-type-property.rb +0 -72
- data/lib/sinatra/swagger-exposer/swagger-type.rb +0 -125
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5aed90279990c755b73bdd72cada6ffa5437050f
|
4
|
+
data.tar.gz: b11db6f75e29d6bce33a8f158e960754a2f94289
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79b57a8f5ddeb0c8d7cc8503550f5393274eec14527a1d5c23c5e123e8b6320a97b952b0945a0107e77ba143f82caaac4aa7c5106e5e39368c5d098872c1407d
|
7
|
+
data.tar.gz: 1a2fe99a4e7c6fd264023c952dfab82abd07f2a58f6009e1c933aa9179cf980c38f5997f860ed76d5265397a4bbf814eeede16ddff87fbabcb4a2ffb575a6e07
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,118 @@
|
|
1
|
+
require_relative '../swagger-invalid-exception'
|
2
|
+
require_relative '../swagger-utilities'
|
3
|
+
require_relative 'swagger-parameter-validation-helper'
|
4
|
+
require_relative 'swagger-type-property'
|
5
|
+
|
6
|
+
module Sinatra
|
7
|
+
|
8
|
+
module SwaggerExposer
|
9
|
+
|
10
|
+
module Configuration
|
11
|
+
|
12
|
+
class SwaggerEndpointParameter
|
13
|
+
|
14
|
+
include Sinatra::SwaggerExposer::SwaggerUtilities
|
15
|
+
include SwaggerParameterValidationHelper
|
16
|
+
|
17
|
+
attr_reader :type, :name, :required, :default, :params, :items, :how_to_pass
|
18
|
+
|
19
|
+
# Create a new instance
|
20
|
+
# @param name [String] the name
|
21
|
+
# @param description [String] the description
|
22
|
+
# @param how_to_pass [String] how to pass the parameter
|
23
|
+
# @param required [TrueClass] if the parameter is required
|
24
|
+
# @param type [String] the type name
|
25
|
+
# @param params [Hash] parameters
|
26
|
+
# @param known_types [String] know custom types names
|
27
|
+
def initialize(name, description, how_to_pass, required, type, params, known_types)
|
28
|
+
unless name.is_a?(String) || name.is_a?(Symbol)
|
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
|
35
|
+
@name = name
|
36
|
+
|
37
|
+
if description
|
38
|
+
@description = description
|
39
|
+
end
|
40
|
+
|
41
|
+
how_to_pass = how_to_pass.to_s
|
42
|
+
unless HOW_TO_PASS.include? how_to_pass
|
43
|
+
raise SwaggerInvalidException.new("Unknown how to pass value [#{how_to_pass}]#{list_or_none(HOW_TO_PASS, 'registered types')}")
|
44
|
+
end
|
45
|
+
@how_to_pass = how_to_pass
|
46
|
+
|
47
|
+
if @how_to_pass == HOW_TO_PASS_BODY
|
48
|
+
get_type(type, PRIMITIVE_TYPES + known_types)
|
49
|
+
else
|
50
|
+
get_type(type, PRIMITIVE_TYPES_FOR_NON_BODY)
|
51
|
+
end
|
52
|
+
|
53
|
+
unless [true, false].include? required
|
54
|
+
raise SwaggerInvalidException.new("Required should be a boolean instead of [#{required}]")
|
55
|
+
end
|
56
|
+
@required = required
|
57
|
+
|
58
|
+
params = white_list_params(params, PARAMS_LIST, SwaggerTypeProperty::PROPERTIES)
|
59
|
+
validate_params(@type == TYPE_ARRAY ? @items : @type, params)
|
60
|
+
@default = params[PARAMS_DEFAULT]
|
61
|
+
@params = params
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# Return the swagger version
|
66
|
+
# @return [Hash]
|
67
|
+
def to_swagger
|
68
|
+
result = {
|
69
|
+
:name => @name,
|
70
|
+
:in => @how_to_pass,
|
71
|
+
:required => @required
|
72
|
+
}
|
73
|
+
|
74
|
+
if @type
|
75
|
+
if @type == TYPE_ARRAY
|
76
|
+
result[:type] = TYPE_ARRAY
|
77
|
+
if @items
|
78
|
+
if PRIMITIVE_TYPES.include? @items
|
79
|
+
result[:items] = {:type => @items}
|
80
|
+
else
|
81
|
+
result[:schema] = ref_to_type(@items)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
else
|
85
|
+
if PRIMITIVE_TYPES.include? @type
|
86
|
+
result[:type] = @type
|
87
|
+
else
|
88
|
+
result[:schema] = ref_to_type(@type)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
if @description
|
94
|
+
result[:description] = @description
|
95
|
+
end
|
96
|
+
unless @params.empty?
|
97
|
+
result.merge!(@params)
|
98
|
+
end
|
99
|
+
|
100
|
+
result
|
101
|
+
end
|
102
|
+
|
103
|
+
def to_s
|
104
|
+
{
|
105
|
+
:name => @name,
|
106
|
+
:in => @how_to_pass,
|
107
|
+
:required => @required,
|
108
|
+
:type => @type,
|
109
|
+
:items => @items,
|
110
|
+
:description => @description,
|
111
|
+
:params => @params,
|
112
|
+
}.to_json
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative '../swagger-utilities'
|
2
|
+
require_relative '../swagger-invalid-exception'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
|
6
|
+
module SwaggerExposer
|
7
|
+
|
8
|
+
module Configuration
|
9
|
+
|
10
|
+
class SwaggerEndpointResponse
|
11
|
+
|
12
|
+
include SwaggerUtilities
|
13
|
+
|
14
|
+
RESPONSE_PRIMITIVES_FILES = PRIMITIVE_TYPES + [TYPE_FILE]
|
15
|
+
|
16
|
+
def initialize(type, description, known_types)
|
17
|
+
get_type(type, known_types + RESPONSE_PRIMITIVES_FILES)
|
18
|
+
if description
|
19
|
+
@description = description
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_swagger
|
24
|
+
result = {}
|
25
|
+
|
26
|
+
if @type
|
27
|
+
if @type == TYPE_ARRAY
|
28
|
+
schema = {:type => TYPE_ARRAY}
|
29
|
+
if @items
|
30
|
+
if RESPONSE_PRIMITIVES_FILES.include? @items
|
31
|
+
schema[:items] = {:type => @items}
|
32
|
+
else
|
33
|
+
schema[:items] = ref_to_type(@items)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
result[:schema] = schema
|
37
|
+
else
|
38
|
+
if RESPONSE_PRIMITIVES_FILES.include? @type
|
39
|
+
result[:schema] = {:type => @type}
|
40
|
+
else
|
41
|
+
result[:schema] = ref_to_type(@type)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if @description
|
47
|
+
result[:description] = @description
|
48
|
+
end
|
49
|
+
|
50
|
+
result
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
{
|
55
|
+
:type => @type,
|
56
|
+
:items => @items,
|
57
|
+
:description => @description,
|
58
|
+
}.to_json
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require_relative '../swagger-invalid-exception'
|
2
|
+
require_relative '../swagger-utilities'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
|
6
|
+
module SwaggerExposer
|
7
|
+
|
8
|
+
module Configuration
|
9
|
+
|
10
|
+
# An endpoint
|
11
|
+
class SwaggerEndpoint
|
12
|
+
|
13
|
+
include Sinatra::SwaggerExposer::SwaggerUtilities
|
14
|
+
|
15
|
+
attr_reader :path, :type, :parameters
|
16
|
+
|
17
|
+
def initialize(type, sinatra_path, parameters, responses, summary, description, tags, explicit_path, produces)
|
18
|
+
@type = type
|
19
|
+
@path = swagger_path(sinatra_path, explicit_path)
|
20
|
+
|
21
|
+
@parameters = parameters
|
22
|
+
@responses = responses
|
23
|
+
|
24
|
+
@attributes = {}
|
25
|
+
if summary
|
26
|
+
@attributes[:summary] = summary
|
27
|
+
end
|
28
|
+
if description
|
29
|
+
@attributes[:description] = description
|
30
|
+
end
|
31
|
+
if tags
|
32
|
+
@attributes[:tags] = tags
|
33
|
+
end
|
34
|
+
if produces
|
35
|
+
@attributes[:produces] = produces
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_swagger
|
40
|
+
result = @attributes.clone
|
41
|
+
|
42
|
+
unless @parameters.empty?
|
43
|
+
result[:parameters] = @parameters.collect { |parameter| parameter.to_swagger }
|
44
|
+
end
|
45
|
+
|
46
|
+
unless @responses.empty?
|
47
|
+
result[:responses] = hash_to_swagger(@responses)
|
48
|
+
end
|
49
|
+
|
50
|
+
result
|
51
|
+
end
|
52
|
+
|
53
|
+
REGEX_PATH_PARAM_MIDDLE = /\A(.*\/)\:([a-z]+)\/(.+)\z/
|
54
|
+
REGEX_PATH_PARAM_END = /\A(.*)\/:([a-z]+)\z/
|
55
|
+
|
56
|
+
# Get the endpoint swagger path
|
57
|
+
# @param sinatra_path the path declared in the sinatra app
|
58
|
+
# @param explicit_path an explicit path the user can specify
|
59
|
+
def swagger_path(sinatra_path, explicit_path)
|
60
|
+
if explicit_path
|
61
|
+
explicit_path
|
62
|
+
elsif sinatra_path.is_a? String
|
63
|
+
while (m = REGEX_PATH_PARAM_MIDDLE.match(sinatra_path))
|
64
|
+
sinatra_path = "#{m[1]}{#{m[2]}}/#{m[3]}"
|
65
|
+
end
|
66
|
+
if (m = REGEX_PATH_PARAM_END.match(sinatra_path))
|
67
|
+
sinatra_path = "#{m[1]}/{#{m[2]}}"
|
68
|
+
end
|
69
|
+
sinatra_path
|
70
|
+
else
|
71
|
+
raise SwaggerInvalidException.new("You need to specify a path when using a non-string path [#{sinatra_path}]")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_s
|
76
|
+
{
|
77
|
+
:type => @type,
|
78
|
+
:path => @path,
|
79
|
+
:attributes => @attributes,
|
80
|
+
:parameters => @parameters,
|
81
|
+
:responses => @responses,
|
82
|
+
}.to_json
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require_relative '../swagger-invalid-exception'
|
2
|
+
require_relative '../swagger-utilities'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
|
6
|
+
module SwaggerExposer
|
7
|
+
|
8
|
+
module Configuration
|
9
|
+
|
10
|
+
# The info declaration
|
11
|
+
class SwaggerInfo
|
12
|
+
|
13
|
+
include SwaggerUtilities
|
14
|
+
|
15
|
+
def initialize(values)
|
16
|
+
@values = process(values, 'info', INFO_FIELDS, values)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Known fields for the info field
|
20
|
+
INFO_FIELDS = {
|
21
|
+
:version => String,
|
22
|
+
:title => String,
|
23
|
+
:description => String,
|
24
|
+
:termsOfService => String,
|
25
|
+
:contact => {:name => String, :email => String, :url => String},
|
26
|
+
:license => {:name => String, :url => String},
|
27
|
+
}
|
28
|
+
|
29
|
+
# Recursive function
|
30
|
+
def process(current_hash, current_field_name, current_fields, top_level_hash)
|
31
|
+
result = {}
|
32
|
+
|
33
|
+
current_hash.each_pair do |current_key, current_value|
|
34
|
+
key_sym = current_key.to_sym
|
35
|
+
if current_fields.key? key_sym
|
36
|
+
|
37
|
+
field_content = current_fields[key_sym]
|
38
|
+
if field_content == String
|
39
|
+
if current_value.is_a? String
|
40
|
+
result[key_sym] = current_value
|
41
|
+
else
|
42
|
+
raise SwaggerInvalidException.new("Property [#{current_key}] value [#{current_value}] should be a String for #{current_field_name}: #{top_level_hash}")
|
43
|
+
end
|
44
|
+
else
|
45
|
+
if current_value.is_a? Hash
|
46
|
+
sub_params = process(current_value, current_field_name, field_content, top_level_hash)
|
47
|
+
if sub_params
|
48
|
+
result[key_sym] = sub_params
|
49
|
+
end
|
50
|
+
else
|
51
|
+
raise SwaggerInvalidException.new("Property [#{current_key}] value [#{current_value}] should be a Hash for #{current_field_name}: #{top_level_hash}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
else
|
55
|
+
raise SwaggerInvalidException.new("Unknown property [#{current_key}] for #{current_field_name}#{list_or_none(current_fields.keys, 'values')}")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
result.empty? ? nil : result
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_swagger
|
62
|
+
@values
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
@values.to_json
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require_relative '../swagger-parameter-helper'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
|
5
|
+
module SwaggerExposer
|
6
|
+
|
7
|
+
module Configuration
|
8
|
+
|
9
|
+
# Helper for validating parameters
|
10
|
+
module SwaggerParameterValidationHelper
|
11
|
+
|
12
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
13
|
+
|
14
|
+
# Validate parameters
|
15
|
+
# @param type [String] the parameter type
|
16
|
+
# @param params [Hash]
|
17
|
+
def validate_params(type, params)
|
18
|
+
validate_limit_parameters(type, params)
|
19
|
+
validate_length_parameters(type, params)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Test if a parameter is a boolean
|
23
|
+
# @param name the parameter's name
|
24
|
+
# @param value value the parameter's value
|
25
|
+
# @return [NilClass]
|
26
|
+
def check_boolean(name, value)
|
27
|
+
unless [true, false].include? value
|
28
|
+
raise SwaggerInvalidException.new("Invalid boolean value [#{value}] for [#{name}]")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Validate the limit parameters
|
33
|
+
# @param type [String] the parameter type
|
34
|
+
# @param params [Hash] the parameters
|
35
|
+
def validate_limit_parameters(type, params)
|
36
|
+
max = validate_limit_parameter(type, params, PARAMS_MAXIMUM, PARAMS_EXCLUSIVE_MAXIMUM)
|
37
|
+
min = validate_limit_parameter(type, params, PARAMS_MINIMUM, PARAMS_EXCLUSIVE_MINIMUM)
|
38
|
+
if min && max && (max < min)
|
39
|
+
raise SwaggerInvalidException.new("Minimum value [#{min}] can't be more than maximum value [#{max}]")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Validate a limit param like maximum and exclusiveMaximum
|
44
|
+
# @param type [String] the parameter type
|
45
|
+
# @param params [Hash] the parameters
|
46
|
+
# @param limit_param_name [Symbol] the limit parameter name
|
47
|
+
# @param exclusive_limit_param_name [Symbol] the exclusive limit parameter name
|
48
|
+
def validate_limit_parameter(type, params, limit_param_name, exclusive_limit_param_name)
|
49
|
+
parameter_value = nil
|
50
|
+
if params.key? limit_param_name
|
51
|
+
unless [TYPE_INTEGER, TYPE_NUMBER].include? @type
|
52
|
+
raise SwaggerInvalidException.new("Parameter #{limit_param_name} can only be specified for types #{TYPE_INTEGER} or #{TYPE_NUMBER} and not for [#{@type}]")
|
53
|
+
end
|
54
|
+
parameter_value = params[limit_param_name]
|
55
|
+
unless parameter_value.is_a? Numeric
|
56
|
+
raise SwaggerInvalidException.new("Parameter #{limit_param_name} must be a numeric and can not be [#{parameter_value}]")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
if params.key? exclusive_limit_param_name
|
61
|
+
check_boolean(exclusive_limit_param_name, params[exclusive_limit_param_name])
|
62
|
+
unless params.key? limit_param_name
|
63
|
+
raise SwaggerInvalidException.new("You can't have a #{exclusive_limit_param_name} value without a #{limit_param_name}")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
parameter_value
|
67
|
+
end
|
68
|
+
|
69
|
+
# Validate the length parameters minLength and maxLength
|
70
|
+
# @param type [String] the parameter type
|
71
|
+
# @param params [Hash] the parameters
|
72
|
+
def validate_length_parameters(type, params)
|
73
|
+
min_length = validate_length_parameter(type, params, PARAMS_MIN_LENGTH)
|
74
|
+
max_length = validate_length_parameter(type, params, PARAMS_MAX_LENGTH)
|
75
|
+
|
76
|
+
if min_length && max_length && (max_length < min_length)
|
77
|
+
raise SwaggerInvalidException.new("Minimum length #{min_length} can't be more than maximum length #{max_length}")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Validate a length param like minLength and maxLength
|
82
|
+
# @param type [String] the parameter type
|
83
|
+
# @param params [Hash] the parameters
|
84
|
+
# @param length_param_name [Symbol] the length parameter name
|
85
|
+
# @return [Integer] the parameter value if it is present
|
86
|
+
def validate_length_parameter(type, params, length_param_name)
|
87
|
+
if params.key? length_param_name
|
88
|
+
if type == TYPE_STRING
|
89
|
+
parameter_value = params[length_param_name]
|
90
|
+
unless parameter_value.is_a? Integer
|
91
|
+
raise SwaggerInvalidException.new("Parameter #{length_param_name} must be an integer and can not be [#{parameter_value}]")
|
92
|
+
end
|
93
|
+
parameter_value
|
94
|
+
else
|
95
|
+
raise SwaggerInvalidException.new("Parameter #{length_param_name} can only be specified for type #{TYPE_STRING} and not for [#{@type}]")
|
96
|
+
end
|
97
|
+
|
98
|
+
else
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|