grape 1.7.1 → 1.8.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 +22 -1
- data/CONTRIBUTING.md +1 -1
- data/README.md +12 -4
- data/grape.gemspec +2 -2
- data/lib/grape/api.rb +2 -2
- data/lib/grape/content_types.rb +2 -8
- data/lib/grape/dsl/desc.rb +1 -1
- data/lib/grape/dsl/inside_route.rb +5 -5
- data/lib/grape/dsl/request_response.rb +2 -1
- data/lib/grape/dsl/settings.rb +2 -6
- data/lib/grape/endpoint.rb +19 -17
- data/lib/grape/error_formatter/base.rb +1 -1
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/missing_group_type.rb +1 -6
- data/lib/grape/exceptions/unsupported_group_type.rb +1 -6
- data/lib/grape/exceptions/validation_errors.rb +1 -6
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +3 -3
- data/lib/grape/extensions/hash.rb +4 -7
- data/lib/grape/extensions/hashie/mash.rb +3 -3
- data/lib/grape/formatter/serializable_hash.rb +7 -7
- data/lib/grape/middleware/auth/base.rb +1 -1
- data/lib/grape/middleware/error.rb +1 -1
- data/lib/grape/middleware/formatter.rb +1 -1
- data/lib/grape/middleware/versioner/header.rb +11 -19
- data/lib/grape/router/route.rb +1 -3
- data/lib/grape/util/lazy_value.rb +3 -11
- data/lib/grape/util/strict_hash_configuration.rb +3 -4
- data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
- data/lib/grape/validations/params_scope.rb +8 -2
- data/lib/grape/validations/single_attribute_iterator.rb +3 -1
- data/lib/grape/validations/types/custom_type_coercer.rb +2 -16
- data/lib/grape/validations/validators/base.rb +9 -20
- data/lib/grape/validations/validators/default_validator.rb +2 -20
- data/lib/grape/validations/validators/multiple_params_base.rb +4 -8
- data/lib/grape/validations/validators/values_validator.rb +14 -5
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +11 -3
- data/spec/grape/api/custom_validations_spec.rb +14 -57
- data/spec/grape/api_remount_spec.rb +36 -0
- data/spec/grape/api_spec.rb +10 -1
- data/spec/grape/dsl/desc_spec.rb +84 -87
- data/spec/grape/dsl/inside_route_spec.rb +6 -10
- data/spec/grape/dsl/request_response_spec.rb +21 -2
- data/spec/grape/endpoint_spec.rb +8 -8
- data/spec/grape/exceptions/body_parse_errors_spec.rb +40 -0
- data/spec/grape/exceptions/missing_group_type_spec.rb +5 -9
- data/spec/grape/exceptions/unsupported_group_type_spec.rb +5 -9
- data/spec/grape/grape_spec.rb +9 -0
- data/spec/grape/middleware/formatter_spec.rb +1 -1
- data/spec/grape/request_spec.rb +4 -14
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +6 -8
- data/spec/grape/validations/single_attribute_iterator_spec.rb +8 -9
- data/spec/grape/validations/validators/base_spec.rb +38 -0
- data/spec/grape/validations/validators/values_spec.rb +37 -0
- data/spec/grape/validations_spec.rb +7 -6
- data/spec/shared/deprecated_class_examples.rb +16 -0
- metadata +17 -22
- data/lib/grape/config.rb +0 -34
- data/lib/grape/extensions/deep_mergeable_hash.rb +0 -21
- data/lib/grape/extensions/deep_symbolize_hash.rb +0 -32
- data/spec/grape/config_spec.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac7bd232782ed265b59ec7f4ea0dec03a0896b328694ebe1507cf9680e1bee41
|
4
|
+
data.tar.gz: b81cb45c2b6daab5b413af0df615a542907c9fbf1732e3fc46347321dedc4f65
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1929a95447ec3923443e908a8240195e7e4a0f5a3113f8679e947cc3813e800f45f35c928dfef9495ff277a983bf3bdcb4ca358ab889e28224d890a3d078d7de
|
7
|
+
data.tar.gz: 4d5141c1f331ee07eaa78bd89e1b76f99b6cbcb7d6f0dda3f12f9e6b900c977c9a0757c0d912a6cd53ea5ef9bce8409a211c4a77c4b78a0f5e607ecd1e055480
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,25 @@
|
|
1
|
-
### 1.
|
1
|
+
### 1.8.0 (2023/08/30)
|
2
|
+
|
3
|
+
#### Features
|
4
|
+
|
5
|
+
* [#2326](https://github.com/ruby-grape/grape/pull/2326): Use ActiveSupport extensions - [@ericproulx](https://github.com/ericproulx).
|
6
|
+
* [#2327](https://github.com/ruby-grape/grape/pull/2327): Use ActiveSupport deprecation - [@ericproulx](https://github.com/ericproulx).
|
7
|
+
* [#2330](https://github.com/ruby-grape/grape/pull/2330): Use ActiveSupport inflector - [@ericproulx](https://github.com/ericproulx).
|
8
|
+
* [#2331](https://github.com/ruby-grape/grape/pull/2331): Memory optimization when running validators - [@ericproulx](https://github.com/ericproulx).
|
9
|
+
* [#2332](https://github.com/ruby-grape/grape/pull/2332): Use ActiveSupport configurable - [@ericproulx](https://github.com/ericproulx).
|
10
|
+
* [#2333](https://github.com/ruby-grape/grape/pull/2333): Use custom messages in parameter validation with arity 1 - [@thedevjoao](https://github.com/TheDevJoao).
|
11
|
+
* [#2341](https://github.com/ruby-grape/grape/pull/2341): Stop yielding skip value - [@ericproulx](https://github.com/ericproulx).
|
12
|
+
* [#2342](https://github.com/ruby-grape/grape/pull/2342): Allow specifying a handler for grape_exceptions - [@mscrivo](https://github.com/mscrivo).
|
13
|
+
* [#2338](https://github.com/ruby-grape/grape/pull/2338): Fix unknown validator when using requires/optional with entity - [@mscrivo](https://github.com/mscrivo).
|
14
|
+
|
15
|
+
#### Fixes
|
16
|
+
|
17
|
+
* [#2339](https://github.com/ruby-grape/grape/pull/2339): Documentation and specs for remountable configuration in params - [@myxoh](https://github.com/myxoh).
|
18
|
+
* [#2328](https://github.com/ruby-grape/grape/pull/2328): Don't cache Class.instance_methods - [@byroot](https://github.com/byroot).
|
19
|
+
* [#2337](https://github.com/ruby-grape/grape/pull/2337): Fix: allow custom validators that do not end with _validator - [@ericproulx](https://github.com/ericproulx).
|
20
|
+
* [#2346](https://github.com/ruby-grape/grape/pull/2346): Adjust test expectations to conform to rack 3 - [@kbarrette](https://github.com/kbarrette).
|
21
|
+
|
22
|
+
## 1.7.1 (2023/05/14)
|
2
23
|
|
3
24
|
#### Features
|
4
25
|
|
data/CONTRIBUTING.md
CHANGED
@@ -145,7 +145,7 @@ git push origin my-feature-branch -f
|
|
145
145
|
|
146
146
|
#### Check on Your Pull Request
|
147
147
|
|
148
|
-
Go back to your pull request after a few minutes and see whether it passed muster with
|
148
|
+
Go back to your pull request after a few minutes and see whether it passed muster with CI. Everything should look green, otherwise fix issues and amend your commit as described above.
|
149
149
|
|
150
150
|
#### Be Patient
|
151
151
|
|
data/README.md
CHANGED
@@ -159,7 +159,7 @@ content negotiation, versioning and much more.
|
|
159
159
|
|
160
160
|
## Stable Release
|
161
161
|
|
162
|
-
You're reading the documentation for the stable release of Grape, 1.
|
162
|
+
You're reading the documentation for the stable release of Grape, **1.8.0**.
|
163
163
|
Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
|
164
164
|
|
165
165
|
## Project Resources
|
@@ -524,15 +524,15 @@ end
|
|
524
524
|
```ruby
|
525
525
|
class BasicAPI < Grape::API
|
526
526
|
desc 'Statuses index' do
|
527
|
-
params:
|
527
|
+
params: (configuration[:entity] || API::Entities::Status).documentation
|
528
528
|
end
|
529
529
|
params do
|
530
|
-
requires :all, using:
|
530
|
+
requires :all, using: (configuration[:entity] || API::Entities::Status).documentation
|
531
531
|
end
|
532
532
|
get '/statuses' do
|
533
533
|
statuses = Status.all
|
534
534
|
type = current_user.admin? ? :full : :default
|
535
|
-
present statuses, with:
|
535
|
+
present statuses, with: (configuration[:entity] || API::Entities::Status), type: type
|
536
536
|
end
|
537
537
|
end
|
538
538
|
|
@@ -2624,6 +2624,14 @@ class Twitter::API < Grape::API
|
|
2624
2624
|
end
|
2625
2625
|
```
|
2626
2626
|
|
2627
|
+
If you want to customize the shape of grape exceptions returned to the user, to match your `:all` handler for example, you can pass a block to `rescue_from :grape_exceptions`.
|
2628
|
+
|
2629
|
+
```ruby
|
2630
|
+
rescue_from :grape_exceptions do |e|
|
2631
|
+
error!(e, e.status)
|
2632
|
+
end
|
2633
|
+
```
|
2634
|
+
|
2627
2635
|
You can also rescue specific exceptions.
|
2628
2636
|
|
2629
2637
|
```ruby
|
data/grape.gemspec
CHANGED
@@ -20,11 +20,11 @@ Gem::Specification.new do |s|
|
|
20
20
|
'source_code_uri' => "https://github.com/ruby-grape/grape/tree/v#{s.version}"
|
21
21
|
}
|
22
22
|
|
23
|
-
s.add_runtime_dependency 'activesupport'
|
23
|
+
s.add_runtime_dependency 'activesupport', '>= 5'
|
24
24
|
s.add_runtime_dependency 'builder'
|
25
25
|
s.add_runtime_dependency 'dry-types', '>= 1.1'
|
26
26
|
s.add_runtime_dependency 'mustermann-grape', '~> 1.0.0'
|
27
|
-
s.add_runtime_dependency 'rack', '>= 1.3.0'
|
27
|
+
s.add_runtime_dependency 'rack', '>= 1.3.0'
|
28
28
|
s.add_runtime_dependency 'rack-accept'
|
29
29
|
|
30
30
|
s.files = %w[CHANGELOG.md CONTRIBUTING.md README.md grape.png UPGRADING.md LICENSE]
|
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 =
|
11
|
+
NON_OVERRIDABLE = %i[call call! configuration compile! inherited].freeze
|
12
12
|
|
13
13
|
class Boolean
|
14
14
|
def self.build(val)
|
@@ -50,7 +50,7 @@ module Grape
|
|
50
50
|
|
51
51
|
# Redefines all methods so that are forwarded to add_setup and be recorded
|
52
52
|
def override_all_methods!
|
53
|
-
(base_instance.methods - NON_OVERRIDABLE).each do |method_override|
|
53
|
+
(base_instance.methods - Class.methods - NON_OVERRIDABLE).each do |method_override|
|
54
54
|
define_singleton_method(method_override) do |*args, &block|
|
55
55
|
add_setup(method_override, *args, &block)
|
56
56
|
end
|
data/lib/grape/content_types.rb
CHANGED
@@ -17,17 +17,11 @@ module Grape
|
|
17
17
|
|
18
18
|
class << self
|
19
19
|
def content_types_for_settings(settings)
|
20
|
-
|
21
|
-
|
22
|
-
settings.each_with_object({}) { |value, result| result.merge!(value) }
|
20
|
+
settings&.inject(:merge!)
|
23
21
|
end
|
24
22
|
|
25
23
|
def content_types_for(from_settings)
|
26
|
-
|
27
|
-
from_settings
|
28
|
-
else
|
29
|
-
Grape::ContentTypes::CONTENT_TYPES.merge(default_elements)
|
30
|
-
end
|
24
|
+
from_settings.presence || Grape::ContentTypes::CONTENT_TYPES.merge(default_elements)
|
31
25
|
end
|
32
26
|
end
|
33
27
|
end
|
data/lib/grape/dsl/desc.rb
CHANGED
@@ -68,7 +68,7 @@ module Grape
|
|
68
68
|
end
|
69
69
|
|
70
70
|
config_class.configure(&config_block)
|
71
|
-
warn
|
71
|
+
ActiveSupport::Deprecation.warn('Passing a options hash and a block to `desc` is deprecated. Move all hash options to block.') if options.any?
|
72
72
|
options = config_class.settings
|
73
73
|
else
|
74
74
|
options = options.merge(description: description)
|
@@ -103,7 +103,7 @@ module Grape
|
|
103
103
|
|
104
104
|
if type == 'Hash' && !has_children
|
105
105
|
{}
|
106
|
-
elsif type == 'Array' || (type&.start_with?('[') &&
|
106
|
+
elsif type == 'Array' || (type&.start_with?('[') && type&.exclude?(','))
|
107
107
|
[]
|
108
108
|
elsif type == 'Set' || type&.start_with?('#<Set')
|
109
109
|
Set.new
|
@@ -280,13 +280,13 @@ module Grape
|
|
280
280
|
# Deprecated method to send files to the client. Use `sendfile` or `stream`
|
281
281
|
def file(value = nil)
|
282
282
|
if value.is_a?(String)
|
283
|
-
warn
|
283
|
+
ActiveSupport::Deprecation.warn('Use sendfile or stream to send files.')
|
284
284
|
sendfile(value)
|
285
285
|
elsif !value.is_a?(NilClass)
|
286
|
-
warn
|
286
|
+
ActiveSupport::Deprecation.warn('Use stream to use a Stream object.')
|
287
287
|
stream(value)
|
288
288
|
else
|
289
|
-
warn
|
289
|
+
ActiveSupport::Deprecation.warn('Use sendfile or stream to send files.')
|
290
290
|
sendfile
|
291
291
|
end
|
292
292
|
end
|
@@ -433,7 +433,7 @@ module Grape
|
|
433
433
|
# the given entity_class.
|
434
434
|
def entity_representation_for(entity_class, object, options)
|
435
435
|
embeds = { env: env }
|
436
|
-
embeds[:version] = env[Grape::Env::API_VERSION] if env
|
436
|
+
embeds[:version] = env[Grape::Env::API_VERSION] if env.key?(Grape::Env::API_VERSION)
|
437
437
|
entity_class.represent(object, **embeds.merge(options))
|
438
438
|
end
|
439
439
|
end
|
@@ -112,10 +112,11 @@ module Grape
|
|
112
112
|
|
113
113
|
if args.include?(:all)
|
114
114
|
namespace_inheritable(:rescue_all, true)
|
115
|
-
namespace_inheritable
|
115
|
+
namespace_inheritable(:all_rescue_handler, handler)
|
116
116
|
elsif args.include?(:grape_exceptions)
|
117
117
|
namespace_inheritable(:rescue_all, true)
|
118
118
|
namespace_inheritable(:rescue_grape_exceptions, true)
|
119
|
+
namespace_inheritable(:grape_exceptions_rescue_handler, handler)
|
119
120
|
else
|
120
121
|
handler_type =
|
121
122
|
case options[:rescue_subclasses]
|
data/lib/grape/dsl/settings.rb
CHANGED
@@ -109,13 +109,9 @@ module Grape
|
|
109
109
|
settings = get_or_set :namespace_reverse_stackable, key, nil
|
110
110
|
return if settings.blank?
|
111
111
|
|
112
|
-
|
113
|
-
|
114
|
-
setting.each do |field, value|
|
115
|
-
result[field] ||= value
|
116
|
-
end
|
112
|
+
settings.each_with_object({}) do |setting, result|
|
113
|
+
result.merge!(setting) { |_k, s1, _s2| s1 }
|
117
114
|
end
|
118
|
-
result
|
119
115
|
end
|
120
116
|
|
121
117
|
# (see #unset_global_setting)
|
data/lib/grape/endpoint.rb
CHANGED
@@ -171,10 +171,9 @@ module Grape
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def prepare_routes_requirements
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
base_requirements.merge!(single_requirements)
|
174
|
+
{}.merge!(*namespace_stackable(:namespace).map(&:requirements)).tap do |requirements|
|
175
|
+
endpoint_requirements = options.dig(:route_options, :requirements)
|
176
|
+
requirements.merge!(endpoint_requirements) if endpoint_requirements
|
178
177
|
end
|
179
178
|
end
|
180
179
|
|
@@ -293,7 +292,8 @@ module Grape
|
|
293
292
|
rescue_options: namespace_stackable_with_hash(:rescue_options) || {},
|
294
293
|
rescue_handlers: namespace_reverse_stackable_with_hash(:rescue_handlers) || {},
|
295
294
|
base_only_rescue_handlers: namespace_stackable_with_hash(:base_only_rescue_handlers) || {},
|
296
|
-
all_rescue_handler: namespace_inheritable(:all_rescue_handler)
|
295
|
+
all_rescue_handler: namespace_inheritable(:all_rescue_handler),
|
296
|
+
grape_exceptions_rescue_handler: namespace_inheritable(:grape_exceptions_rescue_handler)
|
297
297
|
|
298
298
|
stack.concat namespace_stackable(:middleware)
|
299
299
|
|
@@ -318,8 +318,8 @@ module Grape
|
|
318
318
|
end
|
319
319
|
|
320
320
|
def build_helpers
|
321
|
-
helpers = namespace_stackable(:helpers)
|
322
|
-
Module.new { helpers
|
321
|
+
helpers = namespace_stackable(:helpers)
|
322
|
+
Module.new { helpers&.each { |mod_to_include| include mod_to_include } }
|
323
323
|
end
|
324
324
|
|
325
325
|
private :build_stack, :build_helpers
|
@@ -345,11 +345,9 @@ module Grape
|
|
345
345
|
end
|
346
346
|
end
|
347
347
|
|
348
|
-
def run_validators(
|
348
|
+
def run_validators(validators, request)
|
349
349
|
validation_errors = []
|
350
350
|
|
351
|
-
validators = validator_factories.map { |options| Grape::Validations::ValidatorFactory.create_validator(**options) }
|
352
|
-
|
353
351
|
ActiveSupport::Notifications.instrument('endpoint_run_validators.grape', endpoint: self, validators: validators, request: request) do
|
354
352
|
validators.each do |validator|
|
355
353
|
validator.validate(request)
|
@@ -367,34 +365,38 @@ module Grape
|
|
367
365
|
|
368
366
|
def run_filters(filters, type = :other)
|
369
367
|
ActiveSupport::Notifications.instrument('endpoint_run_filters.grape', endpoint: self, filters: filters, type: type) do
|
370
|
-
|
368
|
+
filters&.each { |filter| instance_eval(&filter) }
|
371
369
|
end
|
372
370
|
post_extension = DSL::InsideRoute.post_filter_methods(type)
|
373
371
|
extend post_extension if post_extension
|
374
372
|
end
|
375
373
|
|
376
374
|
def befores
|
377
|
-
namespace_stackable(:befores)
|
375
|
+
namespace_stackable(:befores)
|
378
376
|
end
|
379
377
|
|
380
378
|
def before_validations
|
381
|
-
namespace_stackable(:before_validations)
|
379
|
+
namespace_stackable(:before_validations)
|
382
380
|
end
|
383
381
|
|
384
382
|
def after_validations
|
385
|
-
namespace_stackable(:after_validations)
|
383
|
+
namespace_stackable(:after_validations)
|
386
384
|
end
|
387
385
|
|
388
386
|
def afters
|
389
|
-
namespace_stackable(:afters)
|
387
|
+
namespace_stackable(:afters)
|
390
388
|
end
|
391
389
|
|
392
390
|
def finallies
|
393
|
-
namespace_stackable(:finallies)
|
391
|
+
namespace_stackable(:finallies)
|
394
392
|
end
|
395
393
|
|
396
394
|
def validations
|
397
|
-
|
395
|
+
return enum_for(:validations) unless block_given?
|
396
|
+
|
397
|
+
route_setting(:saved_validations)&.each do |saved_validation|
|
398
|
+
yield Grape::Validations::ValidatorFactory.create_validator(**saved_validation)
|
399
|
+
end
|
398
400
|
end
|
399
401
|
|
400
402
|
def options?
|
@@ -27,7 +27,7 @@ module Grape
|
|
27
27
|
|
28
28
|
if presenter
|
29
29
|
embeds = { env: env }
|
30
|
-
embeds[:version] = env[Grape::Env::API_VERSION] if env
|
30
|
+
embeds[:version] = env[Grape::Env::API_VERSION] if env.key?(Grape::Env::API_VERSION)
|
31
31
|
presented_message = presenter.represent(presented_message, embeds).serializable_hash
|
32
32
|
end
|
33
33
|
|
@@ -73,11 +73,11 @@ module Grape
|
|
73
73
|
options = options.dup
|
74
74
|
options[:default] &&= options[:default].to_s
|
75
75
|
message = ::I18n.translate(key, **options)
|
76
|
-
message.
|
76
|
+
message.presence || fallback_message(key, **options)
|
77
77
|
end
|
78
78
|
|
79
79
|
def fallback_message(key, **options)
|
80
|
-
if ::I18n.enforce_available_locales &&
|
80
|
+
if ::I18n.enforce_available_locales && ::I18n.available_locales.exclude?(FALLBACK_LOCALE)
|
81
81
|
key
|
82
82
|
else
|
83
83
|
::I18n.translate(key, locale: FALLBACK_LOCALE, **options)
|
@@ -10,9 +10,4 @@ module Grape
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
Grape::Exceptions::MissingGroupTypeError =
|
14
|
-
def initialize(*)
|
15
|
-
super
|
16
|
-
warn '[DEPRECATION] `Grape::Exceptions::MissingGroupTypeError` is deprecated. Use `Grape::Exceptions::MissingGroupType` instead.'
|
17
|
-
end
|
18
|
-
end
|
13
|
+
Grape::Exceptions::MissingGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::MissingGroupTypeError', 'Grape::Exceptions::MissingGroupType')
|
@@ -10,9 +10,4 @@ module Grape
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
Grape::Exceptions::UnsupportedGroupTypeError =
|
14
|
-
def initialize(*)
|
15
|
-
super
|
16
|
-
warn '[DEPRECATION] `Grape::Exceptions::UnsupportedGroupTypeError` is deprecated. Use `Grape::Exceptions::UnsupportedGroupType` instead.'
|
17
|
-
end
|
18
|
-
end
|
13
|
+
Grape::Exceptions::UnsupportedGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::UnsupportedGroupTypeError', 'Grape::Exceptions::UnsupportedGroupType')
|
@@ -13,12 +13,7 @@ module Grape
|
|
13
13
|
attr_reader :errors
|
14
14
|
|
15
15
|
def initialize(errors: [], headers: {}, **_options)
|
16
|
-
@errors =
|
17
|
-
errors.each do |validation_error|
|
18
|
-
@errors[validation_error.params] ||= []
|
19
|
-
@errors[validation_error.params] << validation_error
|
20
|
-
end
|
21
|
-
|
16
|
+
@errors = errors.group_by(&:params)
|
22
17
|
super message: full_messages.join(', '), status: 400, headers: headers
|
23
18
|
end
|
24
19
|
|
@@ -16,9 +16,9 @@ module Grape
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def build_params
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
::ActiveSupport::HashWithIndifferentAccess.new(rack_params).tap do |params|
|
20
|
+
params.deep_merge!(grape_routing_args) if env.key?(Grape::Env::GRAPE_ROUTING_ARGS)
|
21
|
+
end
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -11,13 +11,10 @@ module Grape
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def build_params
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def post_process_params(params)
|
20
|
-
Grape::Extensions::DeepSymbolizeHash.deep_symbolize_keys_in(params)
|
14
|
+
rack_params.deep_dup.tap do |params|
|
15
|
+
params.deep_merge!(grape_routing_args) if env.key?(Grape::Env::GRAPE_ROUTING_ARGS)
|
16
|
+
params.deep_symbolize_keys!
|
17
|
+
end
|
21
18
|
end
|
22
19
|
end
|
23
20
|
end
|
@@ -15,9 +15,9 @@ module Grape
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def build_params
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
::Hashie::Mash.new(rack_params).tap do |params|
|
19
|
+
params.deep_merge!(grape_routing_args) if env.key?(Grape::Env::GRAPE_ROUTING_ARGS)
|
20
|
+
end
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -15,24 +15,24 @@ module Grape
|
|
15
15
|
private
|
16
16
|
|
17
17
|
def serializable?(object)
|
18
|
-
object.respond_to?(:serializable_hash) ||
|
18
|
+
object.respond_to?(:serializable_hash) || array_serializable?(object) || object.is_a?(Hash)
|
19
19
|
end
|
20
20
|
|
21
21
|
def serialize(object)
|
22
22
|
if object.respond_to? :serializable_hash
|
23
23
|
object.serializable_hash
|
24
|
-
elsif
|
24
|
+
elsif array_serializable?(object)
|
25
25
|
object.map(&:serializable_hash)
|
26
26
|
elsif object.is_a?(Hash)
|
27
|
-
|
28
|
-
object.each_pair do |k, v|
|
29
|
-
h[k] = serialize(v)
|
30
|
-
end
|
31
|
-
h
|
27
|
+
object.transform_values { |v| serialize(v) }
|
32
28
|
else
|
33
29
|
object
|
34
30
|
end
|
35
31
|
end
|
32
|
+
|
33
|
+
def array_serializable?(object)
|
34
|
+
object.is_a?(Array) && object.all? { |o| o.respond_to? :serializable_hash }
|
35
|
+
end
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -28,7 +28,7 @@ module Grape
|
|
28
28
|
|
29
29
|
strategy_info = Grape::Middleware::Auth::Strategies[options[:type]]
|
30
30
|
|
31
|
-
throw(:error, status: 401, message: 'API Authorization Failed.')
|
31
|
+
throw(:error, status: 401, message: 'API Authorization Failed.') if strategy_info.blank?
|
32
32
|
|
33
33
|
strategy = strategy_info.create(@app, options) do |*args|
|
34
34
|
auth_proc_context.instance_exec(*args, &auth_proc)
|
@@ -109,7 +109,7 @@ module Grape
|
|
109
109
|
return :error_response if klass == Grape::Exceptions::InvalidVersionHeader
|
110
110
|
return unless options[:rescue_grape_exceptions] || !options[:rescue_all]
|
111
111
|
|
112
|
-
:error_response
|
112
|
+
options[:grape_exceptions_rescue_handler] || :error_response
|
113
113
|
end
|
114
114
|
|
115
115
|
def rescue_handler_for_any_class(klass)
|
@@ -103,7 +103,7 @@ module Grape
|
|
103
103
|
begin
|
104
104
|
body = (env[Grape::Env::API_REQUEST_BODY] = parser.call(body, env))
|
105
105
|
if body.is_a?(Hash)
|
106
|
-
env[Grape::Env::RACK_REQUEST_FORM_HASH] = if env
|
106
|
+
env[Grape::Env::RACK_REQUEST_FORM_HASH] = if env.key?(Grape::Env::RACK_REQUEST_FORM_HASH)
|
107
107
|
env[Grape::Env::RACK_REQUEST_FORM_HASH].merge(body)
|
108
108
|
else
|
109
109
|
body
|
@@ -57,8 +57,7 @@ module Grape
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def strict_version_vendor_accept_header_presence_check
|
60
|
-
return
|
61
|
-
return if an_accept_header_with_version_and_vendor_is_present?
|
60
|
+
return if versions.blank? || an_accept_header_with_version_and_vendor_is_present?
|
62
61
|
|
63
62
|
fail_with_invalid_accept_header!('API vendor or version not found.')
|
64
63
|
end
|
@@ -101,25 +100,18 @@ module Grape
|
|
101
100
|
end
|
102
101
|
|
103
102
|
def available_media_types
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
]
|
103
|
+
[].tap do |available_media_types|
|
104
|
+
content_types.each_key do |extension|
|
105
|
+
versions.reverse_each do |version|
|
106
|
+
available_media_types << "application/vnd.#{vendor}-#{version}+#{extension}"
|
107
|
+
available_media_types << "application/vnd.#{vendor}-#{version}"
|
108
|
+
end
|
109
|
+
available_media_types << "application/vnd.#{vendor}+#{extension}"
|
112
110
|
end
|
113
|
-
available_media_types << "application/vnd.#{vendor}+#{extension}"
|
114
|
-
end
|
115
|
-
|
116
|
-
available_media_types << "application/vnd.#{vendor}"
|
117
111
|
|
118
|
-
|
119
|
-
available_media_types
|
112
|
+
available_media_types << "application/vnd.#{vendor}"
|
113
|
+
available_media_types.concat(content_types.values.flatten)
|
120
114
|
end
|
121
|
-
|
122
|
-
available_media_types.flatten
|
123
115
|
end
|
124
116
|
|
125
117
|
def headers_contain_wrong_vendor?
|
@@ -130,7 +122,7 @@ module Grape
|
|
130
122
|
|
131
123
|
def headers_contain_wrong_version?
|
132
124
|
header.values.all? do |header_value|
|
133
|
-
version?(header_value) &&
|
125
|
+
version?(header_value) && versions.exclude?(request_version(header_value))
|
134
126
|
end
|
135
127
|
end
|
136
128
|
|
data/lib/grape/router/route.rb
CHANGED
@@ -84,9 +84,7 @@ module Grape
|
|
84
84
|
path, line = *location.scan(SOURCE_LOCATION_REGEXP).first
|
85
85
|
path = File.realpath(path) if Pathname.new(path).relative?
|
86
86
|
expected ||= name
|
87
|
-
warn
|
88
|
-
#{path}:#{line}: The route_xxx methods such as route_#{name} have been deprecated, please use #{expected}.
|
89
|
-
WARNING
|
87
|
+
ActiveSupport::Deprecation.warn("#{path}:#{line}: The route_xxx methods such as route_#{name} have been deprecated, please use #{expected}.")
|
90
88
|
end
|
91
89
|
end
|
92
90
|
end
|
@@ -70,29 +70,21 @@ module Grape
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def evaluate
|
73
|
-
|
74
|
-
@value_hash.each_with_index do |value, index|
|
75
|
-
evaluated[index] = value.evaluate
|
76
|
-
end
|
77
|
-
evaluated
|
73
|
+
@value_hash.map(&:evaluate)
|
78
74
|
end
|
79
75
|
end
|
80
76
|
|
81
77
|
class LazyValueHash < LazyValueEnumerable
|
82
78
|
def initialize(hash)
|
83
79
|
super
|
84
|
-
@value_hash =
|
80
|
+
@value_hash = ActiveSupport::HashWithIndifferentAccess.new
|
85
81
|
hash.each do |key, value|
|
86
82
|
self[key] = value
|
87
83
|
end
|
88
84
|
end
|
89
85
|
|
90
86
|
def evaluate
|
91
|
-
|
92
|
-
@value_hash.each do |key, value|
|
93
|
-
evaluated[key] = value.evaluate
|
94
|
-
end
|
95
|
-
evaluated
|
87
|
+
@value_hash.transform_values(&:evaluate)
|
96
88
|
end
|
97
89
|
end
|
98
90
|
end
|
@@ -66,11 +66,10 @@ module Grape
|
|
66
66
|
end
|
67
67
|
|
68
68
|
define_method :to_hash do
|
69
|
-
merge_hash = {}
|
70
|
-
setting_name.each_key { |k| merge_hash[k] = send("#{k}_context").to_hash }
|
71
|
-
|
72
69
|
@settings.to_hash.merge(
|
73
|
-
merge_hash
|
70
|
+
setting_name.each_key.with_object({}) do |k, merge_hash|
|
71
|
+
merge_hash[k] = send("#{k}_context").to_hash
|
72
|
+
end
|
74
73
|
)
|
75
74
|
end
|
76
75
|
end
|