grape-swagger 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![
|
3
|
+
[![Gem Version](http://img.shields.io/gem/v/grape-swagger.svg)](http://badge.fury.io/rb/grape-swagger)
|
4
|
+
[![Build Status](http://img.shields.io/travis/tim-vandecasteele/grape-swagger.svg)](https://travis-ci.org/tim-vandecasteele/grape-swagger)
|
5
|
+
[![Code Climate](https://codeclimate.com/github/tim-vandecasteele/grape-swagger.svg)](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
|
}
|