grape 1.2.5 → 1.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +97 -0
- data/LICENSE +1 -1
- data/README.md +53 -16
- data/UPGRADING.md +231 -23
- data/grape.gemspec +10 -1
- data/lib/grape.rb +6 -7
- data/lib/grape/api.rb +4 -2
- data/lib/grape/api/helpers.rb +2 -0
- data/lib/grape/api/instance.rb +36 -33
- data/lib/grape/config.rb +2 -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 +2 -0
- data/lib/grape/dsl/configuration.rb +2 -0
- data/lib/grape/dsl/desc.rb +2 -0
- data/lib/grape/dsl/headers.rb +2 -0
- data/lib/grape/dsl/helpers.rb +4 -2
- data/lib/grape/dsl/inside_route.rb +83 -34
- data/lib/grape/dsl/logger.rb +2 -0
- data/lib/grape/dsl/middleware.rb +2 -0
- data/lib/grape/dsl/parameters.rb +8 -6
- data/lib/grape/dsl/request_response.rb +4 -2
- data/lib/grape/dsl/routing.rb +9 -5
- data/lib/grape/dsl/settings.rb +7 -1
- data/lib/grape/dsl/validations.rb +20 -1
- data/lib/grape/eager_load.rb +3 -1
- data/lib/grape/endpoint.rb +21 -13
- data/lib/grape/error_formatter.rb +3 -1
- 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 +11 -13
- 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 +2 -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 +3 -1
- data/lib/grape/exceptions/validation_array_errors.rb +2 -0
- data/lib/grape/exceptions/validation_errors.rb +13 -12
- 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/middleware/auth/base.rb +2 -0
- 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 +7 -7
- data/lib/grape/middleware/error.rb +3 -1
- 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 +2 -0
- data/lib/grape/middleware/stack.rb +4 -1
- 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 +6 -4
- 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 +3 -1
- data/lib/grape/parser/json.rb +2 -0
- data/lib/grape/parser/xml.rb +2 -0
- data/lib/grape/path.rb +15 -3
- data/lib/grape/presenters/presenter.rb +2 -0
- data/lib/grape/request.rb +15 -8
- data/lib/grape/router.rb +30 -29
- data/lib/grape/router/attribute_translator.rb +39 -8
- data/lib/grape/router/pattern.rb +20 -16
- data/lib/grape/router/route.rb +12 -26
- 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 +15 -6
- data/lib/grape/util/cache.rb +20 -0
- data/lib/grape/util/endpoint_configuration.rb +2 -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 +2 -0
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/util/lazy_block.rb +2 -0
- data/lib/grape/util/lazy_object.rb +43 -0
- data/lib/grape/util/lazy_value.rb +2 -0
- data/lib/grape/util/registrable.rb +2 -0
- data/lib/grape/util/reverse_stackable_values.rb +4 -0
- data/lib/grape/util/stackable_values.rb +10 -20
- 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 +3 -3
- data/lib/grape/validations/multiple_attributes_iterator.rb +2 -0
- data/lib/grape/validations/params_scope.rb +27 -14
- data/lib/grape/validations/single_attribute_iterator.rb +13 -2
- data/lib/grape/validations/types.rb +12 -34
- 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 +15 -49
- 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/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 +2 -0
- data/lib/grape/validations/validators/all_or_none.rb +3 -1
- data/lib/grape/validations/validators/allow_blank.rb +3 -1
- data/lib/grape/validations/validators/as.rb +2 -0
- data/lib/grape/validations/validators/at_least_one_of.rb +3 -1
- data/lib/grape/validations/validators/base.rb +8 -5
- data/lib/grape/validations/validators/coerce.rb +39 -29
- data/lib/grape/validations/validators/default.rb +2 -1
- data/lib/grape/validations/validators/exactly_one_of.rb +6 -2
- data/lib/grape/validations/validators/except_values.rb +3 -1
- data/lib/grape/validations/validators/multiple_params_base.rb +2 -0
- data/lib/grape/validations/validators/mutual_exclusion.rb +3 -1
- 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 +6 -3
- data/lib/grape/validations/validators/values.rb +17 -5
- 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 +5 -3
- 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 +2 -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 +2 -0
- data/spec/grape/api_spec.rb +99 -11
- data/spec/grape/config_spec.rb +2 -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 +2 -0
- 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 +177 -33
- data/spec/grape/dsl/logger_spec.rb +2 -0
- data/spec/grape/dsl/middleware_spec.rb +2 -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 +2 -0
- data/spec/grape/dsl/settings_spec.rb +2 -0
- data/spec/grape/dsl/validations_spec.rb +2 -0
- data/spec/grape/endpoint_spec.rb +21 -6
- data/spec/grape/entity_spec.rb +2 -0
- data/spec/grape/exceptions/base_spec.rb +3 -1
- 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 +2 -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 +4 -2
- 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 +3 -1
- 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 +2 -0
- data/spec/grape/middleware/auth/strategies_spec.rb +3 -1
- data/spec/grape/middleware/base_spec.rb +2 -0
- data/spec/grape/middleware/error_spec.rb +2 -0
- data/spec/grape/middleware/exception_spec.rb +3 -1
- data/spec/grape/middleware/formatter_spec.rb +19 -12
- data/spec/grape/middleware/globals_spec.rb +2 -0
- data/spec/grape/middleware/stack_spec.rb +11 -0
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +3 -1
- data/spec/grape/middleware/versioner/header_spec.rb +3 -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 +2 -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 +2 -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 +2 -0
- data/spec/grape/validations/params_scope_spec.rb +3 -1
- data/spec/grape/validations/single_attribute_iterator_spec.rb +18 -4
- 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 +2 -0
- data/spec/grape/validations/validators/allow_blank_spec.rb +2 -0
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +2 -0
- data/spec/grape/validations/validators/coerce_spec.rb +341 -136
- data/spec/grape/validations/validators/default_spec.rb +123 -0
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +14 -12
- data/spec/grape/validations/validators/except_values_spec.rb +3 -1
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +2 -0
- 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 +2 -0
- data/spec/grape/validations/validators/values_spec.rb +30 -5
- data/spec/grape/validations_spec.rb +91 -33
- 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 +2 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/basic_auth_encode_helpers.rb +2 -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 +4 -2
- metadata +48 -28
- 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
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'dry_type_coercer'
|
4
|
+
|
5
|
+
module Grape
|
6
|
+
module Validations
|
7
|
+
module Types
|
8
|
+
# Coerces the given value to a type defined via a +type+ argument during
|
9
|
+
# initialization. When +strict+ is true, it doesn't coerce a value but check
|
10
|
+
# that it has the proper type.
|
11
|
+
class PrimitiveCoercer < DryTypeCoercer
|
12
|
+
MAPPING = {
|
13
|
+
Grape::API::Boolean => DryTypes::Params::Bool,
|
14
|
+
BigDecimal => DryTypes::Params::Decimal,
|
15
|
+
|
16
|
+
# unfortunately, a +Params+ scope doesn't contain String
|
17
|
+
String => DryTypes::Coercible::String
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
STRICT_MAPPING = {
|
21
|
+
Grape::API::Boolean => DryTypes::Strict::Bool,
|
22
|
+
BigDecimal => DryTypes::Strict::Decimal
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
def initialize(type, strict = false)
|
26
|
+
super
|
27
|
+
|
28
|
+
@type = type
|
29
|
+
|
30
|
+
@coercer = if strict
|
31
|
+
STRICT_MAPPING.fetch(type) { scope.const_get(type.name) }
|
32
|
+
else
|
33
|
+
MAPPING.fetch(type) { scope.const_get(type.name) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def call(val)
|
38
|
+
return InvalidValue.new if reject?(val)
|
39
|
+
return nil if val.nil? || treat_as_nil?(val)
|
40
|
+
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
attr_reader :type
|
47
|
+
|
48
|
+
# This method maintains logic which was defined by Virtus. For example,
|
49
|
+
# dry-types is ok to convert an array or a hash to a string, it is supported,
|
50
|
+
# but Virtus wouldn't accept it. So, this method only exists to not introduce
|
51
|
+
# breaking changes.
|
52
|
+
def reject?(val)
|
53
|
+
(val.is_a?(Array) && type == String) ||
|
54
|
+
(val.is_a?(String) && type == Hash) ||
|
55
|
+
(val.is_a?(Hash) && type == String)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Dry-Types treats an empty string as invalid. However, Grape considers an empty string as
|
59
|
+
# absence of a value and coerces it into nil. See a discussion there
|
60
|
+
# https://github.com/ruby-grape/grape/pull/2045
|
61
|
+
def treat_as_nil?(val)
|
62
|
+
val == '' && type != String
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
require_relative 'array_coercer'
|
5
|
+
|
6
|
+
module Grape
|
7
|
+
module Validations
|
8
|
+
module Types
|
9
|
+
# Takes the given array and converts it to a set. Every element of the set
|
10
|
+
# is also coerced.
|
11
|
+
class SetCoercer < ArrayCoercer
|
12
|
+
register_collection Set
|
13
|
+
|
14
|
+
def initialize(type, strict = false)
|
15
|
+
super
|
16
|
+
|
17
|
+
@coercer = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def call(value)
|
21
|
+
return InvalidValue.new unless value.is_a?(Array)
|
22
|
+
|
23
|
+
coerce_elements(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def coerce_elements(collection)
|
29
|
+
collection.each_with_object(Set.new) do |elem, memo|
|
30
|
+
coerced_elem = elem_coercer.call(elem)
|
31
|
+
|
32
|
+
return coerced_elem if coerced_elem.is_a?(InvalidValue)
|
33
|
+
|
34
|
+
memo.add(coerced_elem)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
module Types
|
4
6
|
# This class wraps {MultipleTypeCoercer}, for use with collections
|
5
7
|
# that allow members of more than one type.
|
6
|
-
class VariantCollectionCoercer
|
8
|
+
class VariantCollectionCoercer
|
7
9
|
# Construct a new coercer that will attempt to coerce
|
8
10
|
# a list of values such that all members are of one of
|
9
11
|
# the given types. The container may also optionally be
|
@@ -30,8 +32,8 @@ module Grape
|
|
30
32
|
# @return [Array<Object>,Set<Object>,InvalidValue]
|
31
33
|
# the coerced result, or an instance
|
32
34
|
# of {InvalidValue} if the value could not be coerced.
|
33
|
-
def
|
34
|
-
return
|
35
|
+
def call(value)
|
36
|
+
return unless value.is_a? Array
|
35
37
|
|
36
38
|
value =
|
37
39
|
if @method
|
@@ -43,16 +45,6 @@ module Grape
|
|
43
45
|
|
44
46
|
value
|
45
47
|
end
|
46
|
-
|
47
|
-
# Assert that the value has been coerced successfully.
|
48
|
-
#
|
49
|
-
# @param value [Object] a coerced result returned from {#coerce}
|
50
|
-
# @return [true,false] whether or not the coerced value
|
51
|
-
# satisfies type requirements.
|
52
|
-
def value_coerced?(value)
|
53
|
-
value.is_a?(@types.class) &&
|
54
|
-
value.all? { |v| @member_coercer.success?(@types, v) }
|
55
|
-
end
|
56
48
|
end
|
57
49
|
end
|
58
50
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'grape/validations/validators/multiple_params_base'
|
2
4
|
|
3
5
|
module Grape
|
@@ -6,7 +8,7 @@ module Grape
|
|
6
8
|
def validate_params!(params)
|
7
9
|
keys = keys_in_common(params)
|
8
10
|
return if keys.empty? || keys.length == all_keys.length
|
9
|
-
raise Grape::Exceptions::Validation
|
11
|
+
raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:all_or_none))
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class AllowBlankValidator < Base
|
@@ -9,7 +11,7 @@ module Grape
|
|
9
11
|
|
10
12
|
return if value == false || value.present?
|
11
13
|
|
12
|
-
raise Grape::Exceptions::Validation
|
14
|
+
raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:blank))
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'grape/validations/validators/multiple_params_base'
|
2
4
|
|
3
5
|
module Grape
|
@@ -5,7 +7,7 @@ module Grape
|
|
5
7
|
class AtLeastOneOfValidator < MultipleParamsBase
|
6
8
|
def validate_params!(params)
|
7
9
|
return unless keys_in_common(params).empty?
|
8
|
-
raise Grape::Exceptions::Validation
|
10
|
+
raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:at_least_one))
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class Base
|
@@ -17,6 +19,7 @@ module Grape
|
|
17
19
|
@required = required
|
18
20
|
@scope = scope
|
19
21
|
@fail_fast = opts[:fail_fast] || false
|
22
|
+
@allow_blank = opts[:allow_blank] || false
|
20
23
|
end
|
21
24
|
|
22
25
|
# Validates a given request.
|
@@ -40,12 +43,12 @@ module Grape
|
|
40
43
|
# there may be more than one error per field
|
41
44
|
array_errors = []
|
42
45
|
|
43
|
-
attributes.each do |
|
44
|
-
next if !@scope.required? &&
|
45
|
-
next unless @scope.meets_dependency?(
|
46
|
+
attributes.each do |val, attr_name, empty_val|
|
47
|
+
next if !@scope.required? && empty_val
|
48
|
+
next unless @scope.meets_dependency?(val, params)
|
46
49
|
begin
|
47
|
-
if @required ||
|
48
|
-
validate_param!(attr_name,
|
50
|
+
if @required || val.respond_to?(:key?) && val.key?(attr_name)
|
51
|
+
validate_param!(attr_name, val)
|
49
52
|
end
|
50
53
|
rescue Grape::Exceptions::Validation => e
|
51
54
|
array_errors << e
|
@@ -1,9 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
class API
|
3
|
-
|
5
|
+
class Boolean
|
6
|
+
def self.build(val)
|
7
|
+
return nil if val != true && val != false
|
8
|
+
|
9
|
+
new
|
10
|
+
end
|
11
|
+
end
|
4
12
|
|
5
13
|
class Instance
|
6
|
-
Boolean =
|
14
|
+
Boolean = Grape::API::Boolean
|
7
15
|
end
|
8
16
|
end
|
9
17
|
|
@@ -11,7 +19,12 @@ module Grape
|
|
11
19
|
class CoerceValidator < Base
|
12
20
|
def initialize(*_args)
|
13
21
|
super
|
14
|
-
|
22
|
+
|
23
|
+
@converter = if type.is_a?(Grape::Validations::Types::VariantCollectionCoercer)
|
24
|
+
type
|
25
|
+
else
|
26
|
+
Types.build_coercer(type, method: @option[:method])
|
27
|
+
end
|
15
28
|
end
|
16
29
|
|
17
30
|
def validate(request)
|
@@ -19,10 +32,23 @@ module Grape
|
|
19
32
|
end
|
20
33
|
|
21
34
|
def validate_param!(attr_name, params)
|
22
|
-
raise
|
23
|
-
|
35
|
+
raise validation_exception(attr_name) unless params.is_a? Hash
|
36
|
+
|
24
37
|
new_value = coerce_value(params[attr_name])
|
25
|
-
|
38
|
+
|
39
|
+
raise validation_exception(attr_name) unless valid_type?(new_value)
|
40
|
+
|
41
|
+
# Don't assign a value if it is identical. It fixes a problem with Hashie::Mash
|
42
|
+
# which looses wrappers for hashes and arrays after reassigning values
|
43
|
+
#
|
44
|
+
# h = Hashie::Mash.new(list: [1, 2, 3, 4])
|
45
|
+
# => #<Hashie::Mash list=#<Hashie::Array [1, 2, 3, 4]>>
|
46
|
+
# list = h.list
|
47
|
+
# h[:list] = list
|
48
|
+
# h
|
49
|
+
# => #<Hashie::Mash list=[1, 2, 3, 4]>
|
50
|
+
return if params[attr_name].class == new_value.class && params[attr_name] == new_value
|
51
|
+
|
26
52
|
params[attr_name] = new_value
|
27
53
|
end
|
28
54
|
|
@@ -33,32 +59,17 @@ module Grape
|
|
33
59
|
#
|
34
60
|
# See {Types.build_coercer}
|
35
61
|
#
|
36
|
-
# @return [
|
62
|
+
# @return [Object]
|
37
63
|
attr_reader :converter
|
38
64
|
|
39
65
|
def valid_type?(val)
|
40
|
-
|
41
|
-
return false if val.instance_of?(Types::InvalidValue)
|
42
|
-
|
43
|
-
# Allow nil, to ignore when a parameter is absent
|
44
|
-
return true if val.nil?
|
45
|
-
|
46
|
-
converter.value_coerced? val
|
66
|
+
!val.is_a?(Types::InvalidValue)
|
47
67
|
end
|
48
68
|
|
49
69
|
def coerce_value(val)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
return val || Set.new if type == Set
|
54
|
-
return val || {} if type == Hash
|
55
|
-
end
|
56
|
-
|
57
|
-
converter.coerce(val)
|
58
|
-
|
59
|
-
# not the prettiest but some invalid coercion can currently trigger
|
60
|
-
# errors in Virtus (see coerce_spec.rb:75)
|
61
|
-
rescue
|
70
|
+
converter.call(val)
|
71
|
+
# Some custom types might fail, so it should be treated as an invalid value
|
72
|
+
rescue StandardError
|
62
73
|
Types::InvalidValue.new
|
63
74
|
end
|
64
75
|
|
@@ -69,9 +80,8 @@ module Grape
|
|
69
80
|
@option[:type].is_a?(Hash) ? @option[:type][:value] : @option[:type]
|
70
81
|
end
|
71
82
|
|
72
|
-
def
|
73
|
-
|
74
|
-
!valid_type?(value) || converter.coercer.respond_to?(:method) && !converter.is_a?(Grape::Validations::Types::Json)
|
83
|
+
def validation_exception(attr_name)
|
84
|
+
Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:coerce))
|
75
85
|
end
|
76
86
|
end
|
77
87
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class DefaultValidator < Base
|
@@ -7,7 +9,6 @@ module Grape
|
|
7
9
|
end
|
8
10
|
|
9
11
|
def validate_param!(attr_name, params)
|
10
|
-
return if params.key? attr_name
|
11
12
|
params[attr_name] = if @default.is_a? Proc
|
12
13
|
@default.call
|
13
14
|
elsif @default.frozen? || !duplicatable?(@default)
|
@@ -1,11 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'grape/validations/validators/multiple_params_base'
|
2
4
|
|
3
5
|
module Grape
|
4
6
|
module Validations
|
5
7
|
class ExactlyOneOfValidator < MultipleParamsBase
|
6
8
|
def validate_params!(params)
|
7
|
-
|
8
|
-
|
9
|
+
keys = keys_in_common(params)
|
10
|
+
return if keys.length == 1
|
11
|
+
raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:exactly_one)) if keys.length.zero?
|
12
|
+
raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion))
|
9
13
|
end
|
10
14
|
end
|
11
15
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class ExceptValuesValidator < Base
|
@@ -13,7 +15,7 @@ module Grape
|
|
13
15
|
return if excepts.nil?
|
14
16
|
|
15
17
|
param_array = params[attr_name].nil? ? [nil] : Array.wrap(params[attr_name])
|
16
|
-
raise Grape::Exceptions::Validation
|
18
|
+
raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:except_values)) if param_array.any? { |param| excepts.include?(param) }
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'grape/validations/validators/multiple_params_base'
|
2
4
|
|
3
5
|
module Grape
|
@@ -6,7 +8,7 @@ module Grape
|
|
6
8
|
def validate_params!(params)
|
7
9
|
keys = keys_in_common(params)
|
8
10
|
return if keys.length <= 1
|
9
|
-
raise Grape::Exceptions::Validation
|
11
|
+
raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion))
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class PresenceValidator < Base
|
4
6
|
def validate_param!(attr_name, params)
|
5
7
|
return if params.respond_to?(:key?) && params.key?(attr_name)
|
6
|
-
raise Grape::Exceptions::Validation
|
8
|
+
raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:presence))
|
7
9
|
end
|
8
10
|
end
|
9
11
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class RegexpValidator < Base
|
4
6
|
def validate_param!(attr_name, params)
|
5
7
|
return unless params.respond_to?(:key?) && params.key?(attr_name)
|
6
|
-
return if Array.wrap(params[attr_name]).all? { |param| param.nil? ||
|
7
|
-
raise Grape::Exceptions::Validation
|
8
|
+
return if Array.wrap(params[attr_name]).all? { |param| param.nil? || param.to_s.match?((options_key?(:value) ? @option[:value] : @option)) }
|
9
|
+
raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:regexp))
|
8
10
|
end
|
9
11
|
end
|
10
12
|
end
|