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.
- checksums.yaml +4 -4
- data/README.md +7 -6
- data/lib/swagger/blocks.rb +28 -775
- data/lib/swagger/blocks/class_methods.rb +65 -0
- data/lib/swagger/blocks/errors.rb +8 -0
- data/lib/swagger/blocks/internal_helpers.rb +52 -0
- data/lib/swagger/blocks/node.rb +64 -0
- data/lib/swagger/blocks/nodes/all_of_node.rb +42 -0
- data/lib/swagger/blocks/nodes/contact_node.rb +9 -0
- data/lib/swagger/blocks/nodes/example_node.rb +9 -0
- data/lib/swagger/blocks/nodes/external_docs_node.rb +9 -0
- data/lib/swagger/blocks/nodes/header_node.rb +12 -0
- data/lib/swagger/blocks/nodes/info_node.rb +16 -0
- data/lib/swagger/blocks/nodes/items_node.rb +14 -0
- data/lib/swagger/blocks/nodes/license_node.rb +9 -0
- data/lib/swagger/blocks/nodes/operation_node.rb +30 -0
- data/lib/swagger/blocks/nodes/parameter_node.rb +16 -0
- data/lib/swagger/blocks/nodes/path_node.rb +24 -0
- data/lib/swagger/blocks/nodes/properties_node.rb +11 -0
- data/lib/swagger/blocks/nodes/property_node.rb +17 -0
- data/lib/swagger/blocks/nodes/response_node.rb +24 -0
- data/lib/swagger/blocks/nodes/root_node.rb +53 -0
- data/lib/swagger/blocks/nodes/schema_node.rb +30 -0
- data/lib/swagger/blocks/nodes/scopes_node.rb +9 -0
- data/lib/swagger/blocks/nodes/security_requirement_node.rb +9 -0
- data/lib/swagger/blocks/nodes/security_scheme_node.rb +14 -0
- data/lib/swagger/blocks/nodes/tag_node.rb +15 -0
- data/lib/swagger/blocks/nodes/xml_node.rb +9 -0
- data/lib/swagger/blocks/root.rb +25 -0
- data/lib/swagger/blocks/version.rb +1 -1
- data/spec/lib/swagger_v2_blocks_spec.rb +0 -5
- metadata +28 -9
- data/README_v1_2.md +0 -143
- data/spec/lib/swagger_api_declaration.json +0 -201
- data/spec/lib/swagger_blocks_spec.rb +0 -349
- 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,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,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,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
|