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