grape 2.4.0 → 3.2.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 +109 -0
- data/CONTRIBUTING.md +2 -10
- data/README.md +137 -181
- data/UPGRADING.md +154 -0
- data/grape.gemspec +4 -4
- data/lib/grape/api/instance.rb +51 -104
- data/lib/grape/api.rb +29 -42
- data/lib/grape/content_types.rb +1 -4
- data/lib/grape/declared_params_handler.rb +118 -0
- data/lib/grape/dry_types.rb +48 -4
- data/lib/grape/dsl/callbacks.rb +8 -58
- data/lib/grape/dsl/declared.rb +35 -0
- data/lib/grape/dsl/desc.rb +8 -67
- data/lib/grape/dsl/helpers.rb +59 -64
- data/lib/grape/dsl/inside_route.rb +28 -189
- data/lib/grape/dsl/logger.rb +3 -6
- data/lib/grape/dsl/middleware.rb +22 -40
- data/lib/grape/dsl/parameters.rb +24 -51
- data/lib/grape/dsl/request_response.rb +136 -139
- data/lib/grape/dsl/routing.rb +240 -200
- data/lib/grape/dsl/settings.rb +23 -135
- data/lib/grape/dsl/validations.rb +38 -44
- data/lib/grape/endpoint.rb +169 -205
- data/lib/grape/error_formatter/base.rb +4 -2
- data/lib/grape/exceptions/base.rb +19 -45
- data/lib/grape/exceptions/incompatible_option_values.rb +1 -1
- data/lib/grape/exceptions/invalid_accept_header.rb +1 -1
- data/lib/grape/exceptions/invalid_formatter.rb +1 -1
- data/lib/grape/exceptions/invalid_message_body.rb +1 -1
- data/lib/grape/exceptions/invalid_version_header.rb +1 -1
- data/lib/grape/exceptions/invalid_versioner_option.rb +1 -1
- data/lib/grape/exceptions/method_not_allowed.rb +1 -1
- data/lib/grape/exceptions/missing_group_type.rb +0 -2
- data/lib/grape/exceptions/missing_mime_type.rb +1 -1
- data/lib/grape/exceptions/request_error.rb +11 -0
- data/lib/grape/exceptions/unknown_auth_strategy.rb +1 -1
- data/lib/grape/exceptions/unknown_parameter.rb +1 -1
- data/lib/grape/exceptions/unknown_params_builder.rb +1 -1
- data/lib/grape/exceptions/unknown_validator.rb +1 -1
- data/lib/grape/exceptions/unsupported_group_type.rb +0 -2
- data/lib/grape/exceptions/validation.rb +7 -4
- data/lib/grape/exceptions/validation_errors.rb +13 -7
- data/lib/grape/locale/en.yml +0 -5
- data/lib/grape/middleware/auth/base.rb +2 -0
- data/lib/grape/middleware/auth/dsl.rb +9 -10
- data/lib/grape/middleware/base.rb +6 -4
- data/lib/grape/middleware/error.rb +4 -14
- data/lib/grape/middleware/formatter.rb +11 -7
- data/lib/grape/middleware/stack.rb +3 -2
- data/lib/grape/middleware/versioner/accept_version_header.rb +3 -3
- data/lib/grape/middleware/versioner/base.rb +42 -40
- data/lib/grape/middleware/versioner/header.rb +2 -18
- data/lib/grape/middleware/versioner/param.rb +2 -2
- data/lib/grape/middleware/versioner/path.rb +2 -2
- data/lib/grape/namespace.rb +15 -8
- data/lib/grape/params_builder/base.rb +2 -0
- data/lib/grape/params_builder.rb +2 -19
- data/lib/grape/request.rb +2 -10
- data/lib/grape/router/base_route.rb +14 -5
- data/lib/grape/router/greedy_route.rb +11 -5
- data/lib/grape/router/pattern.rb +6 -20
- data/lib/grape/router/route.rb +7 -11
- data/lib/grape/router.rb +42 -65
- data/lib/grape/util/api_description.rb +58 -0
- data/lib/grape/util/base_inheritable.rb +5 -2
- data/lib/grape/util/cache.rb +1 -0
- data/lib/grape/util/deep_freeze.rb +35 -0
- data/lib/grape/util/inheritable_setting.rb +8 -1
- data/lib/grape/util/media_type.rb +2 -2
- data/lib/grape/util/registry.rb +1 -1
- data/lib/grape/util/translation.rb +42 -0
- data/lib/grape/validations/attributes_iterator.rb +35 -20
- data/lib/grape/validations/contract_scope.rb +2 -8
- data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
- data/lib/grape/validations/param_scope_tracker.rb +57 -0
- data/lib/grape/validations/params_documentation.rb +50 -0
- data/lib/grape/validations/params_scope.rb +147 -156
- data/lib/grape/validations/single_attribute_iterator.rb +2 -2
- data/lib/grape/validations/types/array_coercer.rb +2 -3
- data/lib/grape/validations/types/dry_type_coercer.rb +4 -11
- data/lib/grape/validations/types/primitive_coercer.rb +1 -28
- data/lib/grape/validations/types.rb +10 -25
- data/lib/grape/validations/validators/all_or_none_of_validator.rb +6 -3
- data/lib/grape/validations/validators/allow_blank_validator.rb +10 -5
- data/lib/grape/validations/validators/at_least_one_of_validator.rb +5 -2
- data/lib/grape/validations/validators/base.rb +95 -25
- data/lib/grape/validations/validators/coerce_validator.rb +15 -35
- data/lib/grape/validations/validators/contract_scope_validator.rb +9 -5
- data/lib/grape/validations/validators/default_validator.rb +12 -18
- data/lib/grape/validations/validators/exactly_one_of_validator.rb +10 -3
- data/lib/grape/validations/validators/except_values_validator.rb +13 -4
- data/lib/grape/validations/validators/length_validator.rb +21 -22
- data/lib/grape/validations/validators/multiple_params_base.rb +5 -5
- data/lib/grape/validations/validators/{mutual_exclusion_validator.rb → mutually_exclusive_validator.rb} +4 -2
- data/lib/grape/validations/validators/presence_validator.rb +4 -2
- data/lib/grape/validations/validators/regexp_validator.rb +11 -3
- data/lib/grape/validations/validators/same_as_validator.rb +6 -15
- data/lib/grape/validations/validators/values_validator.rb +29 -21
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +29 -23
- metadata +31 -26
- data/lib/grape/api/helpers.rb +0 -9
- data/lib/grape/dsl/api.rb +0 -17
- data/lib/grape/dsl/configuration.rb +0 -15
- data/lib/grape/exceptions/conflicting_types.rb +0 -11
- data/lib/grape/exceptions/empty_message_body.rb +0 -11
- data/lib/grape/exceptions/invalid_parameters.rb +0 -11
- data/lib/grape/exceptions/missing_option.rb +0 -11
- data/lib/grape/exceptions/too_deep_parameters.rb +0 -11
- data/lib/grape/exceptions/too_many_multipart_files.rb +0 -11
- data/lib/grape/exceptions/unknown_options.rb +0 -11
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +0 -24
- data/lib/grape/extensions/hash.rb +0 -27
- data/lib/grape/extensions/hashie/mash.rb +0 -24
- data/lib/grape/types/invalid_value.rb +0 -8
- data/lib/grape/util/strict_hash_configuration.rb +0 -108
- data/lib/grape/validations/attributes_doc.rb +0 -60
- data/lib/grape/validations/validator_factory.rb +0 -15
|
@@ -3,152 +3,10 @@
|
|
|
3
3
|
module Grape
|
|
4
4
|
module DSL
|
|
5
5
|
module InsideRoute
|
|
6
|
-
|
|
7
|
-
include Grape::DSL::Settings
|
|
8
|
-
include Grape::DSL::Headers
|
|
6
|
+
include Declared
|
|
9
7
|
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
class MethodNotYetAvailable < StandardError; end
|
|
13
|
-
|
|
14
|
-
# @param type [Symbol] The type of filter for which evaluation has been
|
|
15
|
-
# completed
|
|
16
|
-
# @return [Module] A module containing method overrides suitable for the
|
|
17
|
-
# position in the filter evaluation sequence denoted by +type+. This
|
|
18
|
-
# defaults to an empty module if no overrides are defined for the given
|
|
19
|
-
# filter +type+.
|
|
20
|
-
def self.post_filter_methods(type)
|
|
21
|
-
@post_filter_modules ||= { before: PostBeforeFilter }
|
|
22
|
-
@post_filter_modules[type]
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Methods which should not be available in filters until the before filter
|
|
26
|
-
# has completed
|
|
27
|
-
module PostBeforeFilter
|
|
28
|
-
def declared(passed_params, options = {}, declared_params = nil, params_nested_path = [])
|
|
29
|
-
options.reverse_merge!(include_missing: true, include_parent_namespaces: true, evaluate_given: false)
|
|
30
|
-
declared_params ||= optioned_declared_params(options[:include_parent_namespaces])
|
|
31
|
-
|
|
32
|
-
res = if passed_params.is_a?(Array)
|
|
33
|
-
declared_array(passed_params, options, declared_params, params_nested_path)
|
|
34
|
-
else
|
|
35
|
-
declared_hash(passed_params, options, declared_params, params_nested_path)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
if (key_maps = namespace_stackable(:contract_key_map))
|
|
39
|
-
key_maps.each { |key_map| key_map.write(passed_params, res) }
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
res
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
private
|
|
46
|
-
|
|
47
|
-
def declared_array(passed_params, options, declared_params, params_nested_path)
|
|
48
|
-
passed_params.map do |passed_param|
|
|
49
|
-
declared(passed_param || {}, options, declared_params, params_nested_path)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def declared_hash(passed_params, options, declared_params, params_nested_path)
|
|
54
|
-
declared_params.each_with_object(passed_params.class.new) do |declared_param_attr, memo|
|
|
55
|
-
next if options[:evaluate_given] && !declared_param_attr.scope.attr_meets_dependency?(passed_params)
|
|
56
|
-
|
|
57
|
-
declared_hash_attr(passed_params, options, declared_param_attr.key, params_nested_path, memo)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def declared_hash_attr(passed_params, options, declared_param, params_nested_path, memo)
|
|
62
|
-
renamed_params = route_setting(:renamed_params) || {}
|
|
63
|
-
if declared_param.is_a?(Hash)
|
|
64
|
-
declared_param.each_pair do |declared_parent_param, declared_children_params|
|
|
65
|
-
params_nested_path_dup = params_nested_path.dup
|
|
66
|
-
params_nested_path_dup << declared_parent_param.to_s
|
|
67
|
-
next unless options[:include_missing] || passed_params.key?(declared_parent_param)
|
|
68
|
-
|
|
69
|
-
rename_path = params_nested_path + [declared_parent_param.to_s]
|
|
70
|
-
renamed_param_name = renamed_params[rename_path]
|
|
71
|
-
|
|
72
|
-
memo_key = optioned_param_key(renamed_param_name || declared_parent_param, options)
|
|
73
|
-
passed_children_params = passed_params[declared_parent_param] || passed_params.class.new
|
|
74
|
-
|
|
75
|
-
memo[memo_key] = handle_passed_param(params_nested_path_dup, passed_children_params.any?) do
|
|
76
|
-
declared(passed_children_params, options, declared_children_params, params_nested_path_dup)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
else
|
|
80
|
-
# If it is not a Hash then it does not have children.
|
|
81
|
-
# Find its value or set it to nil.
|
|
82
|
-
return unless options[:include_missing] || passed_params.try(:key?, declared_param)
|
|
83
|
-
|
|
84
|
-
rename_path = params_nested_path + [declared_param.to_s]
|
|
85
|
-
renamed_param_name = renamed_params[rename_path]
|
|
86
|
-
|
|
87
|
-
memo_key = optioned_param_key(renamed_param_name || declared_param, options)
|
|
88
|
-
passed_param = passed_params[declared_param]
|
|
89
|
-
|
|
90
|
-
params_nested_path_dup = params_nested_path.dup
|
|
91
|
-
params_nested_path_dup << declared_param.to_s
|
|
92
|
-
memo[memo_key] = passed_param || handle_passed_param(params_nested_path_dup) do
|
|
93
|
-
passed_param
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def handle_passed_param(params_nested_path, has_passed_children = false, &_block)
|
|
99
|
-
return yield if has_passed_children
|
|
100
|
-
|
|
101
|
-
key = params_nested_path[0]
|
|
102
|
-
key += "[#{params_nested_path[1..].join('][')}]" if params_nested_path.size > 1
|
|
103
|
-
|
|
104
|
-
route_options_params = options[:route_options][:params] || {}
|
|
105
|
-
type = route_options_params.dig(key, :type)
|
|
106
|
-
has_children = route_options_params.keys.any? { |k| k != key && k.start_with?("#{key}[") }
|
|
107
|
-
|
|
108
|
-
if type == 'Hash' && !has_children
|
|
109
|
-
{}
|
|
110
|
-
elsif type == 'Array' || (type&.start_with?('[') && type.exclude?(','))
|
|
111
|
-
[]
|
|
112
|
-
elsif type == 'Set' || type&.start_with?('#<Set')
|
|
113
|
-
Set.new
|
|
114
|
-
else
|
|
115
|
-
yield
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def optioned_param_key(declared_param, options)
|
|
120
|
-
options[:stringify] ? declared_param.to_s : declared_param.to_sym
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def optioned_declared_params(include_parent_namespaces)
|
|
124
|
-
declared_params = if include_parent_namespaces
|
|
125
|
-
# Declared params including parent namespaces
|
|
126
|
-
route_setting(:declared_params)
|
|
127
|
-
else
|
|
128
|
-
# Declared params at current namespace
|
|
129
|
-
namespace_stackable(:declared_params).last || []
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
raise ArgumentError, 'Tried to filter for declared parameters but none exist.' unless declared_params
|
|
133
|
-
|
|
134
|
-
declared_params
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# A filtering method that will return a hash
|
|
139
|
-
# consisting only of keys that have been declared by a
|
|
140
|
-
# `params` statement against the current/target endpoint or parent
|
|
141
|
-
# namespaces.
|
|
142
|
-
#
|
|
143
|
-
# @see +PostBeforeFilter#declared+
|
|
144
|
-
#
|
|
145
|
-
# @param params [Hash] The initial hash to filter. Usually this will just be `params`
|
|
146
|
-
# @param options [Hash] Can pass `:include_missing`, `:stringify` and `:include_parent_namespaces`
|
|
147
|
-
# options. `:include_parent_namespaces` defaults to true, hence must be set to false if
|
|
148
|
-
# you want only to return params declared against the current/target endpoint.
|
|
149
|
-
def declared(*)
|
|
150
|
-
raise MethodNotYetAvailable, '#declared is not available prior to parameter validation.'
|
|
151
|
-
end
|
|
8
|
+
# Backward compatibility: alias exception class to previous location
|
|
9
|
+
MethodNotYetAvailable = Declared::MethodNotYetAvailable
|
|
152
10
|
|
|
153
11
|
# The API version as specified in the URL.
|
|
154
12
|
def version
|
|
@@ -168,32 +26,14 @@ module Grape
|
|
|
168
26
|
# @param backtrace [Array<String>] The backtrace of the exception that caused the error.
|
|
169
27
|
# @param original_exception [Exception] The original exception that caused the error.
|
|
170
28
|
def error!(message, status = nil, additional_headers = nil, backtrace = nil, original_exception = nil)
|
|
171
|
-
status = self.status(status || namespace_inheritable
|
|
29
|
+
status = self.status(status || inheritable_setting.namespace_inheritable[:default_error_status])
|
|
172
30
|
headers = additional_headers.present? ? header.merge(additional_headers) : header
|
|
173
31
|
throw :error,
|
|
174
|
-
message
|
|
175
|
-
status
|
|
176
|
-
headers
|
|
177
|
-
backtrace
|
|
178
|
-
original_exception:
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
# Creates a Rack response based on the provided message, status, and headers.
|
|
182
|
-
# The content type in the headers is set to the default content type unless provided.
|
|
183
|
-
# The message is HTML-escaped if the content type is 'text/html'.
|
|
184
|
-
#
|
|
185
|
-
# @param message [String] The content of the response.
|
|
186
|
-
# @param status [Integer] The HTTP status code.
|
|
187
|
-
# @params headers [Hash] (optional) Headers for the response
|
|
188
|
-
# (default: {Rack::CONTENT_TYPE => content_type}).
|
|
189
|
-
#
|
|
190
|
-
# Returns:
|
|
191
|
-
# A Rack::Response object containing the specified message, status, and headers.
|
|
192
|
-
#
|
|
193
|
-
def rack_response(message, status = 200, headers = { Rack::CONTENT_TYPE => content_type })
|
|
194
|
-
Grape.deprecator.warn('The rack_response method has been deprecated, use error! instead.')
|
|
195
|
-
message = Rack::Utils.escape_html(message) if headers[Rack::CONTENT_TYPE] == 'text/html'
|
|
196
|
-
Rack::Response.new(Array.wrap(message), Rack::Utils.status_code(status), headers)
|
|
32
|
+
message:,
|
|
33
|
+
status:,
|
|
34
|
+
headers:,
|
|
35
|
+
backtrace:,
|
|
36
|
+
original_exception:
|
|
197
37
|
end
|
|
198
38
|
|
|
199
39
|
# Redirect to a new url.
|
|
@@ -230,12 +70,12 @@ module Grape
|
|
|
230
70
|
when Integer
|
|
231
71
|
@status = status
|
|
232
72
|
when nil
|
|
233
|
-
return @status if
|
|
73
|
+
return @status if @status
|
|
234
74
|
|
|
235
75
|
if request.post?
|
|
236
76
|
201
|
|
237
77
|
elsif request.delete?
|
|
238
|
-
if
|
|
78
|
+
if @body.present?
|
|
239
79
|
200
|
|
240
80
|
else
|
|
241
81
|
204
|
|
@@ -274,7 +114,7 @@ module Grape
|
|
|
274
114
|
@body = ''
|
|
275
115
|
status 204
|
|
276
116
|
else
|
|
277
|
-
|
|
117
|
+
@body
|
|
278
118
|
end
|
|
279
119
|
end
|
|
280
120
|
|
|
@@ -359,8 +199,7 @@ module Grape
|
|
|
359
199
|
# with: API::Entities::User,
|
|
360
200
|
# admin: current_user.admin?
|
|
361
201
|
# end
|
|
362
|
-
def present(*args)
|
|
363
|
-
options = args.count > 1 ? args.extract_options! : {}
|
|
202
|
+
def present(*args, **options)
|
|
364
203
|
key, object = if args.count == 2 && args.first.is_a?(Symbol)
|
|
365
204
|
args
|
|
366
205
|
else
|
|
@@ -411,29 +250,29 @@ module Grape
|
|
|
411
250
|
# @return [Class] the located Entity class, or nil if none is found
|
|
412
251
|
def entity_class_for_obj(object, options)
|
|
413
252
|
entity_class = options.delete(:with)
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
entity_class ||= object_class.const_get(:Entity) if object_class.const_defined?(:Entity) && object_class.const_get(:Entity).respond_to?(:represent)
|
|
253
|
+
return entity_class if entity_class
|
|
254
|
+
|
|
255
|
+
# entity class not explicitly defined, auto-detect from relation#klass or first object in the collection
|
|
256
|
+
object_class = if object.respond_to?(:klass)
|
|
257
|
+
object.klass
|
|
258
|
+
else
|
|
259
|
+
object.respond_to?(:first) ? object.first.class : object.class
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
representations = inheritable_setting.namespace_stackable_with_hash(:representations)
|
|
263
|
+
if representations
|
|
264
|
+
potential = object_class.ancestors.detect { |potential| representations.key?(potential) }
|
|
265
|
+
entity_class = representations[potential] if potential
|
|
428
266
|
end
|
|
429
267
|
|
|
268
|
+
entity_class = object_class.const_get(:Entity) if !entity_class && object_class.const_defined?(:Entity) && object_class.const_get(:Entity).respond_to?(:represent)
|
|
430
269
|
entity_class
|
|
431
270
|
end
|
|
432
271
|
|
|
433
272
|
# @return the representation of the given object as done through
|
|
434
273
|
# the given entity_class.
|
|
435
274
|
def entity_representation_for(entity_class, object, options)
|
|
436
|
-
embeds = { env:
|
|
275
|
+
embeds = { env: }
|
|
437
276
|
embeds[:version] = env[Grape::Env::API_VERSION] if env.key?(Grape::Env::API_VERSION)
|
|
438
277
|
entity_class.represent(object, **embeds, **options)
|
|
439
278
|
end
|
data/lib/grape/dsl/logger.rb
CHANGED
|
@@ -3,18 +3,15 @@
|
|
|
3
3
|
module Grape
|
|
4
4
|
module DSL
|
|
5
5
|
module Logger
|
|
6
|
-
include Grape::DSL::Settings
|
|
7
|
-
|
|
8
|
-
attr_writer :logger
|
|
9
|
-
|
|
10
6
|
# Set or retrive the configured logger. If none was configured, this
|
|
11
7
|
# method will create a new one, logging to stdout.
|
|
12
8
|
# @param logger [Object] the new logger to use
|
|
13
9
|
def logger(logger = nil)
|
|
10
|
+
global_settings = inheritable_setting.global
|
|
14
11
|
if logger
|
|
15
|
-
|
|
12
|
+
global_settings[:logger] = logger
|
|
16
13
|
else
|
|
17
|
-
|
|
14
|
+
global_settings[:logger] || global_settings[:logger] = ::Logger.new($stdout)
|
|
18
15
|
end
|
|
19
16
|
end
|
|
20
17
|
end
|
data/lib/grape/dsl/middleware.rb
CHANGED
|
@@ -3,51 +3,33 @@
|
|
|
3
3
|
module Grape
|
|
4
4
|
module DSL
|
|
5
5
|
module Middleware
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
arr = [:use, middleware_class, *args]
|
|
19
|
-
arr << block if block
|
|
20
|
-
|
|
21
|
-
namespace_stackable(:middleware, arr)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def insert(*args, &block)
|
|
25
|
-
arr = [:insert, *args]
|
|
26
|
-
arr << block if block
|
|
27
|
-
|
|
28
|
-
namespace_stackable(:middleware, arr)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def insert_before(*args, &block)
|
|
32
|
-
arr = [:insert_before, *args]
|
|
33
|
-
arr << block if block
|
|
34
|
-
|
|
35
|
-
namespace_stackable(:middleware, arr)
|
|
36
|
-
end
|
|
6
|
+
# Apply a custom middleware to the API. Applies
|
|
7
|
+
# to the current namespace and any children, but
|
|
8
|
+
# not parents.
|
|
9
|
+
#
|
|
10
|
+
# @param middleware_class [Class] The class of the middleware you'd like
|
|
11
|
+
# to inject.
|
|
12
|
+
def use(middleware_class, *args, &block)
|
|
13
|
+
arr = [:use, middleware_class, *args]
|
|
14
|
+
arr << block if block
|
|
15
|
+
|
|
16
|
+
inheritable_setting.namespace_stackable[:middleware] = arr
|
|
17
|
+
end
|
|
37
18
|
|
|
38
|
-
|
|
39
|
-
|
|
19
|
+
%i[insert insert_before insert_after].each do |method_name|
|
|
20
|
+
define_method method_name do |*args, &block|
|
|
21
|
+
arr = [method_name, *args]
|
|
40
22
|
arr << block if block
|
|
41
23
|
|
|
42
|
-
namespace_stackable
|
|
24
|
+
inheritable_setting.namespace_stackable[:middleware] = arr
|
|
43
25
|
end
|
|
26
|
+
end
|
|
44
27
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
end
|
|
28
|
+
# Retrieve an array of the middleware classes
|
|
29
|
+
# and arguments that are currently applied to the
|
|
30
|
+
# application.
|
|
31
|
+
def middleware
|
|
32
|
+
inheritable_setting.namespace_stackable[:middleware] || []
|
|
51
33
|
end
|
|
52
34
|
end
|
|
53
35
|
end
|
data/lib/grape/dsl/parameters.rb
CHANGED
|
@@ -6,8 +6,6 @@ module Grape
|
|
|
6
6
|
# and describe the parameters accepted by an endpoint, or all endpoints
|
|
7
7
|
# within a namespace.
|
|
8
8
|
module Parameters
|
|
9
|
-
extend ActiveSupport::Concern
|
|
10
|
-
|
|
11
9
|
# Set the module used to build the request.params.
|
|
12
10
|
#
|
|
13
11
|
# @param build_with the ParamBuilder module to use when building request.params
|
|
@@ -31,7 +29,7 @@ module Grape
|
|
|
31
29
|
# end
|
|
32
30
|
# end
|
|
33
31
|
def build_with(build_with)
|
|
34
|
-
@api.namespace_inheritable
|
|
32
|
+
@api.inheritable_setting.namespace_inheritable[:build_params_with] = build_with
|
|
35
33
|
end
|
|
36
34
|
|
|
37
35
|
# Include reusable params rules among current.
|
|
@@ -55,9 +53,8 @@ module Grape
|
|
|
55
53
|
# Collection.page(params[:page]).per(params[:per_page])
|
|
56
54
|
# end
|
|
57
55
|
# end
|
|
58
|
-
def use(*names)
|
|
59
|
-
named_params = @api.namespace_stackable_with_hash(:named_params) || {}
|
|
60
|
-
options = names.extract_options!
|
|
56
|
+
def use(*names, **options)
|
|
57
|
+
named_params = @api.inheritable_setting.namespace_stackable_with_hash(:named_params) || {}
|
|
61
58
|
names.each do |name|
|
|
62
59
|
params_block = named_params.fetch(name) do
|
|
63
60
|
raise "Params :#{name} not found!"
|
|
@@ -125,18 +122,15 @@ module Grape
|
|
|
125
122
|
# requires :name, type: String
|
|
126
123
|
# end
|
|
127
124
|
# end
|
|
128
|
-
def requires(*attrs, &block)
|
|
129
|
-
orig_attrs = attrs.clone
|
|
130
|
-
|
|
131
|
-
opts = attrs.extract_options!.clone
|
|
125
|
+
def requires(*attrs, **opts, &block)
|
|
132
126
|
opts[:presence] = { value: true, message: opts[:message] }
|
|
133
|
-
opts = @group.deep_merge(opts) if
|
|
127
|
+
opts = @group.deep_merge(opts) if @group
|
|
134
128
|
|
|
135
129
|
if opts[:using]
|
|
136
|
-
require_required_and_optional_fields(attrs.first, opts)
|
|
130
|
+
require_required_and_optional_fields(attrs.first, using: opts[:using], except: opts[:except])
|
|
137
131
|
else
|
|
138
|
-
validate_attributes(attrs, opts, &block)
|
|
139
|
-
block ? new_scope(
|
|
132
|
+
validate_attributes(attrs, **opts, &block)
|
|
133
|
+
block ? new_scope(attrs.first, type: opts[:type], as: opts[:as], &block) : push_declared_params(attrs, as: opts[:as])
|
|
140
134
|
end
|
|
141
135
|
end
|
|
142
136
|
|
|
@@ -144,12 +138,9 @@ module Grape
|
|
|
144
138
|
# endpoint.
|
|
145
139
|
# @param (see #requires)
|
|
146
140
|
# @option (see #requires)
|
|
147
|
-
def optional(*attrs, &block)
|
|
148
|
-
orig_attrs = attrs.clone
|
|
149
|
-
|
|
150
|
-
opts = attrs.extract_options!.clone
|
|
141
|
+
def optional(*attrs, **opts, &block)
|
|
151
142
|
type = opts[:type]
|
|
152
|
-
opts = @group.deep_merge(opts) if
|
|
143
|
+
opts = @group.deep_merge(opts) if @group
|
|
153
144
|
|
|
154
145
|
# check type for optional parameter group
|
|
155
146
|
if attrs && block
|
|
@@ -158,44 +149,26 @@ module Grape
|
|
|
158
149
|
end
|
|
159
150
|
|
|
160
151
|
if opts[:using]
|
|
161
|
-
require_optional_fields(attrs.first, opts)
|
|
152
|
+
require_optional_fields(attrs.first, using: opts[:using], except: opts[:except])
|
|
162
153
|
else
|
|
163
|
-
validate_attributes(attrs, opts, &block)
|
|
154
|
+
validate_attributes(attrs, **opts, &block)
|
|
164
155
|
|
|
165
|
-
block ? new_scope(
|
|
156
|
+
block ? new_scope(attrs.first, type: opts[:type], as: opts[:as], optional: true, &block) : push_declared_params(attrs, as: opts[:as])
|
|
166
157
|
end
|
|
167
158
|
end
|
|
168
159
|
|
|
169
160
|
# Define common settings for one or more parameters
|
|
170
161
|
# @param (see #requires)
|
|
171
162
|
# @option (see #requires)
|
|
172
|
-
def with(
|
|
173
|
-
new_group_attrs =
|
|
174
|
-
new_group_scope(
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# Disallow the given parameters to be present in the same request.
|
|
178
|
-
# @param attrs [*Symbol] parameters to validate
|
|
179
|
-
def mutually_exclusive(*attrs)
|
|
180
|
-
validates(attrs, mutual_exclusion: { value: true, message: extract_message_option(attrs) })
|
|
163
|
+
def with(**opts, &)
|
|
164
|
+
new_group_attrs = @group&.deep_merge(opts) || opts
|
|
165
|
+
new_group_scope(new_group_attrs, &)
|
|
181
166
|
end
|
|
182
167
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
# Require at least one of the given parameters to be present.
|
|
190
|
-
# @param (see #mutually_exclusive)
|
|
191
|
-
def at_least_one_of(*attrs)
|
|
192
|
-
validates(attrs, at_least_one_of: { value: true, message: extract_message_option(attrs) })
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
# Require that either all given params are present, or none are.
|
|
196
|
-
# @param (see #mutually_exclusive)
|
|
197
|
-
def all_or_none_of(*attrs)
|
|
198
|
-
validates(attrs, all_or_none_of: { value: true, message: extract_message_option(attrs) })
|
|
168
|
+
%i[mutually_exclusive exactly_one_of at_least_one_of all_or_none_of].each do |validator|
|
|
169
|
+
define_method validator do |*attrs, message: nil|
|
|
170
|
+
validates(attrs, validator => { value: true, message: })
|
|
171
|
+
end
|
|
199
172
|
end
|
|
200
173
|
|
|
201
174
|
# Define a block of validations which should be applied if and only if
|
|
@@ -205,12 +178,12 @@ module Grape
|
|
|
205
178
|
# @raise Grape::Exceptions::UnknownParameter if `attr` has not been
|
|
206
179
|
# defined in this scope yet
|
|
207
180
|
# @yield a parameter definition DSL
|
|
208
|
-
def given(*attrs, &
|
|
181
|
+
def given(*attrs, &)
|
|
209
182
|
attrs.each do |attr|
|
|
210
183
|
proxy_attr = first_hash_key_or_param(attr)
|
|
211
184
|
raise Grape::Exceptions::UnknownParameter.new(proxy_attr) unless declared_param?(proxy_attr)
|
|
212
185
|
end
|
|
213
|
-
new_lateral_scope(dependent_on: attrs, &
|
|
186
|
+
new_lateral_scope(dependent_on: attrs, &)
|
|
214
187
|
end
|
|
215
188
|
|
|
216
189
|
# Test for whether a certain parameter has been defined in this params
|
|
@@ -251,8 +224,8 @@ module Grape
|
|
|
251
224
|
# @return hash of parameters relevant for the current scope
|
|
252
225
|
# @api private
|
|
253
226
|
def params(params)
|
|
254
|
-
params = @parent.
|
|
255
|
-
params = map_params(params, @element) if
|
|
227
|
+
params = @parent.qualifying_params.presence || @parent.params(params) if @parent
|
|
228
|
+
params = map_params(params, @element) if @element
|
|
256
229
|
params
|
|
257
230
|
end
|
|
258
231
|
|