grape 2.3.0 → 3.0.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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -0
  3. data/CONTRIBUTING.md +2 -10
  4. data/README.md +106 -43
  5. data/UPGRADING.md +90 -1
  6. data/grape.gemspec +4 -4
  7. data/lib/grape/api/instance.rb +51 -73
  8. data/lib/grape/api.rb +56 -89
  9. data/lib/grape/cookies.rb +31 -25
  10. data/lib/grape/dry_types.rb +48 -4
  11. data/lib/grape/dsl/callbacks.rb +8 -58
  12. data/lib/grape/dsl/desc.rb +8 -67
  13. data/lib/grape/dsl/headers.rb +1 -1
  14. data/lib/grape/dsl/helpers.rb +60 -65
  15. data/lib/grape/dsl/inside_route.rb +26 -61
  16. data/lib/grape/dsl/logger.rb +3 -6
  17. data/lib/grape/dsl/middleware.rb +22 -40
  18. data/lib/grape/dsl/parameters.rb +10 -19
  19. data/lib/grape/dsl/request_response.rb +136 -139
  20. data/lib/grape/dsl/routing.rb +230 -194
  21. data/lib/grape/dsl/settings.rb +22 -134
  22. data/lib/grape/dsl/validations.rb +37 -45
  23. data/lib/grape/endpoint.rb +91 -126
  24. data/lib/grape/error_formatter/base.rb +2 -0
  25. data/lib/grape/exceptions/base.rb +1 -1
  26. data/lib/grape/exceptions/conflicting_types.rb +11 -0
  27. data/lib/grape/exceptions/invalid_parameters.rb +11 -0
  28. data/lib/grape/exceptions/missing_group_type.rb +0 -2
  29. data/lib/grape/exceptions/too_deep_parameters.rb +11 -0
  30. data/lib/grape/exceptions/unknown_auth_strategy.rb +11 -0
  31. data/lib/grape/exceptions/unknown_params_builder.rb +11 -0
  32. data/lib/grape/exceptions/unsupported_group_type.rb +0 -2
  33. data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +2 -5
  34. data/lib/grape/extensions/hash.rb +2 -1
  35. data/lib/grape/extensions/hashie/mash.rb +3 -5
  36. data/lib/grape/locale/en.yml +44 -44
  37. data/lib/grape/middleware/auth/base.rb +11 -32
  38. data/lib/grape/middleware/auth/dsl.rb +22 -29
  39. data/lib/grape/middleware/base.rb +30 -11
  40. data/lib/grape/middleware/error.rb +14 -32
  41. data/lib/grape/middleware/formatter.rb +40 -72
  42. data/lib/grape/middleware/stack.rb +28 -38
  43. data/lib/grape/middleware/versioner/accept_version_header.rb +2 -4
  44. data/lib/grape/middleware/versioner/base.rb +30 -56
  45. data/lib/grape/middleware/versioner/header.rb +2 -2
  46. data/lib/grape/middleware/versioner/param.rb +2 -3
  47. data/lib/grape/middleware/versioner/path.rb +1 -1
  48. data/lib/grape/namespace.rb +11 -0
  49. data/lib/grape/params_builder/base.rb +20 -0
  50. data/lib/grape/params_builder/hash.rb +11 -0
  51. data/lib/grape/params_builder/hash_with_indifferent_access.rb +11 -0
  52. data/lib/grape/params_builder/hashie_mash.rb +11 -0
  53. data/lib/grape/params_builder.rb +32 -0
  54. data/lib/grape/request.rb +161 -22
  55. data/lib/grape/router/route.rb +1 -1
  56. data/lib/grape/router.rb +27 -8
  57. data/lib/grape/util/api_description.rb +56 -0
  58. data/lib/grape/util/base_inheritable.rb +5 -2
  59. data/lib/grape/util/inheritable_setting.rb +7 -0
  60. data/lib/grape/util/media_type.rb +1 -1
  61. data/lib/grape/util/registry.rb +1 -1
  62. data/lib/grape/validations/contract_scope.rb +2 -2
  63. data/lib/grape/validations/params_documentation.rb +50 -0
  64. data/lib/grape/validations/params_scope.rb +46 -56
  65. data/lib/grape/validations/types/array_coercer.rb +2 -3
  66. data/lib/grape/validations/types/dry_type_coercer.rb +4 -11
  67. data/lib/grape/validations/types/primitive_coercer.rb +1 -28
  68. data/lib/grape/validations/types.rb +10 -25
  69. data/lib/grape/validations/validators/base.rb +2 -9
  70. data/lib/grape/validations/validators/except_values_validator.rb +1 -1
  71. data/lib/grape/validations/validators/presence_validator.rb +1 -1
  72. data/lib/grape/validations/validators/regexp_validator.rb +1 -1
  73. data/lib/grape/version.rb +1 -1
  74. data/lib/grape.rb +18 -9
  75. metadata +35 -20
  76. data/lib/grape/api/helpers.rb +0 -9
  77. data/lib/grape/dsl/api.rb +0 -19
  78. data/lib/grape/dsl/configuration.rb +0 -15
  79. data/lib/grape/error_formatter/jsonapi.rb +0 -7
  80. data/lib/grape/http/headers.rb +0 -56
  81. data/lib/grape/middleware/helpers.rb +0 -12
  82. data/lib/grape/parser/jsonapi.rb +0 -7
  83. data/lib/grape/types/invalid_value.rb +0 -8
  84. data/lib/grape/util/lazy/object.rb +0 -45
  85. data/lib/grape/util/strict_hash_configuration.rb +0 -108
  86. data/lib/grape/validations/attributes_doc.rb +0 -60
@@ -3,54 +3,46 @@
3
3
  module Grape
4
4
  module DSL
5
5
  module Validations
6
- extend ActiveSupport::Concern
7
-
8
- include Grape::DSL::Configuration
9
-
10
- module ClassMethods
11
- # Clears all defined parameters and validations. The main purpose of it is to clean up
12
- # settings, so next endpoint won't interfere with previous one.
13
- #
14
- # params do
15
- # # params for the endpoint below this block
16
- # end
17
- # post '/current' do
18
- # # whatever
19
- # end
20
- #
21
- # # somewhere between them the reset_validations! method gets called
22
- #
23
- # params do
24
- # # params for the endpoint below this block
25
- # end
26
- # post '/next' do
27
- # # whatever
28
- # end
29
- def reset_validations!
30
- unset_namespace_stackable :declared_params
31
- unset_namespace_stackable :validations
32
- unset_namespace_stackable :params
33
- end
6
+ # Clears all defined parameters and validations. The main purpose of it is to clean up
7
+ # settings, so next endpoint won't interfere with previous one.
8
+ #
9
+ # params do
10
+ # # params for the endpoint below this block
11
+ # end
12
+ # post '/current' do
13
+ # # whatever
14
+ # end
15
+ #
16
+ # # somewhere between them the reset_validations! method gets called
17
+ #
18
+ # params do
19
+ # # params for the endpoint below this block
20
+ # end
21
+ # post '/next' do
22
+ # # whatever
23
+ # end
24
+ def reset_validations!
25
+ inheritable_setting.namespace_stackable.delete(:declared_params, :params, :validations)
26
+ end
34
27
 
35
- # Opens a root-level ParamsScope, defining parameter coercions and
36
- # validations for the endpoint.
37
- # @yield instance context of the new scope
38
- def params(&block)
39
- Grape::Validations::ParamsScope.new(api: self, type: Hash, &block)
40
- end
28
+ # Opens a root-level ParamsScope, defining parameter coercions and
29
+ # validations for the endpoint.
30
+ # @yield instance context of the new scope
31
+ def params(&block)
32
+ Grape::Validations::ParamsScope.new(api: self, type: Hash, &block)
33
+ end
41
34
 
42
- # Declare the contract to be used for the endpoint's parameters.
43
- # @param contract [Class<Dry::Validation::Contract> | Dry::Schema::Processor]
44
- # The contract or schema to be used for validation. Optional.
45
- # @yield a block yielding a new instance of Dry::Schema::Params
46
- # subclass, allowing to define the schema inline. When the
47
- # +contract+ parameter is a schema, it will be used as a parent. Optional.
48
- def contract(contract = nil, &block)
49
- raise ArgumentError, 'Either contract or block must be provided' unless contract || block
50
- raise ArgumentError, 'Cannot inherit from contract, only schema' if block && contract.respond_to?(:schema)
35
+ # Declare the contract to be used for the endpoint's parameters.
36
+ # @param contract [Class<Dry::Validation::Contract> | Dry::Schema::Processor]
37
+ # The contract or schema to be used for validation. Optional.
38
+ # @yield a block yielding a new instance of Dry::Schema::Params
39
+ # subclass, allowing to define the schema inline. When the
40
+ # +contract+ parameter is a schema, it will be used as a parent. Optional.
41
+ def contract(contract = nil, &block)
42
+ raise ArgumentError, 'Either contract or block must be provided' unless contract || block
43
+ raise ArgumentError, 'Cannot inherit from contract, only schema' if block && contract.respond_to?(:schema)
51
44
 
52
- Grape::Validations::ContractScope.new(self, contract, &block)
53
- end
45
+ Grape::Validations::ContractScope.new(self, contract, &block)
54
46
  end
55
47
  end
56
48
  end
@@ -6,17 +6,17 @@ module Grape
6
6
  # on the instance level of this class may be called
7
7
  # from inside a `get`, `post`, etc.
8
8
  class Endpoint
9
+ extend Forwardable
9
10
  include Grape::DSL::Settings
11
+ include Grape::DSL::Headers
10
12
  include Grape::DSL::InsideRoute
11
13
 
12
- attr_accessor :block, :source, :options
13
- attr_reader :env, :request, :headers, :params
14
+ attr_reader :env, :request, :source, :options
14
15
 
15
- class << self
16
- def new(...)
17
- self == Endpoint ? Class.new(Endpoint).new(...) : super
18
- end
16
+ def_delegators :request, :params, :headers, :cookies
17
+ def_delegator :cookies, :response_cookies
19
18
 
19
+ class << self
20
20
  def before_each(new_setup = false, &block)
21
21
  @before_each ||= []
22
22
  if new_setup == false
@@ -30,34 +30,7 @@ module Grape
30
30
 
31
31
  def run_before_each(endpoint)
32
32
  superclass.run_before_each(endpoint) unless self == Endpoint
33
- before_each.each { |blk| blk.call(endpoint) if blk.respond_to?(:call) }
34
- end
35
-
36
- # @api private
37
- #
38
- # Create an UnboundMethod that is appropriate for executing an endpoint
39
- # route.
40
- #
41
- # The unbound method allows explicit calls to +return+ without raising a
42
- # +LocalJumpError+. The method will be removed, but a +Proc+ reference to
43
- # it will be returned. The returned +Proc+ expects a single argument: the
44
- # instance of +Endpoint+ to bind to the method during the call.
45
- #
46
- # @param [String, Symbol] method_name
47
- # @return [Proc]
48
- # @raise [NameError] an instance method with the same name already exists
49
- def generate_api_method(method_name, &block)
50
- raise NameError.new("method #{method_name.inspect} already exists and cannot be used as an unbound method name") if method_defined?(method_name)
51
-
52
- define_method(method_name, &block)
53
- method = instance_method(method_name)
54
- remove_method(method_name)
55
-
56
- proc do |endpoint_instance|
57
- ActiveSupport::Notifications.instrument('endpoint_render.grape', endpoint: endpoint_instance) do
58
- method.bind_call(endpoint_instance)
59
- end
60
- end
33
+ before_each.each { |blk| blk.try(:call, endpoint) }
61
34
  end
62
35
  end
63
36
 
@@ -82,11 +55,11 @@ module Grape
82
55
  # now +namespace_stackable(:declared_params)+ contains all params defined for
83
56
  # this endpoint and its parents, but later it will be cleaned up,
84
57
  # see +reset_validations!+ in lib/grape/dsl/validations.rb
85
- route_setting(:declared_params, namespace_stackable(:declared_params).flatten)
86
- route_setting(:saved_validations, namespace_stackable(:validations))
58
+ inheritable_setting.route[:declared_params] = inheritable_setting.namespace_stackable[:declared_params].flatten
59
+ inheritable_setting.route[:saved_validations] = inheritable_setting.namespace_stackable[:validations]
87
60
 
88
- namespace_stackable(:representations, []) unless namespace_stackable(:representations)
89
- namespace_inheritable(:default_error_status, 500) unless namespace_inheritable(:default_error_status)
61
+ inheritable_setting.namespace_stackable[:representations] = [] unless inheritable_setting.namespace_stackable[:representations]
62
+ inheritable_setting.namespace_inheritable[:default_error_status] = 500 unless inheritable_setting.namespace_inheritable[:default_error_status]
90
63
 
91
64
  @options = options
92
65
 
@@ -98,17 +71,11 @@ module Grape
98
71
 
99
72
  @lazy_initialize_lock = Mutex.new
100
73
  @lazy_initialized = nil
101
- @block = nil
102
-
103
74
  @status = nil
104
75
  @stream = nil
105
76
  @body = nil
106
- @proc = nil
107
-
108
- return unless block
109
-
110
77
  @source = block
111
- @block = self.class.generate_api_method(method_name, &block)
78
+ @helpers = build_helpers
112
79
  end
113
80
 
114
81
  # Update our settings from a given set of stackable parameters. Used when
@@ -126,16 +93,8 @@ module Grape
126
93
  raise Grape::Exceptions::MissingOption.new(key) unless options.key?(key)
127
94
  end
128
95
 
129
- def method_name
130
- [options[:method],
131
- Namespace.joined_space(namespace_stackable(:namespace)),
132
- (namespace_stackable(:mount_path) || []).join('/'),
133
- options[:path].join('/')]
134
- .join(' ')
135
- end
136
-
137
96
  def routes
138
- @routes ||= endpoints ? endpoints.collect(&:routes).flatten : to_routes
97
+ @routes ||= endpoints&.collect(&:routes)&.flatten || to_routes
139
98
  end
140
99
 
141
100
  def reset_routes!
@@ -150,7 +109,7 @@ module Grape
150
109
  reset_routes!
151
110
  routes.each do |route|
152
111
  router.append(route.apply(self))
153
- next unless !namespace_inheritable(:do_not_route_head) && route.request_method == Rack::GET
112
+ next unless !inheritable_setting.namespace_inheritable[:do_not_route_head] && route.request_method == Rack::GET
154
113
 
155
114
  route.dup.then do |head_route|
156
115
  head_route.convert_to_head_request!
@@ -161,10 +120,9 @@ module Grape
161
120
 
162
121
  def to_routes
163
122
  default_route_options = prepare_default_route_attributes
164
- default_path_settings = prepare_default_path_settings
165
123
 
166
124
  map_routes do |method, raw_path|
167
- prepared_path = Path.new(raw_path, namespace, default_path_settings)
125
+ prepared_path = Path.new(raw_path, namespace, prepare_default_path_settings)
168
126
  params = options[:route_options].present? ? options[:route_options].merge(default_route_options) : default_route_options
169
127
  route = Grape::Router::Route.new(method, prepared_path.origin, prepared_path.suffix, params)
170
128
  route.apply(self)
@@ -172,7 +130,7 @@ module Grape
172
130
  end
173
131
 
174
132
  def prepare_routes_requirements
175
- {}.merge!(*namespace_stackable(:namespace).map(&:requirements)).tap do |requirements|
133
+ {}.merge!(*inheritable_setting.namespace_stackable[:namespace].map(&:requirements)).tap do |requirements|
176
134
  endpoint_requirements = options.dig(:route_options, :requirements)
177
135
  requirements.merge!(endpoint_requirements) if endpoint_requirements
178
136
  end
@@ -183,7 +141,7 @@ module Grape
183
141
  namespace: namespace,
184
142
  version: prepare_version,
185
143
  requirements: prepare_routes_requirements,
186
- prefix: namespace_inheritable(:root_prefix),
144
+ prefix: inheritable_setting.namespace_inheritable[:root_prefix],
187
145
  anchor: options[:route_options].fetch(:anchor, true),
188
146
  settings: inheritable_setting.route.except(:declared_params, :saved_validations),
189
147
  forward_match: options[:forward_match]
@@ -191,7 +149,7 @@ module Grape
191
149
  end
192
150
 
193
151
  def prepare_version
194
- version = namespace_inheritable(:version)
152
+ version = inheritable_setting.namespace_inheritable[:version]
195
153
  return if version.blank?
196
154
 
197
155
  version.length == 1 ? version.first : version
@@ -208,7 +166,7 @@ module Grape
208
166
  end
209
167
 
210
168
  def namespace
211
- @namespace ||= Namespace.joined_space_path(namespace_stackable(:namespace))
169
+ @namespace ||= Namespace.joined_space_path(inheritable_setting.namespace_stackable[:namespace])
212
170
  end
213
171
 
214
172
  def call(env)
@@ -219,13 +177,15 @@ module Grape
219
177
  def call!(env)
220
178
  env[Grape::Env::API_ENDPOINT] = self
221
179
  @env = env
180
+ # this adds the helpers only to the instance
181
+ singleton_class.include(@helpers) if @helpers
222
182
  @app.call(env)
223
183
  end
224
184
 
225
185
  # Return the collection of endpoints within this endpoint.
226
186
  # This is the case when an Grape::API mounts another Grape::API.
227
187
  def endpoints
228
- options[:app].endpoints if options[:app].respond_to?(:endpoints)
188
+ @endpoints ||= options[:app].try(:endpoints)
229
189
  end
230
190
 
231
191
  def equals?(endpoint)
@@ -245,20 +205,16 @@ module Grape
245
205
 
246
206
  def run
247
207
  ActiveSupport::Notifications.instrument('endpoint_run.grape', endpoint: self, env: env) do
248
- @header = Grape::Util::Header.new
249
- @request = Grape::Request.new(env, build_params_with: namespace_inheritable(:build_params_with))
250
- @params = @request.params
251
- @headers = @request.headers
208
+ @request = Grape::Request.new(env, build_params_with: inheritable_setting.namespace_inheritable[:build_params_with])
252
209
  begin
253
- cookies.read(@request)
254
210
  self.class.run_before_each(self)
255
211
  run_filters befores, :before
256
212
 
257
- if (allowed_methods = env[Grape::Env::GRAPE_ALLOWED_METHODS])
258
- allow_header_value = allowed_methods.join(', ')
259
- raise Grape::Exceptions::MethodNotAllowed.new(header.merge('Allow' => allow_header_value)) unless options?
213
+ if env.key?(Grape::Env::GRAPE_ALLOWED_METHODS)
214
+ header['Allow'] = env[Grape::Env::GRAPE_ALLOWED_METHODS].join(', ')
215
+ raise Grape::Exceptions::MethodNotAllowed.new(header) unless options?
260
216
 
261
- header Grape::Http::Headers::ALLOW, allow_header_value
217
+ header 'Allow', header['Allow']
262
218
  response_object = ''
263
219
  status 204
264
220
  else
@@ -269,7 +225,7 @@ module Grape
269
225
  end
270
226
 
271
227
  run_filters afters, :after
272
- cookies.write(header)
228
+ build_response_cookies
273
229
 
274
230
  # status verifies body presence when DELETE
275
231
  @body ||= response_object
@@ -285,11 +241,14 @@ module Grape
285
241
  end
286
242
 
287
243
  def execute
288
- @block&.call(self)
289
- end
244
+ return unless @source
290
245
 
291
- def helpers
292
- lazy_initialize! && @helpers
246
+ ActiveSupport::Notifications.instrument('endpoint_render.grape', endpoint: self) do
247
+ instance_exec(&@source)
248
+ rescue LocalJumpError => e
249
+ Grape.deprecator.warn 'Using `return` in an endpoint has been deprecated. Use `next` instead.'
250
+ return e.exit_value
251
+ end
293
252
  end
294
253
 
295
254
  def lazy_initialize!
@@ -298,9 +257,7 @@ module Grape
298
257
  @lazy_initialize_lock.synchronize do
299
258
  return true if @lazy_initialized
300
259
 
301
- @helpers = build_helpers&.tap { |mod| self.class.include mod }
302
- @app = options[:app] || build_stack(@helpers)
303
-
260
+ @app = options[:app] || build_stack
304
261
  @lazy_initialized = true
305
262
  end
306
263
  end
@@ -331,30 +288,18 @@ module Grape
331
288
  extend post_extension if post_extension
332
289
  end
333
290
 
334
- def befores
335
- namespace_stackable(:befores)
336
- end
337
-
338
- def before_validations
339
- namespace_stackable(:before_validations)
340
- end
341
-
342
- def after_validations
343
- namespace_stackable(:after_validations)
344
- end
345
-
346
- def afters
347
- namespace_stackable(:afters)
348
- end
349
-
350
- def finallies
351
- namespace_stackable(:finallies)
291
+ %i[befores before_validations after_validations afters finallies].each do |method|
292
+ define_method method do
293
+ inheritable_setting.namespace_stackable[method]
294
+ end
352
295
  end
353
296
 
354
297
  def validations
298
+ saved_validations = inheritable_setting.route[:saved_validations]
299
+ return if saved_validations.nil?
355
300
  return enum_for(:validations) unless block_given?
356
301
 
357
- route_setting(:saved_validations)&.each do |saved_validation|
302
+ saved_validations.each do |saved_validation|
358
303
  yield Grape::Validations::ValidatorFactory.create_validator(saved_validation)
359
304
  end
360
305
  end
@@ -366,44 +311,44 @@ module Grape
366
311
 
367
312
  private
368
313
 
369
- def build_stack(helpers)
314
+ def build_stack
370
315
  stack = Grape::Middleware::Stack.new
371
316
 
372
- content_types = namespace_stackable_with_hash(:content_types)
373
- format = namespace_inheritable(:format)
317
+ content_types = inheritable_setting.namespace_stackable_with_hash(:content_types)
318
+ format = inheritable_setting.namespace_inheritable[:format]
374
319
 
375
320
  stack.use Rack::Head
376
- stack.use Class.new(Grape::Middleware::Error),
377
- helpers: helpers,
321
+ stack.use Rack::Lint if lint?
322
+ stack.use Grape::Middleware::Error,
378
323
  format: format,
379
324
  content_types: content_types,
380
- default_status: namespace_inheritable(:default_error_status),
381
- rescue_all: namespace_inheritable(:rescue_all),
382
- rescue_grape_exceptions: namespace_inheritable(:rescue_grape_exceptions),
383
- default_error_formatter: namespace_inheritable(:default_error_formatter),
384
- error_formatters: namespace_stackable_with_hash(:error_formatters),
385
- rescue_options: namespace_stackable_with_hash(:rescue_options),
386
- rescue_handlers: namespace_reverse_stackable_with_hash(:rescue_handlers),
387
- base_only_rescue_handlers: namespace_stackable_with_hash(:base_only_rescue_handlers),
388
- all_rescue_handler: namespace_inheritable(:all_rescue_handler),
389
- grape_exceptions_rescue_handler: namespace_inheritable(:grape_exceptions_rescue_handler)
390
-
391
- stack.concat namespace_stackable(:middleware)
392
-
393
- if namespace_inheritable(:version).present?
394
- stack.use Grape::Middleware::Versioner.using(namespace_inheritable(:version_options)[:using]),
395
- versions: namespace_inheritable(:version).flatten,
396
- version_options: namespace_inheritable(:version_options),
397
- prefix: namespace_inheritable(:root_prefix),
398
- mount_path: namespace_stackable(:mount_path).first
325
+ default_status: inheritable_setting.namespace_inheritable[:default_error_status],
326
+ rescue_all: inheritable_setting.namespace_inheritable[:rescue_all],
327
+ rescue_grape_exceptions: inheritable_setting.namespace_inheritable[:rescue_grape_exceptions],
328
+ default_error_formatter: inheritable_setting.namespace_inheritable[:default_error_formatter],
329
+ error_formatters: inheritable_setting.namespace_stackable_with_hash(:error_formatters),
330
+ rescue_options: inheritable_setting.namespace_stackable_with_hash(:rescue_options),
331
+ rescue_handlers: rescue_handlers,
332
+ base_only_rescue_handlers: inheritable_setting.namespace_stackable_with_hash(:base_only_rescue_handlers),
333
+ all_rescue_handler: inheritable_setting.namespace_inheritable[:all_rescue_handler],
334
+ grape_exceptions_rescue_handler: inheritable_setting.namespace_inheritable[:grape_exceptions_rescue_handler]
335
+
336
+ stack.concat inheritable_setting.namespace_stackable[:middleware]
337
+
338
+ if inheritable_setting.namespace_inheritable[:version].present?
339
+ stack.use Grape::Middleware::Versioner.using(inheritable_setting.namespace_inheritable[:version_options][:using]),
340
+ versions: inheritable_setting.namespace_inheritable[:version].flatten,
341
+ version_options: inheritable_setting.namespace_inheritable[:version_options],
342
+ prefix: inheritable_setting.namespace_inheritable[:root_prefix],
343
+ mount_path: inheritable_setting.namespace_stackable[:mount_path].first
399
344
  end
400
345
 
401
346
  stack.use Grape::Middleware::Formatter,
402
347
  format: format,
403
- default_format: namespace_inheritable(:default_format) || :txt,
348
+ default_format: inheritable_setting.namespace_inheritable[:default_format] || :txt,
404
349
  content_types: content_types,
405
- formatters: namespace_stackable_with_hash(:formatters),
406
- parsers: namespace_stackable_with_hash(:parsers)
350
+ formatters: inheritable_setting.namespace_stackable_with_hash(:formatters),
351
+ parsers: inheritable_setting.namespace_stackable_with_hash(:parsers)
407
352
 
408
353
  builder = stack.build
409
354
  builder.run ->(env) { env[Grape::Env::API_ENDPOINT].run }
@@ -411,10 +356,30 @@ module Grape
411
356
  end
412
357
 
413
358
  def build_helpers
414
- helpers = namespace_stackable(:helpers)
359
+ helpers = inheritable_setting.namespace_stackable[:helpers]
415
360
  return if helpers.empty?
416
361
 
417
362
  Module.new { helpers.each { |mod_to_include| include mod_to_include } }
418
363
  end
364
+
365
+ def build_response_cookies
366
+ response_cookies do |name, value|
367
+ cookie_value = value.is_a?(Hash) ? value : { value: value }
368
+ Rack::Utils.set_cookie_header! header, name, cookie_value
369
+ end
370
+ end
371
+
372
+ def lint?
373
+ inheritable_setting.namespace_inheritable[:lint] || Grape.config.lint
374
+ end
375
+
376
+ def rescue_handlers
377
+ rescue_handlers = inheritable_setting.namespace_reverse_stackable[:rescue_handlers]
378
+ return if rescue_handlers.blank?
379
+
380
+ rescue_handlers.each_with_object({}) do |rescue_handler, result|
381
+ result.merge!(rescue_handler) { |_k, s1, _s2| s1 }
382
+ end
383
+ end
419
384
  end
420
385
  end
@@ -58,6 +58,8 @@ module Grape
58
58
  raise NotImplementedError
59
59
  end
60
60
 
61
+ private
62
+
61
63
  def inherited(klass)
62
64
  super
63
65
  ErrorFormatter.register(klass)
@@ -17,7 +17,7 @@ module Grape
17
17
  end
18
18
 
19
19
  def [](index)
20
- send index
20
+ __send__ index
21
21
  end
22
22
 
23
23
  protected
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Exceptions
5
+ class ConflictingTypes < Base
6
+ def initialize
7
+ super(message: compose_message(:conflicting_types), status: 400)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Exceptions
5
+ class InvalidParameters < Base
6
+ def initialize
7
+ super(message: compose_message(:invalid_parameters), status: 400)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -9,5 +9,3 @@ module Grape
9
9
  end
10
10
  end
11
11
  end
12
-
13
- Grape::Exceptions::MissingGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::MissingGroupTypeError', 'Grape::Exceptions::MissingGroupType', Grape.deprecator)
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Exceptions
5
+ class TooDeepParameters < Base
6
+ def initialize(limit)
7
+ super(message: compose_message(:too_deep_parameters, limit: limit), status: 400)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Exceptions
5
+ class UnknownAuthStrategy < Base
6
+ def initialize(strategy:)
7
+ super(message: compose_message(:unknown_auth_strategy, strategy: strategy))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Exceptions
5
+ class UnknownParamsBuilder < Base
6
+ def initialize(params_builder_type)
7
+ super(message: compose_message(:unknown_params_builder, params_builder_type: params_builder_type))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -9,5 +9,3 @@ module Grape
9
9
  end
10
10
  end
11
11
  end
12
-
13
- Grape::Exceptions::UnsupportedGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::UnsupportedGroupTypeError', 'Grape::Exceptions::UnsupportedGroupType', Grape.deprecator)
@@ -8,11 +8,8 @@ module Grape
8
8
  extend ::ActiveSupport::Concern
9
9
 
10
10
  included do
11
- namespace_inheritable(:build_params_with, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder)
12
- end
13
-
14
- def params_builder
15
- Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
11
+ Grape.deprecator.warn 'This concern has been deprecated. Use `build_with` with one of the following short_name (:hash, :hash_with_indifferent_access, :hashie_mash) instead.'
12
+ namespace_inheritable(:build_params_with, :hash_with_indifferent_access)
16
13
  end
17
14
 
18
15
  def build_params
@@ -7,7 +7,8 @@ module Grape
7
7
  extend ::ActiveSupport::Concern
8
8
 
9
9
  included do
10
- namespace_inheritable(:build_params_with, Grape::Extensions::Hash::ParamBuilder)
10
+ Grape.deprecator.warn 'This concern has been deprecated. Use `build_with` with one of the following short_name (:hash, :hash_with_indifferent_access, :hashie_mash) instead.'
11
+ namespace_inheritable(:build_params_with, :hash)
11
12
  end
12
13
 
13
14
  def build_params
@@ -6,12 +6,10 @@ module Grape
6
6
  module Mash
7
7
  module ParamBuilder
8
8
  extend ::ActiveSupport::Concern
9
- included do
10
- namespace_inheritable(:build_params_with, Grape::Extensions::Hashie::Mash::ParamBuilder)
11
- end
12
9
 
13
- def params_builder
14
- Grape::Extensions::Hashie::Mash::ParamBuilder
10
+ included do
11
+ Grape.deprecator.warn 'This concern has been deprecated. Use `build_with` with one of the following short_name (:hash, :hash_with_indifferent_access, :hashie_mash) instead.'
12
+ namespace_inheritable(:build_params_with, :hashie_mash)
15
13
  end
16
14
 
17
15
  def build_params