swagger-blocks 1.4.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -6
  3. data/lib/swagger/blocks.rb +28 -775
  4. data/lib/swagger/blocks/class_methods.rb +65 -0
  5. data/lib/swagger/blocks/errors.rb +8 -0
  6. data/lib/swagger/blocks/internal_helpers.rb +52 -0
  7. data/lib/swagger/blocks/node.rb +64 -0
  8. data/lib/swagger/blocks/nodes/all_of_node.rb +42 -0
  9. data/lib/swagger/blocks/nodes/contact_node.rb +9 -0
  10. data/lib/swagger/blocks/nodes/example_node.rb +9 -0
  11. data/lib/swagger/blocks/nodes/external_docs_node.rb +9 -0
  12. data/lib/swagger/blocks/nodes/header_node.rb +12 -0
  13. data/lib/swagger/blocks/nodes/info_node.rb +16 -0
  14. data/lib/swagger/blocks/nodes/items_node.rb +14 -0
  15. data/lib/swagger/blocks/nodes/license_node.rb +9 -0
  16. data/lib/swagger/blocks/nodes/operation_node.rb +30 -0
  17. data/lib/swagger/blocks/nodes/parameter_node.rb +16 -0
  18. data/lib/swagger/blocks/nodes/path_node.rb +24 -0
  19. data/lib/swagger/blocks/nodes/properties_node.rb +11 -0
  20. data/lib/swagger/blocks/nodes/property_node.rb +17 -0
  21. data/lib/swagger/blocks/nodes/response_node.rb +24 -0
  22. data/lib/swagger/blocks/nodes/root_node.rb +53 -0
  23. data/lib/swagger/blocks/nodes/schema_node.rb +30 -0
  24. data/lib/swagger/blocks/nodes/scopes_node.rb +9 -0
  25. data/lib/swagger/blocks/nodes/security_requirement_node.rb +9 -0
  26. data/lib/swagger/blocks/nodes/security_scheme_node.rb +14 -0
  27. data/lib/swagger/blocks/nodes/tag_node.rb +15 -0
  28. data/lib/swagger/blocks/nodes/xml_node.rb +9 -0
  29. data/lib/swagger/blocks/root.rb +25 -0
  30. data/lib/swagger/blocks/version.rb +1 -1
  31. data/spec/lib/swagger_v2_blocks_spec.rb +0 -5
  32. metadata +28 -9
  33. data/README_v1_2.md +0 -143
  34. data/spec/lib/swagger_api_declaration.json +0 -201
  35. data/spec/lib/swagger_blocks_spec.rb +0 -349
  36. data/spec/lib/swagger_resource_listing.json +0 -60
@@ -0,0 +1,65 @@
1
+ module Swagger
2
+ module Blocks
3
+ module ClassMethods
4
+ private
5
+
6
+ # v2.0: Defines a Swagger Object
7
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#swagger-object
8
+ def swagger_root(inline_keys = nil, &block)
9
+ @swagger_root_node ||= Swagger::Blocks::Nodes::RootNode.call(inline_keys: inline_keys, &block)
10
+ end
11
+
12
+ # v2.0: Defines a Swagger Path Item object
13
+ # https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#path-item-object
14
+ def swagger_path(path, &block)
15
+ path = path.to_sym
16
+
17
+ # TODO enforce that path name begins with a '/'
18
+ # (or x- , but need to research Vendor Extensions first)
19
+
20
+ @swagger_path_node_map ||= {}
21
+
22
+ path_node = @swagger_path_node_map[path]
23
+ if path_node
24
+ # Merge this path declaration into the previous one
25
+ path_node.instance_eval(&block)
26
+ else
27
+ # First time we've seen this path
28
+ @swagger_path_node_map[path] = Swagger::Blocks::Nodes::PathNode.call(version: '2.0', &block)
29
+ end
30
+ end
31
+
32
+ # v2.0: Defines a Swagger Definition Schema,
33
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#definitionsObject and
34
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schema-object
35
+ def swagger_schema(name, inline_keys = nil, &block)
36
+ @swagger_schema_node_map ||= {}
37
+
38
+ schema_node = @swagger_schema_node_map[name]
39
+ if schema_node
40
+ # Merge this schema_node declaration into the previous one
41
+ schema_node.instance_eval(&block)
42
+ else
43
+ # First time we've seen this schema_node
44
+ @swagger_schema_node_map[name] = Swagger::Blocks::Nodes::SchemaNode.call(version: '2.0', inline_keys: inline_keys, &block)
45
+ end
46
+ end
47
+
48
+ def _swagger_nodes
49
+ # Avoid initialization warnings.
50
+ @swagger_root_node ||= nil
51
+ @swagger_path_node_map ||= {}
52
+ @swagger_schema_node_map ||= nil
53
+ @swagger_api_root_node_map ||= {}
54
+ @swagger_models_node ||= nil
55
+
56
+ data = {root_node: @swagger_root_node}
57
+ data[:path_node_map] = @swagger_path_node_map
58
+ data[:schema_node_map] = @swagger_schema_node_map
59
+ data[:api_node_map] = @swagger_api_root_node_map
60
+ data[:models_node] = @swagger_models_node
61
+ data
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,8 @@
1
+ module Swagger
2
+ module Blocks
3
+ class Error < StandardError; end
4
+ class DeclarationError < Error; end
5
+ class NotFoundError < Error; end
6
+ class NotSupportedError < Error; end
7
+ end
8
+ end
@@ -0,0 +1,52 @@
1
+ module Swagger
2
+ module Blocks
3
+ module InternalHelpers
4
+ # Return [root_node, api_node_map] from all of the given swaggered_classes.
5
+ def self.parse_swaggered_classes(swaggered_classes)
6
+ root_nodes = []
7
+
8
+ api_node_map = {}
9
+ models_nodes = []
10
+
11
+ path_node_map = {}
12
+ schema_node_map = {}
13
+ swaggered_classes.each do |swaggered_class|
14
+ next unless swaggered_class.respond_to?(:_swagger_nodes, true)
15
+ swagger_nodes = swaggered_class.send(:_swagger_nodes)
16
+ root_node = swagger_nodes[:root_node]
17
+ root_nodes << root_node if root_node
18
+
19
+ # 2.0
20
+ if swagger_nodes[:path_node_map]
21
+ path_node_map.merge!(swagger_nodes[:path_node_map])
22
+ end
23
+ if swagger_nodes[:schema_node_map]
24
+ schema_node_map.merge!(swagger_nodes[:schema_node_map])
25
+ end
26
+ end
27
+ data = {root_node: self.limit_root_node(root_nodes)}
28
+ if data[:root_node].is_swagger_2_0?
29
+ data[:path_nodes] = path_node_map
30
+ data[:schema_nodes] = schema_node_map
31
+ else
32
+ data[:api_node_map] = api_node_map
33
+ data[:models_nodes] = models_nodes
34
+ end
35
+ data
36
+ end
37
+
38
+ # Make sure there is exactly one root_node and return it.
39
+ # TODO should this merge the contents of the root nodes instead?
40
+ def self.limit_root_node(root_nodes)
41
+ if root_nodes.length == 0
42
+ raise Swagger::Blocks::DeclarationError.new(
43
+ 'swagger_root must be declared')
44
+ elsif root_nodes.length > 1
45
+ raise Swagger::Blocks::DeclarationError.new(
46
+ 'Only one swagger_root declaration is allowed.')
47
+ end
48
+ root_nodes.first
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,64 @@
1
+ module Swagger
2
+ module Blocks
3
+ # Base node for representing every object in the Swagger DSL.
4
+ class Node
5
+ attr_accessor :name
6
+ attr_writer :version
7
+
8
+ def self.call(options = {}, &block)
9
+ # Create a new instance and evaluate the block into it.
10
+ instance = new
11
+ instance.name = options[:name] if options[:name]
12
+ instance.version = options[:version]
13
+ instance.keys options[:inline_keys]
14
+ instance.instance_eval(&block) if block
15
+ instance
16
+ end
17
+
18
+ def as_json
19
+ result = {}
20
+
21
+ self.data.each do |key, value|
22
+ if value.is_a?(Node)
23
+ result[key] = value.as_json
24
+ elsif value.is_a?(Array)
25
+ result[key] = []
26
+ value.each { |v| result[key] << (v.respond_to?(:as_json) ? v.as_json : v) }
27
+ elsif is_swagger_2_0? && value.is_a?(Hash)
28
+ result[key] = {}
29
+ value.each_pair {|k, v| result[key][k] = (v.respond_to?(:as_json) ? v.as_json : v) }
30
+ elsif is_swagger_2_0? && key.to_s.eql?('$ref') && (value.to_s !~ %r{^#/|https?://})
31
+ result[key] = "#/definitions/#{value}"
32
+ else
33
+ result[key] = value
34
+ end
35
+ end
36
+ return result if !name
37
+ # If 'name' is given to this node, wrap the data with a root element with the given name.
38
+ {name => result}
39
+ end
40
+
41
+ def data
42
+ @data ||= {}
43
+ end
44
+
45
+ def keys(data)
46
+ self.data.merge!(data) if data
47
+ end
48
+
49
+ def key(key, value)
50
+ self.data[key] = value
51
+ end
52
+
53
+ def version
54
+ return @version if instance_variable_defined?('@version') && @version
55
+ return '2.0' if data.has_key?(:swagger) && data[:swagger] == '2.0'
56
+ raise DeclarationError, "You must specify swagger '2.0'"
57
+ end
58
+
59
+ def is_swagger_2_0?
60
+ version == '2.0'
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,42 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ class AllOfNode < Node
5
+ def as_json
6
+ result = []
7
+
8
+ self.data.each do |value|
9
+ if value.is_a?(Node)
10
+ result << value.as_json
11
+ elsif value.is_a?(Array)
12
+ r = []
13
+ value.each { |v| r << (v.respond_to?(:as_json) ? v.as_json : v) }
14
+ result << r
15
+ elsif is_swagger_2_0? && value.is_a?(Hash)
16
+ r = {}
17
+ value.each_pair {|k, v| r[k] = (v.respond_to?(:as_json) ? v.as_json : v) }
18
+ result << r
19
+ else
20
+ result = value
21
+ end
22
+ end
23
+ return result if !name
24
+ # If 'name' is given to this node, wrap the data with a root element with the given name.
25
+ {name => result}
26
+ end
27
+
28
+ def data
29
+ @data ||= []
30
+ end
31
+
32
+ def key(key, value)
33
+ raise NotSupportedError
34
+ end
35
+
36
+ def schema(inline_keys = nil, &block)
37
+ data << Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#contact-object
5
+ class ContactNode < Node
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0:
5
+ class ExampleNode < Node
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#externalDocumentationObject
5
+ class ExternalDocsNode < Node
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#headerObject
5
+ class HeaderNode < Node
6
+ def items(inline_keys = nil, &block)
7
+ self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#infoObject
5
+ class InfoNode < Node
6
+ def contact(inline_keys = nil, &block)
7
+ self.data[:contact] = Swagger::Blocks::Nodes::ContactNode.call(version: version, inline_keys: inline_keys, &block)
8
+ end
9
+
10
+ def license(inline_keys = nil, &block)
11
+ self.data[:license] = Swagger::Blocks::Nodes::LicenseNode.call(version: version, inline_keys: inline_keys, &block)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0:
5
+ class ItemsNode < Node
6
+ def property(name, inline_keys = nil, &block)
7
+ self.data[:properties] ||= Swagger::Blocks::Nodes::PropertiesNode.new
8
+ self.data[:properties].version = version
9
+ self.data[:properties].property(name, inline_keys, &block)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#license-object
5
+ class LicenseNode < Node
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operation-object
5
+ class OperationNode < Node
6
+ def parameter(inline_keys = nil, &block)
7
+ inline_keys = {'$ref' => "#/parameters/#{inline_keys}"} if inline_keys.is_a?(Symbol)
8
+
9
+ self.data[:parameters] ||= []
10
+ self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(version: version, inline_keys: inline_keys, &block)
11
+ end
12
+
13
+ def response(resp, inline_keys = nil, &block)
14
+ # TODO validate 'resp' is as per spec
15
+ self.data[:responses] ||= {}
16
+ self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(version: version, inline_keys: inline_keys, &block)
17
+ end
18
+
19
+ def externalDocs(inline_keys = nil, &block)
20
+ self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(version: version, inline_keys: inline_keys, &block)
21
+ end
22
+
23
+ def security(inline_keys = nil, &block)
24
+ self.data[:security] ||= []
25
+ self.data[:security] << Swagger::Blocks::Nodes::SecurityRequirementNode.call(version: version, inline_keys: inline_keys, &block)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameter-object
5
+ class ParameterNode < Node
6
+ def schema(inline_keys = nil, &block)
7
+ self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block)
8
+ end
9
+
10
+ def items(inline_keys = nil, &block)
11
+ self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#path-item-object
5
+ class PathNode < Node
6
+ OPERATION_TYPES = [:get, :put, :post, :delete, :options, :head, :patch].freeze
7
+
8
+ # TODO support ^x- Vendor Extensions
9
+ def operation(op, inline_keys = nil, &block)
10
+ op = op.to_sym
11
+ raise ArgumentError.new("#{name} not in #{OPERATION_TYPES}") if !OPERATION_TYPES.include?(op)
12
+ self.data[op] = Swagger::Blocks::Nodes::OperationNode.call(version: version, inline_keys: inline_keys, &block)
13
+ end
14
+
15
+ def parameter(inline_keys = nil, &block)
16
+ inline_keys = {'$ref' => "#/parameters/#{inline_keys}"} if inline_keys.is_a?(Symbol)
17
+
18
+ self.data[:parameters] ||= []
19
+ self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(version: version, inline_keys: inline_keys, &block)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ class PropertiesNode < Node
5
+ def property(name, inline_keys = nil, &block)
6
+ self.data[name] = Swagger::Blocks::Nodes::PropertyNode.call(version: version, inline_keys: inline_keys, &block)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ class PropertyNode < Node
5
+ def items(inline_keys = nil, &block)
6
+ self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block)
7
+ end
8
+
9
+ def property(name, inline_keys = nil, &block)
10
+ self.data[:properties] ||= Swagger::Blocks::Nodes::PropertiesNode.new
11
+ self.data[:properties].version = version
12
+ self.data[:properties].property(name, inline_keys, &block)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ module Swagger
2
+ module Blocks
3
+ module Nodes
4
+ # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#responseObject
5
+ class ResponseNode < Node
6
+ def schema(inline_keys = nil, &block)
7
+ self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block)
8
+ end
9
+
10
+ def header(head, inline_keys = nil, &block)
11
+ # TODO validate 'head' is as per spec
12
+ self.data[:headers] ||= {}
13
+ self.data[:headers][head] = Swagger::Blocks::Nodes::HeaderNode.call(version: version, inline_keys: inline_keys, &block)
14
+ end
15
+
16
+ def example(exam, inline_keys = nil, &block)
17
+ # TODO validate 'exam' is as per spec
18
+ self.data[:examples] ||= {}
19
+ self.data[:examples][exam] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end