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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-parameter.rb +118 -0
  4. data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint-response.rb +64 -0
  5. data/lib/sinatra/swagger-exposer/configuration/swagger-endpoint.rb +88 -0
  6. data/lib/sinatra/swagger-exposer/configuration/swagger-info.rb +72 -0
  7. data/lib/sinatra/swagger-exposer/configuration/swagger-parameter-validation-helper.rb +106 -0
  8. data/lib/sinatra/swagger-exposer/configuration/swagger-type-property.rb +82 -0
  9. data/lib/sinatra/swagger-exposer/configuration/swagger-type.rb +127 -0
  10. data/lib/sinatra/swagger-exposer/configuration/swagger-types.rb +51 -0
  11. data/lib/sinatra/swagger-exposer/processing/swagger-array-value-preprocessor.rb +46 -0
  12. data/lib/sinatra/swagger-exposer/processing/swagger-base-value-preprocessor.rb +48 -0
  13. data/lib/sinatra/swagger-exposer/processing/swagger-parameter-preprocessor.rb +47 -0
  14. data/lib/sinatra/swagger-exposer/processing/swagger-preprocessor-dispatcher.rb +45 -0
  15. data/lib/sinatra/swagger-exposer/processing/swagger-primitive-value-preprocessor.rb +165 -0
  16. data/lib/sinatra/swagger-exposer/processing/swagger-request-preprocessor.rb +64 -0
  17. data/lib/sinatra/swagger-exposer/processing/swagger-type-value-preprocessor.rb +37 -0
  18. data/lib/sinatra/swagger-exposer/swagger-content-creator.rb +3 -2
  19. data/lib/sinatra/swagger-exposer/swagger-exposer.rb +18 -20
  20. data/lib/sinatra/swagger-exposer/swagger-parameter-helper.rb +1 -1
  21. data/lib/sinatra/swagger-exposer/swagger-preprocessor-creator.rb +137 -0
  22. data/lib/sinatra/swagger-exposer/swagger-utilities.rb +1 -1
  23. data/lib/sinatra/swagger-exposer/version.rb +1 -1
  24. metadata +18 -10
  25. data/lib/sinatra/swagger-exposer/swagger-endpoint-parameter.rb +0 -197
  26. data/lib/sinatra/swagger-exposer/swagger-endpoint-response.rb +0 -63
  27. data/lib/sinatra/swagger-exposer/swagger-endpoint.rb +0 -94
  28. data/lib/sinatra/swagger-exposer/swagger-info.rb +0 -70
  29. data/lib/sinatra/swagger-exposer/swagger-parameter-preprocessor.rb +0 -187
  30. data/lib/sinatra/swagger-exposer/swagger-request-preprocessor.rb +0 -56
  31. data/lib/sinatra/swagger-exposer/swagger-type-property.rb +0 -72
  32. 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