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
@@ -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
|