swagger-blocks 1.4.0 → 2.0.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 (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