swagger_yard 0.4.4 → 1.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.
- checksums.yaml +4 -4
- data/README.md +202 -103
- data/lib/swagger_yard.rb +8 -4
- data/lib/swagger_yard/api_group.rb +106 -0
- data/lib/swagger_yard/authorization.rb +21 -18
- data/lib/swagger_yard/configuration.rb +6 -11
- data/lib/swagger_yard/example.rb +11 -0
- data/lib/swagger_yard/model.rb +16 -34
- data/lib/swagger_yard/openapi.rb +120 -0
- data/lib/swagger_yard/operation.rb +67 -50
- data/lib/swagger_yard/operation.rb.~9b471577ebed4e4ba6ed266566355dbe5990787d~ +161 -0
- data/lib/swagger_yard/parameter.rb +1 -18
- data/lib/swagger_yard/path_item.rb +21 -0
- data/lib/swagger_yard/property.rb +3 -16
- data/lib/swagger_yard/{resource_listing.rb → specification.rb} +21 -34
- data/lib/swagger_yard/swagger.rb +172 -4
- data/lib/swagger_yard/type.rb +20 -12
- data/lib/swagger_yard/type.rb.~master~ +34 -0
- data/lib/swagger_yard/type_parser.rb +10 -4
- data/lib/swagger_yard/version.rb +1 -1
- metadata +9 -5
- data/lib/swagger_yard/api.rb +0 -39
- data/lib/swagger_yard/api_declaration.rb +0 -72
@@ -0,0 +1,161 @@
|
|
1
|
+
module SwaggerYard
|
2
|
+
class Operation
|
3
|
+
attr_accessor :description, :ruby_method
|
4
|
+
attr_writer :summary
|
5
|
+
attr_reader :path, :http_method, :error_messages, :response_type, :response_desc
|
6
|
+
attr_reader :parameters, :model_names
|
7
|
+
|
8
|
+
# TODO: extract to operation builder?
|
9
|
+
def self.from_yard_object(yard_object, api)
|
10
|
+
new(api).tap do |operation|
|
11
|
+
operation.ruby_method = yard_object.name(false)
|
12
|
+
operation.description = yard_object.docstring
|
13
|
+
yard_object.tags.each do |tag|
|
14
|
+
case tag.tag_name
|
15
|
+
when "path"
|
16
|
+
tag = SwaggerYard.requires_type(tag)
|
17
|
+
operation.add_path_params_and_method(tag) if tag
|
18
|
+
when "parameter"
|
19
|
+
operation.add_parameter(tag)
|
20
|
+
when "response_type"
|
21
|
+
tag = SwaggerYard.requires_type(tag)
|
22
|
+
operation.add_response_type(Type.from_type_list(tag.types), tag.text) if tag
|
23
|
+
when "error_message"
|
24
|
+
operation.add_error_message(tag)
|
25
|
+
when "summary"
|
26
|
+
operation.summary = tag.text
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
operation.sort_parameters
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(api)
|
35
|
+
@api = api
|
36
|
+
@summary = nil
|
37
|
+
@description = ""
|
38
|
+
@parameters = []
|
39
|
+
@model_names = []
|
40
|
+
@error_messages = []
|
41
|
+
end
|
42
|
+
|
43
|
+
def summary
|
44
|
+
@summary || description.split("\n\n").first || ""
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_h
|
48
|
+
params = parameters.map(&:to_h)
|
49
|
+
responses = { "default" => { "description" => response_desc || summary } }
|
50
|
+
|
51
|
+
if response_type
|
52
|
+
responses["default"]["schema"] = response_type.to_h
|
53
|
+
end
|
54
|
+
|
55
|
+
unless error_messages.empty?
|
56
|
+
error_messages.each do |err|
|
57
|
+
responses[err["code"].to_s] = {}.tap do |h|
|
58
|
+
h["description"] = err["message"]
|
59
|
+
h["schema"] = Type.from_type_list(Array(err["responseModel"])).to_h if err["responseModel"]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
api_decl = @api.api_declaration
|
65
|
+
|
66
|
+
{
|
67
|
+
"tags" => [api_decl.resource].compact,
|
68
|
+
"operationId" => "#{api_decl.resource}-#{ruby_method}",
|
69
|
+
"parameters" => params,
|
70
|
+
"responses" => responses,
|
71
|
+
}.tap do |h|
|
72
|
+
h["description"] = description unless description.empty?
|
73
|
+
h["summary"] = summary unless summary.empty?
|
74
|
+
|
75
|
+
authorizations = api_decl.authorizations
|
76
|
+
unless authorizations.empty?
|
77
|
+
h["security"] = authorizations.map {|k,v| { k => v} }
|
78
|
+
end
|
79
|
+
|
80
|
+
# Rails controller/action: if constantize/controller_path methods are
|
81
|
+
# unavailable or constant is not defined, catch exception and skip these
|
82
|
+
# attributes.
|
83
|
+
begin
|
84
|
+
h["x-controller"] = api_decl.class_name.constantize.controller_path.to_s
|
85
|
+
h["x-action"] = ruby_method.to_s
|
86
|
+
rescue NameError, NoMethodError
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Example: [GET] /api/v2/ownerships
|
93
|
+
# Example: [PUT] /api/v1/accounts/{account_id}
|
94
|
+
def add_path_params_and_method(tag)
|
95
|
+
if @path && @http_method
|
96
|
+
SwaggerYard.log.warn 'multiple path tags not supported: ' \
|
97
|
+
"ignored [#{tag.types.first}] #{tag.text}"
|
98
|
+
return
|
99
|
+
end
|
100
|
+
|
101
|
+
@path = tag.text
|
102
|
+
@http_method = tag.types.first
|
103
|
+
|
104
|
+
parse_path_params(tag.text).each do |name|
|
105
|
+
add_or_update_parameter Parameter.from_path_param(name)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Example: [Array] status Filter by status. (e.g. status[]=1&status[]=2&status[]=3)
|
111
|
+
# Example: [Array] status(required) Filter by status. (e.g. status[]=1&status[]=2&status[]=3)
|
112
|
+
# Example: [Array] status(required, body) Filter by status. (e.g. status[]=1&status[]=2&status[]=3)
|
113
|
+
# Example: [Integer] media[media_type_id] ID of the desired media type.
|
114
|
+
def add_parameter(tag)
|
115
|
+
param = Parameter.from_yard_tag(tag, self)
|
116
|
+
add_or_update_parameter param if param
|
117
|
+
end
|
118
|
+
|
119
|
+
def add_or_update_parameter(parameter)
|
120
|
+
if existing = @parameters.detect {|param| param.name == parameter.name }
|
121
|
+
existing.description = parameter.description unless parameter.from_path?
|
122
|
+
existing.param_type = parameter.param_type if parameter.from_path?
|
123
|
+
existing.required ||= parameter.required
|
124
|
+
existing.allow_multiple = parameter.allow_multiple
|
125
|
+
elsif parameter.param_type == 'body' && @parameters.detect {|param| param.param_type == 'body'}
|
126
|
+
SwaggerYard.log.warn 'multiple body parameters invalid: ' \
|
127
|
+
"ignored #{parameter.name} for #{@api.api_declaration.class_name}##{ruby_method}"
|
128
|
+
else
|
129
|
+
@parameters << parameter
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# Example:
|
135
|
+
# @response_type [Ownership] the requested ownership
|
136
|
+
def add_response_type(type, desc)
|
137
|
+
model_names << type.model_name
|
138
|
+
@response_type = type
|
139
|
+
@response_desc = desc
|
140
|
+
end
|
141
|
+
|
142
|
+
def add_error_message(tag)
|
143
|
+
tag = SwaggerYard.requires_name(tag)
|
144
|
+
return unless tag
|
145
|
+
@error_messages << {
|
146
|
+
"code" => Integer(tag.name),
|
147
|
+
"message" => tag.text,
|
148
|
+
"responseModel" => Array(tag.types).first
|
149
|
+
}.reject {|_,v| v.nil?}
|
150
|
+
end
|
151
|
+
|
152
|
+
def sort_parameters
|
153
|
+
@parameters.sort_by! {|p| p.name}
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
def parse_path_params(path)
|
158
|
+
path.scan(/\{([^\}]+)\}/).flatten
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -2,7 +2,7 @@ module SwaggerYard
|
|
2
2
|
class Parameter
|
3
3
|
attr_accessor :name, :type, :description, :param_type, :required, :allow_multiple
|
4
4
|
|
5
|
-
def self.from_yard_tag(tag
|
5
|
+
def self.from_yard_tag(tag)
|
6
6
|
tag = SwaggerYard.requires_name_and_type(tag)
|
7
7
|
return nil unless tag
|
8
8
|
|
@@ -13,8 +13,6 @@ module SwaggerYard
|
|
13
13
|
|
14
14
|
options = {}
|
15
15
|
|
16
|
-
operation.model_names << type.name if type.ref?
|
17
|
-
|
18
16
|
unless options_string.nil?
|
19
17
|
options_string.split(',').map(&:strip).tap do |arr|
|
20
18
|
options[:required] = !arr.delete('required').nil?
|
@@ -48,20 +46,5 @@ module SwaggerYard
|
|
48
46
|
def from_path?
|
49
47
|
@from_path
|
50
48
|
end
|
51
|
-
|
52
|
-
def to_h
|
53
|
-
{ "name" => name,
|
54
|
-
"description" => description,
|
55
|
-
"required" => required,
|
56
|
-
"in" => param_type
|
57
|
-
}.tap do |h|
|
58
|
-
if h["in"] == "body"
|
59
|
-
h["schema"] = @type.to_h
|
60
|
-
else
|
61
|
-
h.update(@type.to_h)
|
62
|
-
end
|
63
|
-
h["collectionFormat"] = 'multi' if !Array(allow_multiple).empty? && h["items"]
|
64
|
-
end
|
65
|
-
end
|
66
49
|
end
|
67
50
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SwaggerYard
|
2
|
+
class PathItem
|
3
|
+
attr_accessor :operations, :api_group
|
4
|
+
|
5
|
+
def initialize(api_group = nil)
|
6
|
+
@api_group = api_group
|
7
|
+
@operations = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_operation(yard_object)
|
11
|
+
operation = Operation.from_yard_object(yard_object, self)
|
12
|
+
@operations[operation.http_method.downcase] = operation
|
13
|
+
end
|
14
|
+
|
15
|
+
def +(other)
|
16
|
+
PathItem.new(api_group).tap do |pi|
|
17
|
+
pi.operations = operations.merge(other.operations)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -3,7 +3,8 @@ module SwaggerYard
|
|
3
3
|
# Holds the name and type for a single model property
|
4
4
|
#
|
5
5
|
class Property
|
6
|
-
|
6
|
+
include Example
|
7
|
+
attr_reader :name, :description, :required, :type, :nullable
|
7
8
|
|
8
9
|
def self.from_tag(tag)
|
9
10
|
tag = SwaggerYard.requires_name_and_type(tag)
|
@@ -23,22 +24,8 @@ module SwaggerYard
|
|
23
24
|
@type = Type.from_type_list(types)
|
24
25
|
end
|
25
26
|
|
26
|
-
|
27
|
+
def required?
|
27
28
|
@required
|
28
29
|
end
|
29
|
-
|
30
|
-
def to_h
|
31
|
-
@type.to_h.tap do |h|
|
32
|
-
unless h['$ref']
|
33
|
-
h["description"] = description if description && !description.strip.empty?
|
34
|
-
if @nullable
|
35
|
-
h["x-nullable"] = true
|
36
|
-
if h["type"]
|
37
|
-
h["type"] = [h["type"], "null"]
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
30
|
end
|
44
31
|
end
|
@@ -1,12 +1,9 @@
|
|
1
1
|
module SwaggerYard
|
2
|
-
class
|
2
|
+
class Specification
|
3
3
|
attr_accessor :authorizations
|
4
4
|
|
5
|
-
def
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
def initialize(controller_path, model_path)
|
5
|
+
def initialize(controller_path = SwaggerYard.config.controller_path,
|
6
|
+
model_path = SwaggerYard.config.model_path)
|
10
7
|
@model_paths = [*model_path].compact
|
11
8
|
@controller_paths = [*controller_path].compact
|
12
9
|
|
@@ -14,44 +11,34 @@ module SwaggerYard
|
|
14
11
|
@authorizations = []
|
15
12
|
end
|
16
13
|
|
17
|
-
def models
|
18
|
-
@models ||= parse_models
|
19
|
-
end
|
20
|
-
|
21
|
-
def controllers
|
22
|
-
@controllers ||= parse_controllers
|
23
|
-
end
|
24
|
-
|
25
|
-
def to_h
|
26
|
-
{ "paths" => path_objects,
|
27
|
-
"definitions" => model_objects,
|
28
|
-
"tags" => tag_objects,
|
29
|
-
"securityDefinitions" => security_objects }
|
30
|
-
end
|
31
|
-
|
32
14
|
def path_objects
|
33
|
-
|
15
|
+
api_groups.map(&:paths).reduce(Paths.new({}), :merge).tap do |paths|
|
34
16
|
warn_duplicate_operations(paths)
|
35
17
|
end
|
36
18
|
end
|
37
19
|
|
38
20
|
# Resources
|
39
21
|
def tag_objects
|
40
|
-
|
22
|
+
api_groups.map(&:tag)
|
41
23
|
end
|
42
24
|
|
43
25
|
def model_objects
|
44
|
-
Hash[models.map {|m| [m.id, m
|
26
|
+
Hash[models.map {|m| [m.id, m]}]
|
45
27
|
end
|
46
28
|
|
47
29
|
def security_objects
|
48
|
-
|
49
|
-
|
50
|
-
Hash[authorizations.map {|auth| [auth.name, auth.to_h]}]
|
51
|
-
)
|
30
|
+
api_groups # triggers controller parsing in case it did not happen before
|
31
|
+
Hash[authorizations.map {|auth| [auth.id, auth]}]
|
52
32
|
end
|
53
33
|
|
54
34
|
private
|
35
|
+
def models
|
36
|
+
@models ||= parse_models
|
37
|
+
end
|
38
|
+
|
39
|
+
def api_groups
|
40
|
+
@api_groups ||= parse_controllers
|
41
|
+
end
|
55
42
|
|
56
43
|
def parse_models
|
57
44
|
@model_paths.map do |model_path|
|
@@ -70,7 +57,7 @@ module SwaggerYard
|
|
70
57
|
obj.tags.select {|t| t.tag_name == "authorization"}.each do |t|
|
71
58
|
@authorizations << Authorization.from_yard_object(t)
|
72
59
|
end
|
73
|
-
|
60
|
+
ApiGroup.from_yard_object(obj)
|
74
61
|
end
|
75
62
|
end
|
76
63
|
end.flatten.select(&:valid?)
|
@@ -78,13 +65,13 @@ module SwaggerYard
|
|
78
65
|
|
79
66
|
def warn_duplicate_operations(paths)
|
80
67
|
operation_ids = []
|
81
|
-
paths.each do |path,
|
82
|
-
|
83
|
-
if operation_ids.include?(op
|
84
|
-
SwaggerYard.log.warn("duplicate operation #{op
|
68
|
+
paths.path_items.each do |path,pi|
|
69
|
+
pi.operations.each do |_, op|
|
70
|
+
if operation_ids.include?(op.operation_id)
|
71
|
+
SwaggerYard.log.warn("duplicate operation #{op.operation_id}")
|
85
72
|
next
|
86
73
|
end
|
87
|
-
operation_ids << op
|
74
|
+
operation_ids << op.operation_id
|
88
75
|
end
|
89
76
|
end
|
90
77
|
end
|
data/lib/swagger_yard/swagger.rb
CHANGED
@@ -10,15 +10,45 @@ module SwaggerYard
|
|
10
10
|
end
|
11
11
|
|
12
12
|
class Swagger
|
13
|
+
class << self; alias object_new new; end
|
14
|
+
|
15
|
+
def self.new(*args)
|
16
|
+
return OpenAPI.object_new(*args) if SwaggerYard.config.swagger_version.start_with?("3.0")
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :specification
|
21
|
+
|
22
|
+
def initialize(spec = Specification.new)
|
23
|
+
@specification = spec
|
24
|
+
end
|
25
|
+
|
13
26
|
def to_h
|
27
|
+
metadata.merge(definitions).merge(model_definitions)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def model_path
|
32
|
+
Type::MODEL_PATH
|
33
|
+
end
|
34
|
+
|
35
|
+
def definitions
|
36
|
+
{ "paths" => paths(specification.path_objects),
|
37
|
+
"tags" => tags(specification.tag_objects),
|
38
|
+
"securityDefinitions" => security_defs(specification.security_objects) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def model_definitions
|
42
|
+
{ "definitions" => models(specification.model_objects) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def metadata
|
14
46
|
{
|
15
47
|
"swagger" => "2.0",
|
16
48
|
"info" => Info.new.to_h
|
17
|
-
}.merge(uri_info)
|
49
|
+
}.merge(uri_info)
|
18
50
|
end
|
19
51
|
|
20
|
-
private
|
21
|
-
|
22
52
|
def uri_info
|
23
53
|
uri = URI(SwaggerYard.config.api_base_path)
|
24
54
|
host = uri.host
|
@@ -26,8 +56,146 @@ module SwaggerYard
|
|
26
56
|
|
27
57
|
{
|
28
58
|
'host' => host,
|
29
|
-
'basePath' => uri.request_uri
|
59
|
+
'basePath' => uri.request_uri,
|
60
|
+
'schemes' => [uri.scheme]
|
30
61
|
}
|
31
62
|
end
|
63
|
+
|
64
|
+
def paths(paths)
|
65
|
+
Hash[paths.path_items.map {|path,pi| [path, operations(pi.operations)] }]
|
66
|
+
end
|
67
|
+
|
68
|
+
def operations(ops)
|
69
|
+
expanded_ops = ops.map do |meth, op|
|
70
|
+
|
71
|
+
[meth, operation(op)]
|
72
|
+
end
|
73
|
+
Hash[expanded_ops]
|
74
|
+
end
|
75
|
+
|
76
|
+
def operation(op)
|
77
|
+
op_hash = {
|
78
|
+
"tags" => op.tags,
|
79
|
+
"operationId" => op.operation_id,
|
80
|
+
"parameters" => parameters(op.parameters),
|
81
|
+
"responses" => responses(op.responses_by_status, op),
|
82
|
+
}
|
83
|
+
|
84
|
+
op_hash["description"] = op.description unless op.description.empty?
|
85
|
+
op_hash["summary"] = op.summary unless op.summary.empty?
|
86
|
+
|
87
|
+
authorizations = op.api_group.authorizations
|
88
|
+
unless authorizations.empty?
|
89
|
+
op_hash["security"] = authorizations.map {|k,v| { k => v} }
|
90
|
+
end
|
91
|
+
|
92
|
+
op_hash.update(op.extended_attributes)
|
93
|
+
end
|
94
|
+
|
95
|
+
def parameters(params)
|
96
|
+
params.map do |param|
|
97
|
+
{ "name" => param.name,
|
98
|
+
"description" => param.description,
|
99
|
+
"required" => param.required,
|
100
|
+
"in" => param.param_type
|
101
|
+
}.tap do |h|
|
102
|
+
schema = param.type.schema_with(model_path: model_path)
|
103
|
+
if h["in"] == "body"
|
104
|
+
h["schema"] = schema
|
105
|
+
else
|
106
|
+
h.update(schema)
|
107
|
+
end
|
108
|
+
h["collectionFormat"] = 'multi' if !Array(param.allow_multiple).empty? && h["items"]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def responses(responses_by_status, op)
|
114
|
+
Hash[responses_by_status.map { |status, resp| [status, response(resp, op)] }]
|
115
|
+
end
|
116
|
+
|
117
|
+
def response(resp, op)
|
118
|
+
{}.tap do |h|
|
119
|
+
h['description'] = resp && resp.description || op.summary || ''
|
120
|
+
h['schema'] = resp.type.schema_with(model_path: model_path) if resp && resp.type
|
121
|
+
if resp && resp.example
|
122
|
+
h['examples'] = {
|
123
|
+
'application/json' => resp.example
|
124
|
+
}
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def models(model_objects)
|
130
|
+
Hash[model_objects.map { |name, mod| [name, model(mod)] }]
|
131
|
+
end
|
132
|
+
|
133
|
+
def model(mod)
|
134
|
+
h = {}
|
135
|
+
|
136
|
+
if !mod.properties.empty? || mod.inherits.empty?
|
137
|
+
h["type"] = "object"
|
138
|
+
h["properties"] = Hash[mod.properties.map {|p| [p.name, property(p)]}]
|
139
|
+
h["required"] = mod.properties.select(&:required?).map(&:name) if mod.properties.detect(&:required?)
|
140
|
+
end
|
141
|
+
|
142
|
+
h["discriminator"] = mod.discriminator if mod.discriminator
|
143
|
+
|
144
|
+
# Polymorphism
|
145
|
+
unless mod.inherits.empty?
|
146
|
+
all_of = mod.inherits.map { |name| Type.new(name).schema_with(model_path: model_path) }
|
147
|
+
all_of << h unless h.empty?
|
148
|
+
|
149
|
+
if all_of.length == 1 && mod.description.empty?
|
150
|
+
h.update(all_of.first)
|
151
|
+
else
|
152
|
+
h = { "allOf" => all_of }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Description
|
157
|
+
h["description"] = mod.description unless mod.description.empty?
|
158
|
+
|
159
|
+
h["example"] = mod.example if mod.example
|
160
|
+
|
161
|
+
h
|
162
|
+
end
|
163
|
+
|
164
|
+
def property(prop)
|
165
|
+
prop.type.schema_with(model_path: model_path).tap do |h|
|
166
|
+
unless h['$ref']
|
167
|
+
h["description"] = prop.description if prop.description && !prop.description.strip.empty?
|
168
|
+
if prop.nullable
|
169
|
+
h["x-nullable"] = true
|
170
|
+
if h["type"]
|
171
|
+
h["type"] = [h["type"], "null"]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
h["example"] = prop.example if prop.example
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def tags(tag_objects)
|
180
|
+
tag_objects.sort_by {|t| t.name.upcase }.map do |t|
|
181
|
+
{ 'name' => t.name, 'description' => t.description }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def security_defs(security_objects)
|
186
|
+
config_defs = SwaggerYard.config.security_definitions
|
187
|
+
config_defs.merge(Hash[security_objects.map { |name, obj| [name, security(obj)] }])
|
188
|
+
end
|
189
|
+
|
190
|
+
def security(obj)
|
191
|
+
case obj.type
|
192
|
+
when /api_?key/i
|
193
|
+
{ 'type' => 'apiKey', 'name' => obj.key, 'in' => obj.name }
|
194
|
+
else
|
195
|
+
{ 'type' => 'basic' }
|
196
|
+
end.tap do |result|
|
197
|
+
result['description'] = obj.description if obj.description && !obj.description.empty?
|
198
|
+
end
|
199
|
+
end
|
32
200
|
end
|
33
201
|
end
|