grape-swagger 0.9.0 → 0.10.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/.rubocop_todo.yml +13 -13
- data/.travis.yml +1 -0
- data/CHANGELOG.md +19 -0
- data/README.md +49 -2
- data/UPGRADING.md +20 -0
- data/lib/grape-swagger.rb +149 -23
- data/lib/grape-swagger/version.rb +1 -1
- data/spec/api_global_models_spec.rb +0 -2
- data/spec/api_models_spec.rb +39 -3
- data/spec/api_paths_spec.rb +0 -3
- data/spec/api_root_spec.rb +0 -1
- data/spec/api_with_path_versioning_spec.rb +33 -0
- data/spec/api_with_standalone_namespace_spec.rb +215 -0
- data/spec/array_params_spec.rb +34 -0
- data/spec/float_api_spec.rb +30 -0
- data/spec/form_params_spec.rb +15 -0
- data/spec/grape-swagger_helper_spec.rb +18 -3
- data/spec/hide_api_spec.rb +15 -0
- data/spec/markdown/kramdown_adapter_spec.rb +0 -1
- data/spec/markdown/redcarpet_adapter_spec.rb +0 -1
- data/spec/mutually_exclusive_spec.rb +36 -0
- data/spec/non_default_api_spec.rb +0 -5
- data/spec/range_values_spec.rb +49 -0
- data/spec/response_model_spec.rb +10 -0
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80476f6e354bf1964123a1f592e8a6ca9fd38d54
|
4
|
+
data.tar.gz: b9c15ab8ac8cacbd87e69e187a1afd2a838ff7d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f6d6e3da7140010e92a6a94a716572cf2da3093bc2233c172c6a9d0caa420a4108da068d73a145ae901dd61cc2c754c22974881cab22a5959fb55439fdfaeb1
|
7
|
+
data.tar.gz: 04db505e755cf5fa4f72684becaa3ad2a580a1f83baf566fb8c7407f2c1b425f809d813b1151c7b286f0f4ed90e587307be53c15f3ab9ef90b579af4d5c8d803
|
data/.rubocop_todo.yml
CHANGED
@@ -1,42 +1,42 @@
|
|
1
1
|
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
-
# on
|
2
|
+
# on 2015-02-26 15:04:26 +0100 using RuboCop version 0.27.0.
|
3
3
|
# The point is for the user to remove these configuration records
|
4
4
|
# one by one as the offenses are removed from the code base.
|
5
5
|
# Note that changes in the inspected code, or installation of new
|
6
6
|
# versions of RuboCop, may require this file to be generated again.
|
7
7
|
|
8
|
-
# Offense count:
|
8
|
+
# Offense count: 9
|
9
9
|
Metrics/AbcSize:
|
10
|
-
Max:
|
10
|
+
Max: 347
|
11
11
|
|
12
12
|
# Offense count: 1
|
13
13
|
# Configuration parameters: CountComments.
|
14
14
|
Metrics/ClassLength:
|
15
|
-
Max:
|
15
|
+
Max: 485
|
16
16
|
|
17
|
-
# Offense count:
|
17
|
+
# Offense count: 6
|
18
18
|
Metrics/CyclomaticComplexity:
|
19
|
-
Max:
|
19
|
+
Max: 99
|
20
20
|
|
21
|
-
# Offense count:
|
21
|
+
# Offense count: 289
|
22
22
|
# Configuration parameters: AllowURI, URISchemes.
|
23
23
|
Metrics/LineLength:
|
24
24
|
Max: 254
|
25
25
|
|
26
|
-
# Offense count:
|
26
|
+
# Offense count: 17
|
27
27
|
# Configuration parameters: CountComments.
|
28
28
|
Metrics/MethodLength:
|
29
|
-
Max:
|
29
|
+
Max: 368
|
30
30
|
|
31
|
-
# Offense count:
|
31
|
+
# Offense count: 5
|
32
32
|
Metrics/PerceivedComplexity:
|
33
|
-
Max:
|
33
|
+
Max: 101
|
34
34
|
|
35
|
-
# Offense count:
|
35
|
+
# Offense count: 8
|
36
36
|
Style/ClassVars:
|
37
37
|
Enabled: false
|
38
38
|
|
39
|
-
# Offense count:
|
39
|
+
# Offense count: 76
|
40
40
|
Style/Documentation:
|
41
41
|
Enabled: false
|
42
42
|
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
### 0.10.0 (March 10, 2015)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* [#217](https://github.com/tim-vandecasteele/grape-swagger/pull/217): Support Array of entities for proper rendering of grape-entity input dependencies - [@swistaczek](https://github.com/swistaczek).
|
6
|
+
* [#214](https://github.com/tim-vandecasteele/grape-swagger/pull/214): Allow anything that responds to `call` to be used in `:hidden` - [@zbelzer](https://github.com/zbelzer).
|
7
|
+
* [#196](https://github.com/tim-vandecasteele/grape-swagger/pull/196): If `:type` is omitted, see if it's available in `:using` - [@jhollinger](https://github.com/jhollinger).
|
8
|
+
* [#200](https://github.com/tim-vandecasteele/grape-swagger/pull/200): Treat `type: Symbol` as string form parameter - [@ypresto](https://github.com/ypresto).
|
9
|
+
* [#207](https://github.com/tim-vandecasteele/grape-swagger/pull/207): Support grape `mutually_exclusive` - [@mintuhouse](https://github.com/mintuhouse).
|
10
|
+
* [#220](https://github.com/tim-vandecasteele/grape-swagger/pull/220): Support standalone appearance of namespace routes with a custom name instead of forced nesting - [@croeck](https://github.com/croeck).
|
11
|
+
|
12
|
+
#### Fixes
|
13
|
+
|
14
|
+
* [#221](https://github.com/tim-vandecasteele/grape-swagger/pull/221): Fixed group parameters' name with type Array - [@u2](https://github.com/u2).
|
15
|
+
* [#211](https://github.com/tim-vandecasteele/grape-swagger/pull/211): Fixed the dependency, just `require 'grape'` - [@u2](https://github.com/u2).
|
16
|
+
* [#210](https://github.com/tim-vandecasteele/grape-swagger/pull/210): Fixed the range `:values` option, now exposed as `enum` parameters - [@u2](https://github.com/u2).
|
17
|
+
* [#208](https://github.com/tim-vandecasteele/grape-swagger/pull/208): Fixed `Float` parameters, exposed as Swagger `float` types - [@u2](https://github.com/u2).
|
18
|
+
* [#216](https://github.com/tim-vandecasteele/grape-swagger/pull/216), [#192](https://github.com/tim-vandecasteele/grape-swagger/issues/192), [#189](https://github.com/tim-vandecasteele/grape-swagger/issues/189): Fixed API route paths matching for root endpoints with `grape ~> 0.10.0`, specific `format` and `:path` versioning - [@dm1try](https://github.com/dm1try), [@minch](https://github.com/minch).
|
19
|
+
|
1
20
|
### 0.9.0 (December 19, 2014)
|
2
21
|
|
3
22
|
* [#91](https://github.com/tim-vandecasteele/grape-swagger/issues/91): Fixed empty field for group parameters' name with type hash or Array - [@dukedave](https://github.com/dukedave).
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# grape-swagger
|
2
2
|
|
3
|
-
[](http://badge.fury.io/rb/grape-swagger)
|
4
|
+
[](https://travis-ci.org/tim-vandecasteele/grape-swagger)
|
5
|
+
[](https://codeclimate.com/github/tim-vandecasteele/grape-swagger)
|
4
6
|
|
5
7
|
## What is grape-swagger?
|
6
8
|
|
@@ -174,6 +176,13 @@ You can hide an endpoint by adding ```hidden: true``` in the description of the
|
|
174
176
|
desc 'Hide this endpoint', hidden: true
|
175
177
|
```
|
176
178
|
|
179
|
+
Endpoints can be conditionally hidden by providing a callable object such as a lambda which evaluates to the desired
|
180
|
+
state:
|
181
|
+
|
182
|
+
``` ruby
|
183
|
+
desc 'Conditionally hide this endpoint', hidden: lambda { ENV['EXPERIMENTAL'] != 'true' }
|
184
|
+
```
|
185
|
+
|
177
186
|
## Overriding Auto-Generated Nicknames
|
178
187
|
|
179
188
|
You can specify a swagger nickname to use instead of the auto generated name by adding `:nickname 'string'``` in the description of the endpoint.
|
@@ -182,6 +191,44 @@ You can specify a swagger nickname to use instead of the auto generated name by
|
|
182
191
|
desc 'Get a full list of pets', nickname: 'getAllPets'
|
183
192
|
```
|
184
193
|
|
194
|
+
## Expose nested namespace as standalone route
|
195
|
+
Use the `nested: false` property in the `swagger` option to make nested namespaces appear as standalone resources.
|
196
|
+
This option can help to structure and keep the swagger schema simple.
|
197
|
+
|
198
|
+
namespace 'store/order', desc: 'Order operations within a store', swagger: { nested: false } do
|
199
|
+
get :order_id do
|
200
|
+
...
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
All routes that belong to this namespace (here: the `GET /order_id`) will then be assigned to the `store_order` route instead of the `store` resource route.
|
205
|
+
|
206
|
+
It is also possible to expose a namspace within another already exposed namespace:
|
207
|
+
|
208
|
+
namespace 'store/order', desc: 'Order operations within a store', swagger: { nested: false } do
|
209
|
+
get :order_id do
|
210
|
+
...
|
211
|
+
end
|
212
|
+
namespace 'actions', desc: 'Order actions' do, nested: false
|
213
|
+
get 'evaluate' do
|
214
|
+
...
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
Here, the `GET /order_id` appears as operation of the `store_order` resource and the `GET /evaluate` as operation of the `store_orders_actions` route.
|
220
|
+
|
221
|
+
### With a custom name
|
222
|
+
Auto generated names for the standalone version of complex nested resource do not have a nice look.
|
223
|
+
You can set a custom name with the `name` property inside the `swagger` option, but only if the namespace gets exposed as standalone route.
|
224
|
+
The name should not contain whitespaces or any other special characters due to further issues within swagger-ui.
|
225
|
+
|
226
|
+
namespace 'store/order', desc: 'Order operations within a store', swagger: { nested: false, name: 'Store-orders' } do
|
227
|
+
get :order_id do
|
228
|
+
...
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
185
232
|
## Grape Entities
|
186
233
|
|
187
234
|
Add the [grape-entity](https://github.com/agileanimal/grape-entity) gem to our Gemfile.
|
@@ -227,7 +274,7 @@ end
|
|
227
274
|
|
228
275
|
### Relationships
|
229
276
|
|
230
|
-
|
277
|
+
You may safely omit `type` from relationships, as it can be inferred. However, if you need to specify or override it, use the full name of the class leaving out any modules named `Entities` or `Entity`.
|
231
278
|
|
232
279
|
#### 1xN
|
233
280
|
|
data/UPGRADING.md
CHANGED
@@ -1,6 +1,26 @@
|
|
1
1
|
Upgrading Grape-swagger
|
2
2
|
=======================
|
3
3
|
|
4
|
+
### Upgrading to >= 0.9.0
|
5
|
+
|
6
|
+
#### Changes in Configuration
|
7
|
+
|
8
|
+
If you're using [grape-swagger-rails](https://github.com/BrandyMint/grape-swagger-rails), remove the `.json` extension from `GrapeSwaggerRails.options.url`.
|
9
|
+
|
10
|
+
For example, change
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
GrapeSwaggerRails.options.url = '/api/v1/swagger_doc.json'
|
14
|
+
```
|
15
|
+
|
16
|
+
to
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
GrapeSwaggerRails.options.url = '/api/v1/swagger_doc'
|
20
|
+
```
|
21
|
+
|
22
|
+
See [#187](https://github.com/tim-vandecasteele/grape-swagger/issues/187) for more information.
|
23
|
+
|
4
24
|
### Upgrading to >= 0.8.0
|
5
25
|
|
6
26
|
#### Changes in Configuration
|
data/lib/grape-swagger.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'grape'
|
1
2
|
require 'grape-swagger/version'
|
2
3
|
require 'grape-swagger/errors'
|
3
4
|
require 'grape-swagger/markdown'
|
@@ -7,7 +8,7 @@ require 'grape-swagger/markdown/redcarpet_adapter'
|
|
7
8
|
module Grape
|
8
9
|
class API
|
9
10
|
class << self
|
10
|
-
attr_reader :combined_routes, :combined_namespaces
|
11
|
+
attr_reader :combined_routes, :combined_namespaces, :combined_namespace_routes, :combined_namespace_identifiers
|
11
12
|
|
12
13
|
def add_swagger_documentation(options = {})
|
13
14
|
documentation_class = create_documentation_class
|
@@ -20,7 +21,7 @@ module Grape
|
|
20
21
|
route_path = route.route_path
|
21
22
|
route_match = route_path.split(/^.*?#{route.route_prefix.to_s}/).last
|
22
23
|
next unless route_match
|
23
|
-
route_match = route_match.match('\/([\w|-]*?)[\.\/\(]') || route_match.match('\/([\w|-]*)')
|
24
|
+
route_match = route_match.match('\/([\w|-]*?)[\.\/\(]') || route_match.match('\/([\w|-]*)$')
|
24
25
|
next unless route_match
|
25
26
|
resource = route_match.captures.first
|
26
27
|
next if resource.empty?
|
@@ -32,6 +33,13 @@ module Grape
|
|
32
33
|
|
33
34
|
@combined_namespaces = {}
|
34
35
|
combine_namespaces(self)
|
36
|
+
|
37
|
+
@combined_namespace_routes = {}
|
38
|
+
@combined_namespace_identifiers = {}
|
39
|
+
combine_namespace_routes(@combined_namespaces)
|
40
|
+
|
41
|
+
exclusive_route_keys = @combined_routes.keys - @combined_namespaces.keys
|
42
|
+
exclusive_route_keys.each { |key| @combined_namespace_routes[key] = @combined_routes[key] }
|
35
43
|
documentation_class
|
36
44
|
end
|
37
45
|
|
@@ -44,12 +52,112 @@ module Grape
|
|
44
52
|
else
|
45
53
|
endpoint.settings.stack.last[:namespace]
|
46
54
|
end
|
47
|
-
|
55
|
+
# use the full namespace here (not the latest level only)
|
56
|
+
# and strip leading slash
|
57
|
+
@combined_namespaces[endpoint.namespace.sub(/^\//, '')] = ns if ns
|
48
58
|
|
49
59
|
combine_namespaces(endpoint.options[:app]) if endpoint.options[:app]
|
50
60
|
end
|
51
61
|
end
|
52
62
|
|
63
|
+
def combine_namespace_routes(namespaces)
|
64
|
+
# iterate over each single namespace
|
65
|
+
namespaces.each do |name, namespace|
|
66
|
+
# get the parent route for the namespace
|
67
|
+
parent_route_name = name.match(%r{^/?([^/]*).*$})[1]
|
68
|
+
parent_route = @combined_routes[parent_route_name]
|
69
|
+
# fetch all routes that are within the current namespace
|
70
|
+
namespace_routes = parent_route.collect do |route|
|
71
|
+
route if (route.route_path.start_with?("/#{name}") || route.route_path.start_with?("/:version/#{name}")) &&
|
72
|
+
(route.instance_variable_get(:@options)[:namespace] == "/#{name}" || route.instance_variable_get(:@options)[:namespace] == "/:version/#{name}")
|
73
|
+
end.compact
|
74
|
+
|
75
|
+
if namespace.options.key?(:swagger) && namespace.options[:swagger][:nested] == false
|
76
|
+
# Namespace shall appear as standalone resource, use specified name or use normalized path as name
|
77
|
+
if namespace.options[:swagger].key?(:name)
|
78
|
+
identifier = namespace.options[:swagger][:name].gsub(/ /, '-')
|
79
|
+
else
|
80
|
+
identifier = name.gsub(/_/, '-').gsub(/\//, '_')
|
81
|
+
end
|
82
|
+
@combined_namespace_identifiers[identifier] = name
|
83
|
+
@combined_namespace_routes[identifier] = namespace_routes
|
84
|
+
|
85
|
+
# get all nested namespaces below the current namespace
|
86
|
+
sub_namespaces = standalone_sub_namespaces(name, namespaces)
|
87
|
+
# convert namespace to route names
|
88
|
+
sub_ns_paths = sub_namespaces.collect { |ns_name, _| "/#{ns_name}" }
|
89
|
+
sub_ns_paths_versioned = sub_namespaces.collect { |ns_name, _| "/:version/#{ns_name}" }
|
90
|
+
# get the actual route definitions for the namespace path names
|
91
|
+
sub_routes = parent_route.collect do |route|
|
92
|
+
route if sub_ns_paths.include?(route.instance_variable_get(:@options)[:namespace]) || sub_ns_paths_versioned.include?(route.instance_variable_get(:@options)[:namespace])
|
93
|
+
end.compact
|
94
|
+
# add all determined routes of the sub namespaces to standalone resource
|
95
|
+
@combined_namespace_routes[identifier].push(*sub_routes)
|
96
|
+
else
|
97
|
+
# default case when not explicitly specified or nested == true
|
98
|
+
standalone_namespaces = namespaces.reject { |_, ns| !ns.options.key?(:swagger) || !ns.options[:swagger].key?(:nested) || ns.options[:swagger][:nested] != false }
|
99
|
+
parent_standalone_namespaces = standalone_namespaces.reject { |ns_name, _| !name.start_with?(ns_name) }
|
100
|
+
# add only to the main route if the namespace is not within any other namespace appearing as standalone resource
|
101
|
+
if parent_standalone_namespaces.empty?
|
102
|
+
# default option, append namespace methods to parent route
|
103
|
+
@combined_namespace_routes[parent_route_name] = [] unless @combined_namespace_routes.key?(parent_route_name)
|
104
|
+
@combined_namespace_routes[parent_route_name].push(*namespace_routes)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def standalone_sub_namespaces(name, namespaces)
|
111
|
+
# assign all nested namespace routes to this resource, too
|
112
|
+
# (unless they are assigned to another standalone namespace themselves)
|
113
|
+
sub_namespaces = {}
|
114
|
+
# fetch all namespaces that are children of the current namespace
|
115
|
+
namespaces.each { |ns_name, ns| sub_namespaces[ns_name] = ns if ns_name.start_with?(name) && ns_name != name }
|
116
|
+
# remove the sub namespaces if they are assigned to another standalone namespace themselves
|
117
|
+
sub_namespaces.each do |sub_name, sub_ns|
|
118
|
+
# skip if sub_ns is standalone, too
|
119
|
+
next unless sub_ns.options.key?(:swagger) && sub_ns.options[:swagger][:nested] == false
|
120
|
+
# remove all namespaces that are nested below this standalone sub_ns
|
121
|
+
sub_namespaces.each { |sub_sub_name, _| sub_namespaces.delete(sub_sub_name) if sub_sub_name.start_with?(sub_name) }
|
122
|
+
end
|
123
|
+
sub_namespaces
|
124
|
+
end
|
125
|
+
|
126
|
+
def get_non_nested_params(params)
|
127
|
+
# Duplicate the params as we are going to modify them
|
128
|
+
dup_params = params.each_with_object(Hash.new) do |(param, value), dparams|
|
129
|
+
dparams[param] = value.dup
|
130
|
+
end
|
131
|
+
|
132
|
+
dup_params.reject do |param, value|
|
133
|
+
is_nested_param = /^#{ Regexp.quote param }\[.+\]$/
|
134
|
+
0 < dup_params.count do |p, _|
|
135
|
+
match = p.match(is_nested_param)
|
136
|
+
dup_params[p][:required] = false if match && !value[:required]
|
137
|
+
match
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def parse_array_params(params)
|
143
|
+
modified_params = {}
|
144
|
+
array_param = nil
|
145
|
+
params.each_key do |k|
|
146
|
+
if params[k].is_a?(Hash) && params[k][:type] == 'Array'
|
147
|
+
array_param = k
|
148
|
+
else
|
149
|
+
new_key = k
|
150
|
+
unless array_param.nil?
|
151
|
+
if k.to_s.start_with?(array_param.to_s + '[')
|
152
|
+
new_key = array_param.to_s + '[]' + k.to_s.split(array_param)[1]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
modified_params[new_key] = params[k]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
modified_params
|
159
|
+
end
|
160
|
+
|
53
161
|
def create_documentation_class
|
54
162
|
Class.new(Grape::API) do
|
55
163
|
class << self
|
@@ -64,10 +172,9 @@ module Grape
|
|
64
172
|
def parse_params(params, path, method)
|
65
173
|
params ||= []
|
66
174
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
175
|
+
parsed_array_params = parse_array_params(params)
|
176
|
+
|
177
|
+
non_nested_parent_params = get_non_nested_params(parsed_array_params)
|
71
178
|
|
72
179
|
non_nested_parent_params.map do |param, value|
|
73
180
|
items = {}
|
@@ -80,7 +187,7 @@ module Grape
|
|
80
187
|
'File'
|
81
188
|
when 'Virtus::Attribute::Boolean'
|
82
189
|
'boolean'
|
83
|
-
when 'Boolean', 'Date', 'Integer', 'String'
|
190
|
+
when 'Boolean', 'Date', 'Integer', 'String', 'Float'
|
84
191
|
raw_data_type.downcase
|
85
192
|
when 'BigDecimal'
|
86
193
|
'long'
|
@@ -88,6 +195,8 @@ module Grape
|
|
88
195
|
'dateTime'
|
89
196
|
when 'Numeric'
|
90
197
|
'double'
|
198
|
+
when 'Symbol'
|
199
|
+
'string'
|
91
200
|
else
|
92
201
|
@@documentation_class.parse_entity_name(raw_data_type)
|
93
202
|
end
|
@@ -96,6 +205,7 @@ module Grape
|
|
96
205
|
default_value = value.is_a?(Hash) ? value[:default] : nil
|
97
206
|
is_array = value.is_a?(Hash) ? (value[:is_array] || false) : false
|
98
207
|
enum_values = value.is_a?(Hash) ? value[:values] : nil
|
208
|
+
enum_values = enum_values.to_a if enum_values && enum_values.is_a?(Range)
|
99
209
|
enum_values = enum_values.call if enum_values && enum_values.is_a?(Proc)
|
100
210
|
|
101
211
|
if value.is_a?(Hash) && value.key?(:param_type)
|
@@ -220,11 +330,17 @@ module Grape
|
|
220
330
|
|
221
331
|
required << property_name.to_s if p.delete(:required)
|
222
332
|
|
333
|
+
type = if p[:type]
|
334
|
+
p.delete(:type)
|
335
|
+
elsif (entity = model.exposures[property_name][:using])
|
336
|
+
parse_entity_name(entity)
|
337
|
+
end
|
338
|
+
|
223
339
|
if p.delete(:is_array)
|
224
|
-
p[:items] = generate_typeref(
|
340
|
+
p[:items] = generate_typeref(type)
|
225
341
|
p[:type] = 'array'
|
226
342
|
else
|
227
|
-
p.merge! generate_typeref(
|
343
|
+
p.merge! generate_typeref(type)
|
228
344
|
end
|
229
345
|
|
230
346
|
# rename Grape Entity's "desc" to "description"
|
@@ -239,7 +355,6 @@ module Grape
|
|
239
355
|
end
|
240
356
|
|
241
357
|
properties[property_name] = p
|
242
|
-
|
243
358
|
end
|
244
359
|
|
245
360
|
result[name] = {
|
@@ -372,20 +487,21 @@ module Grape
|
|
372
487
|
header['Access-Control-Allow-Origin'] = '*'
|
373
488
|
header['Access-Control-Request-Method'] = '*'
|
374
489
|
|
375
|
-
routes = target_class.combined_routes
|
376
490
|
namespaces = target_class.combined_namespaces
|
491
|
+
namespace_routes = target_class.combined_namespace_routes
|
377
492
|
|
378
493
|
if @@hide_documentation_path
|
379
|
-
|
494
|
+
namespace_routes.reject! { |route, _value| "/#{route}/".index(@@documentation_class.parse_path(@@mount_path, nil) << '/') == 0 }
|
380
495
|
end
|
381
496
|
|
382
|
-
|
383
|
-
next if
|
497
|
+
namespace_routes_array = namespace_routes.keys.map do |local_route|
|
498
|
+
next if namespace_routes[local_route].map(&:route_hidden).all? { |value| value.respond_to?(:call) ? value.call : value }
|
384
499
|
|
385
500
|
url_format = '.{format}' unless @@hide_format
|
386
501
|
|
387
|
-
|
388
|
-
description
|
502
|
+
original_namespace_name = target_class.combined_namespace_identifiers.key?(local_route) ? target_class.combined_namespace_identifiers[local_route] : local_route
|
503
|
+
description = namespaces[original_namespace_name] && namespaces[original_namespace_name].options[:desc]
|
504
|
+
description ||= "Operations about #{original_namespace_name.pluralize}"
|
389
505
|
|
390
506
|
{
|
391
507
|
path: "/#{local_route}#{url_format}",
|
@@ -397,7 +513,7 @@ module Grape
|
|
397
513
|
apiVersion: api_version,
|
398
514
|
swaggerVersion: '1.2',
|
399
515
|
produces: @@documentation_class.content_types_for(target_class),
|
400
|
-
apis:
|
516
|
+
apis: namespace_routes_array,
|
401
517
|
info: @@documentation_class.parse_info(extra_info)
|
402
518
|
}
|
403
519
|
|
@@ -419,10 +535,14 @@ module Grape
|
|
419
535
|
header['Access-Control-Request-Method'] = '*'
|
420
536
|
|
421
537
|
models = []
|
422
|
-
routes = target_class.
|
538
|
+
routes = target_class.combined_namespace_routes[params[:name]]
|
423
539
|
error!('Not Found', 404) unless routes
|
424
540
|
|
425
|
-
|
541
|
+
visible_ops = routes.reject do |route|
|
542
|
+
route.route_hidden.respond_to?(:call) ? route.route_hidden.call : route.route_hidden
|
543
|
+
end
|
544
|
+
|
545
|
+
ops = visible_ops.group_by do |route|
|
426
546
|
@@documentation_class.parse_path(route.route_path, api_version)
|
427
547
|
end
|
428
548
|
|
@@ -438,7 +558,7 @@ module Grape
|
|
438
558
|
|
439
559
|
models |= @@models if @@models.present?
|
440
560
|
|
441
|
-
models |=
|
561
|
+
models |= Array(route.route_entity) if route.route_entity.present?
|
442
562
|
|
443
563
|
models = @@documentation_class.models_with_included_presenters(models.flatten.compact)
|
444
564
|
|
@@ -457,7 +577,7 @@ module Grape
|
|
457
577
|
operation.merge!(responseMessages: http_codes) unless http_codes.empty?
|
458
578
|
|
459
579
|
if route.route_entity
|
460
|
-
type = @@documentation_class.parse_entity_name(route.route_entity)
|
580
|
+
type = @@documentation_class.parse_entity_name(Array(route.route_entity).first)
|
461
581
|
operation.merge!('type' => type)
|
462
582
|
end
|
463
583
|
|
@@ -470,10 +590,16 @@ module Grape
|
|
470
590
|
}
|
471
591
|
end
|
472
592
|
|
593
|
+
# use custom resource naming if available
|
594
|
+
if target_class.combined_namespace_identifiers.key? params[:name]
|
595
|
+
resource_path = target_class.combined_namespace_identifiers[params[:name]]
|
596
|
+
else
|
597
|
+
resource_path = params[:name]
|
598
|
+
end
|
473
599
|
api_description = {
|
474
600
|
apiVersion: api_version,
|
475
601
|
swaggerVersion: '1.2',
|
476
|
-
resourcePath: "/#{
|
602
|
+
resourcePath: "/#{resource_path}",
|
477
603
|
produces: @@documentation_class.content_types_for(target_class),
|
478
604
|
apis: apis
|
479
605
|
}
|