grape 1.1.0 → 1.5.3
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 +278 -44
- data/LICENSE +1 -1
- data/README.md +514 -69
- data/UPGRADING.md +424 -17
- data/grape.gemspec +13 -2
- data/lib/grape.rb +104 -71
- data/lib/grape/api.rb +138 -175
- data/lib/grape/api/helpers.rb +2 -0
- data/lib/grape/api/instance.rb +283 -0
- data/lib/grape/config.rb +34 -0
- data/lib/grape/content_types.rb +34 -0
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dsl/api.rb +2 -0
- data/lib/grape/dsl/callbacks.rb +22 -0
- data/lib/grape/dsl/configuration.rb +2 -0
- data/lib/grape/dsl/desc.rb +41 -7
- data/lib/grape/dsl/headers.rb +2 -0
- data/lib/grape/dsl/helpers.rb +5 -2
- data/lib/grape/dsl/inside_route.rb +92 -49
- data/lib/grape/dsl/logger.rb +2 -0
- data/lib/grape/dsl/middleware.rb +9 -0
- data/lib/grape/dsl/parameters.rb +25 -14
- data/lib/grape/dsl/request_response.rb +4 -2
- data/lib/grape/dsl/routing.rb +17 -10
- data/lib/grape/dsl/settings.rb +7 -1
- data/lib/grape/dsl/validations.rb +24 -4
- data/lib/grape/eager_load.rb +20 -0
- data/lib/grape/endpoint.rb +59 -35
- data/lib/grape/error_formatter.rb +4 -2
- data/lib/grape/error_formatter/base.rb +2 -0
- data/lib/grape/error_formatter/json.rb +2 -0
- data/lib/grape/error_formatter/txt.rb +2 -0
- data/lib/grape/error_formatter/xml.rb +2 -0
- data/lib/grape/exceptions/base.rb +20 -14
- data/lib/grape/exceptions/empty_message_body.rb +11 -0
- data/lib/grape/exceptions/incompatible_option_values.rb +2 -0
- data/lib/grape/exceptions/invalid_accept_header.rb +2 -0
- data/lib/grape/exceptions/invalid_formatter.rb +2 -0
- data/lib/grape/exceptions/invalid_message_body.rb +2 -0
- data/lib/grape/exceptions/invalid_response.rb +11 -0
- data/lib/grape/exceptions/invalid_version_header.rb +2 -0
- data/lib/grape/exceptions/invalid_versioner_option.rb +2 -0
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +2 -0
- data/lib/grape/exceptions/method_not_allowed.rb +2 -0
- data/lib/grape/exceptions/missing_group_type.rb +2 -0
- data/lib/grape/exceptions/missing_mime_type.rb +2 -0
- data/lib/grape/exceptions/missing_option.rb +2 -0
- data/lib/grape/exceptions/missing_vendor_option.rb +2 -0
- data/lib/grape/exceptions/unknown_options.rb +2 -0
- data/lib/grape/exceptions/unknown_parameter.rb +2 -0
- data/lib/grape/exceptions/unknown_validator.rb +2 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +2 -0
- data/lib/grape/exceptions/validation.rb +4 -2
- data/lib/grape/exceptions/validation_array_errors.rb +2 -0
- data/lib/grape/exceptions/validation_errors.rb +16 -13
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +4 -3
- data/lib/grape/extensions/deep_mergeable_hash.rb +2 -0
- data/lib/grape/extensions/deep_symbolize_hash.rb +2 -0
- data/lib/grape/extensions/hash.rb +2 -0
- data/lib/grape/extensions/hashie/mash.rb +2 -0
- data/lib/grape/formatter.rb +5 -3
- data/lib/grape/formatter/json.rb +2 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -0
- data/lib/grape/formatter/txt.rb +2 -0
- data/lib/grape/formatter/xml.rb +2 -0
- data/lib/grape/http/headers.rb +50 -18
- data/lib/grape/locale/en.yml +3 -1
- data/lib/grape/middleware/auth/base.rb +7 -7
- data/lib/grape/middleware/auth/dsl.rb +2 -0
- data/lib/grape/middleware/auth/strategies.rb +2 -0
- data/lib/grape/middleware/auth/strategy_info.rb +2 -0
- data/lib/grape/middleware/base.rb +10 -7
- data/lib/grape/middleware/error.rb +21 -16
- data/lib/grape/middleware/filter.rb +2 -0
- data/lib/grape/middleware/formatter.rb +8 -6
- data/lib/grape/middleware/globals.rb +2 -0
- data/lib/grape/middleware/helpers.rb +12 -0
- data/lib/grape/middleware/stack.rb +13 -3
- data/lib/grape/middleware/versioner.rb +2 -0
- data/lib/grape/middleware/versioner/accept_version_header.rb +2 -0
- data/lib/grape/middleware/versioner/header.rb +10 -8
- data/lib/grape/middleware/versioner/param.rb +3 -1
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +4 -1
- data/lib/grape/middleware/versioner/path.rb +3 -1
- data/lib/grape/namespace.rb +14 -2
- data/lib/grape/parser.rb +4 -2
- data/lib/grape/parser/json.rb +3 -1
- data/lib/grape/parser/xml.rb +3 -1
- data/lib/grape/path.rb +15 -3
- data/lib/grape/presenters/presenter.rb +2 -0
- data/lib/grape/request.rb +19 -10
- data/lib/grape/router.rb +30 -29
- data/lib/grape/router/attribute_translator.rb +41 -8
- data/lib/grape/router/pattern.rb +20 -16
- data/lib/grape/router/route.rb +14 -28
- data/lib/grape/{serve_file → serve_stream}/file_body.rb +3 -1
- data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +3 -1
- data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +10 -8
- data/lib/grape/util/base_inheritable.rb +43 -0
- data/lib/grape/util/cache.rb +20 -0
- data/lib/grape/util/endpoint_configuration.rb +8 -0
- data/lib/grape/util/env.rb +19 -17
- data/lib/grape/util/inheritable_setting.rb +2 -0
- data/lib/grape/util/inheritable_values.rb +7 -25
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/util/lazy_block.rb +27 -0
- data/lib/grape/util/lazy_object.rb +43 -0
- data/lib/grape/util/lazy_value.rb +98 -0
- data/lib/grape/util/registrable.rb +2 -0
- data/lib/grape/util/reverse_stackable_values.rb +10 -35
- data/lib/grape/util/stackable_values.rb +21 -34
- data/lib/grape/util/strict_hash_configuration.rb +2 -0
- data/lib/grape/util/xml.rb +2 -0
- data/lib/grape/validations.rb +2 -0
- data/lib/grape/validations/attributes_iterator.rb +16 -6
- data/lib/grape/validations/multiple_attributes_iterator.rb +13 -0
- data/lib/grape/validations/params_scope.rb +51 -30
- data/lib/grape/validations/single_attribute_iterator.rb +24 -0
- data/lib/grape/validations/types.rb +13 -38
- data/lib/grape/validations/types/array_coercer.rb +65 -0
- data/lib/grape/validations/types/build_coercer.rb +47 -49
- data/lib/grape/validations/types/custom_type_coercer.rb +29 -51
- data/lib/grape/validations/types/custom_type_collection_coercer.rb +10 -25
- data/lib/grape/validations/types/dry_type_coercer.rb +76 -0
- data/lib/grape/validations/types/file.rb +22 -18
- data/lib/grape/validations/types/invalid_value.rb +24 -0
- data/lib/grape/validations/types/json.rb +46 -39
- data/lib/grape/validations/types/multiple_type_coercer.rb +14 -33
- data/lib/grape/validations/types/primitive_coercer.rb +67 -0
- data/lib/grape/validations/types/set_coercer.rb +40 -0
- data/lib/grape/validations/types/variant_collection_coercer.rb +5 -13
- data/lib/grape/validations/validator_factory.rb +8 -11
- data/lib/grape/validations/validators/all_or_none.rb +8 -13
- data/lib/grape/validations/validators/allow_blank.rb +3 -1
- data/lib/grape/validations/validators/as.rb +5 -4
- data/lib/grape/validations/validators/at_least_one_of.rb +7 -13
- data/lib/grape/validations/validators/base.rb +20 -16
- data/lib/grape/validations/validators/coerce.rb +46 -29
- data/lib/grape/validations/validators/default.rb +6 -6
- data/lib/grape/validations/validators/exactly_one_of.rb +10 -23
- data/lib/grape/validations/validators/except_values.rb +4 -2
- data/lib/grape/validations/validators/multiple_params_base.rb +17 -10
- data/lib/grape/validations/validators/mutual_exclusion.rb +8 -18
- data/lib/grape/validations/validators/presence.rb +3 -1
- data/lib/grape/validations/validators/regexp.rb +4 -2
- data/lib/grape/validations/validators/same_as.rb +26 -0
- data/lib/grape/validations/validators/values.rb +18 -6
- data/lib/grape/version.rb +3 -1
- data/spec/grape/api/custom_validations_spec.rb +5 -3
- data/spec/grape/api/deeply_included_options_spec.rb +2 -0
- data/spec/grape/api/defines_boolean_in_params_spec.rb +39 -0
- data/spec/grape/api/inherited_helpers_spec.rb +2 -0
- data/spec/grape/api/instance_spec.rb +104 -0
- data/spec/grape/api/invalid_format_spec.rb +2 -0
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +2 -0
- data/spec/grape/api/nested_helpers_spec.rb +2 -0
- data/spec/grape/api/optional_parameters_in_route_spec.rb +2 -0
- data/spec/grape/api/parameters_modification_spec.rb +3 -1
- data/spec/grape/api/patch_method_helpers_spec.rb +2 -0
- data/spec/grape/api/recognize_path_spec.rb +2 -0
- data/spec/grape/api/required_parameters_in_route_spec.rb +2 -0
- data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +2 -0
- data/spec/grape/api/routes_with_requirements_spec.rb +61 -0
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +2 -0
- data/spec/grape/api/shared_helpers_spec.rb +2 -0
- data/spec/grape/api_remount_spec.rb +473 -0
- data/spec/grape/api_spec.rb +565 -12
- data/spec/grape/config_spec.rb +19 -0
- data/spec/grape/dsl/callbacks_spec.rb +2 -0
- data/spec/grape/dsl/configuration_spec.rb +2 -0
- data/spec/grape/dsl/desc_spec.rb +42 -16
- data/spec/grape/dsl/headers_spec.rb +2 -0
- data/spec/grape/dsl/helpers_spec.rb +4 -2
- data/spec/grape/dsl/inside_route_spec.rb +184 -33
- data/spec/grape/dsl/logger_spec.rb +2 -0
- data/spec/grape/dsl/middleware_spec.rb +10 -0
- data/spec/grape/dsl/parameters_spec.rb +2 -0
- data/spec/grape/dsl/request_response_spec.rb +2 -0
- data/spec/grape/dsl/routing_spec.rb +12 -0
- data/spec/grape/dsl/settings_spec.rb +2 -0
- data/spec/grape/dsl/validations_spec.rb +2 -0
- data/spec/grape/endpoint/declared_spec.rb +601 -0
- data/spec/grape/endpoint_spec.rb +53 -523
- data/spec/grape/entity_spec.rb +9 -1
- data/spec/grape/exceptions/base_spec.rb +67 -0
- data/spec/grape/exceptions/body_parse_errors_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_formatter_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_response_spec.rb +13 -0
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +2 -0
- data/spec/grape/exceptions/missing_mime_type_spec.rb +2 -0
- data/spec/grape/exceptions/missing_option_spec.rb +2 -0
- data/spec/grape/exceptions/unknown_options_spec.rb +2 -0
- data/spec/grape/exceptions/unknown_validator_spec.rb +2 -0
- data/spec/grape/exceptions/validation_errors_spec.rb +8 -4
- data/spec/grape/exceptions/validation_spec.rb +3 -1
- data/spec/grape/extensions/param_builders/hash_spec.rb +2 -0
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +2 -0
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +2 -0
- data/spec/grape/integration/global_namespace_function_spec.rb +2 -0
- data/spec/grape/integration/rack_sendfile_spec.rb +14 -8
- data/spec/grape/integration/rack_spec.rb +25 -7
- data/spec/grape/loading_spec.rb +2 -0
- data/spec/grape/middleware/auth/base_spec.rb +2 -0
- data/spec/grape/middleware/auth/dsl_spec.rb +5 -3
- data/spec/grape/middleware/auth/strategies_spec.rb +3 -1
- data/spec/grape/middleware/base_spec.rb +10 -0
- data/spec/grape/middleware/error_spec.rb +3 -1
- data/spec/grape/middleware/exception_spec.rb +4 -2
- data/spec/grape/middleware/formatter_spec.rb +33 -16
- data/spec/grape/middleware/globals_spec.rb +2 -0
- data/spec/grape/middleware/stack_spec.rb +12 -0
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +3 -1
- data/spec/grape/middleware/versioner/header_spec.rb +9 -1
- data/spec/grape/middleware/versioner/param_spec.rb +3 -1
- data/spec/grape/middleware/versioner/path_spec.rb +3 -1
- data/spec/grape/middleware/versioner_spec.rb +2 -0
- data/spec/grape/named_api_spec.rb +21 -0
- data/spec/grape/parser_spec.rb +7 -5
- data/spec/grape/path_spec.rb +6 -4
- data/spec/grape/presenters/presenter_spec.rb +2 -0
- data/spec/grape/request_spec.rb +26 -0
- data/spec/grape/util/inheritable_setting_spec.rb +2 -0
- data/spec/grape/util/inheritable_values_spec.rb +2 -0
- data/spec/grape/util/reverse_stackable_values_spec.rb +2 -0
- data/spec/grape/util/stackable_values_spec.rb +3 -1
- data/spec/grape/util/strict_hash_configuration_spec.rb +2 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +2 -0
- data/spec/grape/validations/instance_behaivour_spec.rb +5 -3
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +41 -0
- data/spec/grape/validations/params_scope_spec.rb +213 -9
- data/spec/grape/validations/single_attribute_iterator_spec.rb +58 -0
- data/spec/grape/validations/types/array_coercer_spec.rb +35 -0
- data/spec/grape/validations/types/primitive_coercer_spec.rb +135 -0
- data/spec/grape/validations/types/set_coercer_spec.rb +34 -0
- data/spec/grape/validations/types_spec.rb +9 -36
- data/spec/grape/validations/validators/all_or_none_spec.rb +140 -30
- data/spec/grape/validations/validators/allow_blank_spec.rb +2 -0
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +175 -29
- data/spec/grape/validations/validators/coerce_spec.rb +476 -135
- data/spec/grape/validations/validators/default_spec.rb +172 -0
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +204 -38
- data/spec/grape/validations/validators/except_values_spec.rb +4 -1
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +186 -27
- data/spec/grape/validations/validators/presence_spec.rb +30 -0
- data/spec/grape/validations/validators/regexp_spec.rb +2 -0
- data/spec/grape/validations/validators/same_as_spec.rb +65 -0
- data/spec/grape/validations/validators/values_spec.rb +30 -5
- data/spec/grape/validations_spec.rb +388 -50
- data/spec/integration/eager_load/eager_load_spec.rb +15 -0
- data/spec/integration/multi_json/json_spec.rb +2 -0
- data/spec/integration/multi_xml/xml_spec.rb +2 -0
- data/spec/shared/versioning_examples.rb +22 -20
- data/spec/spec_helper.rb +12 -1
- data/spec/support/basic_auth_encode_helpers.rb +2 -0
- data/spec/support/chunks.rb +14 -0
- data/spec/support/content_type_helpers.rb +2 -0
- data/spec/support/eager_load.rb +19 -0
- data/spec/support/endpoint_faker.rb +2 -0
- data/spec/support/file_streamer.rb +2 -0
- data/spec/support/integer_helpers.rb +2 -0
- data/spec/support/versioned_helpers.rb +8 -8
- metadata +86 -48
- data/Appraisals +0 -32
- data/Dangerfile +0 -2
- data/Gemfile +0 -33
- data/Gemfile.lock +0 -231
- data/Guardfile +0 -10
- data/RELEASING.md +0 -111
- data/Rakefile +0 -25
- data/benchmark/simple.rb +0 -27
- data/benchmark/simple_with_type_coercer.rb +0 -22
- data/gemfiles/multi_json.gemfile +0 -35
- data/gemfiles/multi_xml.gemfile +0 -35
- data/gemfiles/rack_1.5.2.gemfile +0 -35
- data/gemfiles/rack_edge.gemfile +0 -35
- data/gemfiles/rails_3.gemfile +0 -36
- data/gemfiles/rails_4.gemfile +0 -35
- data/gemfiles/rails_5.gemfile +0 -35
- data/gemfiles/rails_edge.gemfile +0 -35
- data/lib/grape/extensions/deep_hash_with_indifferent_access.rb +0 -18
- data/lib/grape/util/content_types.rb +0 -26
- data/lib/grape/validations/types/virtus_collection_patch.rb +0 -16
- data/pkg/grape-0.17.0.gem +0 -0
- data/pkg/grape-0.19.0.gem +0 -0
data/lib/grape/dsl/routing.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/concern'
|
2
4
|
|
3
5
|
module Grape
|
@@ -49,7 +51,7 @@ module Grape
|
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
52
|
-
@versions.last
|
54
|
+
@versions.last if instance_variable_defined?(:@versions) && @versions
|
53
55
|
end
|
54
56
|
|
55
57
|
# Define a root URL prefix for your entire API.
|
@@ -77,9 +79,14 @@ module Grape
|
|
77
79
|
namespace_inheritable(:do_not_route_options, true)
|
78
80
|
end
|
79
81
|
|
80
|
-
def mount(mounts)
|
82
|
+
def mount(mounts, *opts)
|
81
83
|
mounts = { mounts => '/' } unless mounts.respond_to?(:each_pair)
|
82
84
|
mounts.each_pair do |app, path|
|
85
|
+
if app.respond_to?(:mount_instance)
|
86
|
+
opts_with = opts.any? ? opts.shift[:with] : {}
|
87
|
+
mount({ app.mount_instance(configuration: opts_with) => path })
|
88
|
+
next
|
89
|
+
end
|
83
90
|
in_setting = inheritable_setting
|
84
91
|
|
85
92
|
if app.respond_to?(:inheritable_setting, true)
|
@@ -136,16 +143,16 @@ module Grape
|
|
136
143
|
reset_validations!
|
137
144
|
end
|
138
145
|
|
139
|
-
|
140
|
-
define_method
|
146
|
+
Grape::Http::Headers::SUPPORTED_METHODS.each do |supported_method|
|
147
|
+
define_method supported_method.downcase do |*args, &block|
|
141
148
|
options = args.extract_options!
|
142
149
|
paths = args.first || ['/']
|
143
|
-
route(
|
150
|
+
route(supported_method, paths, options, &block)
|
144
151
|
end
|
145
152
|
end
|
146
153
|
|
147
154
|
# Declare a "namespace", which prefixes all subordinate routes with its
|
148
|
-
# name. Any endpoints within a namespace,
|
155
|
+
# name. Any endpoints within a namespace, group, resource or segment,
|
149
156
|
# etc., will share their parent context as well as any configuration
|
150
157
|
# done in the namespace context.
|
151
158
|
#
|
@@ -157,14 +164,14 @@ module Grape
|
|
157
164
|
# end
|
158
165
|
# end
|
159
166
|
def namespace(space = nil, options = {}, &block)
|
167
|
+
@namespace_description = nil unless instance_variable_defined?(:@namespace_description) && @namespace_description
|
168
|
+
|
160
169
|
if space || block_given?
|
161
170
|
within_namespace do
|
162
171
|
previous_namespace_description = @namespace_description
|
163
172
|
@namespace_description = (@namespace_description || {}).deep_merge(namespace_setting(:description) || {})
|
164
173
|
nest(block) do
|
165
|
-
if space
|
166
|
-
namespace_stackable(:namespace, Namespace.new(space, options))
|
167
|
-
end
|
174
|
+
namespace_stackable(:namespace, Namespace.new(space, **options)) if space
|
168
175
|
end
|
169
176
|
@namespace_description = previous_namespace_description
|
170
177
|
end
|
@@ -193,7 +200,7 @@ module Grape
|
|
193
200
|
@endpoints = []
|
194
201
|
end
|
195
202
|
|
196
|
-
#
|
203
|
+
# This method allows you to quickly define a parameter route segment
|
197
204
|
# in your API.
|
198
205
|
#
|
199
206
|
# @param param [Symbol] The name of the parameter you wish to declare.
|
data/lib/grape/dsl/settings.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/concern'
|
2
4
|
|
3
5
|
module Grape
|
@@ -169,7 +171,11 @@ module Grape
|
|
169
171
|
# the superclass's :inheritable_setting.
|
170
172
|
def build_top_level_setting
|
171
173
|
Grape::Util::InheritableSetting.new.tap do |setting|
|
172
|
-
|
174
|
+
# Doesn't try to inherit settings from +Grape::API::Instance+ which also responds to
|
175
|
+
# +inheritable_setting+, however, it doesn't contain any user-defined settings.
|
176
|
+
# Otherwise, it would lead to an extra instance of +Grape::Util::InheritableSetting+
|
177
|
+
# in the chain for every endpoint.
|
178
|
+
if defined?(superclass) && superclass.respond_to?(:inheritable_setting) && superclass != Grape::API::Instance
|
173
179
|
setting.inherit_from superclass.inheritable_setting
|
174
180
|
end
|
175
181
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/concern'
|
2
4
|
|
3
5
|
module Grape
|
@@ -8,7 +10,24 @@ module Grape
|
|
8
10
|
include Grape::DSL::Configuration
|
9
11
|
|
10
12
|
module ClassMethods
|
11
|
-
# Clears all defined parameters and validations.
|
13
|
+
# Clears all defined parameters and validations. The main purpose of it is to clean up
|
14
|
+
# settings, so next endpoint won't interfere with previous one.
|
15
|
+
#
|
16
|
+
# params do
|
17
|
+
# # params for the endpoint below this block
|
18
|
+
# end
|
19
|
+
# post '/current' do
|
20
|
+
# # whatever
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# # somewhere between them the reset_validations! method gets called
|
24
|
+
#
|
25
|
+
# params do
|
26
|
+
# # params for the endpoint below this block
|
27
|
+
# end
|
28
|
+
# post '/next' do
|
29
|
+
# # whatever
|
30
|
+
# end
|
12
31
|
def reset_validations!
|
13
32
|
unset_namespace_stackable :declared_params
|
14
33
|
unset_namespace_stackable :validations
|
@@ -27,10 +46,11 @@ module Grape
|
|
27
46
|
setting = description_field(:params)
|
28
47
|
setting ||= description_field(:params, {})
|
29
48
|
Array(names).each do |name|
|
30
|
-
|
31
|
-
setting[
|
49
|
+
full_name = name[:full_name].to_s
|
50
|
+
setting[full_name] ||= {}
|
51
|
+
setting[full_name].merge!(opts)
|
32
52
|
|
33
|
-
namespace_stackable(:params,
|
53
|
+
namespace_stackable(:params, full_name => opts)
|
34
54
|
end
|
35
55
|
end
|
36
56
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Grape.eager_load!
|
4
|
+
Grape::Http.eager_load!
|
5
|
+
Grape::Exceptions.eager_load!
|
6
|
+
Grape::Extensions.eager_load!
|
7
|
+
Grape::Extensions::ActiveSupport.eager_load!
|
8
|
+
Grape::Extensions::Hashie.eager_load!
|
9
|
+
Grape::Middleware.eager_load!
|
10
|
+
Grape::Middleware::Auth.eager_load!
|
11
|
+
Grape::Middleware::Versioner.eager_load!
|
12
|
+
Grape::Util.eager_load!
|
13
|
+
Grape::ErrorFormatter.eager_load!
|
14
|
+
Grape::Formatter.eager_load!
|
15
|
+
Grape::Parser.eager_load!
|
16
|
+
Grape::DSL.eager_load!
|
17
|
+
Grape::API.eager_load!
|
18
|
+
Grape::Presenters.eager_load!
|
19
|
+
Grape::ServeStream.eager_load!
|
20
|
+
Rack::Head # AutoLoads the Rack::Head
|
data/lib/grape/endpoint.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
# An Endpoint is the proxy scope in which all routing
|
3
5
|
# blocks are executed. In other words, any methods
|
@@ -78,7 +80,10 @@ module Grape
|
|
78
80
|
|
79
81
|
self.inheritable_setting = new_settings.point_in_time_copy
|
80
82
|
|
81
|
-
|
83
|
+
# now +namespace_stackable(:declared_params)+ contains all params defined for
|
84
|
+
# this endpoint and its parents, but later it will be cleaned up,
|
85
|
+
# see +reset_validations!+ in lib/grape/dsl/validations.rb
|
86
|
+
route_setting(:declared_params, namespace_stackable(:declared_params).flatten)
|
82
87
|
route_setting(:saved_validations, namespace_stackable(:validations))
|
83
88
|
|
84
89
|
namespace_stackable(:representations, []) unless namespace_stackable(:representations)
|
@@ -97,7 +102,7 @@ module Grape
|
|
97
102
|
@block = nil
|
98
103
|
|
99
104
|
@status = nil
|
100
|
-
@
|
105
|
+
@stream = nil
|
101
106
|
@body = nil
|
102
107
|
@proc = nil
|
103
108
|
|
@@ -114,7 +119,6 @@ module Grape
|
|
114
119
|
parent_declared_params = namespace_stackable[:declared_params]
|
115
120
|
|
116
121
|
if parent_declared_params
|
117
|
-
inheritable_setting.route[:declared_params] ||= []
|
118
122
|
inheritable_setting.route[:declared_params].concat(parent_declared_params.flatten)
|
119
123
|
end
|
120
124
|
|
@@ -154,8 +158,8 @@ module Grape
|
|
154
158
|
methods << Grape::Http::Headers::HEAD
|
155
159
|
end
|
156
160
|
methods.each do |method|
|
157
|
-
unless route.request_method
|
158
|
-
route = Grape::Router::Route.new(method, route.origin, route.attributes.to_h)
|
161
|
+
unless route.request_method == method
|
162
|
+
route = Grape::Router::Route.new(method, route.origin, **route.attributes.to_h)
|
159
163
|
end
|
160
164
|
router.append(route.apply(self))
|
161
165
|
end
|
@@ -167,8 +171,8 @@ module Grape
|
|
167
171
|
route_options = prepare_default_route_attributes
|
168
172
|
map_routes do |method, path|
|
169
173
|
path = prepare_path(path)
|
170
|
-
params = merge_route_options(route_options.merge(suffix: path.suffix))
|
171
|
-
route = Router::Route.new(method, path.path, params)
|
174
|
+
params = merge_route_options(**route_options.merge(suffix: path.suffix))
|
175
|
+
route = Router::Route.new(method, path.path, **params)
|
172
176
|
route.apply(self)
|
173
177
|
end.flatten
|
174
178
|
end
|
@@ -188,7 +192,7 @@ module Grape
|
|
188
192
|
requirements: prepare_routes_requirements,
|
189
193
|
prefix: namespace_inheritable(:root_prefix),
|
190
194
|
anchor: options[:route_options].fetch(:anchor, true),
|
191
|
-
settings: inheritable_setting.route.except(:
|
195
|
+
settings: inheritable_setting.route.except(:declared_params, :saved_validations),
|
192
196
|
forward_match: options[:forward_match]
|
193
197
|
}
|
194
198
|
end
|
@@ -200,7 +204,7 @@ module Grape
|
|
200
204
|
end
|
201
205
|
|
202
206
|
def merge_route_options(**default)
|
203
|
-
options[:route_options].clone.
|
207
|
+
options[:route_options].clone.merge!(**default)
|
204
208
|
end
|
205
209
|
|
206
210
|
def map_routes
|
@@ -245,32 +249,37 @@ module Grape
|
|
245
249
|
@request = Grape::Request.new(env, build_params_with: namespace_inheritable(:build_params_with))
|
246
250
|
@params = @request.params
|
247
251
|
@headers = @request.headers
|
252
|
+
begin
|
253
|
+
cookies.read(@request)
|
254
|
+
self.class.run_before_each(self)
|
255
|
+
run_filters befores, :before
|
256
|
+
|
257
|
+
if (allowed_methods = env[Grape::Env::GRAPE_ALLOWED_METHODS])
|
258
|
+
raise Grape::Exceptions::MethodNotAllowed.new(header.merge('Allow' => allowed_methods)) unless options?
|
259
|
+
header 'Allow', allowed_methods
|
260
|
+
response_object = ''
|
261
|
+
status 204
|
262
|
+
else
|
263
|
+
run_filters before_validations, :before_validation
|
264
|
+
run_validators validations, request
|
265
|
+
remove_renamed_params
|
266
|
+
run_filters after_validations, :after_validation
|
267
|
+
response_object = execute
|
268
|
+
end
|
248
269
|
|
249
|
-
|
250
|
-
|
251
|
-
run_filters befores, :before
|
270
|
+
run_filters afters, :after
|
271
|
+
cookies.write(header)
|
252
272
|
|
253
|
-
|
254
|
-
|
255
|
-
header 'Allow', allowed_methods
|
256
|
-
response_object = ''
|
257
|
-
status 204
|
258
|
-
else
|
259
|
-
run_filters before_validations, :before_validation
|
260
|
-
run_validators validations, request
|
261
|
-
run_filters after_validations, :after_validation
|
262
|
-
response_object = @block ? @block.call(self) : nil
|
263
|
-
end
|
273
|
+
# status verifies body presence when DELETE
|
274
|
+
@body ||= response_object
|
264
275
|
|
265
|
-
|
266
|
-
|
276
|
+
# The body commonly is an Array of Strings, the application instance itself, or a Stream-like object
|
277
|
+
response_object = stream || [body]
|
267
278
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
response_object = file || [body]
|
273
|
-
[status, header, response_object]
|
279
|
+
[status, header, response_object]
|
280
|
+
ensure
|
281
|
+
run_filters finallies, :finally
|
282
|
+
end
|
274
283
|
end
|
275
284
|
end
|
276
285
|
|
@@ -319,7 +328,18 @@ module Grape
|
|
319
328
|
Module.new { helpers.each { |mod_to_include| include mod_to_include } }
|
320
329
|
end
|
321
330
|
|
322
|
-
|
331
|
+
def remove_renamed_params
|
332
|
+
return unless route_setting(:renamed_params)
|
333
|
+
route_setting(:renamed_params).flat_map(&:keys).each do |renamed_param|
|
334
|
+
@params.delete(renamed_param)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
private :build_stack, :build_helpers, :remove_renamed_params
|
339
|
+
|
340
|
+
def execute
|
341
|
+
@block ? @block.call(self) : nil
|
342
|
+
end
|
323
343
|
|
324
344
|
def helpers
|
325
345
|
lazy_initialize! && @helpers
|
@@ -341,7 +361,7 @@ module Grape
|
|
341
361
|
def run_validators(validator_factories, request)
|
342
362
|
validation_errors = []
|
343
363
|
|
344
|
-
validators = validator_factories.map(
|
364
|
+
validators = validator_factories.map { |options| Grape::Validations::ValidatorFactory.create_validator(**options) }
|
345
365
|
|
346
366
|
ActiveSupport::Notifications.instrument('endpoint_run_validators.grape', endpoint: self, validators: validators, request: request) do
|
347
367
|
validators.each do |validator|
|
@@ -351,13 +371,13 @@ module Grape
|
|
351
371
|
validation_errors << e
|
352
372
|
break if validator.fail_fast?
|
353
373
|
rescue Grape::Exceptions::ValidationArrayErrors => e
|
354
|
-
validation_errors
|
374
|
+
validation_errors.concat e.errors
|
355
375
|
break if validator.fail_fast?
|
356
376
|
end
|
357
377
|
end
|
358
378
|
end
|
359
379
|
|
360
|
-
validation_errors.any? && raise(Grape::Exceptions::ValidationErrors
|
380
|
+
validation_errors.any? && raise(Grape::Exceptions::ValidationErrors.new(errors: validation_errors, headers: header))
|
361
381
|
end
|
362
382
|
|
363
383
|
def run_filters(filters, type = :other)
|
@@ -384,6 +404,10 @@ module Grape
|
|
384
404
|
namespace_stackable(:afters) || []
|
385
405
|
end
|
386
406
|
|
407
|
+
def finallies
|
408
|
+
namespace_stackable(:finallies) || []
|
409
|
+
end
|
410
|
+
|
387
411
|
def validations
|
388
412
|
route_setting(:saved_validations) || []
|
389
413
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module ErrorFormatter
|
3
5
|
extend Util::Registrable
|
@@ -13,8 +15,8 @@ module Grape
|
|
13
15
|
}
|
14
16
|
end
|
15
17
|
|
16
|
-
def formatters(options)
|
17
|
-
builtin_formatters.merge(default_elements).merge(options[:error_formatters] || {})
|
18
|
+
def formatters(**options)
|
19
|
+
builtin_formatters.merge(default_elements).merge!(options[:error_formatters] || {})
|
18
20
|
end
|
19
21
|
|
20
22
|
def formatter_for(api_format, **options)
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Exceptions
|
3
5
|
class Base < StandardError
|
4
|
-
BASE_MESSAGES_KEY = 'grape.errors.messages'
|
5
|
-
BASE_ATTRIBUTES_KEY = 'grape.errors.attributes'
|
6
|
+
BASE_MESSAGES_KEY = 'grape.errors.messages'
|
7
|
+
BASE_ATTRIBUTES_KEY = 'grape.errors.attributes'
|
6
8
|
FALLBACK_LOCALE = :en
|
7
9
|
|
8
10
|
attr_reader :status, :message, :headers
|
@@ -28,7 +30,7 @@ module Grape
|
|
28
30
|
@problem = problem(key, **attributes)
|
29
31
|
@summary = summary(key, **attributes)
|
30
32
|
@resolution = resolution(key, **attributes)
|
31
|
-
[['Problem', @problem], ['Summary', @summary], ['Resolution', @resolution]].
|
33
|
+
[['Problem', @problem], ['Summary', @summary], ['Resolution', @resolution]].each_with_object(+'') do |detail_array, message|
|
32
34
|
message << "\n#{detail_array[0]}:\n #{detail_array[1]}" unless detail_array[1].blank?
|
33
35
|
message
|
34
36
|
end
|
@@ -37,16 +39,16 @@ module Grape
|
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
40
|
-
def problem(key, attributes)
|
41
|
-
translate_message("#{key}.problem".to_sym, attributes)
|
42
|
+
def problem(key, **attributes)
|
43
|
+
translate_message("#{key}.problem".to_sym, **attributes)
|
42
44
|
end
|
43
45
|
|
44
|
-
def summary(key, attributes)
|
45
|
-
translate_message("#{key}.summary".to_sym, attributes)
|
46
|
+
def summary(key, **attributes)
|
47
|
+
translate_message("#{key}.summary".to_sym, **attributes)
|
46
48
|
end
|
47
49
|
|
48
|
-
def resolution(key, attributes)
|
49
|
-
translate_message("#{key}.resolution".to_sym, attributes)
|
50
|
+
def resolution(key, **attributes)
|
51
|
+
translate_message("#{key}.resolution".to_sym, **attributes)
|
50
52
|
end
|
51
53
|
|
52
54
|
def translate_attributes(keys, **options)
|
@@ -55,10 +57,6 @@ module Grape
|
|
55
57
|
end.join(', ')
|
56
58
|
end
|
57
59
|
|
58
|
-
def translate_attribute(key, **options)
|
59
|
-
translate("#{BASE_ATTRIBUTES_KEY}.#{key}", default: key, **options)
|
60
|
-
end
|
61
|
-
|
62
60
|
def translate_message(key, **options)
|
63
61
|
case key
|
64
62
|
when Symbol
|
@@ -74,7 +72,15 @@ module Grape
|
|
74
72
|
options = options.dup
|
75
73
|
options[:default] &&= options[:default].to_s
|
76
74
|
message = ::I18n.translate(key, **options)
|
77
|
-
message.present? ? message :
|
75
|
+
message.present? ? message : fallback_message(key, **options)
|
76
|
+
end
|
77
|
+
|
78
|
+
def fallback_message(key, **options)
|
79
|
+
if ::I18n.enforce_available_locales && !::I18n.available_locales.include?(FALLBACK_LOCALE)
|
80
|
+
key
|
81
|
+
else
|
82
|
+
::I18n.translate(key, locale: FALLBACK_LOCALE, **options)
|
83
|
+
end
|
78
84
|
end
|
79
85
|
end
|
80
86
|
end
|