grape-swagger 2.1.0 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -2
- data/README.md +17 -15
- data/grape-swagger.gemspec +3 -3
- data/lib/grape-swagger/doc_methods/parse_params.rb +11 -0
- data/lib/grape-swagger/doc_methods/produces_consumes.rb +1 -1
- data/lib/grape-swagger/endpoint.rb +39 -9
- data/lib/grape-swagger/rake/oapi_tasks.rb +1 -1
- data/lib/grape-swagger/version.rb +1 -1
- data/lib/grape-swagger.rb +38 -15
- metadata +4 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c24ea948c1239e50ed34d39ebb5e80386016fa27989454d1be18661f5829fc91
|
4
|
+
data.tar.gz: 3e85a52315ff15529005170bcda996cefa908efa1a6df5aac936edbe8bf907de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99e8711c4ee7ed930b5e670b263a0f2e2b19125869e8d216c4afe6bdb0bc8569142f3c28e3bf69867771e4629d6edc6a2c1b342f4843b7b849e1be256f5128a6
|
7
|
+
data.tar.gz: d06630524a8dfa7a45c6926cb61c752fa0856850fc53fc01db85e355da81dde76ff4d6fa913a7d8471aed1bc3ac0a9b0455695ac7b30533a5de7f5198c811279
|
data/CHANGELOG.md
CHANGED
@@ -1,14 +1,34 @@
|
|
1
|
-
###
|
1
|
+
### Next
|
2
2
|
|
3
3
|
#### Features
|
4
4
|
|
5
|
-
*
|
5
|
+
* your contribution
|
6
|
+
|
7
|
+
#### Fixes
|
8
|
+
|
9
|
+
* your contribution
|
10
|
+
|
11
|
+
|
12
|
+
### 2.1.2 (Jan 7, 2025)
|
13
|
+
|
14
|
+
#### Features
|
15
|
+
|
16
|
+
* [#945](https://github.com/ruby-grape/grape-swagger/pull/945): Add support for primitive data types in responses - [@gregg-platogo](https://github.com/gregg-platogo).
|
6
17
|
|
7
18
|
#### Fixes
|
8
19
|
|
20
|
+
* [#943](https://github.com/ruby-grape/grape-swagger/pull/943): Fix route_param documentation and type - [@4ndv](https://github.com/4ndv)
|
21
|
+
* [#944](https://github.com/ruby-grape/grape-swagger/pull/944): Amend a few typographic errors - [@pieterocp](https://github.com/pieterocp)
|
9
22
|
* Your contribution here.
|
10
23
|
|
11
24
|
|
25
|
+
### 2.1.1 (Sep 21, 2024)
|
26
|
+
|
27
|
+
#### Fixes
|
28
|
+
|
29
|
+
* [#940](https://github.com/ruby-grape/grape-swagger/pull/940): Grape 2.2.0 compatibility - [@padde](https://github.com/padde)
|
30
|
+
|
31
|
+
|
12
32
|
### 2.1.0 (May 14, 2024)
|
13
33
|
|
14
34
|
#### Features
|
data/README.md
CHANGED
@@ -43,17 +43,18 @@ This screenshot is based on the [Hussars](https://github.com/LeFnord/hussars) sa
|
|
43
43
|
|
44
44
|
The following versions of grape, grape-entity and grape-swagger can currently be used together.
|
45
45
|
|
46
|
-
| grape-swagger
|
47
|
-
|
|
48
|
-
| 0.10.5
|
49
|
-
| 0.11.0
|
50
|
-
| 0.25.2
|
51
|
-
| 0.26.0
|
52
|
-
| 0.27.0
|
53
|
-
| 0.32.0
|
54
|
-
| 0.34.0
|
55
|
-
| >= 1.0.0
|
56
|
-
| >= 2.0.0
|
46
|
+
| grape-swagger | swagger spec | grape | grape-entity | representable |
|
47
|
+
| ------------------ | ------------ | ----------------------- | ------------ | ------------- |
|
48
|
+
| 0.10.5 | 1.2 | >= 0.10.0 ... <= 0.14.0 | < 0.5.0 | n/a |
|
49
|
+
| 0.11.0 | 1.2 | >= 0.16.2 | < 0.5.0 | n/a |
|
50
|
+
| 0.25.2 | 2.0 | >= 0.14.0 ... <= 0.18.0 | <= 0.6.0 | >= 2.4.1 |
|
51
|
+
| 0.26.0 | 2.0 | >= 0.16.2 ... <= 1.1.0 | <= 0.6.1 | >= 2.4.1 |
|
52
|
+
| 0.27.0 | 2.0 | >= 0.16.2 ... <= 1.1.0 | >= 0.5.0 | >= 2.4.1 |
|
53
|
+
| 0.32.0 | 2.0 | >= 0.16.2 | >= 0.5.0 | >= 2.4.1 |
|
54
|
+
| 0.34.0 | 2.0 | >= 0.16.2 ... < 1.3.0 | >= 0.5.0 | >= 2.4.1 |
|
55
|
+
| >= 1.0.0 | 2.0 | >= 1.3.0 | >= 0.5.0 | >= 2.4.1 |
|
56
|
+
| >= 2.0.0 | 2.0 | >= 1.7.0 | >= 0.5.0 | >= 2.4.1 |
|
57
|
+
| >= 2.0.0 ... < 2.2 | 2.0 | >= 1.8.0 ... < 2.3.0 | >= 0.5.0 | >= 2.4.1 |
|
57
58
|
|
58
59
|
|
59
60
|
## Swagger-Spec <a name="swagger-spec"></a>
|
@@ -485,7 +486,7 @@ add_swagger_documentation \
|
|
485
486
|
|
486
487
|
#### Swagger Header Parameters <a name="headers"></a>
|
487
488
|
|
488
|
-
Swagger also supports the documentation of parameters passed in the header. Since grape's ```params[]``` doesn't return header parameters we can specify header parameters
|
489
|
+
Swagger also supports the documentation of parameters passed in the header. Since grape's ```params[]``` doesn't return header parameters we can specify header parameters separately in a block after the description.
|
489
490
|
|
490
491
|
```ruby
|
491
492
|
desc "Return super-secret information", {
|
@@ -955,7 +956,8 @@ The result is then something like following:
|
|
955
956
|
|
956
957
|
#### Changing default status codes <a name="change-status"></a>
|
957
958
|
|
958
|
-
|
959
|
+
|
960
|
+
The default status codes, one could be found (-> [status codes](lib/grape-swagger/doc_methods/status_codes.rb)) can be changed to your specific needs, to achieve it, you have to change it for grape itself and for the documentation.
|
959
961
|
|
960
962
|
```ruby
|
961
963
|
desc 'Get a list of stuff',
|
@@ -1678,7 +1680,7 @@ This is how to configure the grape_swagger documentation:
|
|
1678
1680
|
The guard method should inject the Security Requirement Object into the endpoint's route settings (see Grape::DSL::Settings.route_setting method).
|
1679
1681
|
|
1680
1682
|
The 'oauth2 false' added to swagger_documentation is making the main Swagger endpoint protected with OAuth, i.e. the
|
1681
|
-
access_token is being
|
1683
|
+
access_token is being retrieving from the HTTP request, but the 'false' scope is for skipping authorization and
|
1682
1684
|
showing the UI for everyone. If the scope would be set to something else, like 'oauth2 admin', for example, than the UI
|
1683
1685
|
wouldn't be displayed at all to unauthorized users.
|
1684
1686
|
|
@@ -1786,7 +1788,7 @@ params:
|
|
1786
1788
|
- store={ true | file_name.json } – save as JSON (optional)
|
1787
1789
|
- resource=resource_name – get only for this one (optional)
|
1788
1790
|
```
|
1789
|
-
For
|
1791
|
+
For multiversion API it creates several files with following naming: file_name_`API_VERSION`.json
|
1790
1792
|
|
1791
1793
|
#### OpenApi/Swagger Validation
|
1792
1794
|
|
data/grape-swagger.gemspec
CHANGED
@@ -14,9 +14,9 @@ Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.metadata['rubygems_mfa_required'] = 'true'
|
16
16
|
|
17
|
-
s.required_ruby_version = '>= 3.
|
18
|
-
s.
|
19
|
-
s.
|
17
|
+
s.required_ruby_version = '>= 3.1'
|
18
|
+
s.add_dependency 'grape', '>= 1.7', '< 3.0'
|
19
|
+
s.add_dependency 'rack-test', '~> 2'
|
20
20
|
|
21
21
|
s.files = Dir['lib/**/*', '*.md', 'LICENSE.txt', 'grape-swagger.gemspec']
|
22
22
|
s.require_paths = ['lib']
|
@@ -25,6 +25,7 @@ module GrapeSwagger
|
|
25
25
|
document_default_value(settings) unless value_type[:is_array]
|
26
26
|
document_range_values(settings) unless value_type[:is_array]
|
27
27
|
document_required(settings)
|
28
|
+
document_length_limits(value_type)
|
28
29
|
document_additional_properties(definitions, settings) unless value_type[:is_array]
|
29
30
|
document_add_extensions(settings)
|
30
31
|
document_example(settings)
|
@@ -163,6 +164,16 @@ module GrapeSwagger
|
|
163
164
|
end
|
164
165
|
end
|
165
166
|
|
167
|
+
def document_length_limits(value_type)
|
168
|
+
if value_type[:is_array]
|
169
|
+
@parsed_param[:minItems] = value_type[:min_length] if value_type.key?(:min_length)
|
170
|
+
@parsed_param[:maxItems] = value_type[:max_length] if value_type.key?(:max_length)
|
171
|
+
else
|
172
|
+
@parsed_param[:minLength] = value_type[:min_length] if value_type.key?(:min_length)
|
173
|
+
@parsed_param[:maxLength] = value_type[:max_length] if value_type.key?(:max_length)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
166
177
|
def parse_enum_or_range_values(values)
|
167
178
|
case values
|
168
179
|
when Proc
|
@@ -7,7 +7,7 @@ module GrapeSwagger
|
|
7
7
|
def call(*args)
|
8
8
|
return ['application/json'] unless args.flatten.present?
|
9
9
|
|
10
|
-
args.flatten.map { |x|
|
10
|
+
args.flatten.map { |x| GrapeSwagger::CONTENT_TYPE_DEFAULTS[x] || x }.uniq
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -11,8 +11,8 @@ module Grape
|
|
11
11
|
|
12
12
|
if content_types.empty?
|
13
13
|
formats = [target_class.format, target_class.default_format].compact.uniq
|
14
|
-
formats =
|
15
|
-
content_types =
|
14
|
+
formats = GrapeSwagger::FORMATTER_DEFAULTS.keys if formats.empty?
|
15
|
+
content_types = GrapeSwagger::CONTENT_TYPE_DEFAULTS.select do |content_type, _mime_type|
|
16
16
|
formats.include? content_type
|
17
17
|
end.values
|
18
18
|
end
|
@@ -207,11 +207,8 @@ module Grape
|
|
207
207
|
|
208
208
|
next build_file_response(memo[value[:code]]) if file_response?(value[:model])
|
209
209
|
|
210
|
-
if
|
211
|
-
|
212
|
-
value[:code] = 204
|
213
|
-
next
|
214
|
-
end
|
210
|
+
next build_delete_response(memo, value) if delete_response?(memo, route, value)
|
211
|
+
next build_response_for_type_parameter(memo, route, value, options) if value[:type]
|
215
212
|
|
216
213
|
# Explicitly request no model with { model: '' }
|
217
214
|
next if value[:model] == ''
|
@@ -284,6 +281,15 @@ module Grape
|
|
284
281
|
[default_code]
|
285
282
|
end
|
286
283
|
|
284
|
+
def build_delete_response(memo, value)
|
285
|
+
memo[204] = memo.delete(200)
|
286
|
+
value[:code] = 204
|
287
|
+
end
|
288
|
+
|
289
|
+
def delete_response?(memo, route, value)
|
290
|
+
memo.key?(200) && route.request_method == 'DELETE' && value[:model].nil?
|
291
|
+
end
|
292
|
+
|
287
293
|
def build_memo_schema(memo, route, value, response_model, options)
|
288
294
|
if memo[value[:code]][:schema] && value[:as]
|
289
295
|
memo[value[:code]][:schema][:properties].merge!(build_reference(route, value, response_model, options))
|
@@ -304,6 +310,29 @@ module Grape
|
|
304
310
|
end
|
305
311
|
end
|
306
312
|
|
313
|
+
def build_response_for_type_parameter(memo, _route, value, _options)
|
314
|
+
type, format = prepare_type_and_format(value)
|
315
|
+
|
316
|
+
if memo[value[:code]].include?(:schema) && value.include?(:as)
|
317
|
+
memo[value[:code]][:schema][:properties].merge!(value[:as] => { type: type, format: format }.compact)
|
318
|
+
elsif value.include?(:as)
|
319
|
+
memo[value[:code]][:schema] =
|
320
|
+
{ type: :object, properties: { value[:as] => { type: type, format: format }.compact } }
|
321
|
+
else
|
322
|
+
memo[value[:code]][:schema] = { type: type }
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def prepare_type_and_format(value)
|
327
|
+
data_type = GrapeSwagger::DocMethods::DataType.call(value[:type])
|
328
|
+
|
329
|
+
if GrapeSwagger::DocMethods::DataType.primitive?(data_type)
|
330
|
+
GrapeSwagger::DocMethods::DataType.mapping(data_type)
|
331
|
+
else
|
332
|
+
data_type
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
307
336
|
def build_reference(route, value, response_model, settings)
|
308
337
|
# TODO: proof that the definition exist, if model isn't specified
|
309
338
|
reference = if value.key?(:as)
|
@@ -377,7 +406,7 @@ module Grape
|
|
377
406
|
route_params[key] = path.merge(params)
|
378
407
|
end
|
379
408
|
|
380
|
-
|
409
|
+
route_params.delete_if { |key| key.is_a?(String) && param_keys.include?(key.to_sym) }.to_a
|
381
410
|
end
|
382
411
|
|
383
412
|
# Iterates over namespaces recursively
|
@@ -387,7 +416,7 @@ module Grape
|
|
387
416
|
return param unless stackable_values
|
388
417
|
return params unless stackable_values.is_a? Grape::Util::StackableValues
|
389
418
|
|
390
|
-
stackable_values&.new_values&.dig(:namespace)&.each do |namespace|
|
419
|
+
stackable_values&.new_values&.dig(:namespace)&.each do |namespace| # rubocop:disable Style/SafeNavigationChainLength
|
391
420
|
space = namespace.space.to_s.gsub(':', '')
|
392
421
|
params[space] = namespace.options || {}
|
393
422
|
end
|
@@ -464,6 +493,7 @@ module Grape
|
|
464
493
|
default_code[:as] = entity[:as] if entity[:as]
|
465
494
|
default_code[:is_array] = entity[:is_array] if entity[:is_array]
|
466
495
|
default_code[:required] = entity[:required] if entity[:required]
|
496
|
+
default_code[:type] = entity[:type] if entity[:type]
|
467
497
|
else
|
468
498
|
default_code = GrapeSwagger::DocMethods::StatusCodes.get[route.request_method.downcase.to_sym]
|
469
499
|
default_code[:model] = entity if entity
|
data/lib/grape-swagger.rb
CHANGED
@@ -18,6 +18,24 @@ module GrapeSwagger
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
autoload :Rake, 'grape-swagger/rake/oapi_tasks'
|
21
|
+
|
22
|
+
# Copied from https://github.com/ruby-grape/grape/blob/v2.2.0/lib/grape/formatter.rb
|
23
|
+
FORMATTER_DEFAULTS = {
|
24
|
+
json: Grape::Formatter::Json,
|
25
|
+
jsonapi: Grape::Formatter::Json,
|
26
|
+
serializable_hash: Grape::Formatter::SerializableHash,
|
27
|
+
txt: Grape::Formatter::Txt,
|
28
|
+
xml: Grape::Formatter::Xml
|
29
|
+
}.freeze
|
30
|
+
|
31
|
+
# Copied from https://github.com/ruby-grape/grape/blob/v2.2.0/lib/grape/content_types.rb
|
32
|
+
CONTENT_TYPE_DEFAULTS = {
|
33
|
+
xml: 'application/xml',
|
34
|
+
serializable_hash: 'application/json',
|
35
|
+
json: 'application/json',
|
36
|
+
binary: 'application/octet-stream',
|
37
|
+
txt: 'text/plain'
|
38
|
+
}.freeze
|
21
39
|
end
|
22
40
|
|
23
41
|
module SwaggerRouting
|
@@ -45,12 +63,10 @@ module SwaggerRouting
|
|
45
63
|
end
|
46
64
|
|
47
65
|
def determine_namespaced_routes(name, parent_route, routes)
|
48
|
-
if parent_route.nil?
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
!route_path_start_with?(route, name) || !route_instance_variable_equals?(route, name)
|
53
|
-
end
|
66
|
+
return routes.values.flatten if parent_route.nil?
|
67
|
+
|
68
|
+
parent_route.select do |route|
|
69
|
+
route_path_start_with?(route, name) || route_namespace_equals?(route, name)
|
54
70
|
end
|
55
71
|
end
|
56
72
|
|
@@ -94,20 +110,27 @@ module SwaggerRouting
|
|
94
110
|
matches.nil? ? route_name : matches[0].delete('/')
|
95
111
|
end
|
96
112
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
113
|
+
def route_namespace_equals?(route, name)
|
114
|
+
patterns = Enumerator.new do |yielder|
|
115
|
+
yielder << "/#{name}"
|
116
|
+
yielder << "/:version/#{name}"
|
117
|
+
end
|
100
118
|
|
101
|
-
|
102
|
-
route_instance_variable(route) == "/#{name}" ||
|
103
|
-
route_instance_variable(route) == "/:version/#{name}"
|
119
|
+
patterns.any? { |p| route.namespace == p }
|
104
120
|
end
|
105
121
|
|
106
122
|
def route_path_start_with?(route, name)
|
107
|
-
|
108
|
-
|
123
|
+
patterns = Enumerator.new do |yielder|
|
124
|
+
if route.prefix
|
125
|
+
yielder << "/#{route.prefix}/#{name}"
|
126
|
+
yielder << "/#{route.prefix}/:version/#{name}"
|
127
|
+
else
|
128
|
+
yielder << "/#{name}"
|
129
|
+
yielder << "/:version/#{name}"
|
130
|
+
end
|
131
|
+
end
|
109
132
|
|
110
|
-
route.path.start_with?(
|
133
|
+
patterns.any? { |p| route.path.start_with?(p) }
|
111
134
|
end
|
112
135
|
end
|
113
136
|
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape-swagger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LeFnord
|
8
8
|
- Tim Vandecasteele
|
9
|
-
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2025-01-07 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: grape
|
@@ -45,7 +44,6 @@ dependencies:
|
|
45
44
|
- - "~>"
|
46
45
|
- !ruby/object:Gem::Version
|
47
46
|
version: '2'
|
48
|
-
description:
|
49
47
|
email:
|
50
48
|
- pscholz.le@gmail.com
|
51
49
|
- tim.vandecasteele@gmail.com
|
@@ -88,7 +86,6 @@ licenses:
|
|
88
86
|
- MIT
|
89
87
|
metadata:
|
90
88
|
rubygems_mfa_required: 'true'
|
91
|
-
post_install_message:
|
92
89
|
rdoc_options: []
|
93
90
|
require_paths:
|
94
91
|
- lib
|
@@ -96,15 +93,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
93
|
requirements:
|
97
94
|
- - ">="
|
98
95
|
- !ruby/object:Gem::Version
|
99
|
-
version: '3.
|
96
|
+
version: '3.1'
|
100
97
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
98
|
requirements:
|
102
99
|
- - ">="
|
103
100
|
- !ruby/object:Gem::Version
|
104
101
|
version: '0'
|
105
102
|
requirements: []
|
106
|
-
rubygems_version: 3.
|
107
|
-
signing_key:
|
103
|
+
rubygems_version: 3.6.2
|
108
104
|
specification_version: 4
|
109
105
|
summary: Add auto generated documentation to your Grape API that can be displayed
|
110
106
|
with Swagger.
|