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
@@ -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,14 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class AsValidator < Base
|
4
|
-
def initialize(attrs, options, required, scope, opts
|
5
|
-
@
|
6
|
+
def initialize(attrs, options, required, scope, **opts)
|
7
|
+
@renamed_options = options
|
6
8
|
super
|
7
9
|
end
|
8
10
|
|
9
11
|
def validate_param!(attr_name, params)
|
10
|
-
params[@
|
11
|
-
params.delete(attr_name)
|
12
|
+
params[@renamed_options] = params[attr_name]
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -1,19 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grape/validations/validators/multiple_params_base'
|
4
|
+
|
1
5
|
module Grape
|
2
6
|
module Validations
|
3
|
-
require 'grape/validations/validators/multiple_params_base'
|
4
7
|
class AtLeastOneOfValidator < MultipleParamsBase
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
raise Grape::Exceptions::Validation, params: all_keys, message: message(:at_least_one)
|
9
|
-
end
|
10
|
-
params
|
11
|
-
end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
def no_exclusive_params_are_present
|
16
|
-
scoped_params.any? { |resource_params| keys_in_common(resource_params).empty? }
|
8
|
+
def validate_params!(params)
|
9
|
+
return unless keys_in_common(params).empty?
|
10
|
+
raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:at_least_one))
|
17
11
|
end
|
18
12
|
end
|
19
13
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class Base
|
@@ -10,13 +12,15 @@ module Grape
|
|
10
12
|
# @param options [Object] implementation-dependent Validator options
|
11
13
|
# @param required [Boolean] attribute(s) are required or optional
|
12
14
|
# @param scope [ParamsScope] parent scope for this Validator
|
13
|
-
# @param opts [
|
14
|
-
def initialize(attrs, options, required, scope, opts
|
15
|
+
# @param opts [Array] additional validation options
|
16
|
+
def initialize(attrs, options, required, scope, *opts)
|
15
17
|
@attrs = Array(attrs)
|
16
18
|
@option = options
|
17
19
|
@required = required
|
18
20
|
@scope = scope
|
19
|
-
|
21
|
+
opts = opts.any? ? opts.shift : {}
|
22
|
+
@fail_fast = opts.fetch(:fail_fast, false)
|
23
|
+
@allow_blank = opts.fetch(:allow_blank, false)
|
20
24
|
end
|
21
25
|
|
22
26
|
# Validates a given request.
|
@@ -35,31 +39,31 @@ module Grape
|
|
35
39
|
# @raise [Grape::Exceptions::Validation] if validation failed
|
36
40
|
# @return [void]
|
37
41
|
def validate!(params)
|
38
|
-
attributes =
|
42
|
+
attributes = SingleAttributeIterator.new(self, @scope, params)
|
43
|
+
# we collect errors inside array because
|
44
|
+
# there may be more than one error per field
|
39
45
|
array_errors = []
|
40
|
-
attributes.each do |resource_params, attr_name|
|
41
|
-
next if !@scope.required? && resource_params.empty?
|
42
|
-
next unless @required || (resource_params.respond_to?(:key?) && resource_params.key?(attr_name))
|
43
|
-
next unless @scope.meets_dependency?(resource_params, params)
|
44
46
|
|
47
|
+
attributes.each do |val, attr_name, empty_val, skip_value|
|
48
|
+
next if skip_value
|
49
|
+
next if !@scope.required? && empty_val
|
50
|
+
next unless @scope.meets_dependency?(val, params)
|
45
51
|
begin
|
46
|
-
validate_param!(attr_name,
|
52
|
+
validate_param!(attr_name, val) if @required || val.respond_to?(:key?) && val.key?(attr_name)
|
47
53
|
rescue Grape::Exceptions::Validation => e
|
48
|
-
# we collect errors inside array because
|
49
|
-
# there may be more than one error per field
|
50
54
|
array_errors << e
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
|
-
raise Grape::Exceptions::ValidationArrayErrors
|
58
|
+
raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
|
55
59
|
end
|
56
60
|
|
57
61
|
def self.convert_to_short_name(klass)
|
58
62
|
ret = klass.name.gsub(/::/, '/')
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
+
ret.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
64
|
+
ret.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
65
|
+
ret.tr!('-', '_')
|
66
|
+
ret.downcase!
|
63
67
|
File.basename(ret, '_validator')
|
64
68
|
end
|
65
69
|
|
@@ -1,13 +1,30 @@
|
|
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
|
12
|
+
|
13
|
+
class Instance
|
14
|
+
Boolean = Grape::API::Boolean
|
15
|
+
end
|
4
16
|
end
|
5
17
|
|
6
18
|
module Validations
|
7
19
|
class CoerceValidator < Base
|
8
|
-
def initialize(
|
20
|
+
def initialize(attrs, options, required, scope, **opts)
|
9
21
|
super
|
10
|
-
|
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
|
11
28
|
end
|
12
29
|
|
13
30
|
def validate(request)
|
@@ -15,10 +32,23 @@ module Grape
|
|
15
32
|
end
|
16
33
|
|
17
34
|
def validate_param!(attr_name, params)
|
18
|
-
raise
|
19
|
-
|
35
|
+
raise validation_exception(attr_name) unless params.is_a? Hash
|
36
|
+
|
20
37
|
new_value = coerce_value(params[attr_name])
|
21
|
-
|
38
|
+
|
39
|
+
raise validation_exception(attr_name, new_value.message) 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
|
+
|
22
52
|
params[attr_name] = new_value
|
23
53
|
end
|
24
54
|
|
@@ -29,32 +59,17 @@ module Grape
|
|
29
59
|
#
|
30
60
|
# See {Types.build_coercer}
|
31
61
|
#
|
32
|
-
# @return [
|
62
|
+
# @return [Object]
|
33
63
|
attr_reader :converter
|
34
64
|
|
35
65
|
def valid_type?(val)
|
36
|
-
|
37
|
-
return false if val.instance_of?(Types::InvalidValue)
|
38
|
-
|
39
|
-
# Allow nil, to ignore when a parameter is absent
|
40
|
-
return true if val.nil?
|
41
|
-
|
42
|
-
converter.value_coerced? val
|
66
|
+
!val.is_a?(Types::InvalidValue)
|
43
67
|
end
|
44
68
|
|
45
69
|
def coerce_value(val)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
return val || Set.new if type == Set
|
50
|
-
return val || {} if type == Hash
|
51
|
-
end
|
52
|
-
|
53
|
-
converter.coerce(val)
|
54
|
-
|
55
|
-
# not the prettiest but some invalid coercion can currently trigger
|
56
|
-
# errors in Virtus (see coerce_spec.rb:75)
|
57
|
-
rescue
|
70
|
+
converter.call(val)
|
71
|
+
# Some custom types might fail, so it should be treated as an invalid value
|
72
|
+
rescue StandardError
|
58
73
|
Types::InvalidValue.new
|
59
74
|
end
|
60
75
|
|
@@ -65,9 +80,11 @@ module Grape
|
|
65
80
|
@option[:type].is_a?(Hash) ? @option[:type][:value] : @option[:type]
|
66
81
|
end
|
67
82
|
|
68
|
-
def
|
69
|
-
|
70
|
-
|
83
|
+
def validation_exception(attr_name, custom_msg = nil)
|
84
|
+
Grape::Exceptions::Validation.new(
|
85
|
+
params: [@scope.full_name(attr_name)],
|
86
|
+
message: custom_msg || message(:coerce)
|
87
|
+
)
|
71
88
|
end
|
72
89
|
end
|
73
90
|
end
|
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class DefaultValidator < Base
|
4
|
-
def initialize(attrs, options, required, scope, opts
|
6
|
+
def initialize(attrs, options, required, scope, **opts)
|
5
7
|
@default = options
|
6
8
|
super
|
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)
|
@@ -18,11 +19,10 @@ module Grape
|
|
18
19
|
end
|
19
20
|
|
20
21
|
def validate!(params)
|
21
|
-
attrs =
|
22
|
+
attrs = SingleAttributeIterator.new(self, @scope, params)
|
22
23
|
attrs.each do |resource_params, attr_name|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
24
|
+
next unless @scope.meets_dependency?(resource_params, params)
|
25
|
+
validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil?
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
@@ -1,28 +1,15 @@
|
|
1
|
-
|
2
|
-
module Validations
|
3
|
-
require 'grape/validations/validators/mutual_exclusion'
|
4
|
-
class ExactlyOneOfValidator < MutualExclusionValidator
|
5
|
-
def validate!(params)
|
6
|
-
super
|
7
|
-
if scope_requires_params && none_of_restricted_params_is_present
|
8
|
-
raise Grape::Exceptions::Validation, params: all_keys, message: message(:exactly_one)
|
9
|
-
end
|
10
|
-
params
|
11
|
-
end
|
1
|
+
# frozen_string_literal: true
|
12
2
|
|
13
|
-
|
14
|
-
options = instance_variable_get(:@option)
|
15
|
-
if options_key?(:message)
|
16
|
-
(options_key?(default_key, options[:message]) ? options[:message][default_key] : options[:message])
|
17
|
-
else
|
18
|
-
default_key
|
19
|
-
end
|
20
|
-
end
|
3
|
+
require 'grape/validations/validators/multiple_params_base'
|
21
4
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
5
|
+
module Grape
|
6
|
+
module Validations
|
7
|
+
class ExactlyOneOfValidator < MultipleParamsBase
|
8
|
+
def validate_params!(params)
|
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))
|
26
13
|
end
|
27
14
|
end
|
28
15
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class ExceptValuesValidator < Base
|
4
|
-
def initialize(attrs, options, required, scope, opts
|
6
|
+
def initialize(attrs, options, required, scope, **opts)
|
5
7
|
@except = options.is_a?(Hash) ? options[:value] : options
|
6
8
|
super
|
7
9
|
end
|
@@ -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,26 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Grape
|
2
4
|
module Validations
|
3
5
|
class MultipleParamsBase < Base
|
4
|
-
attr_reader :scoped_params
|
5
|
-
|
6
6
|
def validate!(params)
|
7
|
-
|
8
|
-
|
9
|
-
end
|
7
|
+
attributes = MultipleAttributesIterator.new(self, @scope, params)
|
8
|
+
array_errors = []
|
10
9
|
|
11
|
-
|
10
|
+
attributes.each do |resource_params, skip_value|
|
11
|
+
next if skip_value
|
12
|
+
begin
|
13
|
+
validate_params!(resource_params)
|
14
|
+
rescue Grape::Exceptions::Validation => e
|
15
|
+
array_errors << e
|
16
|
+
end
|
17
|
+
end
|
12
18
|
|
13
|
-
|
14
|
-
@scope.required? || scoped_params.any?(&:any?)
|
19
|
+
raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
|
15
20
|
end
|
16
21
|
|
22
|
+
private
|
23
|
+
|
17
24
|
def keys_in_common(resource_params)
|
18
25
|
return [] unless resource_params.is_a?(Hash)
|
19
|
-
|
26
|
+
all_keys & resource_params.keys.map! { |attr| @scope.full_name(attr) }
|
20
27
|
end
|
21
28
|
|
22
29
|
def all_keys
|
23
|
-
attrs.map(
|
30
|
+
attrs.map { |attr| @scope.full_name(attr) }
|
24
31
|
end
|
25
32
|
end
|
26
33
|
end
|
@@ -1,24 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'grape/validations/validators/multiple_params_base'
|
4
|
+
|
1
5
|
module Grape
|
2
6
|
module Validations
|
3
|
-
require 'grape/validations/validators/multiple_params_base'
|
4
7
|
class MutualExclusionValidator < MultipleParamsBase
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
if two_or_more_exclusive_params_are_present
|
10
|
-
raise Grape::Exceptions::Validation, params: processing_keys_in_common, message: message(:mutual_exclusion)
|
11
|
-
end
|
12
|
-
params
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
def two_or_more_exclusive_params_are_present
|
18
|
-
scoped_params.any? do |resource_params|
|
19
|
-
@processing_keys_in_common = keys_in_common(resource_params)
|
20
|
-
@processing_keys_in_common.length > 1
|
21
|
-
end
|
8
|
+
def validate_params!(params)
|
9
|
+
keys = keys_in_common(params)
|
10
|
+
return if keys.length <= 1
|
11
|
+
raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion))
|
22
12
|
end
|
23
13
|
end
|
24
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
|