grape 1.3.0 → 1.3.1
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/CHANGELOG.md +22 -0
- data/README.md +3 -4
- data/lib/grape.rb +2 -3
- data/lib/grape/api.rb +2 -2
- data/lib/grape/api/instance.rb +4 -4
- data/lib/grape/content_types.rb +34 -0
- data/lib/grape/dsl/helpers.rb +1 -1
- data/lib/grape/dsl/inside_route.rb +10 -9
- data/lib/grape/dsl/parameters.rb +4 -4
- data/lib/grape/dsl/routing.rb +6 -4
- data/lib/grape/exceptions/base.rb +0 -4
- data/lib/grape/exceptions/validation_errors.rb +11 -12
- data/lib/grape/http/headers.rb +25 -0
- data/lib/grape/middleware/base.rb +1 -3
- data/lib/grape/middleware/stack.rb +2 -1
- data/lib/grape/middleware/versioner/header.rb +3 -3
- data/lib/grape/middleware/versioner/path.rb +1 -1
- data/lib/grape/namespace.rb +12 -2
- data/lib/grape/path.rb +11 -1
- data/lib/grape/request.rb +12 -7
- data/lib/grape/router.rb +16 -7
- data/lib/grape/router/pattern.rb +17 -16
- data/lib/grape/router/route.rb +2 -2
- data/lib/grape/util/base_inheritable.rb +4 -0
- data/lib/grape/util/cache.rb +20 -0
- data/lib/grape/util/lazy_object.rb +43 -0
- data/lib/grape/util/reverse_stackable_values.rb +1 -1
- data/lib/grape/util/stackable_values.rb +6 -21
- data/lib/grape/validations/params_scope.rb +1 -1
- data/lib/grape/validations/types/file.rb +1 -0
- data/lib/grape/validations/types/primitive_coercer.rb +7 -4
- data/lib/grape/validations/validators/coerce.rb +1 -1
- data/lib/grape/validations/validators/exactly_one_of.rb +4 -2
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +7 -6
- data/spec/grape/exceptions/validation_errors_spec.rb +2 -2
- data/spec/grape/middleware/formatter_spec.rb +2 -2
- data/spec/grape/middleware/stack_spec.rb +9 -0
- data/spec/grape/validations/instance_behaivour_spec.rb +1 -1
- data/spec/grape/validations/types/primitive_coercer_spec.rb +75 -0
- data/spec/grape/validations/validators/coerce_spec.rb +15 -51
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +12 -12
- data/spec/grape/validations_spec.rb +8 -12
- data/spec/spec_helper.rb +3 -0
- data/spec/support/eager_load.rb +19 -0
- metadata +12 -6
- data/lib/grape/util/content_types.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1711dd2fb0f0c86757c7e73d780907efa87e3da54e0a999a4b45c276b5eec92c
|
4
|
+
data.tar.gz: f5ba49001d1816d92130f70fb1b63ae061d7d9250142605f706d75c207880ad9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b2dcf4d4903e3923dd10086a3371258404756cf294cd42c6fb64f3d2520fe7243c0accfe1b68f2e02fbaa85f29396c161d830cde4c5fdedd660b31e8d223a7f
|
7
|
+
data.tar.gz: 88a4d5e9740495430cd28ed1e213d6aafd92895c1b7966bd6358dd6aeb5b2e1f16eac2e14834d63e7791a6d66e16475ef30cdef5e37d10bca0f38f1d1a22c1e4
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
### 1.3.1 (2020/03/11)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* [#2005](https://github.com/ruby-grape/grape/pull/2005): Content types registrable - [@ericproulx](https://github.com/ericproulx).
|
6
|
+
* [#2003](https://github.com/ruby-grape/grape/pull/2003): Upgraded Rubocop to 0.80.1 - [@ericproulx](https://github.com/ericproulx).
|
7
|
+
* [#2002](https://github.com/ruby-grape/grape/pull/2002): Objects allocation optimization (lazy_lookup) - [@ericproulx](https://github.com/ericproulx).
|
8
|
+
|
9
|
+
#### Fixes
|
10
|
+
|
11
|
+
* [#2006](https://github.com/ruby-grape/grape/pull/2006): Fix explicit rescue StandardError - [@ericproulx](https://github.com/ericproulx).
|
12
|
+
* [#2004](https://github.com/ruby-grape/grape/pull/2004): Rubocop fixes - [@ericproulx](https://github.com/ericproulx).
|
13
|
+
* [#1995](https://github.com/ruby-grape/grape/pull/1995): Fix: "undefined instance variables" and "method redefined" warnings - [@nbeyer](https://github.com/nbeyer).
|
14
|
+
* [#1994](https://github.com/ruby-grape/grape/pull/1993): Fix typos in README - [@bellmyer](https://github.com/bellmyer).
|
15
|
+
* [#1993](https://github.com/ruby-grape/grape/pull/1993): Lazy join allow header - [@ericproulx](https://github.com/ericproulx).
|
16
|
+
* [#1987](https://github.com/ruby-grape/grape/pull/1987): Re-add exactly_one_of mutually exclusive error message - [@ZeroInputCtrl](https://github.com/ZeroInputCtrl).
|
17
|
+
* [#1977](https://github.com/ruby-grape/grape/pull/1977): Skip validation for a file if it is optional and nil - [@dnesteryuk](https://github.com/dnesteryuk).
|
18
|
+
* [#1976](https://github.com/ruby-grape/grape/pull/1976): Ensure classes/modules listed for autoload really exist - [@dnesteryuk](https://github.com/dnesteryuk).
|
19
|
+
* [#1971](https://github.com/ruby-grape/grape/pull/1971): Fix BigDecimal coercion - [@FlickStuart](https://github.com/FlickStuart).
|
20
|
+
* [#1968](https://github.com/ruby-grape/grape/pull/1968): Fix args forwarding in Grape::Middleware::Stack#merge_with for ruby 2.7.0 - [@dm1try](https://github.com/dm1try).
|
21
|
+
* [#1988](https://github.com/ruby-grape/grape/pull/1988): Refactored the full_messages method and stop overriding full_message - [@hosseintoussi](https://github.com/hosseintoussi).
|
22
|
+
|
1
23
|
### 1.3.0 (2020/01/11)
|
2
24
|
|
3
25
|
#### Features
|
data/README.md
CHANGED
@@ -154,8 +154,7 @@ content negotiation, versioning and much more.
|
|
154
154
|
|
155
155
|
## Stable Release
|
156
156
|
|
157
|
-
You're reading the documentation for the stable release of Grape, **1.3.
|
158
|
-
Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
|
157
|
+
You're reading the documentation for the stable release of Grape, **1.3.1**.
|
159
158
|
|
160
159
|
## Project Resources
|
161
160
|
|
@@ -1722,7 +1721,7 @@ params do
|
|
1722
1721
|
end
|
1723
1722
|
```
|
1724
1723
|
|
1725
|
-
Every validation will have
|
1724
|
+
Every validation will have its own instance of the validator, which means that the validator can have a state.
|
1726
1725
|
|
1727
1726
|
### Validation Errors
|
1728
1727
|
|
@@ -3301,7 +3300,7 @@ end
|
|
3301
3300
|
|
3302
3301
|
Blocks can be executed before or after every API call, using `before`, `after`,
|
3303
3302
|
`before_validation` and `after_validation`.
|
3304
|
-
If the API fails the `after` call will not be
|
3303
|
+
If the API fails the `after` call will not be triggered, if you need code to execute for sure
|
3305
3304
|
use the `finally`.
|
3306
3305
|
|
3307
3306
|
Before and after callbacks execute in the following order:
|
data/lib/grape.rb
CHANGED
@@ -20,7 +20,6 @@ require 'active_support/core_ext/hash/conversions'
|
|
20
20
|
require 'active_support/dependencies/autoload'
|
21
21
|
require 'active_support/notifications'
|
22
22
|
require 'i18n'
|
23
|
-
require 'thread'
|
24
23
|
|
25
24
|
I18n.load_path << File.expand_path('../grape/locale/en.yml', __FILE__)
|
26
25
|
|
@@ -84,7 +83,6 @@ module Grape
|
|
84
83
|
eager_autoload do
|
85
84
|
autoload :DeepMergeableHash
|
86
85
|
autoload :DeepSymbolizeHash
|
87
|
-
autoload :DeepHashWithIndifferentAccess
|
88
86
|
autoload :Hash
|
89
87
|
end
|
90
88
|
module ActiveSupport
|
@@ -219,7 +217,8 @@ module Grape
|
|
219
217
|
end
|
220
218
|
|
221
219
|
require 'grape/config'
|
222
|
-
require 'grape/
|
220
|
+
require 'grape/content_types'
|
221
|
+
|
223
222
|
require 'grape/util/lazy_value'
|
224
223
|
require 'grape/util/lazy_block'
|
225
224
|
require 'grape/util/endpoint_configuration'
|
data/lib/grape/api.rb
CHANGED
@@ -8,7 +8,7 @@ module Grape
|
|
8
8
|
# should subclass this class in order to build an API.
|
9
9
|
class API
|
10
10
|
# Class methods that we want to call on the API rather than on the API object
|
11
|
-
NON_OVERRIDABLE = (Class.new.methods + %i[call call! configuration compile!]).freeze
|
11
|
+
NON_OVERRIDABLE = (Class.new.methods + %i[call call! configuration compile! inherited]).freeze
|
12
12
|
|
13
13
|
class << self
|
14
14
|
attr_accessor :base_instance, :instances
|
@@ -175,7 +175,7 @@ module Grape
|
|
175
175
|
if argument.respond_to?(:lazy?) && argument.lazy?
|
176
176
|
argument.evaluate_from(configuration)
|
177
177
|
elsif argument.is_a?(Hash)
|
178
|
-
argument.
|
178
|
+
argument.transform_values { |value| evaluate_arguments(configuration, value).first }
|
179
179
|
elsif argument.is_a?(Array)
|
180
180
|
evaluate_arguments(configuration, *argument)
|
181
181
|
else
|
data/lib/grape/api/instance.rb
CHANGED
@@ -74,7 +74,7 @@ module Grape
|
|
74
74
|
# (see #cascade?)
|
75
75
|
def cascade(value = nil)
|
76
76
|
if value.nil?
|
77
|
-
inheritable_setting.namespace_inheritable.
|
77
|
+
inheritable_setting.namespace_inheritable.key?(:cascade) ? !namespace_inheritable(:cascade).nil? : true
|
78
78
|
else
|
79
79
|
namespace_inheritable(:cascade, value)
|
80
80
|
end
|
@@ -178,7 +178,7 @@ module Grape
|
|
178
178
|
# errors from reaching upstream. This is effectivelly done by unsetting
|
179
179
|
# X-Cascade. Default :cascade is true.
|
180
180
|
def cascade?
|
181
|
-
return self.class.namespace_inheritable(:cascade) if self.class.inheritable_setting.namespace_inheritable.
|
181
|
+
return self.class.namespace_inheritable(:cascade) if self.class.inheritable_setting.namespace_inheritable.key?(:cascade)
|
182
182
|
return self.class.namespace_inheritable(:version_options)[:cascade] if self.class.namespace_inheritable(:version_options) && self.class.namespace_inheritable(:version_options).key?(:cascade)
|
183
183
|
true
|
184
184
|
end
|
@@ -209,7 +209,7 @@ module Grape
|
|
209
209
|
route_settings[:endpoint] = route.app
|
210
210
|
|
211
211
|
# using the :any shorthand produces [nil] for route methods, substitute all manually
|
212
|
-
route_settings[:methods] =
|
212
|
+
route_settings[:methods] = Grape::Http::Headers::SUPPORTED_METHODS if route_settings[:methods].include?('*')
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
@@ -227,7 +227,7 @@ module Grape
|
|
227
227
|
allowed_methods |= [Grape::Http::Headers::HEAD] if allowed_methods.include?(Grape::Http::Headers::GET)
|
228
228
|
end
|
229
229
|
|
230
|
-
allow_header = (self.class.namespace_inheritable(:do_not_route_options) ? allowed_methods : [Grape::Http::Headers::OPTIONS] | allowed_methods)
|
230
|
+
allow_header = (self.class.namespace_inheritable(:do_not_route_options) ? allowed_methods : [Grape::Http::Headers::OPTIONS] | allowed_methods)
|
231
231
|
|
232
232
|
unless self.class.namespace_inheritable(:do_not_route_options) || allowed_methods.include?(Grape::Http::Headers::OPTIONS)
|
233
233
|
config[:endpoint].options[:options_route_enabled] = true
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grape/util/registrable'
|
4
|
+
|
5
|
+
module Grape
|
6
|
+
module ContentTypes
|
7
|
+
extend Util::Registrable
|
8
|
+
|
9
|
+
# Content types are listed in order of preference.
|
10
|
+
CONTENT_TYPES = {
|
11
|
+
xml: 'application/xml',
|
12
|
+
serializable_hash: 'application/json',
|
13
|
+
json: 'application/json',
|
14
|
+
binary: 'application/octet-stream',
|
15
|
+
txt: 'text/plain'
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def content_types_for_settings(settings)
|
20
|
+
return if settings.blank?
|
21
|
+
|
22
|
+
settings.each_with_object({}) { |value, result| result.merge!(value) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def content_types_for(from_settings)
|
26
|
+
if from_settings.present?
|
27
|
+
from_settings
|
28
|
+
else
|
29
|
+
Grape::ContentTypes::CONTENT_TYPES.merge(default_elements)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/grape/dsl/helpers.rb
CHANGED
@@ -94,7 +94,7 @@ module Grape
|
|
94
94
|
protected
|
95
95
|
|
96
96
|
def process_named_params
|
97
|
-
return unless @named_params && @named_params.any?
|
97
|
+
return unless instance_variable_defined?(:@named_params) && @named_params && @named_params.any?
|
98
98
|
api.namespace_stackable(:named_params, @named_params)
|
99
99
|
end
|
100
100
|
end
|
@@ -177,17 +177,17 @@ module Grape
|
|
177
177
|
def status(status = nil)
|
178
178
|
case status
|
179
179
|
when Symbol
|
180
|
-
raise ArgumentError, "Status code :#{status} is invalid." unless Rack::Utils::SYMBOL_TO_STATUS_CODE.
|
180
|
+
raise ArgumentError, "Status code :#{status} is invalid." unless Rack::Utils::SYMBOL_TO_STATUS_CODE.key?(status)
|
181
181
|
@status = Rack::Utils.status_code(status)
|
182
182
|
when Integer
|
183
183
|
@status = status
|
184
184
|
when nil
|
185
|
-
return @status if @status
|
185
|
+
return @status if instance_variable_defined?(:@status) && @status
|
186
186
|
case request.request_method.to_s.upcase
|
187
187
|
when Grape::Http::Headers::POST
|
188
188
|
201
|
189
189
|
when Grape::Http::Headers::DELETE
|
190
|
-
if @body.present?
|
190
|
+
if instance_variable_defined?(:@body) && @body.present?
|
191
191
|
200
|
192
192
|
else
|
193
193
|
204
|
@@ -238,7 +238,7 @@ module Grape
|
|
238
238
|
@body = ''
|
239
239
|
status 204
|
240
240
|
else
|
241
|
-
@body
|
241
|
+
instance_variable_defined?(:@body) ? @body : nil
|
242
242
|
end
|
243
243
|
end
|
244
244
|
|
@@ -272,7 +272,7 @@ module Grape
|
|
272
272
|
warn '[DEPRECATION] Argument as FileStreamer-like object is deprecated. Use path to file instead.'
|
273
273
|
@file = Grape::ServeFile::FileResponse.new(value)
|
274
274
|
else
|
275
|
-
@file
|
275
|
+
instance_variable_defined?(:@file) ? @file : nil
|
276
276
|
end
|
277
277
|
end
|
278
278
|
|
@@ -331,11 +331,12 @@ module Grape
|
|
331
331
|
end
|
332
332
|
|
333
333
|
representation = { root => representation } if root
|
334
|
+
|
334
335
|
if key
|
335
|
-
representation = (
|
336
|
-
elsif entity_class.present? &&
|
336
|
+
representation = (body || {}).merge(key => representation)
|
337
|
+
elsif entity_class.present? && body
|
337
338
|
raise ArgumentError, "Representation of type #{representation.class} cannot be merged." unless representation.respond_to?(:merge)
|
338
|
-
representation =
|
339
|
+
representation = body.merge(representation)
|
339
340
|
end
|
340
341
|
|
341
342
|
body representation
|
@@ -387,7 +388,7 @@ module Grape
|
|
387
388
|
def entity_representation_for(entity_class, object, options)
|
388
389
|
embeds = { env: env }
|
389
390
|
embeds[:version] = env[Grape::Env::API_VERSION] if env[Grape::Env::API_VERSION]
|
390
|
-
entity_class.represent(object,
|
391
|
+
entity_class.represent(object, embeds.merge(options))
|
391
392
|
end
|
392
393
|
end
|
393
394
|
end
|
data/lib/grape/dsl/parameters.rb
CHANGED
@@ -127,7 +127,7 @@ module Grape
|
|
127
127
|
|
128
128
|
opts = attrs.extract_options!.clone
|
129
129
|
opts[:presence] = { value: true, message: opts[:message] }
|
130
|
-
opts = @group.merge(opts) if @group
|
130
|
+
opts = @group.merge(opts) if instance_variable_defined?(:@group) && @group
|
131
131
|
|
132
132
|
if opts[:using]
|
133
133
|
require_required_and_optional_fields(attrs.first, opts)
|
@@ -146,7 +146,7 @@ module Grape
|
|
146
146
|
|
147
147
|
opts = attrs.extract_options!.clone
|
148
148
|
type = opts[:type]
|
149
|
-
opts = @group.merge(opts) if @group
|
149
|
+
opts = @group.merge(opts) if instance_variable_defined?(:@group) && @group
|
150
150
|
|
151
151
|
# check type for optional parameter group
|
152
152
|
if attrs && block_given?
|
@@ -243,8 +243,8 @@ module Grape
|
|
243
243
|
# @return hash of parameters relevant for the current scope
|
244
244
|
# @api private
|
245
245
|
def params(params)
|
246
|
-
params = @parent.params(params) if @parent
|
247
|
-
params = map_params(params, @element) if @element
|
246
|
+
params = @parent.params(params) if instance_variable_defined?(:@parent) && @parent
|
247
|
+
params = map_params(params, @element) if instance_variable_defined?(:@element) && @element
|
248
248
|
params
|
249
249
|
end
|
250
250
|
|
data/lib/grape/dsl/routing.rb
CHANGED
@@ -51,7 +51,7 @@ module Grape
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
@versions.last
|
54
|
+
@versions.last if instance_variable_defined?(:@versions) && @versions
|
55
55
|
end
|
56
56
|
|
57
57
|
# Define a root URL prefix for your entire API.
|
@@ -142,11 +142,11 @@ module Grape
|
|
142
142
|
reset_validations!
|
143
143
|
end
|
144
144
|
|
145
|
-
|
146
|
-
define_method
|
145
|
+
Grape::Http::Headers::SUPPORTED_METHODS.each do |supported_method|
|
146
|
+
define_method supported_method.downcase do |*args, &block|
|
147
147
|
options = args.extract_options!
|
148
148
|
paths = args.first || ['/']
|
149
|
-
route(
|
149
|
+
route(supported_method, paths, options, &block)
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
@@ -163,6 +163,8 @@ module Grape
|
|
163
163
|
# end
|
164
164
|
# end
|
165
165
|
def namespace(space = nil, options = {}, &block)
|
166
|
+
@namespace_description = nil unless instance_variable_defined?(:@namespace_description) && @namespace_description
|
167
|
+
|
166
168
|
if space || block_given?
|
167
169
|
within_namespace do
|
168
170
|
previous_namespace_description = @namespace_description
|
@@ -5,6 +5,9 @@ require 'grape/exceptions/base'
|
|
5
5
|
module Grape
|
6
6
|
module Exceptions
|
7
7
|
class ValidationErrors < Grape::Exceptions::Base
|
8
|
+
ERRORS_FORMAT_KEY = 'grape.errors.format'
|
9
|
+
DEFAULT_ERRORS_FORMAT = '%{attributes} %{message}'
|
10
|
+
|
8
11
|
include Enumerable
|
9
12
|
|
10
13
|
attr_reader :errors
|
@@ -41,21 +44,17 @@ module Grape
|
|
41
44
|
end
|
42
45
|
|
43
46
|
def full_messages
|
44
|
-
messages = map
|
47
|
+
messages = map do |attributes, error|
|
48
|
+
I18n.t(
|
49
|
+
ERRORS_FORMAT_KEY,
|
50
|
+
default: DEFAULT_ERRORS_FORMAT,
|
51
|
+
attributes: translate_attributes(attributes),
|
52
|
+
message: error.message
|
53
|
+
)
|
54
|
+
end
|
45
55
|
messages.uniq!
|
46
56
|
messages
|
47
57
|
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def full_message(attributes, error)
|
52
|
-
I18n.t(
|
53
|
-
'grape.errors.format',
|
54
|
-
default: '%{attributes} %{message}',
|
55
|
-
attributes: attributes.count == 1 ? translate_attribute(attributes.first) : translate_attributes(attributes),
|
56
|
-
message: error.message
|
57
|
-
)
|
58
|
-
end
|
59
58
|
end
|
60
59
|
end
|
61
60
|
end
|
data/lib/grape/http/headers.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'grape/util/lazy_object'
|
4
|
+
|
3
5
|
module Grape
|
4
6
|
module Http
|
5
7
|
module Headers
|
@@ -27,6 +29,29 @@ module Grape
|
|
27
29
|
|
28
30
|
FORMAT = 'format'
|
29
31
|
|
32
|
+
HTTP_HEADERS = Grape::Util::LazyObject.new do
|
33
|
+
common_http_headers = %w[
|
34
|
+
Version
|
35
|
+
Host
|
36
|
+
Connection
|
37
|
+
Cache-Control
|
38
|
+
Dnt
|
39
|
+
Upgrade-Insecure-Requests
|
40
|
+
User-Agent
|
41
|
+
Sec-Fetch-Dest
|
42
|
+
Accept
|
43
|
+
Sec-Fetch-Site
|
44
|
+
Sec-Fetch-Mode
|
45
|
+
Sec-Fetch-User
|
46
|
+
Accept-Encoding
|
47
|
+
Accept-Language
|
48
|
+
Cookie
|
49
|
+
].freeze
|
50
|
+
common_http_headers.each_with_object({}) do |header, response|
|
51
|
+
response["HTTP_#{header.upcase.tr('-', '_')}"] = header
|
52
|
+
end.freeze
|
53
|
+
end
|
54
|
+
|
30
55
|
def self.find_supported_method(route_method)
|
31
56
|
Grape::Http::Headers::SUPPORTED_METHODS.detect { |supported_method| supported_method.casecmp(route_method).zero? }
|
32
57
|
end
|
@@ -74,11 +74,9 @@ module Grape
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def mime_types
|
77
|
-
|
78
|
-
content_types.each_pair do |k, v|
|
77
|
+
@mime_type ||= content_types.each_pair.with_object({}) do |(k, v), types_without_params|
|
79
78
|
types_without_params[v.split(';').first] = k
|
80
79
|
end
|
81
|
-
types_without_params
|
82
80
|
end
|
83
81
|
|
84
82
|
private
|
@@ -78,7 +78,8 @@ module Grape
|
|
78
78
|
def merge_with(middleware_specs)
|
79
79
|
middleware_specs.each do |operation, *args|
|
80
80
|
if args.last.is_a?(Proc)
|
81
|
-
|
81
|
+
last_proc = args.pop
|
82
|
+
public_send(operation, *args, &last_proc)
|
82
83
|
else
|
83
84
|
public_send(operation, *args)
|
84
85
|
end
|
@@ -26,10 +26,10 @@ module Grape
|
|
26
26
|
# route.
|
27
27
|
class Header < Base
|
28
28
|
VENDOR_VERSION_HEADER_REGEX =
|
29
|
-
/\Avnd\.([a-z0-9.\-_!#\$&\^]+?)(?:-([a-z0-9*.]+))?(?:\+([a-z0-9*\-.]+))?\z
|
29
|
+
/\Avnd\.([a-z0-9.\-_!#\$&\^]+?)(?:-([a-z0-9*.]+))?(?:\+([a-z0-9*\-.]+))?\z/.freeze
|
30
30
|
|
31
|
-
HAS_VENDOR_REGEX = /\Avnd\.[a-z0-9.\-_!#\$&\^]
|
32
|
-
HAS_VERSION_REGEX = /\Avnd\.([a-z0-9.\-_!#\$&\^]+?)(?:-([a-z0-9*.]+))
|
31
|
+
HAS_VENDOR_REGEX = /\Avnd\.[a-z0-9.\-_!#\$&\^]+/.freeze
|
32
|
+
HAS_VERSION_REGEX = /\Avnd\.([a-z0-9.\-_!#\$&\^]+?)(?:-([a-z0-9*.]+))+/.freeze
|
33
33
|
|
34
34
|
def before
|
35
35
|
strict_header_checks if strict?
|
@@ -36,7 +36,7 @@ module Grape
|
|
36
36
|
|
37
37
|
pieces = path.split('/')
|
38
38
|
potential_version = pieces[1]
|
39
|
-
return unless potential_version
|
39
|
+
return unless potential_version&.match?(options[:pattern])
|
40
40
|
throw :error, status: 404, message: '404 API Version Not Found' if options[:versions] && !options[:versions].find { |v| v.to_s == potential_version }
|
41
41
|
env[Grape::Env::API_VERSION] = potential_version
|
42
42
|
end
|