grape 1.5.3 → 1.7.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.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +92 -0
  3. data/CONTRIBUTING.md +32 -1
  4. data/README.md +176 -25
  5. data/UPGRADING.md +61 -4
  6. data/grape.gemspec +6 -6
  7. data/lib/grape/api/instance.rb +14 -18
  8. data/lib/grape/api.rb +17 -12
  9. data/lib/grape/cookies.rb +2 -0
  10. data/lib/grape/dry_types.rb +12 -0
  11. data/lib/grape/dsl/api.rb +0 -2
  12. data/lib/grape/dsl/callbacks.rb +0 -2
  13. data/lib/grape/dsl/configuration.rb +0 -2
  14. data/lib/grape/dsl/desc.rb +4 -20
  15. data/lib/grape/dsl/headers.rb +5 -2
  16. data/lib/grape/dsl/helpers.rb +7 -7
  17. data/lib/grape/dsl/inside_route.rb +43 -30
  18. data/lib/grape/dsl/middleware.rb +4 -6
  19. data/lib/grape/dsl/parameters.rb +13 -10
  20. data/lib/grape/dsl/request_response.rb +9 -8
  21. data/lib/grape/dsl/routing.rb +6 -4
  22. data/lib/grape/dsl/settings.rb +5 -7
  23. data/lib/grape/dsl/validations.rb +0 -15
  24. data/lib/grape/endpoint.rb +22 -37
  25. data/lib/grape/error_formatter/json.rb +9 -7
  26. data/lib/grape/error_formatter/xml.rb +2 -6
  27. data/lib/grape/exceptions/base.rb +3 -2
  28. data/lib/grape/exceptions/missing_group_type.rb +8 -1
  29. data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
  30. data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
  31. data/lib/grape/exceptions/validation.rb +1 -6
  32. data/lib/grape/formatter/json.rb +1 -0
  33. data/lib/grape/formatter/serializable_hash.rb +2 -1
  34. data/lib/grape/formatter/xml.rb +1 -0
  35. data/lib/grape/locale/en.yml +9 -8
  36. data/lib/grape/middleware/auth/dsl.rb +7 -2
  37. data/lib/grape/middleware/base.rb +3 -1
  38. data/lib/grape/middleware/error.rb +2 -2
  39. data/lib/grape/middleware/formatter.rb +4 -4
  40. data/lib/grape/middleware/stack.rb +3 -3
  41. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
  42. data/lib/grape/middleware/versioner/header.rb +6 -4
  43. data/lib/grape/middleware/versioner/param.rb +1 -0
  44. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
  45. data/lib/grape/middleware/versioner/path.rb +2 -0
  46. data/lib/grape/path.rb +1 -0
  47. data/lib/grape/request.rb +4 -1
  48. data/lib/grape/router/attribute_translator.rb +1 -1
  49. data/lib/grape/router/pattern.rb +1 -1
  50. data/lib/grape/router/route.rb +2 -2
  51. data/lib/grape/router.rb +6 -0
  52. data/lib/grape/types/invalid_value.rb +8 -0
  53. data/lib/grape/util/cache.rb +1 -1
  54. data/lib/grape/util/inheritable_setting.rb +1 -3
  55. data/lib/grape/util/json.rb +2 -0
  56. data/lib/grape/util/lazy_value.rb +3 -2
  57. data/lib/grape/util/strict_hash_configuration.rb +1 -1
  58. data/lib/grape/validations/attributes_doc.rb +58 -0
  59. data/lib/grape/validations/params_scope.rb +138 -79
  60. data/lib/grape/validations/types/array_coercer.rb +0 -2
  61. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  62. data/lib/grape/validations/types/dry_type_coercer.rb +4 -8
  63. data/lib/grape/validations/types/invalid_value.rb +0 -7
  64. data/lib/grape/validations/types/json.rb +2 -1
  65. data/lib/grape/validations/types/primitive_coercer.rb +16 -8
  66. data/lib/grape/validations/types/set_coercer.rb +0 -2
  67. data/lib/grape/validations/types.rb +98 -30
  68. data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
  69. data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
  70. data/lib/grape/validations/validators/as_validator.rb +14 -0
  71. data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
  72. data/lib/grape/validations/validators/base.rb +82 -70
  73. data/lib/grape/validations/validators/coerce_validator.rb +75 -0
  74. data/lib/grape/validations/validators/default_validator.rb +51 -0
  75. data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
  76. data/lib/grape/validations/validators/except_values_validator.rb +24 -0
  77. data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
  78. data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
  79. data/lib/grape/validations/validators/presence_validator.rb +15 -0
  80. data/lib/grape/validations/validators/regexp_validator.rb +16 -0
  81. data/lib/grape/validations/validators/same_as_validator.rb +29 -0
  82. data/lib/grape/validations/validators/values_validator.rb +88 -0
  83. data/lib/grape/validations.rb +16 -6
  84. data/lib/grape/version.rb +1 -1
  85. data/lib/grape.rb +77 -29
  86. data/spec/grape/api/custom_validations_spec.rb +116 -45
  87. data/spec/grape/api/deeply_included_options_spec.rb +3 -5
  88. data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -3
  89. data/spec/grape/api/documentation_spec.rb +59 -0
  90. data/spec/grape/api/inherited_helpers_spec.rb +0 -2
  91. data/spec/grape/api/instance_spec.rb +0 -1
  92. data/spec/grape/api/invalid_format_spec.rb +2 -2
  93. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
  94. data/spec/grape/api/nested_helpers_spec.rb +0 -2
  95. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
  96. data/spec/grape/api/parameters_modification_spec.rb +0 -2
  97. data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
  98. data/spec/grape/api/recognize_path_spec.rb +1 -3
  99. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
  100. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
  101. data/spec/grape/api/routes_with_requirements_spec.rb +8 -10
  102. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -17
  103. data/spec/grape/api/shared_helpers_spec.rb +0 -2
  104. data/spec/grape/api_remount_spec.rb +16 -16
  105. data/spec/grape/api_spec.rb +462 -251
  106. data/spec/grape/config_spec.rb +0 -2
  107. data/spec/grape/dsl/callbacks_spec.rb +2 -3
  108. data/spec/grape/dsl/desc_spec.rb +2 -2
  109. data/spec/grape/dsl/headers_spec.rb +39 -11
  110. data/spec/grape/dsl/helpers_spec.rb +3 -4
  111. data/spec/grape/dsl/inside_route_spec.rb +16 -16
  112. data/spec/grape/dsl/logger_spec.rb +15 -19
  113. data/spec/grape/dsl/middleware_spec.rb +2 -3
  114. data/spec/grape/dsl/parameters_spec.rb +2 -2
  115. data/spec/grape/dsl/request_response_spec.rb +7 -8
  116. data/spec/grape/dsl/routing_spec.rb +11 -10
  117. data/spec/grape/dsl/settings_spec.rb +0 -2
  118. data/spec/grape/dsl/validations_spec.rb +0 -17
  119. data/spec/grape/endpoint/declared_spec.rb +261 -16
  120. data/spec/grape/endpoint_spec.rb +88 -59
  121. data/spec/grape/entity_spec.rb +22 -23
  122. data/spec/grape/exceptions/base_spec.rb +16 -2
  123. data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -2
  124. data/spec/grape/exceptions/invalid_accept_header_spec.rb +64 -24
  125. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
  126. data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
  127. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
  128. data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
  129. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
  130. data/spec/grape/exceptions/missing_option_spec.rb +1 -3
  131. data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
  132. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
  133. data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
  134. data/spec/grape/exceptions/validation_errors_spec.rb +13 -11
  135. data/spec/grape/exceptions/validation_spec.rb +5 -5
  136. data/spec/grape/extensions/param_builders/hash_spec.rb +7 -9
  137. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -10
  138. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -10
  139. data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
  140. data/spec/grape/integration/rack_sendfile_spec.rb +1 -3
  141. data/spec/grape/integration/rack_spec.rb +6 -7
  142. data/spec/grape/loading_spec.rb +8 -10
  143. data/spec/grape/middleware/auth/base_spec.rb +0 -1
  144. data/spec/grape/middleware/auth/dsl_spec.rb +15 -8
  145. data/spec/grape/middleware/auth/strategies_spec.rb +60 -22
  146. data/spec/grape/middleware/base_spec.rb +28 -19
  147. data/spec/grape/middleware/error_spec.rb +8 -3
  148. data/spec/grape/middleware/exception_spec.rb +111 -163
  149. data/spec/grape/middleware/formatter_spec.rb +33 -14
  150. data/spec/grape/middleware/globals_spec.rb +7 -6
  151. data/spec/grape/middleware/stack_spec.rb +14 -14
  152. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -3
  153. data/spec/grape/middleware/versioner/header_spec.rb +30 -15
  154. data/spec/grape/middleware/versioner/param_spec.rb +7 -3
  155. data/spec/grape/middleware/versioner/path_spec.rb +5 -3
  156. data/spec/grape/middleware/versioner_spec.rb +1 -3
  157. data/spec/grape/named_api_spec.rb +0 -2
  158. data/spec/grape/parser_spec.rb +4 -2
  159. data/spec/grape/path_spec.rb +52 -54
  160. data/spec/grape/presenters/presenter_spec.rb +7 -8
  161. data/spec/grape/request_spec.rb +6 -6
  162. data/spec/grape/util/inheritable_setting_spec.rb +7 -8
  163. data/spec/grape/util/inheritable_values_spec.rb +3 -3
  164. data/spec/grape/util/reverse_stackable_values_spec.rb +3 -2
  165. data/spec/grape/util/stackable_values_spec.rb +7 -6
  166. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
  167. data/spec/grape/validations/attributes_doc_spec.rb +153 -0
  168. data/spec/grape/validations/instance_behaivour_spec.rb +9 -12
  169. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -2
  170. data/spec/grape/validations/params_scope_spec.rb +361 -96
  171. data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -3
  172. data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
  173. data/spec/grape/validations/types/primitive_coercer_spec.rb +24 -9
  174. data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
  175. data/spec/grape/validations/types_spec.rb +36 -10
  176. data/spec/grape/validations/validators/all_or_none_spec.rb +50 -58
  177. data/spec/grape/validations/validators/allow_blank_spec.rb +135 -141
  178. data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -58
  179. data/spec/grape/validations/validators/coerce_spec.rb +23 -24
  180. data/spec/grape/validations/validators/default_spec.rb +72 -80
  181. data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -79
  182. data/spec/grape/validations/validators/except_values_spec.rb +3 -5
  183. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -79
  184. data/spec/grape/validations/validators/presence_spec.rb +16 -3
  185. data/spec/grape/validations/validators/regexp_spec.rb +25 -33
  186. data/spec/grape/validations/validators/same_as_spec.rb +14 -22
  187. data/spec/grape/validations/validators/values_spec.rb +201 -179
  188. data/spec/grape/validations_spec.rb +171 -79
  189. data/spec/integration/eager_load/eager_load_spec.rb +2 -2
  190. data/spec/integration/multi_json/json_spec.rb +1 -3
  191. data/spec/integration/multi_xml/xml_spec.rb +1 -3
  192. data/spec/shared/versioning_examples.rb +12 -9
  193. data/spec/spec_helper.rb +21 -6
  194. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  195. metadata +41 -29
  196. data/lib/grape/validations/validators/all_or_none.rb +0 -15
  197. data/lib/grape/validations/validators/allow_blank.rb +0 -18
  198. data/lib/grape/validations/validators/as.rb +0 -16
  199. data/lib/grape/validations/validators/at_least_one_of.rb +0 -14
  200. data/lib/grape/validations/validators/coerce.rb +0 -91
  201. data/lib/grape/validations/validators/default.rb +0 -48
  202. data/lib/grape/validations/validators/exactly_one_of.rb +0 -16
  203. data/lib/grape/validations/validators/except_values.rb +0 -22
  204. data/lib/grape/validations/validators/mutual_exclusion.rb +0 -15
  205. data/lib/grape/validations/validators/presence.rb +0 -12
  206. data/lib/grape/validations/validators/regexp.rb +0 -13
  207. data/lib/grape/validations/validators/same_as.rb +0 -26
  208. data/lib/grape/validations/validators/values.rb +0 -83
  209. data/spec/grape/dsl/configuration_spec.rb +0 -16
  210. data/spec/grape/validations/attributes_iterator_spec.rb +0 -6
  211. data/spec/support/eager_load.rb +0 -19
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Validations
5
+ module Validators
6
+ class DefaultValidator < Base
7
+ def initialize(attrs, options, required, scope, **opts)
8
+ @default = options
9
+ super
10
+ end
11
+
12
+ def validate_param!(attr_name, params)
13
+ params[attr_name] = if @default.is_a? Proc
14
+ @default.call
15
+ elsif @default.frozen? || !duplicatable?(@default)
16
+ @default
17
+ else
18
+ duplicate(@default)
19
+ end
20
+ end
21
+
22
+ def validate!(params)
23
+ attrs = SingleAttributeIterator.new(self, @scope, params)
24
+ attrs.each do |resource_params, attr_name|
25
+ next unless @scope.meets_dependency?(resource_params, params)
26
+
27
+ validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil?
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # return true if we might be able to dup this object
34
+ def duplicatable?(obj)
35
+ !obj.nil? &&
36
+ obj != true &&
37
+ obj != false &&
38
+ !obj.is_a?(Symbol) &&
39
+ !obj.is_a?(Numeric)
40
+ end
41
+
42
+ # make a best effort to dup the object
43
+ def duplicate(obj)
44
+ obj.dup
45
+ rescue TypeError
46
+ obj
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Validations
5
+ module Validators
6
+ class ExactlyOneOfValidator < MultipleParamsBase
7
+ def validate_params!(params)
8
+ keys = keys_in_common(params)
9
+ return if keys.length == 1
10
+ raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:exactly_one)) if keys.length.zero?
11
+
12
+ raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Validations
5
+ module Validators
6
+ class ExceptValuesValidator < Base
7
+ def initialize(attrs, options, required, scope, **opts)
8
+ @except = options.is_a?(Hash) ? options[:value] : options
9
+ super
10
+ end
11
+
12
+ def validate_param!(attr_name, params)
13
+ return unless params.respond_to?(:key?) && params.key?(attr_name)
14
+
15
+ excepts = @except.is_a?(Proc) ? @except.call : @except
16
+ return if excepts.nil?
17
+
18
+ param_array = params[attr_name].nil? ? [nil] : Array.wrap(params[attr_name])
19
+ raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:except_values)) if param_array.any? { |param| excepts.include?(param) }
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -2,32 +2,36 @@
2
2
 
3
3
  module Grape
4
4
  module Validations
5
- class MultipleParamsBase < Base
6
- def validate!(params)
7
- attributes = MultipleAttributesIterator.new(self, @scope, params)
8
- array_errors = []
9
-
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
5
+ module Validators
6
+ class MultipleParamsBase < Base
7
+ def validate!(params)
8
+ attributes = MultipleAttributesIterator.new(self, @scope, params)
9
+ array_errors = []
10
+
11
+ attributes.each do |resource_params, skip_value|
12
+ next if skip_value
13
+
14
+ begin
15
+ validate_params!(resource_params)
16
+ rescue Grape::Exceptions::Validation => e
17
+ array_errors << e
18
+ end
16
19
  end
20
+
21
+ raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
17
22
  end
18
23
 
19
- raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any?
20
- end
24
+ private
21
25
 
22
- private
26
+ def keys_in_common(resource_params)
27
+ return [] unless resource_params.is_a?(Hash)
23
28
 
24
- def keys_in_common(resource_params)
25
- return [] unless resource_params.is_a?(Hash)
26
- all_keys & resource_params.keys.map! { |attr| @scope.full_name(attr) }
27
- end
29
+ all_keys & resource_params.keys.map! { |attr| @scope.full_name(attr) }
30
+ end
28
31
 
29
- def all_keys
30
- attrs.map { |attr| @scope.full_name(attr) }
32
+ def all_keys
33
+ attrs.map { |attr| @scope.full_name(attr) }
34
+ end
31
35
  end
32
36
  end
33
37
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Validations
5
+ module Validators
6
+ class MutualExclusionValidator < MultipleParamsBase
7
+ def validate_params!(params)
8
+ keys = keys_in_common(params)
9
+ return if keys.length <= 1
10
+
11
+ raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion))
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Validations
5
+ module Validators
6
+ class PresenceValidator < Base
7
+ def validate_param!(attr_name, params)
8
+ return if params.respond_to?(:key?) && params.key?(attr_name)
9
+
10
+ raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:presence))
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Validations
5
+ module Validators
6
+ class RegexpValidator < Base
7
+ def validate_param!(attr_name, params)
8
+ return unless params.respond_to?(:key?) && params.key?(attr_name)
9
+ return if Array.wrap(params[attr_name]).all? { |param| param.nil? || param.to_s.match?((options_key?(:value) ? @option[:value] : @option)) }
10
+
11
+ raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:regexp))
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Validations
5
+ module Validators
6
+ class SameAsValidator < Base
7
+ def validate_param!(attr_name, params)
8
+ confirmation = options_key?(:value) ? @option[:value] : @option
9
+ return if params[attr_name] == params[confirmation]
10
+
11
+ raise Grape::Exceptions::Validation.new(
12
+ params: [@scope.full_name(attr_name)],
13
+ message: build_message
14
+ )
15
+ end
16
+
17
+ private
18
+
19
+ def build_message
20
+ if options_key?(:message)
21
+ @option[:message]
22
+ else
23
+ format I18n.t(:same_as, scope: 'grape.errors.messages'), parameter: @option
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Validations
5
+ module Validators
6
+ class ValuesValidator < Base
7
+ def initialize(attrs, options, required, scope, **opts)
8
+ if options.is_a?(Hash)
9
+ @excepts = options[:except]
10
+ @values = options[:value]
11
+ @proc = options[:proc]
12
+
13
+ warn '[DEPRECATION] The values validator except option is deprecated. ' \
14
+ 'Use the except validator instead.' if @excepts
15
+
16
+ raise ArgumentError, 'proc must be a Proc' if @proc && !@proc.is_a?(Proc)
17
+
18
+ warn '[DEPRECATION] The values validator proc option is deprecated. ' \
19
+ 'The lambda expression can now be assigned directly to values.' if @proc
20
+ else
21
+ @excepts = nil
22
+ @values = nil
23
+ @proc = nil
24
+ @values = options
25
+ end
26
+ super
27
+ end
28
+
29
+ def validate_param!(attr_name, params)
30
+ return unless params.is_a?(Hash)
31
+
32
+ val = params[attr_name]
33
+
34
+ return if val.nil? && !required_for_root_scope?
35
+
36
+ # don't forget that +false.blank?+ is true
37
+ return if val != false && val.blank? && @allow_blank
38
+
39
+ param_array = val.nil? ? [nil] : Array.wrap(val)
40
+
41
+ raise validation_exception(attr_name, except_message) \
42
+ unless check_excepts(param_array)
43
+
44
+ raise validation_exception(attr_name, message(:values)) \
45
+ unless check_values(param_array, attr_name)
46
+
47
+ raise validation_exception(attr_name, message(:values)) \
48
+ if @proc && !param_array.all? { |param| @proc.call(param) }
49
+ end
50
+
51
+ private
52
+
53
+ def check_values(param_array, attr_name)
54
+ values = @values.is_a?(Proc) && @values.arity.zero? ? @values.call : @values
55
+ return true if values.nil?
56
+
57
+ begin
58
+ return param_array.all? { |param| values.call(param) } if values.is_a? Proc
59
+ rescue StandardError => e
60
+ warn "Error '#{e}' raised while validating attribute '#{attr_name}'"
61
+ return false
62
+ end
63
+ param_array.all? { |param| values.include?(param) }
64
+ end
65
+
66
+ def check_excepts(param_array)
67
+ excepts = @excepts.is_a?(Proc) ? @excepts.call : @excepts
68
+ return true if excepts.nil?
69
+
70
+ param_array.none? { |param| excepts.include?(param) }
71
+ end
72
+
73
+ def except_message
74
+ options = instance_variable_get(:@option)
75
+ options_key?(:except_message) ? options[:except_message] : message(:except_values)
76
+ end
77
+
78
+ def required_for_root_scope?
79
+ @required && @scope.root?
80
+ end
81
+
82
+ def validation_exception(attr_name, message)
83
+ Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -3,22 +3,32 @@
3
3
  module Grape
4
4
  # Registry to store and locate known Validators.
5
5
  module Validations
6
- class << self
7
- attr_accessor :validators
8
- end
6
+ module_function
9
7
 
10
- self.validators = {}
8
+ def validators
9
+ @validators ||= {}
10
+ end
11
11
 
12
12
  # Register a new validator, so it can be used to validate parameters.
13
13
  # @param short_name [String] all lower-case, no spaces
14
14
  # @param klass [Class] the validator class. Should inherit from
15
15
  # Validations::Base.
16
- def self.register_validator(short_name, klass)
16
+ def register_validator(short_name, klass)
17
17
  validators[short_name] = klass
18
18
  end
19
19
 
20
- def self.deregister_validator(short_name)
20
+ def deregister_validator(short_name)
21
21
  validators.delete(short_name)
22
22
  end
23
+
24
+ # Find a validator and if not found will try to load it
25
+ def require_validator(short_name)
26
+ str_name = short_name.to_s
27
+ validators.fetch(str_name) do
28
+ Grape::Validations::Validators.const_get("#{str_name.camelize}Validator")
29
+ end
30
+ rescue NameError
31
+ raise Grape::Exceptions::UnknownValidator.new(short_name)
32
+ end
23
33
  end
24
34
  end
data/lib/grape/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Grape
4
4
  # The current version of Grape.
5
- VERSION = '1.5.3'
5
+ VERSION = '1.7.1'
6
6
  end
data/lib/grape.rb CHANGED
@@ -7,22 +7,27 @@ require 'rack/accept'
7
7
  require 'rack/auth/basic'
8
8
  require 'rack/auth/digest/md5'
9
9
  require 'set'
10
+ require 'bigdecimal'
11
+ require 'date'
12
+ require 'active_support'
13
+ require 'active_support/concern'
10
14
  require 'active_support/version'
11
- require 'active_support/core_ext/hash/indifferent_access'
12
- require 'active_support/core_ext/object/blank'
15
+ require 'active_support/isolated_execution_state' if ActiveSupport::VERSION::MAJOR > 6
16
+ require 'active_support/core_ext/array/conversions'
13
17
  require 'active_support/core_ext/array/extract_options'
14
18
  require 'active_support/core_ext/array/wrap'
15
- require 'active_support/core_ext/array/conversions'
19
+ require 'active_support/core_ext/hash/conversions'
16
20
  require 'active_support/core_ext/hash/deep_merge'
17
- require 'active_support/core_ext/hash/reverse_merge'
18
21
  require 'active_support/core_ext/hash/except'
22
+ require 'active_support/core_ext/hash/indifferent_access'
23
+ require 'active_support/core_ext/hash/reverse_merge'
19
24
  require 'active_support/core_ext/hash/slice'
20
- require 'active_support/core_ext/hash/conversions'
25
+ require 'active_support/core_ext/object/blank'
21
26
  require 'active_support/dependencies/autoload'
22
27
  require 'active_support/notifications'
23
28
  require 'i18n'
24
29
 
25
- I18n.load_path << File.expand_path('../grape/locale/en.yml', __FILE__)
30
+ I18n.load_path << File.expand_path('grape/locale/en.yml', __dir__)
26
31
 
27
32
  module Grape
28
33
  extend ::ActiveSupport::Autoload
@@ -43,6 +48,7 @@ module Grape
43
48
  autoload :Env, 'grape/util/env'
44
49
  autoload :Json, 'grape/util/json'
45
50
  autoload :Xml, 'grape/util/xml'
51
+ autoload :DryTypes
46
52
  end
47
53
 
48
54
  module Http
@@ -69,14 +75,17 @@ module Grape
69
75
  autoload :UnknownParameter
70
76
  autoload :InvalidWithOptionForRepresent
71
77
  autoload :IncompatibleOptionValues
72
- autoload :MissingGroupTypeError, 'grape/exceptions/missing_group_type'
73
- autoload :UnsupportedGroupTypeError, 'grape/exceptions/unsupported_group_type'
78
+ autoload :MissingGroupType
79
+ autoload :UnsupportedGroupType
74
80
  autoload :InvalidMessageBody
75
81
  autoload :InvalidAcceptHeader
76
82
  autoload :InvalidVersionHeader
77
83
  autoload :MethodNotAllowed
78
84
  autoload :InvalidResponse
79
85
  autoload :EmptyMessageBody
86
+ autoload :TooManyMultipartFiles
87
+ autoload :MissingGroupTypeError, 'grape/exceptions/missing_group_type'
88
+ autoload :UnsupportedGroupTypeError, 'grape/exceptions/unsupported_group_type'
80
89
  end
81
90
  end
82
91
 
@@ -216,6 +225,66 @@ module Grape
216
225
  autoload :StreamResponse
217
226
  end
218
227
  end
228
+
229
+ module Validations
230
+ extend ::ActiveSupport::Autoload
231
+
232
+ eager_autoload do
233
+ autoload :AttributesIterator
234
+ autoload :MultipleAttributesIterator
235
+ autoload :SingleAttributeIterator
236
+ autoload :Types
237
+ autoload :ParamsScope
238
+ autoload :ValidatorFactory
239
+ autoload :Base, 'grape/validations/validators/base'
240
+ end
241
+
242
+ module Types
243
+ extend ::ActiveSupport::Autoload
244
+
245
+ eager_autoload do
246
+ autoload :InvalidValue
247
+ autoload :DryTypeCoercer
248
+ autoload :ArrayCoercer
249
+ autoload :SetCoercer
250
+ autoload :PrimitiveCoercer
251
+ autoload :CustomTypeCoercer
252
+ autoload :CustomTypeCollectionCoercer
253
+ autoload :MultipleTypeCoercer
254
+ autoload :VariantCollectionCoercer
255
+ end
256
+ end
257
+
258
+ module Validators
259
+ extend ::ActiveSupport::Autoload
260
+
261
+ eager_autoload do
262
+ autoload :Base
263
+ autoload :MultipleParamsBase
264
+ autoload :AllOrNoneOfValidator
265
+ autoload :AllowBlankValidator
266
+ autoload :AsValidator
267
+ autoload :AtLeastOneOfValidator
268
+ autoload :CoerceValidator
269
+ autoload :DefaultValidator
270
+ autoload :ExactlyOneOfValidator
271
+ autoload :ExceptValuesValidator
272
+ autoload :MutualExclusionValidator
273
+ autoload :PresenceValidator
274
+ autoload :RegexpValidator
275
+ autoload :SameAsValidator
276
+ autoload :ValuesValidator
277
+ end
278
+ end
279
+ end
280
+
281
+ module Types
282
+ extend ::ActiveSupport::Autoload
283
+
284
+ eager_autoload do
285
+ autoload :InvalidValue
286
+ end
287
+ end
219
288
  end
220
289
 
221
290
  require 'grape/config'
@@ -225,25 +294,4 @@ require 'grape/util/lazy_value'
225
294
  require 'grape/util/lazy_block'
226
295
  require 'grape/util/endpoint_configuration'
227
296
 
228
- require 'grape/validations/validators/base'
229
- require 'grape/validations/attributes_iterator'
230
- require 'grape/validations/single_attribute_iterator'
231
- require 'grape/validations/multiple_attributes_iterator'
232
- require 'grape/validations/validators/allow_blank'
233
- require 'grape/validations/validators/as'
234
- require 'grape/validations/validators/at_least_one_of'
235
- require 'grape/validations/validators/coerce'
236
- require 'grape/validations/validators/default'
237
- require 'grape/validations/validators/exactly_one_of'
238
- require 'grape/validations/validators/mutual_exclusion'
239
- require 'grape/validations/validators/presence'
240
- require 'grape/validations/validators/regexp'
241
- require 'grape/validations/validators/same_as'
242
- require 'grape/validations/validators/values'
243
- require 'grape/validations/validators/except_values'
244
- require 'grape/validations/params_scope'
245
- require 'grape/validations/validators/all_or_none'
246
- require 'grape/validations/types'
247
- require 'grape/validations/validator_factory'
248
-
249
297
  require 'grape/version'