sinatra-swagger-exposer-ng 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|