sinatra-swagger-exposer 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative '../swagger-invalid-exception'
|
2
|
+
require_relative '../swagger-utilities'
|
3
|
+
require_relative 'swagger-parameter-validation-helper'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
|
7
|
+
module SwaggerExposer
|
8
|
+
|
9
|
+
module Configuration
|
10
|
+
# A property of a type
|
11
|
+
class SwaggerTypeProperty
|
12
|
+
|
13
|
+
attr_reader :name, :type, :items
|
14
|
+
|
15
|
+
include Sinatra::SwaggerExposer::SwaggerUtilities
|
16
|
+
include SwaggerParameterValidationHelper
|
17
|
+
|
18
|
+
OTHER_PROPERTIES = [:example, :description, :format, :minLength, :maxLength, :default]
|
19
|
+
PROPERTIES = [:type] + OTHER_PROPERTIES
|
20
|
+
|
21
|
+
def initialize(type_name, property_name, property_properties, known_types)
|
22
|
+
@name = property_name
|
23
|
+
|
24
|
+
unless property_properties.is_a? Hash
|
25
|
+
raise SwaggerInvalidException.new("Property [#{property_name}] value [#{property_properties}] of [#{type_name}] should be a hash")
|
26
|
+
end
|
27
|
+
|
28
|
+
if property_properties.key? :type
|
29
|
+
get_type(property_properties[:type], PRIMITIVE_TYPES + known_types)
|
30
|
+
end
|
31
|
+
|
32
|
+
white_list_params(property_properties, PROPERTIES)
|
33
|
+
|
34
|
+
validate_params(@type, property_properties)
|
35
|
+
|
36
|
+
@other_properties = property_properties.select do |key, value|
|
37
|
+
OTHER_PROPERTIES.include? key
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def properties
|
42
|
+
@other_properties
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_swagger
|
46
|
+
result = @other_properties.clone
|
47
|
+
|
48
|
+
if @type
|
49
|
+
if @type == TYPE_ARRAY
|
50
|
+
result[:type] = TYPE_ARRAY
|
51
|
+
if @items
|
52
|
+
if PRIMITIVE_TYPES.include? @items
|
53
|
+
result[:items] = {:type => @items}
|
54
|
+
else
|
55
|
+
result[:items] = ref_to_type(@items)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
else
|
59
|
+
if PRIMITIVE_TYPES.include? @type
|
60
|
+
result[:type] = @type
|
61
|
+
else
|
62
|
+
result['$ref'] = "#/definitions/#{@type}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
result
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_s
|
71
|
+
{
|
72
|
+
:name => @name,
|
73
|
+
:type => @type,
|
74
|
+
:items => @items,
|
75
|
+
:other_properties => @other_properties,
|
76
|
+
}.to_json
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require_relative '../swagger-invalid-exception'
|
2
|
+
require_relative '../swagger-utilities'
|
3
|
+
require_relative 'swagger-type-property'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
|
7
|
+
module SwaggerExposer
|
8
|
+
|
9
|
+
module Configuration
|
10
|
+
# A type
|
11
|
+
class SwaggerType
|
12
|
+
|
13
|
+
attr_reader :properties, :required, :extends
|
14
|
+
|
15
|
+
include Sinatra::SwaggerExposer::SwaggerUtilities
|
16
|
+
|
17
|
+
PROPERTY_PROPERTIES = :properties
|
18
|
+
PROPERTY_REQUIRED = :required
|
19
|
+
PROPERTY_EXAMPLE = :example
|
20
|
+
PROPERTY_EXTENDS = :extends
|
21
|
+
PROPERTIES = [PROPERTY_PROPERTIES, PROPERTY_REQUIRED, PROPERTY_EXAMPLE, PROPERTY_EXTENDS]
|
22
|
+
|
23
|
+
def initialize(type_name, type_properties, known_types)
|
24
|
+
white_list_params(type_properties, PROPERTIES)
|
25
|
+
@properties = process_properties(type_name, type_properties, known_types)
|
26
|
+
@required = process_required(type_name, type_properties, @properties.keys)
|
27
|
+
@example = process_example(type_name, type_properties, @properties.keys)
|
28
|
+
@extends = process_extends(type_properties, known_types)
|
29
|
+
end
|
30
|
+
|
31
|
+
def process_properties(type_name, type_content, known_types)
|
32
|
+
possible_value = check_attribute_empty_or_bad(type_name, type_content, PROPERTY_PROPERTIES, Hash)
|
33
|
+
if possible_value
|
34
|
+
possible_value
|
35
|
+
else
|
36
|
+
result = {}
|
37
|
+
type_content[PROPERTY_PROPERTIES].each_pair do |property_name, property_properties|
|
38
|
+
result[property_name.to_s] = SwaggerTypeProperty.new(type_name, property_name, property_properties, known_types)
|
39
|
+
end
|
40
|
+
result
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def process_required(type_name, type_content, properties_names)
|
45
|
+
possible_value = check_attribute_empty_or_bad(type_name, type_content, PROPERTY_REQUIRED, Array)
|
46
|
+
if possible_value
|
47
|
+
possible_value
|
48
|
+
else
|
49
|
+
type_content[PROPERTY_REQUIRED].each do |property_name|
|
50
|
+
property_name = property_name.to_s
|
51
|
+
unless properties_names.include? property_name
|
52
|
+
raise SwaggerInvalidException.new("Required property [#{property_name}] of [#{type_name}] is unknown#{list_or_none(properties_names, 'properties')}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
type_content[PROPERTY_REQUIRED]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def process_example(type_name, type_content, properties_names)
|
60
|
+
possible_value = check_attribute_empty_or_bad(type_name, type_content, PROPERTY_EXAMPLE, Hash)
|
61
|
+
if possible_value
|
62
|
+
possible_value
|
63
|
+
else
|
64
|
+
type_content[PROPERTY_EXAMPLE].each_pair do |property_name, property_value|
|
65
|
+
property_name = property_name.to_s
|
66
|
+
unless properties_names.include? property_name
|
67
|
+
raise SwaggerInvalidException.new("Example property [#{property_name}] with value [#{property_value}] of [#{type_name}] is unknown#{list_or_none(properties_names, 'properties')}")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
type_content[PROPERTY_EXAMPLE]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def check_attribute_empty_or_bad(type_name, type_content, attribute_name, attribute_class)
|
75
|
+
if !type_content.key?(attribute_name)
|
76
|
+
attribute_class.new
|
77
|
+
elsif !type_content[attribute_name].is_a? attribute_class
|
78
|
+
raise SwaggerInvalidException.new("Attribute [#{attribute_name}] of #{type_name} is not an hash: #{type_content[attribute_name]}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def process_extends(type_properties, known_types)
|
83
|
+
if type_properties.key? PROPERTY_EXTENDS
|
84
|
+
check_type(type_properties[PROPERTY_EXTENDS], known_types)
|
85
|
+
@extends = type_properties[PROPERTY_EXTENDS]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def to_swagger
|
90
|
+
result = {:type => 'object'}
|
91
|
+
|
92
|
+
unless @properties.empty?
|
93
|
+
result[PROPERTY_PROPERTIES] = hash_to_swagger(@properties)
|
94
|
+
end
|
95
|
+
|
96
|
+
unless @required.empty?
|
97
|
+
result[PROPERTY_REQUIRED] = @required
|
98
|
+
end
|
99
|
+
|
100
|
+
unless @example.empty?
|
101
|
+
result[PROPERTY_EXAMPLE] = @example
|
102
|
+
end
|
103
|
+
|
104
|
+
if @extends
|
105
|
+
result = {
|
106
|
+
:allOf => [
|
107
|
+
ref_to_type(@extends),
|
108
|
+
result
|
109
|
+
]
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
result
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_s
|
117
|
+
{
|
118
|
+
:properties => @properties,
|
119
|
+
:required => @required,
|
120
|
+
:example => @example,
|
121
|
+
}.to_json
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative 'swagger-type'
|
2
|
+
require_relative '../swagger-utilities'
|
3
|
+
require_relative '../swagger-invalid-exception'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
|
7
|
+
module SwaggerExposer
|
8
|
+
|
9
|
+
module Configuration
|
10
|
+
|
11
|
+
# Contain all the declared types
|
12
|
+
class SwaggerTypes
|
13
|
+
|
14
|
+
attr_reader :types
|
15
|
+
|
16
|
+
include Sinatra::SwaggerExposer::SwaggerUtilities
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@types = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def [](name)
|
23
|
+
@types[name]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Add a new swagger type
|
27
|
+
# @param name [String] the type name
|
28
|
+
# @param params [Hash] the type params
|
29
|
+
def add_type(name, params)
|
30
|
+
if @types.key? name
|
31
|
+
raise SwaggerInvalidException.new("Type [#{name}] already exist with value #{@types[name]}")
|
32
|
+
end
|
33
|
+
@types[name] = SwaggerType.new(name, params, @types.keys)
|
34
|
+
end
|
35
|
+
|
36
|
+
def types_names
|
37
|
+
@types.keys
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_swagger
|
41
|
+
if @types.empty?
|
42
|
+
nil
|
43
|
+
else
|
44
|
+
hash_to_swagger(@types)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative '../swagger-parameter-helper'
|
2
|
+
require_relative '../swagger-invalid-exception'
|
3
|
+
require_relative 'swagger-base-value-preprocessor'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
|
7
|
+
module SwaggerExposer
|
8
|
+
|
9
|
+
module Processing
|
10
|
+
|
11
|
+
# Validate arrays parameters
|
12
|
+
class SwaggerArrayValuePreprocessor < SwaggerBaseValuePreprocessor
|
13
|
+
|
14
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
15
|
+
|
16
|
+
attr_reader :preprocessor_for_values
|
17
|
+
|
18
|
+
# Initialize
|
19
|
+
# @param name [String] the name
|
20
|
+
# @param required [TrueClass] if the parameter is required
|
21
|
+
# @param preprocessor_for_values [Sinatra::SwaggerExposer::Processing::SwaggerBaseValuePreprocessor] processor for the values
|
22
|
+
def initialize(name, required, preprocessor_for_values)
|
23
|
+
super(name, required)
|
24
|
+
@preprocessor_for_values = preprocessor_for_values
|
25
|
+
end
|
26
|
+
|
27
|
+
def useful?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def validate_param_value(value)
|
32
|
+
if value
|
33
|
+
if value.is_a? Array
|
34
|
+
value.collect { |i| @preprocessor_for_values.validate_param_value(i) }
|
35
|
+
else
|
36
|
+
raise SwaggerInvalidException.new("Parameter [#{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,48 @@
|
|
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 preprocessor
|
11
|
+
class SwaggerBaseValuePreprocessor
|
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 = nil)
|
22
|
+
@name = name.to_s
|
23
|
+
@required = required
|
24
|
+
@default = default
|
25
|
+
end
|
26
|
+
|
27
|
+
def useful?
|
28
|
+
@required || (!@default.nil?)
|
29
|
+
end
|
30
|
+
|
31
|
+
def process(params)
|
32
|
+
unless params.is_a? Hash
|
33
|
+
raise SwaggerInvalidException.new("Parameter [#{@name}] should be an object but is a [#{params.class}]")
|
34
|
+
end
|
35
|
+
if params.key?(@name)
|
36
|
+
params[@name] = validate_param_value(params[@name])
|
37
|
+
elsif @required
|
38
|
+
raise SwaggerInvalidException.new("Mandatory parameter [#{@name}] is missing")
|
39
|
+
elsif @default
|
40
|
+
params[@name] = @default
|
41
|
+
end
|
42
|
+
params
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative '../swagger-parameter-helper'
|
2
|
+
require_relative '../swagger-invalid-exception'
|
3
|
+
require_relative '../configuration/swagger-endpoint-parameter'
|
4
|
+
|
5
|
+
module Sinatra
|
6
|
+
|
7
|
+
module SwaggerExposer
|
8
|
+
|
9
|
+
module Processing
|
10
|
+
|
11
|
+
# Process the parameters for validation and enrichment
|
12
|
+
class SwaggerParameterPreprocessor
|
13
|
+
|
14
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
15
|
+
|
16
|
+
# Initialize
|
17
|
+
# @param how_to_pass [String] how to pass the parameter
|
18
|
+
# @param value_preprocessor [Sinatra::SwaggerExposer::Processing::SwaggerBaseValuePreprocessor] the parameter processor
|
19
|
+
def initialize(how_to_pass, value_preprocessor)
|
20
|
+
@how_to_pass = how_to_pass
|
21
|
+
@value_preprocessor = value_preprocessor
|
22
|
+
@useful = @value_preprocessor.useful?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Is the preprocessor useful
|
26
|
+
# @return [TrueClass]
|
27
|
+
def useful?
|
28
|
+
@useful
|
29
|
+
end
|
30
|
+
|
31
|
+
def run(app, parsed_body)
|
32
|
+
case @how_to_pass
|
33
|
+
when HOW_TO_PASS_PATH
|
34
|
+
# can't validate
|
35
|
+
when HOW_TO_PASS_QUERY
|
36
|
+
@value_preprocessor.validate(app.params)
|
37
|
+
when HOW_TO_PASS_HEADER
|
38
|
+
@value_preprocessor.validate(app.headers)
|
39
|
+
when HOW_TO_PASS_BODY
|
40
|
+
@value_preprocessor.validate(parsed_body || {})
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative '../swagger-parameter-helper'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
|
5
|
+
module SwaggerExposer
|
6
|
+
|
7
|
+
module Processing
|
8
|
+
|
9
|
+
# Dispatch content to a preprocessor
|
10
|
+
class SwaggerPreprocessorDispatcher
|
11
|
+
|
12
|
+
attr_reader :how_to_pass, :preprocessor
|
13
|
+
|
14
|
+
include Sinatra::SwaggerExposer::SwaggerParameterHelper
|
15
|
+
|
16
|
+
# Initialize
|
17
|
+
# @param how_to_pass how the value should be passed to the preprocessor
|
18
|
+
# @param preprocessor [Sinatra::SwaggerExposer::Processing::SwaggerBaseValuePreprocessor] processor for the values
|
19
|
+
def initialize(how_to_pass, preprocessor)
|
20
|
+
@how_to_pass = how_to_pass
|
21
|
+
@preprocessor = preprocessor
|
22
|
+
end
|
23
|
+
|
24
|
+
def useful?
|
25
|
+
(@how_to_pass != HOW_TO_PASS_PATH) && @preprocessor.useful?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Process the value
|
29
|
+
def process(app, parsed_body)
|
30
|
+
case @how_to_pass
|
31
|
+
when HOW_TO_PASS_PATH
|
32
|
+
# can't validate
|
33
|
+
when HOW_TO_PASS_QUERY
|
34
|
+
@preprocessor.process(app.params)
|
35
|
+
when HOW_TO_PASS_HEADER
|
36
|
+
@preprocessor.process(app.headers)
|
37
|
+
when HOW_TO_PASS_BODY
|
38
|
+
@preprocessor.process(parsed_body || {})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|