brainstem 1.4.1 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +77 -0
- data/README.md +119 -0
- data/docs/api_doc_generator.markdown +45 -4
- data/docs/brainstem_executable.markdown +1 -1
- data/docs/oas_2_docgen.png +0 -0
- data/docs/oas_2_docgen_ascii.txt +78 -0
- data/lib/brainstem/api_docs.rb +23 -9
- data/lib/brainstem/api_docs/abstract_collection.rb +0 -13
- data/lib/brainstem/api_docs/atlas.rb +0 -14
- data/lib/brainstem/api_docs/builder.rb +0 -14
- data/lib/brainstem/api_docs/controller.rb +7 -16
- data/lib/brainstem/api_docs/controller_collection.rb +0 -3
- data/lib/brainstem/api_docs/endpoint.rb +73 -19
- data/lib/brainstem/api_docs/endpoint_collection.rb +0 -7
- data/lib/brainstem/api_docs/formatters/abstract_formatter.rb +0 -2
- data/lib/brainstem/api_docs/formatters/markdown/controller_formatter.rb +1 -9
- data/lib/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter.rb +1 -9
- data/lib/brainstem/api_docs/formatters/markdown/endpoint_formatter.rb +39 -24
- data/lib/brainstem/api_docs/formatters/markdown/helper.rb +0 -13
- data/lib/brainstem/api_docs/formatters/markdown/presenter_formatter.rb +22 -35
- data/lib/brainstem/api_docs/formatters/open_api_specification/helper.rb +66 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/controller_formatter.rb +57 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter.rb +311 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter.rb +197 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_collection_formatter.rb +60 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_formatter.rb +162 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/info_formatter.rb +126 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter.rb +132 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/security_definitions_formatter.rb +99 -0
- data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/tags_formatter.rb +123 -0
- data/lib/brainstem/api_docs/introspectors/abstract_introspector.rb +0 -7
- data/lib/brainstem/api_docs/introspectors/rails_introspector.rb +1 -20
- data/lib/brainstem/api_docs/presenter.rb +21 -27
- data/lib/brainstem/api_docs/presenter_collection.rb +1 -11
- data/lib/brainstem/api_docs/resolver.rb +1 -8
- data/lib/brainstem/api_docs/sinks/abstract_sink.rb +0 -4
- data/lib/brainstem/api_docs/sinks/controller_presenter_multifile_sink.rb +0 -9
- data/lib/brainstem/api_docs/sinks/open_api_specification_sink.rb +234 -0
- data/lib/brainstem/api_docs/sinks/stdout_sink.rb +0 -5
- data/lib/brainstem/cli.rb +0 -13
- data/lib/brainstem/cli/abstract_command.rb +0 -7
- data/lib/brainstem/cli/generate_api_docs_command.rb +48 -24
- data/lib/brainstem/concerns/controller_dsl.rb +288 -145
- data/lib/brainstem/concerns/formattable.rb +0 -5
- data/lib/brainstem/concerns/optional.rb +0 -1
- data/lib/brainstem/concerns/presenter_dsl.rb +2 -21
- data/lib/brainstem/dsl/configuration.rb +0 -11
- data/lib/brainstem/presenter.rb +0 -4
- data/lib/brainstem/version.rb +1 -1
- data/spec/brainstem/api_docs/abstract_collection_spec.rb +0 -11
- data/spec/brainstem/api_docs/atlas_spec.rb +0 -6
- data/spec/brainstem/api_docs/builder_spec.rb +0 -4
- data/spec/brainstem/api_docs/controller_collection_spec.rb +0 -2
- data/spec/brainstem/api_docs/controller_spec.rb +29 -18
- data/spec/brainstem/api_docs/endpoint_collection_spec.rb +0 -6
- data/spec/brainstem/api_docs/endpoint_spec.rb +343 -13
- data/spec/brainstem/api_docs/formatters/abstract_formatter_spec.rb +0 -2
- data/spec/brainstem/api_docs/formatters/markdown/controller_formatter_spec.rb +0 -1
- data/spec/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter_spec.rb +0 -5
- data/spec/brainstem/api_docs/formatters/markdown/endpoint_formatter_spec.rb +94 -8
- data/spec/brainstem/api_docs/formatters/markdown/helper_spec.rb +0 -8
- data/spec/brainstem/api_docs/formatters/markdown/presenter_formatter_spec.rb +0 -7
- data/spec/brainstem/api_docs/formatters/open_api_specification/helper_spec.rb +210 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/controller_formatter_spec.rb +81 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter_spec.rb +672 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter_spec.rb +335 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_collection_formatter_spec.rb +59 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_formatter_spec.rb +308 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/info_formatter_spec.rb +89 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter_spec.rb +430 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/security_definitions_formatter_spec.rb +190 -0
- data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/tags_formatter_spec.rb +217 -0
- data/spec/brainstem/api_docs/introspectors/abstract_introspector_spec.rb +0 -2
- data/spec/brainstem/api_docs/introspectors/rails_introspector_spec.rb +0 -2
- data/spec/brainstem/api_docs/presenter_collection_spec.rb +0 -2
- data/spec/brainstem/api_docs/presenter_spec.rb +58 -18
- data/spec/brainstem/api_docs/resolver_spec.rb +0 -1
- data/spec/brainstem/api_docs/sinks/controller_presenter_multifile_sink_spec.rb +0 -2
- data/spec/brainstem/api_docs/sinks/open_api_specification_sink_spec.rb +371 -0
- data/spec/brainstem/api_docs_spec.rb +2 -0
- data/spec/brainstem/cli/abstract_command_spec.rb +0 -4
- data/spec/brainstem/cli/generate_api_docs_command_spec.rb +53 -2
- data/spec/brainstem/concerns/controller_dsl_spec.rb +430 -64
- data/spec/brainstem/concerns/presenter_dsl_spec.rb +0 -20
- data/spec/brainstem/preloader_spec.rb +0 -7
- data/spec/brainstem/presenter_spec.rb +0 -1
- data/spec/dummy/rails.rb +0 -1
- data/spec/spec_helpers/db.rb +0 -1
- metadata +37 -2
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'brainstem/api_docs/formatters/abstract_formatter'
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Responsible for formatting each endpoint.
|
|
5
|
+
#
|
|
6
|
+
module Brainstem
|
|
7
|
+
module ApiDocs
|
|
8
|
+
module Formatters
|
|
9
|
+
module OpenApiSpecification
|
|
10
|
+
module Version2
|
|
11
|
+
class EndpointCollectionFormatter < AbstractFormatter
|
|
12
|
+
|
|
13
|
+
attr_accessor :endpoint_collection,
|
|
14
|
+
:output
|
|
15
|
+
|
|
16
|
+
def initialize(endpoint_collection, options = {})
|
|
17
|
+
self.endpoint_collection = endpoint_collection
|
|
18
|
+
self.output = {}
|
|
19
|
+
|
|
20
|
+
super options
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def call
|
|
24
|
+
format_endpoints!
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#####################################################################
|
|
28
|
+
private
|
|
29
|
+
#####################################################################
|
|
30
|
+
|
|
31
|
+
def documentable_endpoints
|
|
32
|
+
endpoint_collection
|
|
33
|
+
.only_documentable
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def format_endpoints!
|
|
37
|
+
documentable_endpoints.each do |endpoint|
|
|
38
|
+
formatted_endpoint = endpoint.formatted_as(:oas_v2)
|
|
39
|
+
next if formatted_endpoint.blank?
|
|
40
|
+
|
|
41
|
+
if (common_keys = output.keys & formatted_endpoint.keys).present?
|
|
42
|
+
common_keys.each do |key|
|
|
43
|
+
output[key].merge!(formatted_endpoint[key])
|
|
44
|
+
end
|
|
45
|
+
else
|
|
46
|
+
output.merge!(formatted_endpoint)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
output
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
Brainstem::ApiDocs::FORMATTERS[:endpoint_collection][:oas_v2] =
|
|
60
|
+
Brainstem::ApiDocs::Formatters::OpenApiSpecification::Version2::EndpointCollectionFormatter.method(:call)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
require 'active_support/core_ext/hash/except'
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
require 'brainstem/api_docs/formatters/abstract_formatter'
|
|
4
|
+
require 'brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter'
|
|
5
|
+
require 'brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter'
|
|
6
|
+
require 'brainstem/api_docs/formatters/open_api_specification/helper'
|
|
7
|
+
|
|
8
|
+
#
|
|
9
|
+
# Responsible for formatting each endpoint.
|
|
10
|
+
#
|
|
11
|
+
module Brainstem
|
|
12
|
+
module ApiDocs
|
|
13
|
+
module Formatters
|
|
14
|
+
module OpenApiSpecification
|
|
15
|
+
module Version2
|
|
16
|
+
class EndpointFormatter < AbstractFormatter
|
|
17
|
+
include Helper
|
|
18
|
+
extend Forwardable
|
|
19
|
+
|
|
20
|
+
attr_accessor :endpoint,
|
|
21
|
+
:presenter,
|
|
22
|
+
:endpoint_key,
|
|
23
|
+
:http_method,
|
|
24
|
+
:output
|
|
25
|
+
|
|
26
|
+
def initialize(endpoint, options = {})
|
|
27
|
+
self.endpoint = endpoint
|
|
28
|
+
self.presenter = endpoint.presenter
|
|
29
|
+
self.endpoint_key = formatted_url
|
|
30
|
+
self.http_method = format_http_method(endpoint)
|
|
31
|
+
self.output = { endpoint_key => { http_method => {} } }.with_indifferent_access
|
|
32
|
+
|
|
33
|
+
super options
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def call
|
|
37
|
+
return {} if endpoint.nodoc?
|
|
38
|
+
|
|
39
|
+
format_summary!
|
|
40
|
+
format_optional_info!
|
|
41
|
+
format_security!
|
|
42
|
+
format_tags!
|
|
43
|
+
format_parameters!
|
|
44
|
+
format_response!
|
|
45
|
+
|
|
46
|
+
output
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
################################################################################
|
|
50
|
+
private
|
|
51
|
+
################################################################################
|
|
52
|
+
|
|
53
|
+
delegate :controller => :endpoint
|
|
54
|
+
|
|
55
|
+
################################################################################
|
|
56
|
+
# Methods to override
|
|
57
|
+
################################################################################
|
|
58
|
+
|
|
59
|
+
#
|
|
60
|
+
# Format the endpoint summary
|
|
61
|
+
#
|
|
62
|
+
def summary
|
|
63
|
+
endpoint.title
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
#
|
|
67
|
+
# Format the endpoint description
|
|
68
|
+
#
|
|
69
|
+
def description
|
|
70
|
+
endpoint.description
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#
|
|
74
|
+
# Formats the actual URI
|
|
75
|
+
#
|
|
76
|
+
def formatted_url
|
|
77
|
+
endpoint.path
|
|
78
|
+
.gsub('(.:format)', '')
|
|
79
|
+
.gsub(/(:(?<param>\w+))/, '{\k<param>}')
|
|
80
|
+
.gsub(Brainstem::ApiDocs.base_path, '')
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
################################################################################
|
|
84
|
+
# Avoid overridding
|
|
85
|
+
################################################################################
|
|
86
|
+
|
|
87
|
+
#
|
|
88
|
+
# Formats the summary as given, falling back to the humanized action
|
|
89
|
+
# name.
|
|
90
|
+
#
|
|
91
|
+
def format_summary!
|
|
92
|
+
output[endpoint_key][http_method].merge! summary: summary.to_s.strip
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
#
|
|
96
|
+
# Adds the following properties.
|
|
97
|
+
# - description
|
|
98
|
+
# - operation_id
|
|
99
|
+
# - consumes
|
|
100
|
+
# - produces
|
|
101
|
+
# - schemes
|
|
102
|
+
# - external_docs
|
|
103
|
+
# - deprecated
|
|
104
|
+
#
|
|
105
|
+
def format_optional_info!
|
|
106
|
+
info = {
|
|
107
|
+
description: format_description(description),
|
|
108
|
+
operation_id: endpoint.operation_id,
|
|
109
|
+
consumes: endpoint.consumes,
|
|
110
|
+
produces: endpoint.produces,
|
|
111
|
+
schemes: endpoint.schemes,
|
|
112
|
+
external_docs: endpoint.external_docs,
|
|
113
|
+
deprecated: endpoint.deprecated,
|
|
114
|
+
}.reject { |_,v| v.blank? }
|
|
115
|
+
|
|
116
|
+
output[endpoint_key][http_method].merge!(info)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
#
|
|
120
|
+
# Adds the security schemes for the given endpoint.
|
|
121
|
+
#
|
|
122
|
+
def format_security!
|
|
123
|
+
return if endpoint.security.nil?
|
|
124
|
+
|
|
125
|
+
output[endpoint_key][http_method].merge! security: endpoint.security
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
#
|
|
129
|
+
# Adds the tags for the given endpoint.
|
|
130
|
+
#
|
|
131
|
+
def format_tags!
|
|
132
|
+
tag_name = endpoint.controller.tag || format_tag_name(endpoint.controller.name)
|
|
133
|
+
|
|
134
|
+
output[endpoint_key][http_method].merge! tags: [tag_name]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
#
|
|
138
|
+
# Formats each parameter.
|
|
139
|
+
#
|
|
140
|
+
def format_parameters!
|
|
141
|
+
output[endpoint_key][http_method].merge!(
|
|
142
|
+
parameters: ::Brainstem::ApiDocs::FORMATTERS[:parameters][:oas_v2].call(endpoint)
|
|
143
|
+
)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
#
|
|
147
|
+
# Formats the response.
|
|
148
|
+
#
|
|
149
|
+
def format_response!
|
|
150
|
+
output[endpoint_key][http_method].merge!(
|
|
151
|
+
responses: ::Brainstem::ApiDocs::FORMATTERS[:response][:oas_v2].call(endpoint)
|
|
152
|
+
)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
Brainstem::ApiDocs::FORMATTERS[:endpoint][:oas_v2] =
|
|
162
|
+
Brainstem::ApiDocs::Formatters::OpenApiSpecification::Version2::EndpointFormatter.method(:call)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require 'brainstem/api_docs/formatters/abstract_formatter'
|
|
2
|
+
|
|
3
|
+
module Brainstem
|
|
4
|
+
module ApiDocs
|
|
5
|
+
module Formatters
|
|
6
|
+
module OpenApiSpecification
|
|
7
|
+
module Version2
|
|
8
|
+
class InfoFormatter < AbstractFormatter
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Declares the options that are permissable to set on this instance.
|
|
12
|
+
#
|
|
13
|
+
def valid_options
|
|
14
|
+
super | [
|
|
15
|
+
:version
|
|
16
|
+
]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
attr_accessor :output,
|
|
20
|
+
:version
|
|
21
|
+
|
|
22
|
+
def initialize(options = {})
|
|
23
|
+
self.output = ActiveSupport::HashWithIndifferentAccess.new
|
|
24
|
+
|
|
25
|
+
super options
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def call
|
|
29
|
+
format_swagger_object!
|
|
30
|
+
format_info_object!
|
|
31
|
+
output
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#####################################################################
|
|
35
|
+
private
|
|
36
|
+
#####################################################################
|
|
37
|
+
|
|
38
|
+
def format_swagger_object!
|
|
39
|
+
output.merge!( swagger_object )
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def format_info_object!
|
|
43
|
+
output.merge!( 'info' => info_object )
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def swagger_object
|
|
47
|
+
{
|
|
48
|
+
'swagger' => '2.0',
|
|
49
|
+
'host' => host,
|
|
50
|
+
'basePath' => Brainstem::ApiDocs.base_path,
|
|
51
|
+
'schemes' => schemes,
|
|
52
|
+
'consumes' => consumes,
|
|
53
|
+
'produces' => produces
|
|
54
|
+
}.with_indifferent_access.reject { |_, v| v.blank? }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def info_object
|
|
58
|
+
{
|
|
59
|
+
'version' => version.presence || '1.0',
|
|
60
|
+
'title' => title,
|
|
61
|
+
'description' => description,
|
|
62
|
+
'termsOfService' => terms_of_service,
|
|
63
|
+
'contact' => contact_object,
|
|
64
|
+
'license' => license_object
|
|
65
|
+
}.with_indifferent_access.reject { |_, v| v.blank? }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#####################################################################
|
|
69
|
+
# Override with custom values #
|
|
70
|
+
#####################################################################
|
|
71
|
+
|
|
72
|
+
def host
|
|
73
|
+
'petstore.swagger.io'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def schemes
|
|
77
|
+
%w(https)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def consumes
|
|
81
|
+
%w(application/json)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def produces
|
|
85
|
+
%w(application/json)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def title
|
|
89
|
+
'Petstore'
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def description
|
|
93
|
+
<<-DESC.strip_heredoc
|
|
94
|
+
This is a sample server Petstore server. You can find out more about Swagger at
|
|
95
|
+
[http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).
|
|
96
|
+
For this sample, you can use the api key `special-key` to test the authorization filters.
|
|
97
|
+
DESC
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def terms_of_service
|
|
101
|
+
'http://swagger.io/terms/'
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def contact_object
|
|
105
|
+
{
|
|
106
|
+
'name' => 'Pet Store Support',
|
|
107
|
+
'url' => 'https://swagger.io/support/',
|
|
108
|
+
'email' => 'apiteam@swagger.io',
|
|
109
|
+
}
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def license_object
|
|
113
|
+
{
|
|
114
|
+
'name' => 'MIT',
|
|
115
|
+
'url' => 'https://opensource.org/licenses/MIT',
|
|
116
|
+
}
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
Brainstem::ApiDocs::FORMATTERS[:info][:oas_v2] =
|
|
126
|
+
Brainstem::ApiDocs::Formatters::OpenApiSpecification::Version2::InfoFormatter.method(:call)
|
data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter.rb
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
|
2
|
+
require 'brainstem/api_docs/formatters/abstract_formatter'
|
|
3
|
+
require 'brainstem/api_docs/formatters/open_api_specification/helper'
|
|
4
|
+
|
|
5
|
+
module Brainstem
|
|
6
|
+
module ApiDocs
|
|
7
|
+
module Formatters
|
|
8
|
+
module OpenApiSpecification
|
|
9
|
+
module Version2
|
|
10
|
+
class PresenterFormatter < AbstractFormatter
|
|
11
|
+
include Helper
|
|
12
|
+
|
|
13
|
+
def initialize(presenter, options = {})
|
|
14
|
+
self.presenter = presenter
|
|
15
|
+
self.definition = ActiveSupport::HashWithIndifferentAccess.new
|
|
16
|
+
self.output = ActiveSupport::HashWithIndifferentAccess.new
|
|
17
|
+
|
|
18
|
+
super options
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
attr_accessor :presenter,
|
|
22
|
+
:output,
|
|
23
|
+
:definition,
|
|
24
|
+
:presented_class
|
|
25
|
+
|
|
26
|
+
def call
|
|
27
|
+
return {} if presenter.nodoc?
|
|
28
|
+
|
|
29
|
+
format_title!
|
|
30
|
+
format_description!
|
|
31
|
+
format_type!
|
|
32
|
+
format_fields!
|
|
33
|
+
|
|
34
|
+
output.merge!(presenter.target_class => definition.reject {|_, v| v.blank?})
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#####################################################################
|
|
38
|
+
private
|
|
39
|
+
#####################################################################
|
|
40
|
+
|
|
41
|
+
def format_title!
|
|
42
|
+
definition.merge! title: presenter_title(presenter)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def format_description!
|
|
46
|
+
definition.merge! description: format_description(presenter.description)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def format_type!
|
|
50
|
+
definition.merge! type: 'object'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def format_fields!
|
|
54
|
+
return unless presenter.valid_fields.any?
|
|
55
|
+
|
|
56
|
+
definition.merge! properties: format_field_branch(presenter.valid_fields)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def format_field_branch(branch)
|
|
60
|
+
branch.inject(ActiveSupport::HashWithIndifferentAccess.new) do |buffer, (name, field)|
|
|
61
|
+
if nested_field?(field)
|
|
62
|
+
buffer[name.to_s] = case field.type
|
|
63
|
+
when 'hash'
|
|
64
|
+
{
|
|
65
|
+
type: 'object',
|
|
66
|
+
properties: format_field_branch(field.to_h)
|
|
67
|
+
}.with_indifferent_access
|
|
68
|
+
when 'array'
|
|
69
|
+
{
|
|
70
|
+
type: 'array',
|
|
71
|
+
items: {
|
|
72
|
+
type: 'object',
|
|
73
|
+
properties: format_field_branch(field.to_h)
|
|
74
|
+
}
|
|
75
|
+
}.with_indifferent_access
|
|
76
|
+
else
|
|
77
|
+
raise "Unknown Brainstem Field type encountered(#{field.type}) for field #{name}"
|
|
78
|
+
end
|
|
79
|
+
else
|
|
80
|
+
buffer[name.to_s] = format_field_leaf(field)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
buffer
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def nested_field?(field)
|
|
88
|
+
field.respond_to?(:configuration)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def format_field_leaf(field)
|
|
92
|
+
field_data = type_and_format(field.type, field.options[:item_type])
|
|
93
|
+
|
|
94
|
+
unless field_data
|
|
95
|
+
raise "Unknown Brainstem Field type encountered(#{field.type}) for field #{field.name}"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
field_data.merge!(description: format_description_for(field))
|
|
99
|
+
field_data.delete(:description) if field_data[:description].blank?
|
|
100
|
+
|
|
101
|
+
field_data
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def format_description_for(field)
|
|
105
|
+
field_description = format_description(field.description) || ''
|
|
106
|
+
field_description << format_conditional_description(field.options)
|
|
107
|
+
field_description << "\nOnly returned when requested through the optional_fields param.\n" if field.optional?
|
|
108
|
+
field_description.try(:chomp!)
|
|
109
|
+
field_description
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def format_conditional_description(field_options)
|
|
113
|
+
return '' if field_options[:if].blank?
|
|
114
|
+
|
|
115
|
+
conditions = field_options[:if]
|
|
116
|
+
.reject { |cond| presenter.conditionals[cond].options[:nodoc] }
|
|
117
|
+
.map { |cond| uncapitalize(presenter.conditionals[cond].description) }
|
|
118
|
+
.delete_if(&:empty?)
|
|
119
|
+
.uniq
|
|
120
|
+
.to_sentence
|
|
121
|
+
|
|
122
|
+
conditions.present? ? "\nVisible when #{conditions}.\n" : ''
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
Brainstem::ApiDocs::FORMATTERS[:presenter][:oas_v2] =
|
|
132
|
+
Brainstem::ApiDocs::Formatters::OpenApiSpecification::Version2::PresenterFormatter.method(:call)
|