sinatra-swagger-exposer-ng 0.5.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 +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,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
|
@@ -0,0 +1,73 @@
|
|
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
|
+
# The info declaration
|
12
|
+
class SwaggerInfo
|
13
|
+
|
14
|
+
include SwaggerConfigurationUtilities
|
15
|
+
|
16
|
+
def initialize(values)
|
17
|
+
@values = process(values, 'info', INFO_FIELDS, values)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Known fields for the info field
|
21
|
+
INFO_FIELDS = {
|
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},
|
28
|
+
}
|
29
|
+
|
30
|
+
# Recursive function
|
31
|
+
def process(current_hash, current_field_name, current_fields, top_level_hash)
|
32
|
+
result = {}
|
33
|
+
|
34
|
+
current_hash.each_pair do |current_key, current_value|
|
35
|
+
key_sym = current_key.to_sym
|
36
|
+
if current_fields.key? key_sym
|
37
|
+
|
38
|
+
field_content = current_fields[key_sym]
|
39
|
+
if field_content == String
|
40
|
+
if current_value.is_a? String
|
41
|
+
result[key_sym] = current_value
|
42
|
+
else
|
43
|
+
raise SwaggerInvalidException.new("Property [#{current_key}] value [#{current_value}] should be a String for #{current_field_name}: #{top_level_hash}")
|
44
|
+
end
|
45
|
+
else
|
46
|
+
if current_value.is_a? Hash
|
47
|
+
sub_params = process(current_value, current_field_name, field_content, top_level_hash)
|
48
|
+
if sub_params
|
49
|
+
result[key_sym] = sub_params
|
50
|
+
end
|
51
|
+
else
|
52
|
+
raise SwaggerInvalidException.new("Property [#{current_key}] value [#{current_value}] should be a Hash for #{current_field_name}: #{top_level_hash}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
else
|
56
|
+
raise SwaggerInvalidException.new("Unknown property [#{current_key}] for #{current_field_name}#{list_or_none(current_fields.keys, 'values')}")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
result.empty? ? nil : result
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_swagger
|
63
|
+
@values
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_s
|
67
|
+
@values.to_json
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
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
|
@@ -0,0 +1,68 @@
|
|
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 SwaggerResponseHeader
|
14
|
+
|
15
|
+
include SwaggerConfigurationUtilities
|
16
|
+
include SwaggerParameterValidationHelper
|
17
|
+
|
18
|
+
attr_reader :type, :name, :description
|
19
|
+
|
20
|
+
PRIMITIVE_HEADERS_TYPES = [
|
21
|
+
TYPE_STRING,
|
22
|
+
TYPE_NUMBER,
|
23
|
+
TYPE_INTEGER,
|
24
|
+
TYPE_BOOLEAN,
|
25
|
+
]
|
26
|
+
|
27
|
+
# Create a new instance
|
28
|
+
# @param name [String] the name
|
29
|
+
# @param description [String] the description
|
30
|
+
# @param type [String] the type name
|
31
|
+
def initialize(name, type, description)
|
32
|
+
check_name(name)
|
33
|
+
@name = name
|
34
|
+
|
35
|
+
if description
|
36
|
+
@description = description
|
37
|
+
end
|
38
|
+
|
39
|
+
get_type(type, PRIMITIVE_HEADERS_TYPES)
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# Return the swagger version
|
44
|
+
# @return [Hash]
|
45
|
+
def to_swagger
|
46
|
+
result = {
|
47
|
+
:type => @type,
|
48
|
+
}
|
49
|
+
|
50
|
+
if @description
|
51
|
+
result[:description] = @description
|
52
|
+
end
|
53
|
+
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
{
|
59
|
+
:name => @name,
|
60
|
+
:type => @type,
|
61
|
+
:description => @description,
|
62
|
+
}.to_json
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'swagger-hash-like'
|
2
|
+
require_relative 'swagger-response-header'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
|
6
|
+
module SwaggerExposer
|
7
|
+
|
8
|
+
module Configuration
|
9
|
+
|
10
|
+
# Contain all the declared response headers
|
11
|
+
class SwaggerResponseHeaders < SwaggerHashLike
|
12
|
+
|
13
|
+
attr_reader :response_headers
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@response_headers = {}
|
17
|
+
super(@response_headers)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Add a new swagger response header
|
21
|
+
# @param name [String] the type name
|
22
|
+
# @param type [Object] the type
|
23
|
+
# @param description [String] the description
|
24
|
+
def add_response_header(name, type, description)
|
25
|
+
name = name.to_s
|
26
|
+
check_duplicate(name, 'Response header')
|
27
|
+
@response_headers[name] = SwaggerResponseHeader.new(name, type, description)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require_relative '../swagger-invalid-exception'
|
2
|
+
|
3
|
+
require_relative 'swagger-configuration-utilities'
|
4
|
+
require_relative 'swagger-parameter-validation-helper'
|
5
|
+
|
6
|
+
module Sinatra
|
7
|
+
|
8
|
+
module SwaggerExposer
|
9
|
+
|
10
|
+
module Configuration
|
11
|
+
# A property of a type
|
12
|
+
class SwaggerTypeProperty
|
13
|
+
|
14
|
+
attr_reader :name, :type, :items
|
15
|
+
|
16
|
+
include SwaggerConfigurationUtilities
|
17
|
+
include SwaggerParameterValidationHelper
|
18
|
+
|
19
|
+
OTHER_PROPERTIES = [:example, :description, :format, :minLength, :maxLength, :default]
|
20
|
+
PROPERTIES = [:type] + OTHER_PROPERTIES
|
21
|
+
|
22
|
+
def initialize(type_name, property_name, property_properties, known_types)
|
23
|
+
@name = property_name
|
24
|
+
|
25
|
+
unless property_properties.is_a? Hash
|
26
|
+
raise SwaggerInvalidException.new("Property [#{property_name}] value [#{property_properties}] of [#{type_name}] should be a hash")
|
27
|
+
end
|
28
|
+
|
29
|
+
if property_properties.key? :type
|
30
|
+
get_type(property_properties[:type], PRIMITIVE_TYPES + known_types)
|
31
|
+
end
|
32
|
+
|
33
|
+
white_list_params(property_properties, PROPERTIES)
|
34
|
+
|
35
|
+
validate_params(@type, property_properties)
|
36
|
+
|
37
|
+
@other_properties = property_properties.select do |key, value|
|
38
|
+
OTHER_PROPERTIES.include? key
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def properties
|
43
|
+
@other_properties
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_swagger
|
47
|
+
result = @other_properties.clone
|
48
|
+
|
49
|
+
if @type
|
50
|
+
if @type == TYPE_ARRAY
|
51
|
+
result[:type] = TYPE_ARRAY
|
52
|
+
if @items
|
53
|
+
if PRIMITIVE_TYPES.include? @items
|
54
|
+
result[:items] = {:type => @items}
|
55
|
+
else
|
56
|
+
result[:items] = ref_to_type(@items)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
else
|
60
|
+
if PRIMITIVE_TYPES.include? @type
|
61
|
+
result[:type] = @type
|
62
|
+
else
|
63
|
+
result['$ref'] = "#/definitions/#{@type}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_s
|
72
|
+
{
|
73
|
+
:name => @name,
|
74
|
+
:type => @type,
|
75
|
+
:items => @items,
|
76
|
+
:other_properties => @other_properties,
|
77
|
+
}.to_json
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require_relative '../swagger-invalid-exception'
|
2
|
+
|
3
|
+
require_relative 'swagger-configuration-utilities'
|
4
|
+
require_relative 'swagger-type-property'
|
5
|
+
|
6
|
+
module Sinatra
|
7
|
+
|
8
|
+
module SwaggerExposer
|
9
|
+
|
10
|
+
module Configuration
|
11
|
+
# A type
|
12
|
+
class SwaggerType
|
13
|
+
|
14
|
+
attr_reader :properties, :required, :extends
|
15
|
+
|
16
|
+
include SwaggerConfigurationUtilities
|
17
|
+
|
18
|
+
PROPERTY_PROPERTIES = :properties
|
19
|
+
PROPERTY_REQUIRED = :required
|
20
|
+
PROPERTY_EXAMPLE = :example
|
21
|
+
PROPERTY_EXTENDS = :extends
|
22
|
+
PROPERTIES = [PROPERTY_PROPERTIES, PROPERTY_REQUIRED, PROPERTY_EXAMPLE, PROPERTY_EXTENDS]
|
23
|
+
|
24
|
+
def initialize(type_name, type_properties, known_types)
|
25
|
+
white_list_params(type_properties, PROPERTIES)
|
26
|
+
@properties = process_properties(type_name, type_properties, known_types)
|
27
|
+
@required = process_required(type_name, type_properties, @properties.keys)
|
28
|
+
@example = process_example(type_name, type_properties, @properties.keys)
|
29
|
+
@extends = process_extends(type_properties, known_types)
|
30
|
+
end
|
31
|
+
|
32
|
+
def process_properties(type_name, type_content, known_types)
|
33
|
+
possible_value = check_attribute_empty_or_bad(type_name, type_content, PROPERTY_PROPERTIES, Hash)
|
34
|
+
if possible_value
|
35
|
+
possible_value
|
36
|
+
else
|
37
|
+
result = {}
|
38
|
+
type_content[PROPERTY_PROPERTIES].each_pair do |property_name, property_properties|
|
39
|
+
result[property_name.to_s] = SwaggerTypeProperty.new(type_name, property_name, property_properties, known_types)
|
40
|
+
end
|
41
|
+
result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def process_required(type_name, type_content, properties_names)
|
46
|
+
possible_value = check_attribute_empty_or_bad(type_name, type_content, PROPERTY_REQUIRED, Array)
|
47
|
+
if possible_value
|
48
|
+
possible_value
|
49
|
+
else
|
50
|
+
type_content[PROPERTY_REQUIRED].each do |property_name|
|
51
|
+
property_name = property_name.to_s
|
52
|
+
unless properties_names.include? property_name
|
53
|
+
raise SwaggerInvalidException.new("Required property [#{property_name}] of [#{type_name}] is unknown#{list_or_none(properties_names, 'properties')}")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
type_content[PROPERTY_REQUIRED]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def process_example(type_name, type_content, properties_names)
|
61
|
+
possible_value = check_attribute_empty_or_bad(type_name, type_content, PROPERTY_EXAMPLE, Hash)
|
62
|
+
if possible_value
|
63
|
+
possible_value
|
64
|
+
else
|
65
|
+
type_content[PROPERTY_EXAMPLE].each_pair do |property_name, property_value|
|
66
|
+
property_name = property_name.to_s
|
67
|
+
unless properties_names.include? property_name
|
68
|
+
raise SwaggerInvalidException.new("Example property [#{property_name}] with value [#{property_value}] of [#{type_name}] is unknown#{list_or_none(properties_names, 'properties')}")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
type_content[PROPERTY_EXAMPLE]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def check_attribute_empty_or_bad(type_name, type_content, attribute_name, attribute_class)
|
76
|
+
if !type_content.key?(attribute_name)
|
77
|
+
attribute_class.new
|
78
|
+
elsif !type_content[attribute_name].is_a? attribute_class
|
79
|
+
raise SwaggerInvalidException.new("Attribute [#{attribute_name}] of #{type_name} is not an hash: #{type_content[attribute_name]}")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def process_extends(type_properties, known_types)
|
84
|
+
if type_properties.key? PROPERTY_EXTENDS
|
85
|
+
check_type(type_properties[PROPERTY_EXTENDS], known_types)
|
86
|
+
@extends = type_properties[PROPERTY_EXTENDS]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_swagger
|
91
|
+
result = {:type => 'object'}
|
92
|
+
|
93
|
+
unless @properties.empty?
|
94
|
+
result[PROPERTY_PROPERTIES] = hash_to_swagger(@properties)
|
95
|
+
end
|
96
|
+
|
97
|
+
unless @required.empty?
|
98
|
+
result[PROPERTY_REQUIRED] = @required
|
99
|
+
end
|
100
|
+
|
101
|
+
unless @example.empty?
|
102
|
+
result[PROPERTY_EXAMPLE] = @example
|
103
|
+
end
|
104
|
+
|
105
|
+
if @extends
|
106
|
+
result = {
|
107
|
+
:allOf => [
|
108
|
+
ref_to_type(@extends),
|
109
|
+
result
|
110
|
+
]
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
result
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_s
|
118
|
+
{
|
119
|
+
:properties => @properties,
|
120
|
+
:required => @required,
|
121
|
+
:example => @example,
|
122
|
+
}.to_json
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'swagger-hash-like'
|
2
|
+
require_relative 'swagger-type'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
|
6
|
+
module SwaggerExposer
|
7
|
+
|
8
|
+
module Configuration
|
9
|
+
|
10
|
+
# Contain all the declared types
|
11
|
+
class SwaggerTypes < SwaggerHashLike
|
12
|
+
|
13
|
+
attr_reader :types
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@types = {}
|
17
|
+
super(types)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Add a new swagger type
|
21
|
+
# @param name [String] the type name
|
22
|
+
# @param params [Hash] the type params
|
23
|
+
def add_type(name, params)
|
24
|
+
check_duplicate(name, 'Type')
|
25
|
+
@types[name] = SwaggerType.new(name, params, @types.keys)
|
26
|
+
end
|
27
|
+
|
28
|
+
def types_names
|
29
|
+
@types.keys
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative '../swagger-parameter-helper'
|
2
|
+
require_relative '../swagger-invalid-exception'
|
3
|
+
require_relative 'swagger-base-value-processor'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
|
7
|
+
module SwaggerExposer
|
8
|
+
|
9
|
+
module Processing
|
10
|
+
|
11
|
+
# Validate arrays
|
12
|
+
class SwaggerArrayValueProcessor < SwaggerBaseValueProcessor
|
13
|
+
|
14
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
15
|
+
|
16
|
+
attr_reader :processor_for_values
|
17
|
+
|
18
|
+
# Initialize
|
19
|
+
# @param name [String] the name
|
20
|
+
# @param required [TrueClass] if the parameter is required
|
21
|
+
# @param processor_for_values [Sinatra::SwaggerExposer::Processing::SwaggerBaseValueProcessor] processor for the values
|
22
|
+
def initialize(name, required, processor_for_values)
|
23
|
+
super(name, required, nil)
|
24
|
+
@processor_for_values = processor_for_values
|
25
|
+
end
|
26
|
+
|
27
|
+
def useful?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def validate_value(value)
|
32
|
+
if value
|
33
|
+
if value.is_a? Array
|
34
|
+
value.collect { |i| @processor_for_values.validate_value(i) }
|
35
|
+
else
|
36
|
+
raise SwaggerInvalidException.new("Value [#{name}] should be an array but is [#{value}]")
|
37
|
+
end
|
38
|
+
else
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative '../swagger-parameter-helper'
|
2
|
+
require_relative '../swagger-invalid-exception'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
|
6
|
+
module SwaggerExposer
|
7
|
+
|
8
|
+
module Processing
|
9
|
+
|
10
|
+
# Base class for value processor
|
11
|
+
class SwaggerBaseValueProcessor
|
12
|
+
|
13
|
+
attr_reader :name, :required
|
14
|
+
|
15
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
16
|
+
|
17
|
+
# Initialize
|
18
|
+
# @param name [String] the name
|
19
|
+
# @param required [TrueClass] if the parameter is required
|
20
|
+
# @param default [Object] the default value
|
21
|
+
def initialize(name, required, default)
|
22
|
+
@name = name.to_s
|
23
|
+
@required = required
|
24
|
+
@default = default
|
25
|
+
end
|
26
|
+
|
27
|
+
# Test if the processor is useful
|
28
|
+
# @return [TrueClass]
|
29
|
+
def useful?
|
30
|
+
@required || (!@default.nil?)
|
31
|
+
end
|
32
|
+
|
33
|
+
def process(params)
|
34
|
+
unless params.is_a? Hash
|
35
|
+
raise SwaggerInvalidException.new("Value [#{@name}] should be an object but is a [#{params.class}]")
|
36
|
+
end
|
37
|
+
if params.key?(@name) && (!params[@name].nil?)
|
38
|
+
params[@name] = validate_value(params[@name])
|
39
|
+
elsif @required
|
40
|
+
raise SwaggerInvalidException.new("Mandatory value [#{@name}] is missing")
|
41
|
+
elsif @default
|
42
|
+
params[@name] = @default
|
43
|
+
end
|
44
|
+
params
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|