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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +77 -0
  3. data/README.md +119 -0
  4. data/docs/api_doc_generator.markdown +45 -4
  5. data/docs/brainstem_executable.markdown +1 -1
  6. data/docs/oas_2_docgen.png +0 -0
  7. data/docs/oas_2_docgen_ascii.txt +78 -0
  8. data/lib/brainstem/api_docs.rb +23 -9
  9. data/lib/brainstem/api_docs/abstract_collection.rb +0 -13
  10. data/lib/brainstem/api_docs/atlas.rb +0 -14
  11. data/lib/brainstem/api_docs/builder.rb +0 -14
  12. data/lib/brainstem/api_docs/controller.rb +7 -16
  13. data/lib/brainstem/api_docs/controller_collection.rb +0 -3
  14. data/lib/brainstem/api_docs/endpoint.rb +73 -19
  15. data/lib/brainstem/api_docs/endpoint_collection.rb +0 -7
  16. data/lib/brainstem/api_docs/formatters/abstract_formatter.rb +0 -2
  17. data/lib/brainstem/api_docs/formatters/markdown/controller_formatter.rb +1 -9
  18. data/lib/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter.rb +1 -9
  19. data/lib/brainstem/api_docs/formatters/markdown/endpoint_formatter.rb +39 -24
  20. data/lib/brainstem/api_docs/formatters/markdown/helper.rb +0 -13
  21. data/lib/brainstem/api_docs/formatters/markdown/presenter_formatter.rb +22 -35
  22. data/lib/brainstem/api_docs/formatters/open_api_specification/helper.rb +66 -0
  23. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/controller_formatter.rb +57 -0
  24. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter.rb +311 -0
  25. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter.rb +197 -0
  26. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_collection_formatter.rb +60 -0
  27. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_formatter.rb +162 -0
  28. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/info_formatter.rb +126 -0
  29. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter.rb +132 -0
  30. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/security_definitions_formatter.rb +99 -0
  31. data/lib/brainstem/api_docs/formatters/open_api_specification/version_2/tags_formatter.rb +123 -0
  32. data/lib/brainstem/api_docs/introspectors/abstract_introspector.rb +0 -7
  33. data/lib/brainstem/api_docs/introspectors/rails_introspector.rb +1 -20
  34. data/lib/brainstem/api_docs/presenter.rb +21 -27
  35. data/lib/brainstem/api_docs/presenter_collection.rb +1 -11
  36. data/lib/brainstem/api_docs/resolver.rb +1 -8
  37. data/lib/brainstem/api_docs/sinks/abstract_sink.rb +0 -4
  38. data/lib/brainstem/api_docs/sinks/controller_presenter_multifile_sink.rb +0 -9
  39. data/lib/brainstem/api_docs/sinks/open_api_specification_sink.rb +234 -0
  40. data/lib/brainstem/api_docs/sinks/stdout_sink.rb +0 -5
  41. data/lib/brainstem/cli.rb +0 -13
  42. data/lib/brainstem/cli/abstract_command.rb +0 -7
  43. data/lib/brainstem/cli/generate_api_docs_command.rb +48 -24
  44. data/lib/brainstem/concerns/controller_dsl.rb +288 -145
  45. data/lib/brainstem/concerns/formattable.rb +0 -5
  46. data/lib/brainstem/concerns/optional.rb +0 -1
  47. data/lib/brainstem/concerns/presenter_dsl.rb +2 -21
  48. data/lib/brainstem/dsl/configuration.rb +0 -11
  49. data/lib/brainstem/presenter.rb +0 -4
  50. data/lib/brainstem/version.rb +1 -1
  51. data/spec/brainstem/api_docs/abstract_collection_spec.rb +0 -11
  52. data/spec/brainstem/api_docs/atlas_spec.rb +0 -6
  53. data/spec/brainstem/api_docs/builder_spec.rb +0 -4
  54. data/spec/brainstem/api_docs/controller_collection_spec.rb +0 -2
  55. data/spec/brainstem/api_docs/controller_spec.rb +29 -18
  56. data/spec/brainstem/api_docs/endpoint_collection_spec.rb +0 -6
  57. data/spec/brainstem/api_docs/endpoint_spec.rb +343 -13
  58. data/spec/brainstem/api_docs/formatters/abstract_formatter_spec.rb +0 -2
  59. data/spec/brainstem/api_docs/formatters/markdown/controller_formatter_spec.rb +0 -1
  60. data/spec/brainstem/api_docs/formatters/markdown/endpoint_collection_formatter_spec.rb +0 -5
  61. data/spec/brainstem/api_docs/formatters/markdown/endpoint_formatter_spec.rb +94 -8
  62. data/spec/brainstem/api_docs/formatters/markdown/helper_spec.rb +0 -8
  63. data/spec/brainstem/api_docs/formatters/markdown/presenter_formatter_spec.rb +0 -7
  64. data/spec/brainstem/api_docs/formatters/open_api_specification/helper_spec.rb +210 -0
  65. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/controller_formatter_spec.rb +81 -0
  66. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/param_definitions_formatter_spec.rb +672 -0
  67. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint/response_definitions_formatter_spec.rb +335 -0
  68. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_collection_formatter_spec.rb +59 -0
  69. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/endpoint_formatter_spec.rb +308 -0
  70. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/info_formatter_spec.rb +89 -0
  71. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/presenter_formatter_spec.rb +430 -0
  72. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/security_definitions_formatter_spec.rb +190 -0
  73. data/spec/brainstem/api_docs/formatters/open_api_specification/version_2/tags_formatter_spec.rb +217 -0
  74. data/spec/brainstem/api_docs/introspectors/abstract_introspector_spec.rb +0 -2
  75. data/spec/brainstem/api_docs/introspectors/rails_introspector_spec.rb +0 -2
  76. data/spec/brainstem/api_docs/presenter_collection_spec.rb +0 -2
  77. data/spec/brainstem/api_docs/presenter_spec.rb +58 -18
  78. data/spec/brainstem/api_docs/resolver_spec.rb +0 -1
  79. data/spec/brainstem/api_docs/sinks/controller_presenter_multifile_sink_spec.rb +0 -2
  80. data/spec/brainstem/api_docs/sinks/open_api_specification_sink_spec.rb +371 -0
  81. data/spec/brainstem/api_docs_spec.rb +2 -0
  82. data/spec/brainstem/cli/abstract_command_spec.rb +0 -4
  83. data/spec/brainstem/cli/generate_api_docs_command_spec.rb +53 -2
  84. data/spec/brainstem/concerns/controller_dsl_spec.rb +430 -64
  85. data/spec/brainstem/concerns/presenter_dsl_spec.rb +0 -20
  86. data/spec/brainstem/preloader_spec.rb +0 -7
  87. data/spec/brainstem/presenter_spec.rb +0 -1
  88. data/spec/dummy/rails.rb +0 -1
  89. data/spec/spec_helpers/db.rb +0 -1
  90. metadata +37 -2
@@ -19,19 +19,16 @@ module Brainstem
19
19
  new(atlas).tap {|n| members.flatten.each { |m| n << m } }
20
20
  end
21
21
 
22
-
23
22
  def initialize(atlas, options = {})
24
23
  self.atlas = atlas
25
24
  self.members = []
26
25
  super options
27
26
  end
28
27
 
29
-
30
28
  attr_accessor :atlas
31
29
 
32
30
  delegate :find_by_class => :atlas
33
31
 
34
-
35
32
  #
36
33
  # Handy accessor for extracting the last member of the collection.
37
34
  #
@@ -39,7 +36,6 @@ module Brainstem
39
36
  members[-1]
40
37
  end
41
38
 
42
-
43
39
  #
44
40
  # Appends a pre-existing object to the collection.
45
41
  #
@@ -47,7 +43,6 @@ module Brainstem
47
43
  members.push(*objects.flatten)
48
44
  end
49
45
 
50
-
51
46
  #
52
47
  # Iterates over each controller in the collection.
53
48
  #
@@ -55,7 +50,6 @@ module Brainstem
55
50
  members.each(&block)
56
51
  end
57
52
 
58
-
59
53
  #
60
54
  # Returns a map of each member formatted as specified.
61
55
  #
@@ -64,7 +58,6 @@ module Brainstem
64
58
  .reject(&:empty?)
65
59
  end
66
60
 
67
-
68
61
  #
69
62
  # Returns a list of each member's filename.
70
63
  #
@@ -75,7 +68,6 @@ module Brainstem
75
68
  formatted_with_filename(format).map { |arr| arr[1] }
76
69
  end
77
70
 
78
-
79
71
  #
80
72
  # Returns a map of each formatted member and its suggested filename.
81
73
  #
@@ -87,25 +79,20 @@ module Brainstem
87
79
  .reject { |(buffer, _)| buffer.empty? }
88
80
  end
89
81
 
90
-
91
82
  def each_formatted_with_filename(format, options = {}, &block)
92
83
  formatted_with_filename(format, options)
93
84
  .each { |args| block.call(*args) }
94
85
  end
95
86
 
96
-
97
87
  def each_formatted(format, options = {}, &block)
98
88
  formatted(format, options)
99
89
  .each { |args| block.call(*args) }
100
90
  end
101
91
 
102
-
103
92
  def each_filename(format, &block)
104
93
  filenames(format).each { |args| block.call(*args) }
105
94
  end
106
95
 
107
-
108
-
109
96
  #########################################################################
110
97
  protected
111
98
  #########################################################################
@@ -17,7 +17,6 @@ module Brainstem
17
17
  extend Forwardable
18
18
  include Concerns::Optional
19
19
 
20
-
21
20
  def initialize(introspector, options = {})
22
21
  self.endpoints = EndpointCollection.new(self)
23
22
  self.controllers = ControllerCollection.new(self)
@@ -34,21 +33,17 @@ module Brainstem
34
33
  validate!
35
34
  end
36
35
 
37
-
38
36
  attr_accessor :endpoints,
39
37
  :controllers,
40
38
  :presenters,
41
39
  :resolver
42
40
 
43
-
44
41
  delegate :find_by_class => :resolver
45
42
 
46
-
47
43
  #########################################################################
48
44
  private
49
45
  #########################################################################
50
46
 
51
-
52
47
  #
53
48
  # Lists valid options that may be passed on instantiation.
54
49
  #
@@ -56,7 +51,6 @@ module Brainstem
56
51
  super | [ :controller_matches ]
57
52
  end
58
53
 
59
-
60
54
  #
61
55
  # Ensures the atlas is valid before allowing consumers to make requests
62
56
  # of it.
@@ -65,20 +59,17 @@ module Brainstem
65
59
  raise InvalidAtlasError, "Atlas is not valid." unless valid?
66
60
  end
67
61
 
68
-
69
62
  #
70
63
  # Set and read the introspector.
71
64
  #
72
65
  attr_accessor :introspector
73
66
 
74
-
75
67
  #
76
68
  # Holds +Regexp+s which each controller name must match in order to be
77
69
  # included in the list of endpoints.
78
70
  #
79
71
  attr_accessor :controller_matches
80
72
 
81
-
82
73
  #
83
74
  # Returns a list of all routes that pass the user's filtering.
84
75
  #
@@ -86,7 +77,6 @@ module Brainstem
86
77
  introspector.routes.keep_if(&method(:allow_route?))
87
78
  end
88
79
 
89
-
90
80
  #
91
81
  # Constructs +Endpoint+ and +Controller wrappers per route.
92
82
  #
@@ -103,7 +93,6 @@ module Brainstem
103
93
  end
104
94
  end
105
95
 
106
-
107
96
  #
108
97
  # Extracts declared presents for each endpoint and converts it into a
109
98
  # Presenter wrapper object.
@@ -121,7 +110,6 @@ module Brainstem
121
110
  end
122
111
  end
123
112
 
124
-
125
113
  #
126
114
  # Returns a list of valid +target_class_to_s => PresenterConst+ pairs,
127
115
  # determining validity by whether they descend from the base presenter.
@@ -134,7 +122,6 @@ module Brainstem
134
122
  end
135
123
  end
136
124
 
137
-
138
125
  #
139
126
  # Whether this Atlas is valid (i.e. if it has at least one endpoint).
140
127
  #
@@ -144,7 +131,6 @@ module Brainstem
144
131
  endpoints.count > 0
145
132
  end
146
133
 
147
-
148
134
  #
149
135
  # Returns whether a route's controller passes the limiting regexp passed to the
150
136
  # generation command.
@@ -16,7 +16,6 @@ module Brainstem
16
16
  class Builder
17
17
  include Brainstem::Concerns::Optional
18
18
 
19
-
20
19
  def valid_options
21
20
  [
22
21
  :introspector_method,
@@ -27,7 +26,6 @@ module Brainstem
27
26
  ]
28
27
  end
29
28
 
30
-
31
29
  #
32
30
  # @param [Hash] options
33
31
  # @option options [Proc] :introspector_method Proc of arity one that
@@ -53,7 +51,6 @@ module Brainstem
53
51
  build_atlas!
54
52
  end
55
53
 
56
-
57
54
  #
58
55
  # Builds an introspector.
59
56
  #
@@ -61,7 +58,6 @@ module Brainstem
61
58
  self.introspector = introspector_method.call(args_for_introspector)
62
59
  end
63
60
 
64
-
65
61
  #
66
62
  # Builds an atlas.
67
63
  #
@@ -69,7 +65,6 @@ module Brainstem
69
65
  self.atlas = atlas_method.call(introspector, args_for_atlas)
70
66
  end
71
67
 
72
-
73
68
  #
74
69
  # Arguments to be passed to the introspector on creation.
75
70
  #
@@ -80,14 +75,12 @@ module Brainstem
80
75
  @args_for_introspector ||= {}
81
76
  end
82
77
 
83
-
84
78
  #
85
79
  # Allows passing args to the introspector if - for example - you are
86
80
  # using a custom base controller class.
87
81
  #
88
82
  attr_writer :args_for_introspector
89
83
 
90
-
91
84
  #
92
85
  # Arguments to be passed to the atlas on creation.
93
86
  #
@@ -97,14 +90,12 @@ module Brainstem
97
90
  @args_for_atlas ||= {}
98
91
  end
99
92
 
100
-
101
93
  #
102
94
  # Allows passing args to the atlas if - for example - you are
103
95
  # specifying match terms for the allowable controller set.
104
96
  #
105
97
  attr_writer :args_for_atlas
106
98
 
107
-
108
99
  #
109
100
  # A method which returns the introspector which extracts information
110
101
  # about the Brainstem-powered API from the host application.
@@ -122,7 +113,6 @@ module Brainstem
122
113
  Introspectors::RailsIntrospector.method(:with_loaded_environment)
123
114
  end
124
115
 
125
-
126
116
  #
127
117
  # Allows setting the introspector_method if - for example - you are using
128
118
  # Brainstem on a Sinatra app and you need to customize how lookups for
@@ -130,13 +120,11 @@ module Brainstem
130
120
  #
131
121
  attr_writer :introspector_method
132
122
 
133
-
134
123
  #
135
124
  # Holds a reference to the constructed introspector.
136
125
  #
137
126
  attr_accessor :introspector
138
127
 
139
-
140
128
  #
141
129
  # A proc of arity 1..2 which takes an introspector and optional options,
142
130
  # and which returns a new Atlas.
@@ -149,7 +137,6 @@ module Brainstem
149
137
  @atlas_method ||= Atlas.method(:new)
150
138
  end
151
139
 
152
-
153
140
  #
154
141
  # Allows setting the introspector_method if - for example - you are using
155
142
  # an alternative formatter and the requisite information is not present
@@ -157,7 +144,6 @@ module Brainstem
157
144
  #
158
145
  attr_writer :atlas_method
159
146
 
160
-
161
147
  #
162
148
  # Holds a reference to the constructed atlas.
163
149
  #
@@ -11,7 +11,6 @@ module Brainstem
11
11
  include Concerns::Optional
12
12
  include Concerns::Formattable
13
13
 
14
-
15
14
  def initialize(atlas, options = {})
16
15
  self.atlas = atlas
17
16
  self.endpoints = EndpointCollection.new(atlas)
@@ -19,18 +18,15 @@ module Brainstem
19
18
  yield self if block_given?
20
19
  end
21
20
 
22
-
23
21
  attr_accessor :const,
24
22
  :name,
25
23
  :endpoints,
26
24
  :filename_pattern,
27
25
  :atlas
28
26
 
29
-
30
27
  attr_writer :filename_pattern,
31
28
  :filename_link_pattern
32
29
 
33
-
34
30
  def valid_options
35
31
  super | [
36
32
  :const,
@@ -41,7 +37,6 @@ module Brainstem
41
37
  ]
42
38
  end
43
39
 
44
-
45
40
  #
46
41
  # Adds an existing endpoint to its endpoint collection.
47
42
  #
@@ -49,7 +44,6 @@ module Brainstem
49
44
  self.endpoints << endpoint
50
45
  end
51
46
 
52
-
53
47
  def suggested_filename(format)
54
48
  filename_pattern
55
49
  .gsub('{{namespace}}', const.to_s.deconstantize.underscore)
@@ -57,52 +51,50 @@ module Brainstem
57
51
  .gsub('{{extension}}', extension)
58
52
  end
59
53
 
60
-
61
54
  def suggested_filename_link(format)
62
55
  filename_link_pattern
63
56
  .gsub('{{name}}', name.to_s)
64
57
  .gsub('{{extension}}', extension)
65
58
  end
66
59
 
67
-
68
60
  def extension
69
61
  @extension ||= Brainstem::ApiDocs.output_extension
70
62
  end
71
63
 
72
-
73
64
  def filename_pattern
74
65
  @filename_pattern ||= Brainstem::ApiDocs.controller_filename_pattern
75
66
  end
76
67
 
77
-
78
68
  def filename_link_pattern
79
69
  @filename_link_pattern ||= Brainstem::ApiDocs.controller_filename_link_pattern
80
70
  end
81
71
 
82
-
83
72
  delegate :configuration => :const
84
73
  delegate :find_by_class => :atlas
85
74
 
86
-
87
75
  def default_configuration
88
76
  configuration[:_default]
89
77
  end
90
78
 
91
-
92
79
  def nodoc?
93
80
  default_configuration[:nodoc]
94
81
  end
95
82
 
96
-
97
83
  def title
98
84
  contextual_documentation(:title) || const.to_s.demodulize
99
85
  end
100
86
 
101
-
102
87
  def description
103
88
  contextual_documentation(:description) || ""
104
89
  end
105
90
 
91
+ def tag
92
+ default_configuration[:tag]
93
+ end
94
+
95
+ def tag_groups
96
+ default_configuration[:tag_groups]
97
+ end
106
98
 
107
99
  #
108
100
  # Returns a key if it exists and is documentable.
@@ -113,7 +105,6 @@ module Brainstem
113
105
  default_configuration[key][:info]
114
106
  end
115
107
 
116
-
117
108
  def valid_sorted_endpoints
118
109
  endpoints.sorted_with_actions_in_controller(const)
119
110
  end
@@ -5,7 +5,6 @@ module Brainstem
5
5
  module ApiDocs
6
6
  class ControllerCollection < AbstractCollection
7
7
 
8
-
9
8
  #
10
9
  # Creates a new controller from a route object and appends it to the
11
10
  # collection.
@@ -16,7 +15,6 @@ module Brainstem
16
15
  ).tap { |controller| self.<< controller }
17
16
  end
18
17
 
19
-
20
18
  #
21
19
  # Finds a controller from a route object.
22
20
  #
@@ -26,7 +24,6 @@ module Brainstem
26
24
  end
27
25
  end
28
26
 
29
-
30
27
  #
31
28
  # Finds a controller from a route object or creates one if it does not
32
29
  # exist.
@@ -27,14 +27,12 @@ module Brainstem
27
27
  ]
28
28
  end
29
29
 
30
-
31
30
  def initialize(atlas, options = {})
32
31
  self.atlas = atlas
33
32
  super options
34
33
  yield self if block_given?
35
34
  end
36
35
 
37
-
38
36
  attr_accessor :path,
39
37
  :http_methods,
40
38
  :controller,
@@ -42,7 +40,6 @@ module Brainstem
42
40
  :action,
43
41
  :atlas
44
42
 
45
-
46
43
  #
47
44
  # Pretty prints each endpoint.
48
45
  #
@@ -50,7 +47,6 @@ module Brainstem
50
47
  "#{http_methods.join(" / ")} #{path}"
51
48
  end
52
49
 
53
-
54
50
  #
55
51
  # Merges http methods (for de-duping Rails' routes).
56
52
  #
@@ -58,7 +54,6 @@ module Brainstem
58
54
  self.http_methods |= methods
59
55
  end
60
56
 
61
-
62
57
  #
63
58
  # Sorts this endpoint in comparison to other endpoints.
64
59
  #
@@ -91,7 +86,6 @@ module Brainstem
91
86
  end
92
87
  end
93
88
 
94
-
95
89
  ################################################################################
96
90
  # Derived fields
97
91
  ################################################################################
@@ -103,21 +97,49 @@ module Brainstem
103
97
  action_configuration[:nodoc]
104
98
  end
105
99
 
106
-
107
100
  def title
108
101
  @title ||= contextual_documentation(:title) || action.to_s.humanize
109
102
  end
110
103
 
111
-
112
104
  def description
113
105
  @description ||= contextual_documentation(:description) || ""
114
106
  end
115
107
 
116
-
117
108
  def valid_params
118
109
  @valid_params ||= key_with_default_fallback(:valid_params)
119
110
  end
120
111
 
112
+ def custom_response
113
+ @custom_response ||= action_configuration[:custom_response]
114
+ end
115
+
116
+ def operation_id
117
+ @operation_id ||= action_configuration[:operation_id]
118
+ end
119
+
120
+ def consumes
121
+ @consumes ||= key_with_default_fallback(:consumes)
122
+ end
123
+
124
+ def produces
125
+ @produces ||= key_with_default_fallback(:produces)
126
+ end
127
+
128
+ def security
129
+ @security ||= key_with_default_fallback(:security)
130
+ end
131
+
132
+ def schemes
133
+ @schemes ||= key_with_default_fallback(:schemes)
134
+ end
135
+
136
+ def external_docs
137
+ @external_docs ||= key_with_default_fallback(:external_docs)
138
+ end
139
+
140
+ def deprecated
141
+ @deprecated ||= key_with_default_fallback(:deprecated)
142
+ end
121
143
 
122
144
  #
123
145
  # Returns a hash of all params nested under the specified root or
@@ -155,6 +177,48 @@ module Brainstem
155
177
  end
156
178
  end
157
179
 
180
+ #
181
+ # Returns a hash of all fields for a custom response nested under the specified
182
+ # parent fields along with their type, item type & children.
183
+ #
184
+ # @return [Hash{Symbol => Hash}] root keys and their type info, item info & children
185
+ # nested under them.
186
+ #
187
+ def custom_response_configuration_tree
188
+ return {} unless custom_response.present?
189
+
190
+ @custom_response_configuration ||= begin
191
+ custom_response_fields = custom_response
192
+ .to_h
193
+ .deep_dup
194
+ .with_indifferent_access
195
+ custom_config_tree = ActiveSupport::HashWithIndifferentAccess.new
196
+ custom_config_tree[:_config] = custom_response_fields[:_config]
197
+
198
+ custom_response_fields
199
+ .except(:_config)
200
+ .inject(custom_config_tree) do |result, (field_name_proc, field_config)|
201
+
202
+ next result if field_config[:nodoc]
203
+
204
+ field_name = evaluate_field_name(field_name_proc)
205
+ if field_config.has_key?(:ancestors)
206
+ ancestors = field_config[:ancestors].map { |ancestor_key| evaluate_field_name(ancestor_key) }
207
+
208
+ parent = ancestors.inject(result) do |traversed_hash, ancestor_name|
209
+ traversed_hash[ancestor_name] ||= { :_config => { type: 'hash' } }
210
+ traversed_hash[ancestor_name]
211
+ end
212
+
213
+ parent[field_name] = { :_config => field_config.except(:ancestors) }
214
+ else
215
+ result[field_name] = { :_config => field_config }
216
+ end
217
+
218
+ result
219
+ end
220
+ end
221
+ end
158
222
 
159
223
  #
160
224
  # Evaluate field name if proc and symbolize it.
@@ -167,7 +231,6 @@ module Brainstem
167
231
  end
168
232
  alias_method :evaluate_root_name, :evaluate_field_name
169
233
 
170
-
171
234
  #
172
235
  # Retrieves the +presents+ settings.
173
236
  #
@@ -175,7 +238,6 @@ module Brainstem
175
238
  key_with_default_fallback(:presents) || {}
176
239
  end
177
240
 
178
-
179
241
  #
180
242
  # Used to retrieve this endpoint's presenter constant.
181
243
  #
@@ -185,13 +247,11 @@ module Brainstem
185
247
  valid_presents[:target_class]
186
248
  end
187
249
 
188
-
189
250
  #
190
251
  # Stores the +ApiDocs::Presenter+ object associated with this endpoint.
191
252
  #
192
253
  attr_accessor :presenter
193
254
 
194
-
195
255
  ################################################################################
196
256
  # Configuration Helpers
197
257
  #################################################################################
@@ -202,7 +262,6 @@ module Brainstem
202
262
  delegate :configuration => :controller
203
263
  delegate :find_by_class => :atlas
204
264
 
205
-
206
265
  #
207
266
  # Helper for retrieving action-specific configuration from the controller.
208
267
  #
@@ -210,7 +269,6 @@ module Brainstem
210
269
  configuration[action] || {}
211
270
  end
212
271
 
213
-
214
272
  #
215
273
  # Retrieves default action context from the controller.
216
274
  #
@@ -218,7 +276,6 @@ module Brainstem
218
276
  configuration[:_default] || {}
219
277
  end
220
278
 
221
-
222
279
  #
223
280
  # Returns a key if it exists and is documentable
224
281
  #
@@ -228,17 +285,14 @@ module Brainstem
228
285
  action_configuration[key][:info]
229
286
  end
230
287
 
231
-
232
288
  def key_with_default_fallback(key)
233
289
  action_configuration[key] || default_configuration[key]
234
290
  end
235
291
 
236
-
237
292
  def presenter_title
238
293
  presenter && presenter.title
239
294
  end
240
295
 
241
-
242
296
  #
243
297
  # Returns the relative path from this endpoint's controller to this
244
298
  # endpoint's declared presenter.