grape-swagger 2.0.3 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/lib/grape-swagger/doc_methods/data_type.rb +8 -0
- data/lib/grape-swagger/doc_methods/parse_params.rb +11 -9
- data/lib/grape-swagger/endpoint.rb +3 -3
- data/lib/grape-swagger/version.rb +1 -1
- data/lib/grape-swagger.rb +34 -29
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8fbf69e7e7bc7f3a836c574fe91df74abb10aab05c778cee716398d76afeace6
|
4
|
+
data.tar.gz: 5ab4bc60eafa3ad32959a040aed645943121912037a738278d88fb649390a0fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8bcb10791418aa79af266d503f7fd5130157bb7971d7acb094964981d9ee8635fe6bcf72e212b81f22a25f2032a002fba99b97a7d078d8d35a908f0117fae379
|
7
|
+
data.tar.gz: d7843b9aaf70d83a9d0de3dc7f075b8f3df2e4cedda4a1c519cbc4109dc9da1cb1de82c9966fcf6a0083ebbe22a89c13654fbd9fe9e1156af4103e8bc70a344e
|
data/CHANGELOG.md
CHANGED
@@ -9,6 +9,18 @@
|
|
9
9
|
* Your contribution here.
|
10
10
|
|
11
11
|
|
12
|
+
### 2.1.0 (May 14, 2024)
|
13
|
+
|
14
|
+
#### Features
|
15
|
+
|
16
|
+
* [#927](https://github.com/ruby-grape/grape-swagger/pull/927): Set default parameter location based on consumes - [@spaceraccoon](https://github.com/spaceraccoon)
|
17
|
+
* [#929](https://github.com/ruby-grape/grape-swagger/pull/929): Set query parameter for array of primitive types - [@spaceraccoon](https://github.com/spaceraccoon)
|
18
|
+
|
19
|
+
#### Fixes
|
20
|
+
|
21
|
+
* [#926](https://github.com/ruby-grape/grape-swagger/pull/926): Refactor route and namespace combination logic - [@numbata](https://github.com/numbata)
|
22
|
+
|
23
|
+
|
12
24
|
### 2.0.3 (April 26, 2024)
|
13
25
|
|
14
26
|
#### Fixes
|
@@ -75,6 +75,14 @@ module GrapeSwagger
|
|
75
75
|
PRIMITIVE_MAPPINGS.keys.map(&:downcase)
|
76
76
|
end
|
77
77
|
|
78
|
+
def query_array_primitive?(type)
|
79
|
+
query_array_primitives.include?(type.to_s.downcase)
|
80
|
+
end
|
81
|
+
|
82
|
+
def query_array_primitives
|
83
|
+
primitives << 'string'
|
84
|
+
end
|
85
|
+
|
78
86
|
def mapping(value)
|
79
87
|
PRIMITIVE_MAPPINGS[value] || 'string'
|
80
88
|
end
|
@@ -4,7 +4,7 @@ module GrapeSwagger
|
|
4
4
|
module DocMethods
|
5
5
|
class ParseParams
|
6
6
|
class << self
|
7
|
-
def call(param, settings, path, route, definitions)
|
7
|
+
def call(param, settings, path, route, definitions, consumes) # rubocop:disable Metrics/ParameterLists
|
8
8
|
method = route.request_method
|
9
9
|
additional_documentation = settings.fetch(:documentation, {})
|
10
10
|
settings.merge!(additional_documentation)
|
@@ -14,7 +14,7 @@ module GrapeSwagger
|
|
14
14
|
|
15
15
|
# required properties
|
16
16
|
@parsed_param = {
|
17
|
-
in: param_type(value_type),
|
17
|
+
in: param_type(value_type, consumes),
|
18
18
|
name: settings[:full_name] || param
|
19
19
|
}
|
20
20
|
|
@@ -70,21 +70,17 @@ module GrapeSwagger
|
|
70
70
|
|
71
71
|
def document_array_param(value_type, definitions)
|
72
72
|
if value_type[:documentation].present?
|
73
|
-
param_type = value_type[:documentation][:param_type] || value_type[:documentation][:in]
|
74
73
|
doc_type = value_type[:documentation][:type]
|
75
74
|
type = DataType.mapping(doc_type) if doc_type && !DataType.request_primitive?(doc_type)
|
76
75
|
collection_format = value_type[:documentation][:collectionFormat]
|
77
76
|
end
|
78
77
|
|
79
|
-
param_type ||= value_type[:param_type]
|
80
|
-
|
81
78
|
array_items = parse_array_item(
|
82
79
|
definitions,
|
83
80
|
type,
|
84
81
|
value_type
|
85
82
|
)
|
86
83
|
|
87
|
-
@parsed_param[:in] = param_type || 'formData'
|
88
84
|
@parsed_param[:items] = array_items
|
89
85
|
@parsed_param[:type] = 'array'
|
90
86
|
@parsed_param[:collectionFormat] = collection_format if DataType.collections.include?(collection_format)
|
@@ -148,14 +144,20 @@ module GrapeSwagger
|
|
148
144
|
@parsed_param[:example] = example if example
|
149
145
|
end
|
150
146
|
|
151
|
-
def param_type(value_type)
|
147
|
+
def param_type(value_type, consumes)
|
152
148
|
param_type = value_type[:param_type] || value_type[:in]
|
153
|
-
if value_type[:path].include?("{#{value_type[:param_name]}}")
|
149
|
+
if !value_type[:is_array] && value_type[:path].include?("{#{value_type[:param_name]}}")
|
154
150
|
'path'
|
155
151
|
elsif param_type
|
156
152
|
param_type
|
157
153
|
elsif %w[POST PUT PATCH].include?(value_type[:method])
|
158
|
-
|
154
|
+
if consumes.include?('application/x-www-form-urlencoded') || consumes.include?('multipart/form-data')
|
155
|
+
'formData'
|
156
|
+
else
|
157
|
+
'body'
|
158
|
+
end
|
159
|
+
elsif value_type[:is_array] && !DataType.query_array_primitive?(value_type[:data_type])
|
160
|
+
'formData'
|
159
161
|
else
|
160
162
|
'query'
|
161
163
|
end
|
@@ -119,7 +119,7 @@ module Grape
|
|
119
119
|
method[:description] = description_object(route)
|
120
120
|
method[:produces] = produces_object(route, options[:produces] || options[:format])
|
121
121
|
method[:consumes] = consumes_object(route, options[:consumes] || options[:format])
|
122
|
-
method[:parameters] = params_object(route, options, path)
|
122
|
+
method[:parameters] = params_object(route, options, path, method[:consumes])
|
123
123
|
method[:security] = security_object(route)
|
124
124
|
method[:responses] = response_object(route, options)
|
125
125
|
method[:tags] = route.options.fetch(:tags, tag_object(route, path))
|
@@ -175,7 +175,7 @@ module Grape
|
|
175
175
|
GrapeSwagger::DocMethods::ProducesConsumes.call(route.settings.dig(:description, :consumes) || format)
|
176
176
|
end
|
177
177
|
|
178
|
-
def params_object(route, options, path)
|
178
|
+
def params_object(route, options, path, consumes)
|
179
179
|
parameters = build_request_params(route, options).each_with_object([]) do |(param, value), memo|
|
180
180
|
next if hidden_parameter?(value)
|
181
181
|
|
@@ -187,7 +187,7 @@ module Grape
|
|
187
187
|
elsif value[:type]
|
188
188
|
expose_params(value[:type])
|
189
189
|
end
|
190
|
-
memo << GrapeSwagger::DocMethods::ParseParams.call(param, value, path, route, @definitions)
|
190
|
+
memo << GrapeSwagger::DocMethods::ParseParams.call(param, value, path, route, @definitions, consumes)
|
191
191
|
end
|
192
192
|
|
193
193
|
if GrapeSwagger::DocMethods::MoveParams.can_be_moved?(route.request_method, parameters)
|
data/lib/grape-swagger.rb
CHANGED
@@ -24,7 +24,7 @@ module SwaggerRouting
|
|
24
24
|
private
|
25
25
|
|
26
26
|
def combine_routes(app, doc_klass)
|
27
|
-
app.routes.
|
27
|
+
app.routes.each_with_object({}) do |route, combined_routes|
|
28
28
|
route_path = route.path
|
29
29
|
route_match = route_path.split(/^.*?#{route.prefix}/).last
|
30
30
|
next unless route_match
|
@@ -37,16 +37,16 @@ module SwaggerRouting
|
|
37
37
|
|
38
38
|
resource = route_match.captures.first
|
39
39
|
resource = '/' if resource.empty?
|
40
|
-
|
40
|
+
combined_routes[resource] ||= []
|
41
41
|
next if doc_klass.hide_documentation_path && route.path.match(/#{doc_klass.mount_path}($|\/|\(\.)/)
|
42
42
|
|
43
|
-
|
43
|
+
combined_routes[resource] << route
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def determine_namespaced_routes(name, parent_route)
|
47
|
+
def determine_namespaced_routes(name, parent_route, routes)
|
48
48
|
if parent_route.nil?
|
49
|
-
|
49
|
+
routes.values.flatten
|
50
50
|
else
|
51
51
|
parent_route.reject do |route|
|
52
52
|
!route_path_start_with?(route, name) || !route_instance_variable_equals?(route, name)
|
@@ -54,14 +54,15 @@ module SwaggerRouting
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
def combine_namespace_routes(namespaces)
|
57
|
+
def combine_namespace_routes(namespaces, routes)
|
58
|
+
combined_namespace_routes = {}
|
58
59
|
# iterate over each single namespace
|
59
60
|
namespaces.each_key do |name, _|
|
60
61
|
# get the parent route for the namespace
|
61
62
|
parent_route_name = extract_parent_route(name)
|
62
|
-
parent_route =
|
63
|
+
parent_route = routes[parent_route_name]
|
63
64
|
# fetch all routes that are within the current namespace
|
64
|
-
namespace_routes = determine_namespaced_routes(name, parent_route)
|
65
|
+
namespace_routes = determine_namespaced_routes(name, parent_route, routes)
|
65
66
|
|
66
67
|
# default case when not explicitly specified or nested == true
|
67
68
|
standalone_namespaces = namespaces.reject do |_, ns|
|
@@ -76,12 +77,13 @@ module SwaggerRouting
|
|
76
77
|
# rubocop:disable Style/Next
|
77
78
|
if parent_standalone_namespaces.empty?
|
78
79
|
# default option, append namespace methods to parent route
|
79
|
-
|
80
|
-
|
81
|
-
@target_class.combined_namespace_routes[parent_route_name].push(*namespace_routes)
|
80
|
+
combined_namespace_routes[parent_route_name] ||= []
|
81
|
+
combined_namespace_routes[parent_route_name].push(*namespace_routes)
|
82
82
|
end
|
83
83
|
# rubocop:enable Style/Next
|
84
84
|
end
|
85
|
+
|
86
|
+
combined_namespace_routes
|
85
87
|
end
|
86
88
|
|
87
89
|
def extract_parent_route(name)
|
@@ -110,7 +112,7 @@ module SwaggerRouting
|
|
110
112
|
end
|
111
113
|
|
112
114
|
module SwaggerDocumentationAdder
|
113
|
-
attr_accessor :combined_namespaces, :
|
115
|
+
attr_accessor :combined_namespaces, :combined_routes, :combined_namespace_routes
|
114
116
|
|
115
117
|
include SwaggerRouting
|
116
118
|
|
@@ -127,20 +129,16 @@ module SwaggerDocumentationAdder
|
|
127
129
|
documentation_class.setup(options)
|
128
130
|
mount(documentation_class)
|
129
131
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
132
|
+
combined_routes = combine_routes(@target_class, documentation_class)
|
133
|
+
combined_namespaces = combine_namespaces(@target_class)
|
134
|
+
combined_namespace_routes = combine_namespace_routes(combined_namespaces, combined_routes)
|
135
|
+
exclusive_route_keys = combined_routes.keys - combined_namespaces.keys
|
136
|
+
@target_class.combined_namespace_routes = combined_namespace_routes.merge(
|
137
|
+
combined_routes.slice(*exclusive_route_keys)
|
138
|
+
)
|
139
|
+
@target_class.combined_routes = combined_routes
|
140
|
+
@target_class.combined_namespaces = combined_namespaces
|
135
141
|
|
136
|
-
@target_class.combined_namespace_routes = {}
|
137
|
-
@target_class.combined_namespace_identifiers = {}
|
138
|
-
combine_namespace_routes(@target_class.combined_namespaces)
|
139
|
-
|
140
|
-
exclusive_route_keys = @target_class.combined_routes.keys - @target_class.combined_namespaces.keys
|
141
|
-
exclusive_route_keys.each do |key|
|
142
|
-
@target_class.combined_namespace_routes[key] = @target_class.combined_routes[key]
|
143
|
-
end
|
144
142
|
documentation_class
|
145
143
|
end
|
146
144
|
|
@@ -151,17 +149,24 @@ module SwaggerDocumentationAdder
|
|
151
149
|
end
|
152
150
|
|
153
151
|
def combine_namespaces(app)
|
154
|
-
|
152
|
+
combined_namespaces = {}
|
153
|
+
endpoints = app.endpoints.clone
|
154
|
+
|
155
|
+
while endpoints.any?
|
156
|
+
endpoint = endpoints.shift
|
157
|
+
|
158
|
+
endpoints.push(*endpoint.options[:app].endpoints) if endpoint.options[:app]
|
155
159
|
ns = endpoint.namespace_stackable(:namespace).last
|
160
|
+
next unless ns
|
156
161
|
|
157
162
|
# use the full namespace here (not the latest level only)
|
158
163
|
# and strip leading slash
|
159
164
|
mount_path = (endpoint.namespace_stackable(:mount_path) || []).join('/')
|
160
165
|
full_namespace = (mount_path + endpoint.namespace).sub(/\/{2,}/, '/').sub(/^\//, '')
|
161
|
-
|
162
|
-
|
163
|
-
combine_namespaces(endpoint.options[:app]) if endpoint.options[:app]
|
166
|
+
combined_namespaces[full_namespace] = ns
|
164
167
|
end
|
168
|
+
|
169
|
+
combined_namespaces
|
165
170
|
end
|
166
171
|
|
167
172
|
def create_documentation_class
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape-swagger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LeFnord
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-05-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: grape
|