grape 1.7.0 → 1.8.0

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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/CONTRIBUTING.md +31 -1
  4. data/README.md +38 -8
  5. data/grape.gemspec +2 -2
  6. data/lib/grape/api.rb +2 -2
  7. data/lib/grape/content_types.rb +2 -8
  8. data/lib/grape/dsl/desc.rb +3 -2
  9. data/lib/grape/dsl/inside_route.rb +6 -6
  10. data/lib/grape/dsl/parameters.rb +6 -1
  11. data/lib/grape/dsl/request_response.rb +3 -2
  12. data/lib/grape/dsl/settings.rb +2 -6
  13. data/lib/grape/endpoint.rb +21 -19
  14. data/lib/grape/error_formatter/base.rb +1 -1
  15. data/lib/grape/exceptions/base.rb +4 -3
  16. data/lib/grape/exceptions/missing_group_type.rb +1 -6
  17. data/lib/grape/exceptions/unsupported_group_type.rb +1 -6
  18. data/lib/grape/exceptions/validation_errors.rb +1 -6
  19. data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +3 -3
  20. data/lib/grape/extensions/hash.rb +4 -7
  21. data/lib/grape/extensions/hashie/mash.rb +3 -3
  22. data/lib/grape/formatter/serializable_hash.rb +7 -7
  23. data/lib/grape/middleware/auth/base.rb +1 -1
  24. data/lib/grape/middleware/error.rb +1 -1
  25. data/lib/grape/middleware/formatter.rb +1 -1
  26. data/lib/grape/middleware/stack.rb +1 -1
  27. data/lib/grape/middleware/versioner/header.rb +11 -19
  28. data/lib/grape/request.rb +1 -1
  29. data/lib/grape/router/attribute_translator.rb +1 -1
  30. data/lib/grape/router/route.rb +1 -3
  31. data/lib/grape/types/invalid_value.rb +8 -0
  32. data/lib/grape/util/cache.rb +1 -1
  33. data/lib/grape/util/lazy_value.rb +3 -11
  34. data/lib/grape/util/strict_hash_configuration.rb +3 -4
  35. data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
  36. data/lib/grape/validations/params_scope.rb +9 -3
  37. data/lib/grape/validations/single_attribute_iterator.rb +3 -1
  38. data/lib/grape/validations/types/custom_type_coercer.rb +2 -16
  39. data/lib/grape/validations/types/invalid_value.rb +0 -7
  40. data/lib/grape/validations/validators/base.rb +9 -20
  41. data/lib/grape/validations/validators/default_validator.rb +2 -20
  42. data/lib/grape/validations/validators/multiple_params_base.rb +4 -8
  43. data/lib/grape/validations/validators/values_validator.rb +14 -5
  44. data/lib/grape/version.rb +1 -1
  45. data/lib/grape.rb +19 -3
  46. data/spec/grape/api/custom_validations_spec.rb +14 -57
  47. data/spec/grape/api_remount_spec.rb +36 -0
  48. data/spec/grape/api_spec.rb +15 -21
  49. data/spec/grape/dsl/desc_spec.rb +84 -85
  50. data/spec/grape/dsl/inside_route_spec.rb +6 -10
  51. data/spec/grape/dsl/request_response_spec.rb +21 -2
  52. data/spec/grape/endpoint_spec.rb +11 -10
  53. data/spec/grape/exceptions/body_parse_errors_spec.rb +40 -0
  54. data/spec/grape/exceptions/invalid_accept_header_spec.rb +3 -0
  55. data/spec/grape/exceptions/missing_group_type_spec.rb +5 -9
  56. data/spec/grape/exceptions/unsupported_group_type_spec.rb +5 -9
  57. data/spec/grape/grape_spec.rb +9 -0
  58. data/spec/grape/integration/rack_spec.rb +6 -5
  59. data/spec/grape/middleware/base_spec.rb +7 -5
  60. data/spec/grape/middleware/formatter_spec.rb +7 -7
  61. data/spec/grape/request_spec.rb +4 -14
  62. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +6 -8
  63. data/spec/grape/validations/single_attribute_iterator_spec.rb +8 -9
  64. data/spec/grape/validations/validators/base_spec.rb +38 -0
  65. data/spec/grape/validations/validators/values_spec.rb +56 -0
  66. data/spec/grape/validations_spec.rb +36 -12
  67. data/spec/shared/deprecated_class_examples.rb +16 -0
  68. metadata +112 -114
  69. data/lib/grape/config.rb +0 -34
  70. data/lib/grape/extensions/deep_mergeable_hash.rb +0 -21
  71. data/lib/grape/extensions/deep_symbolize_hash.rb +0 -32
  72. data/spec/grape/config_spec.rb +0 -17
  73. data/spec/grape/dsl/configuration_spec.rb +0 -14
  74. data/spec/grape/validations/attributes_iterator_spec.rb +0 -4
@@ -15,24 +15,24 @@ module Grape
15
15
  private
16
16
 
17
17
  def serializable?(object)
18
- object.respond_to?(:serializable_hash) || (object.is_a?(Array) && object.all? { |o| o.respond_to? :serializable_hash }) || object.is_a?(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 object.is_a?(Array) && object.all? { |o| o.respond_to? :serializable_hash }
24
+ elsif array_serializable?(object)
25
25
  object.map(&:serializable_hash)
26
26
  elsif object.is_a?(Hash)
27
- h = {}
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.') unless strategy_info.present?
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[Grape::Env::RACK_REQUEST_FORM_HASH]
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
@@ -95,7 +95,7 @@ module Grape
95
95
 
96
96
  # @return [Rack::Builder] the builder object with our middlewares applied
97
97
  def build(builder = Rack::Builder.new)
98
- others.shift(others.size).each(&method(:merge_with))
98
+ others.shift(others.size).each { |m| merge_with(m) }
99
99
  middlewares.each do |m|
100
100
  m.use_in(builder)
101
101
  end
@@ -57,8 +57,7 @@ module Grape
57
57
  end
58
58
 
59
59
  def strict_version_vendor_accept_header_presence_check
60
- return unless versions.present?
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
- available_media_types = []
105
-
106
- content_types.each_key do |extension|
107
- versions.reverse_each do |version|
108
- available_media_types += [
109
- "application/vnd.#{vendor}-#{version}+#{extension}",
110
- "application/vnd.#{vendor}-#{version}"
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
- content_types.each_value do |media_type|
119
- available_media_types << media_type
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) && !versions.include?(request_version(header_value))
125
+ version?(header_value) && versions.exclude?(request_version(header_value))
134
126
  end
135
127
  end
136
128
 
data/lib/grape/request.rb CHANGED
@@ -47,7 +47,7 @@ module Grape
47
47
  end
48
48
 
49
49
  def transform_header(header)
50
- -header[5..-1].split('_').each(&:capitalize!).join('-')
50
+ -header[5..].split('_').each(&:capitalize!).join('-')
51
51
  end
52
52
  end
53
53
  end
@@ -39,7 +39,7 @@ module Grape
39
39
 
40
40
  def method_missing(method_name, *args)
41
41
  if setter?(method_name[-1])
42
- attributes[method_name[0..-1]] = *args
42
+ attributes[method_name[0..]] = *args
43
43
  else
44
44
  attributes[method_name]
45
45
  end
@@ -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 <<~WARNING
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
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # only exists to make it shorter for external use
4
+ module Grape
5
+ module Types
6
+ InvalidValue = Class.new(Grape::Validations::Types::InvalidValue)
7
+ end
8
+ end
@@ -1,4 +1,4 @@
1
- # frozen_String_literal: true
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'singleton'
4
4
  require 'forwardable'
@@ -70,29 +70,21 @@ module Grape
70
70
  end
71
71
 
72
72
  def evaluate
73
- evaluated = []
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 = {}.with_indifferent_access
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
- evaluated = {}.with_indifferent_access
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
@@ -6,7 +6,7 @@ module Grape
6
6
  private
7
7
 
8
8
  def yield_attributes(resource_params, _attrs)
9
- yield resource_params, skip?(resource_params)
9
+ yield resource_params unless skip?(resource_params)
10
10
  end
11
11
  end
12
12
  end
@@ -10,6 +10,11 @@ module Grape
10
10
 
11
11
  include Grape::DSL::Parameters
12
12
 
13
+ # There are a number of documentation options on entities that don't have
14
+ # corresponding validators. Since there is nowhere that enumerates them all,
15
+ # we maintain a list of them here and skip looking up validators for them.
16
+ RESERVED_DOCUMENTATION_KEYWORDS = %i[as required param_type is_array format example].freeze
17
+
13
18
  class Attr
14
19
  attr_accessor :key, :scope
15
20
 
@@ -359,7 +364,8 @@ module Grape
359
364
  coerce_type validations, attrs, doc, opts
360
365
 
361
366
  validations.each do |type, options|
362
- next if type == :as
367
+ # Don't try to look up validators for documentation params that don't have one.
368
+ next if RESERVED_DOCUMENTATION_KEYWORDS.include?(type)
363
369
 
364
370
  validate(type, options, attrs, doc, opts)
365
371
  end
@@ -414,7 +420,7 @@ module Grape
414
420
 
415
421
  # but not special JSON types, which
416
422
  # already imply coercion method
417
- return unless [JSON, Array[JSON]].include? validations[:coerce]
423
+ return if [JSON, Array[JSON]].exclude? validations[:coerce]
418
424
 
419
425
  raise ArgumentError, 'coerce_with disallowed for type: JSON'
420
426
  end
@@ -485,7 +491,7 @@ module Grape
485
491
  values_list.each do |values|
486
492
  next if !values || values.is_a?(Proc)
487
493
 
488
- value_types = values.is_a?(Range) ? [values.begin, values.end] : values
494
+ value_types = values.is_a?(Range) ? [values.begin, values.end].compact : values
489
495
  value_types = value_types.map { |type| Grape::API::Boolean.build(type) } if coerce_type == Grape::API::Boolean
490
496
  raise Grape::Exceptions::IncompatibleOptionValues.new(:type, coerce_type, :values, values) unless value_types.all?(coerce_type)
491
497
  end
@@ -6,8 +6,10 @@ module Grape
6
6
  private
7
7
 
8
8
  def yield_attributes(val, attrs)
9
+ return if skip?(val)
10
+
9
11
  attrs.each do |attr_name|
10
- yield val, attr_name, empty?(val), skip?(val)
12
+ yield val, attr_name, empty?(val)
11
13
  end
12
14
  end
13
15
 
@@ -141,7 +141,7 @@ module Grape
141
141
  lambda do |val|
142
142
  method.call(val).tap do |new_val|
143
143
  new_val.map do |item|
144
- item.is_a?(Hash) ? symbolize_keys(item) : item
144
+ item.is_a?(Hash) ? item.deep_symbolize_keys : item
145
145
  end
146
146
  end
147
147
  end
@@ -149,7 +149,7 @@ module Grape
149
149
  # Hash objects are processed directly
150
150
  elsif type == Hash
151
151
  lambda do |val|
152
- symbolize_keys method.call(val)
152
+ method.call(val).deep_symbolize_keys
153
153
  end
154
154
 
155
155
  # Simple types are not processed.
@@ -158,20 +158,6 @@ module Grape
158
158
  method
159
159
  end
160
160
  end
161
-
162
- def symbolize_keys!(hash)
163
- hash.each_key do |key|
164
- hash[key.to_sym] = hash.delete(key) if key.respond_to?(:to_sym)
165
- end
166
- hash
167
- end
168
-
169
- def symbolize_keys(hash)
170
- hash.inject({}) do |new_hash, (key, value)|
171
- new_key = key.respond_to?(:to_sym) ? key.to_sym : key
172
- new_hash.merge!(new_key => value)
173
- end
174
- end
175
161
  end
176
162
  end
177
163
  end
@@ -15,10 +15,3 @@ module Grape
15
15
  end
16
16
  end
17
17
  end
18
-
19
- # only exists to make it shorter for external use
20
- module Grape
21
- module Types
22
- InvalidValue = Class.new(Grape::Validations::Types::InvalidValue)
23
- end
24
- end
@@ -46,34 +46,23 @@ module Grape
46
46
  # there may be more than one error per field
47
47
  array_errors = []
48
48
 
49
- attributes.each do |val, attr_name, empty_val, skip_value|
50
- next if skip_value
49
+ attributes.each do |val, attr_name, empty_val|
51
50
  next if !@scope.required? && empty_val
52
51
  next unless @scope.meets_dependency?(val, params)
53
52
 
54
- begin
55
- validate_param!(attr_name, val) if @required || (val.respond_to?(:key?) && val.key?(attr_name))
56
- rescue Grape::Exceptions::Validation => e
57
- array_errors << e
58
- end
53
+ validate_param!(attr_name, val) if @required || (val.respond_to?(:key?) && val.key?(attr_name))
54
+ rescue Grape::Exceptions::Validation => e
55
+ array_errors << e
59
56
  end
60
57
 
61
58
  raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
62
59
  end
63
60
 
64
- def self.convert_to_short_name(klass)
65
- ret = klass.name.gsub(/::/, '/')
66
- ret.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
67
- ret.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
68
- ret.tr!('-', '_')
69
- ret.downcase!
70
- File.basename(ret, '_validator')
71
- end
72
-
73
61
  def self.inherited(klass)
74
- return unless klass.name.present?
62
+ return if klass.name.blank?
75
63
 
76
- Validations.register_validator(convert_to_short_name(klass), klass)
64
+ short_validator_name = klass.name.demodulize.underscore.delete_suffix('_validator')
65
+ Validations.register_validator(short_validator_name, klass)
77
66
  end
78
67
 
79
68
  def message(default_key = nil)
@@ -95,8 +84,8 @@ module Grape
95
84
  end
96
85
 
97
86
  Grape::Validations::Base = Class.new(Grape::Validations::Validators::Base) do
98
- def initialize(*)
87
+ def self.inherited(*)
88
+ ActiveSupport::Deprecation.warn 'Grape::Validations::Base is deprecated! Use Grape::Validations::Validators::Base instead.'
99
89
  super
100
- warn '[DEPRECATION] `Grape::Validations::Base` is deprecated. Use `Grape::Validations::Validators::Base` instead.'
101
90
  end
102
91
  end
@@ -12,10 +12,10 @@ module Grape
12
12
  def validate_param!(attr_name, params)
13
13
  params[attr_name] = if @default.is_a? Proc
14
14
  @default.call
15
- elsif @default.frozen? || !duplicatable?(@default)
15
+ elsif @default.frozen? || !@default.duplicable?
16
16
  @default
17
17
  else
18
- duplicate(@default)
18
+ @default.dup
19
19
  end
20
20
  end
21
21
 
@@ -27,24 +27,6 @@ module Grape
27
27
  validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil?
28
28
  end
29
29
  end
30
-
31
- private
32
-
33
- # return true if we might be able to dup this object
34
- def duplicatable?(obj)
35
- !obj.nil? &&
36
- obj != true &&
37
- obj != false &&
38
- !obj.is_a?(Symbol) &&
39
- !obj.is_a?(Numeric)
40
- end
41
-
42
- # make a best effort to dup the object
43
- def duplicate(obj)
44
- obj.dup
45
- rescue TypeError
46
- obj
47
- end
48
30
  end
49
31
  end
50
32
  end
@@ -8,14 +8,10 @@ module Grape
8
8
  attributes = MultipleAttributesIterator.new(self, @scope, params)
9
9
  array_errors = []
10
10
 
11
- attributes.each do |resource_params, skip_value|
12
- next if skip_value
13
-
14
- begin
15
- validate_params!(resource_params)
16
- rescue Grape::Exceptions::Validation => e
17
- array_errors << e
18
- end
11
+ attributes.each do |resource_params|
12
+ validate_params!(resource_params)
13
+ rescue Grape::Exceptions::Validation => e
14
+ array_errors << e
19
15
  end
20
16
 
21
17
  raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
@@ -10,13 +10,11 @@ module Grape
10
10
  @values = options[:value]
11
11
  @proc = options[:proc]
12
12
 
13
- warn '[DEPRECATION] The values validator except option is deprecated. ' \
14
- 'Use the except validator instead.' if @excepts
13
+ ActiveSupport::Deprecation.warn('The values validator except option is deprecated. Use the except validator instead.') if @excepts
15
14
 
16
15
  raise ArgumentError, 'proc must be a Proc' if @proc && !@proc.is_a?(Proc)
17
16
 
18
- warn '[DEPRECATION] The values validator proc option is deprecated. ' \
19
- 'The lambda expression can now be assigned directly to values.' if @proc
17
+ ActiveSupport::Deprecation.warn('The values validator proc option is deprecated. The lambda expression can now be assigned directly to values.') if @proc
20
18
  else
21
19
  @excepts = nil
22
20
  @values = nil
@@ -45,7 +43,7 @@ module Grape
45
43
  unless check_values(param_array, attr_name)
46
44
 
47
45
  raise validation_exception(attr_name, message(:values)) \
48
- if @proc && !param_array.all? { |param| @proc.call(param) }
46
+ if @proc && !validate_proc(@proc, param_array)
49
47
  end
50
48
 
51
49
  private
@@ -70,6 +68,17 @@ module Grape
70
68
  param_array.none? { |param| excepts.include?(param) }
71
69
  end
72
70
 
71
+ def validate_proc(proc, param_array)
72
+ case proc.arity
73
+ when 0
74
+ param_array.all? { |_param| proc.call }
75
+ when 1
76
+ param_array.all? { |param| proc.call(param) }
77
+ else
78
+ raise ArgumentError, 'proc arity must be 0 or 1'
79
+ end
80
+ end
81
+
73
82
  def except_message
74
83
  options = instance_variable_get(:@option)
75
84
  options_key?(:except_message) ? options[:except_message] : message(:except_values)
data/lib/grape/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Grape
4
4
  # The current version of Grape.
5
- VERSION = '1.7.0'
5
+ VERSION = '1.8.0'
6
6
  end
data/lib/grape.rb CHANGED
@@ -11,6 +11,7 @@ require 'bigdecimal'
11
11
  require 'date'
12
12
  require 'active_support'
13
13
  require 'active_support/concern'
14
+ require 'active_support/configurable'
14
15
  require 'active_support/version'
15
16
  require 'active_support/isolated_execution_state' if ActiveSupport::VERSION::MAJOR > 6
16
17
  require 'active_support/core_ext/array/conversions'
@@ -20,16 +21,21 @@ require 'active_support/core_ext/hash/conversions'
20
21
  require 'active_support/core_ext/hash/deep_merge'
21
22
  require 'active_support/core_ext/hash/except'
22
23
  require 'active_support/core_ext/hash/indifferent_access'
24
+ require 'active_support/core_ext/hash/keys'
23
25
  require 'active_support/core_ext/hash/reverse_merge'
24
26
  require 'active_support/core_ext/hash/slice'
25
27
  require 'active_support/core_ext/object/blank'
28
+ require 'active_support/core_ext/object/duplicable'
26
29
  require 'active_support/dependencies/autoload'
30
+ require 'active_support/deprecation'
31
+ require 'active_support/inflector'
27
32
  require 'active_support/notifications'
28
33
  require 'i18n'
29
34
 
30
35
  I18n.load_path << File.expand_path('grape/locale/en.yml', __dir__)
31
36
 
32
37
  module Grape
38
+ include ActiveSupport::Configurable
33
39
  extend ::ActiveSupport::Autoload
34
40
 
35
41
  eager_autoload do
@@ -92,8 +98,6 @@ module Grape
92
98
  module Extensions
93
99
  extend ::ActiveSupport::Autoload
94
100
  eager_autoload do
95
- autoload :DeepMergeableHash
96
- autoload :DeepSymbolizeHash
97
101
  autoload :Hash
98
102
  end
99
103
  module ActiveSupport
@@ -277,9 +281,21 @@ module Grape
277
281
  end
278
282
  end
279
283
  end
284
+
285
+ module Types
286
+ extend ::ActiveSupport::Autoload
287
+
288
+ eager_autoload do
289
+ autoload :InvalidValue
290
+ end
291
+ end
292
+
293
+ configure do |config|
294
+ config.param_builder = Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
295
+ config.compile_methods!
296
+ end
280
297
  end
281
298
 
282
- require 'grape/config'
283
299
  require 'grape/content_types'
284
300
 
285
301
  require 'grape/util/lazy_value'