grape 2.2.0 → 2.3.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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +7 -6
  4. data/UPGRADING.md +19 -0
  5. data/grape.gemspec +5 -5
  6. data/lib/grape/api/instance.rb +22 -58
  7. data/lib/grape/api.rb +2 -11
  8. data/lib/grape/dsl/desc.rb +27 -24
  9. data/lib/grape/dsl/inside_route.rb +12 -23
  10. data/lib/grape/dsl/parameters.rb +2 -2
  11. data/lib/grape/dsl/routing.rb +5 -12
  12. data/lib/grape/endpoint.rb +76 -79
  13. data/lib/grape/error_formatter/base.rb +51 -21
  14. data/lib/grape/error_formatter/json.rb +7 -24
  15. data/lib/grape/error_formatter/jsonapi.rb +7 -0
  16. data/lib/grape/error_formatter/serializable_hash.rb +7 -0
  17. data/lib/grape/error_formatter/txt.rb +13 -20
  18. data/lib/grape/error_formatter/xml.rb +3 -13
  19. data/lib/grape/error_formatter.rb +4 -12
  20. data/lib/grape/exceptions/base.rb +18 -30
  21. data/lib/grape/exceptions/validation.rb +5 -4
  22. data/lib/grape/exceptions/validation_errors.rb +2 -2
  23. data/lib/grape/formatter/base.rb +16 -0
  24. data/lib/grape/formatter/json.rb +4 -6
  25. data/lib/grape/formatter/serializable_hash.rb +1 -1
  26. data/lib/grape/formatter/txt.rb +3 -5
  27. data/lib/grape/formatter/xml.rb +4 -6
  28. data/lib/grape/formatter.rb +4 -12
  29. data/lib/grape/http/headers.rb +1 -0
  30. data/lib/grape/middleware/error.rb +2 -0
  31. data/lib/grape/middleware/formatter.rb +1 -1
  32. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -3
  33. data/lib/grape/middleware/versioner/base.rb +82 -0
  34. data/lib/grape/middleware/versioner/header.rb +3 -9
  35. data/lib/grape/middleware/versioner/param.rb +0 -2
  36. data/lib/grape/middleware/versioner/path.rb +0 -2
  37. data/lib/grape/middleware/versioner.rb +5 -3
  38. data/lib/grape/namespace.rb +1 -1
  39. data/lib/grape/parser/base.rb +16 -0
  40. data/lib/grape/parser/json.rb +6 -8
  41. data/lib/grape/parser/jsonapi.rb +7 -0
  42. data/lib/grape/parser/xml.rb +6 -8
  43. data/lib/grape/parser.rb +5 -7
  44. data/lib/grape/path.rb +39 -56
  45. data/lib/grape/request.rb +2 -2
  46. data/lib/grape/router/base_route.rb +2 -2
  47. data/lib/grape/router/greedy_route.rb +2 -2
  48. data/lib/grape/router/pattern.rb +23 -18
  49. data/lib/grape/router/route.rb +13 -5
  50. data/lib/grape/router.rb +5 -5
  51. data/lib/grape/util/registry.rb +27 -0
  52. data/lib/grape/validations/contract_scope.rb +2 -39
  53. data/lib/grape/validations/params_scope.rb +7 -11
  54. data/lib/grape/validations/types/dry_type_coercer.rb +10 -6
  55. data/lib/grape/validations/validator_factory.rb +2 -2
  56. data/lib/grape/validations/validators/allow_blank_validator.rb +1 -1
  57. data/lib/grape/validations/validators/base.rb +5 -9
  58. data/lib/grape/validations/validators/coerce_validator.rb +1 -1
  59. data/lib/grape/validations/validators/contract_scope_validator.rb +41 -0
  60. data/lib/grape/validations/validators/default_validator.rb +1 -1
  61. data/lib/grape/validations/validators/except_values_validator.rb +1 -1
  62. data/lib/grape/validations/validators/length_validator.rb +1 -1
  63. data/lib/grape/validations/validators/regexp_validator.rb +1 -1
  64. data/lib/grape/validations/validators/values_validator.rb +15 -57
  65. data/lib/grape/validations.rb +8 -17
  66. data/lib/grape/version.rb +1 -1
  67. data/lib/grape.rb +1 -1
  68. metadata +14 -11
  69. data/lib/grape/middleware/versioner_helpers.rb +0 -75
  70. data/lib/grape/validations/types/build_coercer.rb +0 -92
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Util
5
+ module Registry
6
+ def register(klass)
7
+ short_name = build_short_name(klass)
8
+ return if short_name.nil?
9
+
10
+ warn "#{short_name} is already registered with class #{klass}" if registry.key?(short_name)
11
+ registry[short_name] = klass
12
+ end
13
+
14
+ private
15
+
16
+ def build_short_name(klass)
17
+ return if klass.name.blank?
18
+
19
+ klass.name.demodulize.underscore
20
+ end
21
+
22
+ def registry
23
+ @registry ||= {}.with_indifferent_access
24
+ end
25
+ end
26
+ end
27
+ end
@@ -23,49 +23,12 @@ module Grape
23
23
  api.namespace_stackable(:contract_key_map, key_map)
24
24
 
25
25
  validator_options = {
26
- validator_class: Validator,
27
- opts: { schema: contract }
26
+ validator_class: Grape::Validations.require_validator(:contract_scope),
27
+ opts: { schema: contract, fail_fast: false }
28
28
  }
29
29
 
30
30
  api.namespace_stackable(:validations, validator_options)
31
31
  end
32
-
33
- class Validator
34
- attr_reader :schema
35
-
36
- def initialize(*_args, schema:)
37
- @schema = schema
38
- end
39
-
40
- # Validates a given request.
41
- # @param request [Grape::Request] the request currently being handled
42
- # @raise [Grape::Exceptions::ValidationArrayErrors] if validation failed
43
- # @return [void]
44
- def validate(request)
45
- res = schema.call(request.params)
46
-
47
- if res.success?
48
- request.params.deep_merge!(res.to_h)
49
- return
50
- end
51
-
52
- errors = []
53
-
54
- res.errors.messages.each do |message|
55
- full_name = message.path.first.to_s
56
-
57
- full_name += "[#{message.path[1..].join('][')}]" if message.path.size > 1
58
-
59
- errors << Grape::Exceptions::Validation.new(params: [full_name], message: message.text)
60
- end
61
-
62
- raise Grape::Exceptions::ValidationArrayErrors.new(errors)
63
- end
64
-
65
- def fail_fast?
66
- false
67
- end
68
- end
69
32
  end
70
33
  end
71
34
  end
@@ -174,16 +174,12 @@ module Grape
174
174
 
175
175
  # Adds a parameter declaration to our list of validations.
176
176
  # @param attrs [Array] (see Grape::DSL::Parameters#requires)
177
- def push_declared_params(attrs, **opts)
178
- opts = opts.merge(declared_params_scope: self) unless opts.key?(:declared_params_scope)
179
- if lateral?
180
- @parent.push_declared_params(attrs, **opts)
181
- else
182
- push_renamed_param(full_path + [attrs.first], opts[:as]) \
183
- if opts && opts[:as]
177
+ def push_declared_params(attrs, opts = {})
178
+ opts[:declared_params_scope] = self unless opts.key?(:declared_params_scope)
179
+ return @parent.push_declared_params(attrs, opts) if lateral?
184
180
 
185
- @declared_params.concat(attrs.map { |attr| ::Grape::Validations::ParamsScope::Attr.new(attr, opts[:declared_params_scope]) })
186
- end
181
+ push_renamed_param(full_path + [attrs.first], opts[:as]) if opts[:as]
182
+ @declared_params.concat(attrs.map { |attr| ::Grape::Validations::ParamsScope::Attr.new(attr, opts[:declared_params_scope]) })
187
183
  end
188
184
 
189
185
  # Get the full path of the parameter scope in the hierarchy.
@@ -490,7 +486,7 @@ module Grape
490
486
  def validate_value_coercion(coerce_type, *values_list)
491
487
  return unless coerce_type
492
488
 
493
- coerce_type = coerce_type.first if coerce_type.is_a?(Array)
489
+ coerce_type = coerce_type.first if coerce_type.is_a?(Enumerable)
494
490
  values_list.each do |values|
495
491
  next if !values || values.is_a?(Proc)
496
492
 
@@ -529,7 +525,7 @@ module Grape
529
525
  def validates_presence(validations, attrs, doc, opts)
530
526
  return unless validations.key?(:presence) && validations[:presence]
531
527
 
532
- validate(:presence, validations.delete(:presence), attrs, doc, opts)
528
+ validate('presence', validations.delete(:presence), attrs, doc, opts)
533
529
  validations.delete(:message) if validations.key?(:message)
534
530
  end
535
531
  end
@@ -22,16 +22,20 @@ module Grape
22
22
  # collection_coercer_for(Array)
23
23
  # #=> Grape::Validations::Types::ArrayCoercer
24
24
  def collection_coercer_for(type)
25
- Grape::Validations::Types.const_get(:"#{type.name.camelize}Coercer")
25
+ case type
26
+ when Array
27
+ ArrayCoercer
28
+ when Set
29
+ SetCoercer
30
+ else
31
+ raise ArgumentError, "Unknown type: #{type}"
32
+ end
26
33
  end
27
34
 
28
35
  # Returns an instance of a coercer for a given type
29
36
  def coercer_instance_for(type, strict = false)
30
- return PrimitiveCoercer.new(type, strict) if type.instance_of?(Class)
31
-
32
- # in case of a collection (Array[Integer]) the type is an instance of a collection,
33
- # so we need to figure out the actual type
34
- collection_coercer_for(type.class).new(type, strict)
37
+ klass = type.instance_of?(Class) ? PrimitiveCoercer : collection_coercer_for(type)
38
+ klass.new(type, strict)
35
39
  end
36
40
  end
37
41
 
@@ -3,12 +3,12 @@
3
3
  module Grape
4
4
  module Validations
5
5
  class ValidatorFactory
6
- def self.create_validator(**options)
6
+ def self.create_validator(options)
7
7
  options[:validator_class].new(options[:attributes],
8
8
  options[:options],
9
9
  options[:required],
10
10
  options[:params_scope],
11
- **options[:opts])
11
+ options[:opts])
12
12
  end
13
13
  end
14
14
  end
@@ -8,7 +8,7 @@ module Grape
8
8
  return if (options_key?(:value) ? @option[:value] : @option) || !params.is_a?(Hash)
9
9
 
10
10
  value = params[attr_name]
11
- value = value.strip if value.respond_to?(:strip)
11
+ value = value.scrub if value.respond_to?(:scrub)
12
12
 
13
13
  return if value == false || value.present?
14
14
 
@@ -13,15 +13,14 @@ module Grape
13
13
  # @param options [Object] implementation-dependent Validator options
14
14
  # @param required [Boolean] attribute(s) are required or optional
15
15
  # @param scope [ParamsScope] parent scope for this Validator
16
- # @param opts [Array] additional validation options
17
- def initialize(attrs, options, required, scope, *opts)
16
+ # @param opts [Hash] additional validation options
17
+ def initialize(attrs, options, required, scope, opts)
18
18
  @attrs = Array(attrs)
19
19
  @option = options
20
20
  @required = required
21
21
  @scope = scope
22
- opts = opts.any? ? opts.shift : {}
23
- @fail_fast = opts.fetch(:fail_fast, false)
24
- @allow_blank = opts.fetch(:allow_blank, false)
22
+ @fail_fast = opts[:fail_fast]
23
+ @allow_blank = opts[:allow_blank]
25
24
  end
26
25
 
27
26
  # Validates a given request.
@@ -60,10 +59,7 @@ module Grape
60
59
 
61
60
  def self.inherited(klass)
62
61
  super
63
- return if klass.name.blank?
64
-
65
- short_validator_name = klass.name.demodulize.underscore.delete_suffix('_validator')
66
- Validations.register_validator(short_validator_name, klass)
62
+ Validations.register(klass)
67
63
  end
68
64
 
69
65
  def message(default_key = nil)
@@ -4,7 +4,7 @@ module Grape
4
4
  module Validations
5
5
  module Validators
6
6
  class CoerceValidator < Base
7
- def initialize(attrs, options, required, scope, **opts)
7
+ def initialize(attrs, options, required, scope, opts)
8
8
  super
9
9
 
10
10
  @converter = if type.is_a?(Grape::Validations::Types::VariantCollectionCoercer)
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Validations
5
+ module Validators
6
+ class ContractScopeValidator < Base
7
+ attr_reader :schema
8
+
9
+ def initialize(_attrs, _options, _required, _scope, opts)
10
+ super
11
+ @schema = opts.fetch(:schema)
12
+ end
13
+
14
+ # Validates a given request.
15
+ # @param request [Grape::Request] the request currently being handled
16
+ # @raise [Grape::Exceptions::ValidationArrayErrors] if validation failed
17
+ # @return [void]
18
+ def validate(request)
19
+ res = schema.call(request.params)
20
+
21
+ if res.success?
22
+ request.params.deep_merge!(res.to_h)
23
+ return
24
+ end
25
+
26
+ raise Grape::Exceptions::ValidationArrayErrors.new(build_errors_from_messages(res.errors.messages))
27
+ end
28
+
29
+ private
30
+
31
+ def build_errors_from_messages(messages)
32
+ messages.map do |message|
33
+ full_name = message.path.first.to_s
34
+ full_name << "[#{message.path[1..].join('][')}]" if message.path.size > 1
35
+ Grape::Exceptions::Validation.new(params: [full_name], message: message.text)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -4,7 +4,7 @@ module Grape
4
4
  module Validations
5
5
  module Validators
6
6
  class DefaultValidator < Base
7
- def initialize(attrs, options, required, scope, **opts)
7
+ def initialize(attrs, options, required, scope, opts = {})
8
8
  @default = options
9
9
  super
10
10
  end
@@ -4,7 +4,7 @@ module Grape
4
4
  module Validations
5
5
  module Validators
6
6
  class ExceptValuesValidator < Base
7
- def initialize(attrs, options, required, scope, **opts)
7
+ def initialize(attrs, options, required, scope, opts)
8
8
  @except = options.is_a?(Hash) ? options[:value] : options
9
9
  super
10
10
  end
@@ -4,7 +4,7 @@ module Grape
4
4
  module Validations
5
5
  module Validators
6
6
  class LengthValidator < Base
7
- def initialize(attrs, options, required, scope, **opts)
7
+ def initialize(attrs, options, required, scope, opts)
8
8
  @min = options[:min]
9
9
  @max = options[:max]
10
10
  @is = options[:is]
@@ -6,7 +6,7 @@ module Grape
6
6
  class RegexpValidator < Base
7
7
  def validate_param!(attr_name, params)
8
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)) }
9
+ return if Array.wrap(params[attr_name]).all? { |param| param.nil? || param.to_s.scrub.match?((options_key?(:value) ? @option[:value] : @option)) }
10
10
 
11
11
  raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:regexp))
12
12
  end
@@ -4,23 +4,8 @@ module Grape
4
4
  module Validations
5
5
  module Validators
6
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
- Grape.deprecator.warn('The values validator except option is deprecated. Use the except validator instead.') if @excepts
14
-
15
- raise ArgumentError, 'proc must be a Proc' if @proc && !@proc.is_a?(Proc)
16
-
17
- Grape.deprecator.warn('The values validator proc option is deprecated. The lambda expression can now be assigned directly to values.') if @proc
18
- else
19
- @excepts = nil
20
- @values = nil
21
- @proc = nil
22
- @values = options
23
- end
7
+ def initialize(attrs, options, required, scope, opts)
8
+ @values = options.is_a?(Hash) ? options[:value] : options
24
9
  super
25
10
  end
26
11
 
@@ -31,57 +16,34 @@ module Grape
31
16
 
32
17
  return if val.nil? && !required_for_root_scope?
33
18
 
19
+ val = val.scrub if val.respond_to?(:scrub)
20
+
34
21
  # don't forget that +false.blank?+ is true
35
22
  return if val != false && val.blank? && @allow_blank
36
23
 
37
- param_array = val.nil? ? [nil] : Array.wrap(val)
38
-
39
- raise validation_exception(attr_name, except_message) \
40
- unless check_excepts(param_array)
41
-
42
- raise validation_exception(attr_name, message(:values)) \
43
- unless check_values(param_array, attr_name)
24
+ return if check_values?(val, attr_name)
44
25
 
45
- raise validation_exception(attr_name, message(:values)) \
46
- if @proc && !validate_proc(@proc, param_array)
26
+ raise Grape::Exceptions::Validation.new(
27
+ params: [@scope.full_name(attr_name)],
28
+ message: message(:values)
29
+ )
47
30
  end
48
31
 
49
32
  private
50
33
 
51
- def check_values(param_array, attr_name)
34
+ def check_values?(val, attr_name)
52
35
  values = @values.is_a?(Proc) && @values.arity.zero? ? @values.call : @values
53
36
  return true if values.nil?
54
37
 
38
+ param_array = val.nil? ? [nil] : Array.wrap(val)
39
+ return param_array.all? { |param| values.include?(param) } unless values.is_a?(Proc)
40
+
55
41
  begin
56
- return param_array.all? { |param| values.call(param) } if values.is_a? Proc
42
+ param_array.all? { |param| values.call(param) }
57
43
  rescue StandardError => e
58
44
  warn "Error '#{e}' raised while validating attribute '#{attr_name}'"
59
- return false
45
+ false
60
46
  end
61
- param_array.all? { |param| values.include?(param) }
62
- end
63
-
64
- def check_excepts(param_array)
65
- excepts = @excepts.is_a?(Proc) ? @excepts.call : @excepts
66
- return true if excepts.nil?
67
-
68
- param_array.none? { |param| excepts.include?(param) }
69
- end
70
-
71
- def validate_proc(proc, param_array)
72
- case proc.arity
73
- when 0
74
- param_array.all? { |_param| proc.call }
75
- when 1
76
- param_array.all? { |param| proc.call(param) }
77
- else
78
- raise ArgumentError, 'proc arity must be 0 or 1'
79
- end
80
- end
81
-
82
- def except_message
83
- options = instance_variable_get(:@option)
84
- options_key?(:except_message) ? options[:except_message] : message(:except_values)
85
47
  end
86
48
 
87
49
  def required_for_root_scope?
@@ -92,10 +54,6 @@ module Grape
92
54
 
93
55
  scope.root?
94
56
  end
95
-
96
- def validation_exception(attr_name, message)
97
- Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message)
98
- end
99
57
  end
100
58
  end
101
59
  end
@@ -2,29 +2,20 @@
2
2
 
3
3
  module Grape
4
4
  module Validations
5
+ extend Grape::Util::Registry
6
+
5
7
  module_function
6
8
 
7
- def validators
8
- @validators ||= {}
9
- end
9
+ def require_validator(short_name)
10
+ raise Grape::Exceptions::UnknownValidator, short_name unless registry.key?(short_name)
10
11
 
11
- # Register a new validator, so it can be used to validate parameters.
12
- # @param short_name [String] all lower-case, no spaces
13
- # @param klass [Class] the validator class. Should inherit from
14
- # Grape::Validations::Validators::Base.
15
- def register_validator(short_name, klass)
16
- validators[short_name] = klass
12
+ registry[short_name]
17
13
  end
18
14
 
19
- def deregister_validator(short_name)
20
- validators.delete(short_name)
21
- end
15
+ def build_short_name(klass)
16
+ return if klass.name.blank?
22
17
 
23
- def require_validator(short_name)
24
- str_name = short_name.to_s
25
- validators.fetch(str_name) { Grape::Validations::Validators.const_get(:"#{str_name.camelize}Validator") }
26
- rescue NameError
27
- raise Grape::Exceptions::UnknownValidator, short_name
18
+ klass.name.demodulize.underscore.delete_suffix('_validator')
28
19
  end
29
20
  end
30
21
  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 = '2.2.0'
5
+ VERSION = '2.3.0'
6
6
  end
data/lib/grape.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'logger'
3
4
  require 'active_support'
4
5
  require 'active_support/concern'
5
6
  require 'active_support/configurable'
@@ -33,7 +34,6 @@ require 'date'
33
34
  require 'dry-types'
34
35
  require 'forwardable'
35
36
  require 'json'
36
- require 'logger'
37
37
  require 'mustermann/grape'
38
38
  require 'pathname'
39
39
  require 'rack'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-09-14 00:00:00.000000000 Z
10
+ date: 2025-02-08 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -120,6 +119,8 @@ files:
120
119
  - lib/grape/error_formatter.rb
121
120
  - lib/grape/error_formatter/base.rb
122
121
  - lib/grape/error_formatter/json.rb
122
+ - lib/grape/error_formatter/jsonapi.rb
123
+ - lib/grape/error_formatter/serializable_hash.rb
123
124
  - lib/grape/error_formatter/txt.rb
124
125
  - lib/grape/error_formatter/xml.rb
125
126
  - lib/grape/exceptions/base.rb
@@ -149,6 +150,7 @@ files:
149
150
  - lib/grape/extensions/hash.rb
150
151
  - lib/grape/extensions/hashie/mash.rb
151
152
  - lib/grape/formatter.rb
153
+ - lib/grape/formatter/base.rb
152
154
  - lib/grape/formatter/json.rb
153
155
  - lib/grape/formatter/serializable_hash.rb
154
156
  - lib/grape/formatter/txt.rb
@@ -169,13 +171,15 @@ files:
169
171
  - lib/grape/middleware/stack.rb
170
172
  - lib/grape/middleware/versioner.rb
171
173
  - lib/grape/middleware/versioner/accept_version_header.rb
174
+ - lib/grape/middleware/versioner/base.rb
172
175
  - lib/grape/middleware/versioner/header.rb
173
176
  - lib/grape/middleware/versioner/param.rb
174
177
  - lib/grape/middleware/versioner/path.rb
175
- - lib/grape/middleware/versioner_helpers.rb
176
178
  - lib/grape/namespace.rb
177
179
  - lib/grape/parser.rb
180
+ - lib/grape/parser/base.rb
178
181
  - lib/grape/parser/json.rb
182
+ - lib/grape/parser/jsonapi.rb
179
183
  - lib/grape/parser/xml.rb
180
184
  - lib/grape/path.rb
181
185
  - lib/grape/presenters/presenter.rb
@@ -203,6 +207,7 @@ files:
203
207
  - lib/grape/util/lazy/value_enumerable.rb
204
208
  - lib/grape/util/lazy/value_hash.rb
205
209
  - lib/grape/util/media_type.rb
210
+ - lib/grape/util/registry.rb
206
211
  - lib/grape/util/reverse_stackable_values.rb
207
212
  - lib/grape/util/stackable_values.rb
208
213
  - lib/grape/util/strict_hash_configuration.rb
@@ -215,7 +220,6 @@ files:
215
220
  - lib/grape/validations/single_attribute_iterator.rb
216
221
  - lib/grape/validations/types.rb
217
222
  - lib/grape/validations/types/array_coercer.rb
218
- - lib/grape/validations/types/build_coercer.rb
219
223
  - lib/grape/validations/types/custom_type_coercer.rb
220
224
  - lib/grape/validations/types/custom_type_collection_coercer.rb
221
225
  - lib/grape/validations/types/dry_type_coercer.rb
@@ -233,6 +237,7 @@ files:
233
237
  - lib/grape/validations/validators/at_least_one_of_validator.rb
234
238
  - lib/grape/validations/validators/base.rb
235
239
  - lib/grape/validations/validators/coerce_validator.rb
240
+ - lib/grape/validations/validators/contract_scope_validator.rb
236
241
  - lib/grape/validations/validators/default_validator.rb
237
242
  - lib/grape/validations/validators/exactly_one_of_validator.rb
238
243
  - lib/grape/validations/validators/except_values_validator.rb
@@ -250,11 +255,10 @@ licenses:
250
255
  - MIT
251
256
  metadata:
252
257
  bug_tracker_uri: https://github.com/ruby-grape/grape/issues
253
- changelog_uri: https://github.com/ruby-grape/grape/blob/v2.2.0/CHANGELOG.md
254
- documentation_uri: https://www.rubydoc.info/gems/grape/2.2.0
255
- source_code_uri: https://github.com/ruby-grape/grape/tree/v2.2.0
258
+ changelog_uri: https://github.com/ruby-grape/grape/blob/v2.3.0/CHANGELOG.md
259
+ documentation_uri: https://www.rubydoc.info/gems/grape/2.3.0
260
+ source_code_uri: https://github.com/ruby-grape/grape/tree/v2.3.0
256
261
  rubygems_mfa_required: 'true'
257
- post_install_message:
258
262
  rdoc_options: []
259
263
  require_paths:
260
264
  - lib
@@ -269,8 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
269
273
  - !ruby/object:Gem::Version
270
274
  version: '0'
271
275
  requirements: []
272
- rubygems_version: 3.5.13
273
- signing_key:
276
+ rubygems_version: 3.6.2
274
277
  specification_version: 4
275
278
  summary: A simple Ruby framework for building REST-like APIs.
276
279
  test_files: []
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grape
4
- module Middleware
5
- module VersionerHelpers
6
- DEFAULT_PATTERN = /.*/i.freeze
7
- DEFAULT_PARAMETER = 'apiver'
8
-
9
- def default_options
10
- {
11
- versions: nil,
12
- prefix: nil,
13
- mount_path: nil,
14
- pattern: DEFAULT_PATTERN,
15
- version_options: {
16
- strict: false,
17
- cascade: true,
18
- parameter: DEFAULT_PARAMETER
19
- }
20
- }
21
- end
22
-
23
- def versions
24
- options[:versions]
25
- end
26
-
27
- def prefix
28
- options[:prefix]
29
- end
30
-
31
- def mount_path
32
- options[:mount_path]
33
- end
34
-
35
- def pattern
36
- options[:pattern]
37
- end
38
-
39
- def version_options
40
- options[:version_options]
41
- end
42
-
43
- def strict?
44
- version_options[:strict]
45
- end
46
-
47
- # By default those errors contain an `X-Cascade` header set to `pass`, which allows nesting and stacking
48
- # of routes (see Grape::Router) for more information). To prevent
49
- # this behavior, and not add the `X-Cascade` header, one can set the `:cascade` option to `false`.
50
- def cascade?
51
- version_options[:cascade]
52
- end
53
-
54
- def parameter_key
55
- version_options[:parameter]
56
- end
57
-
58
- def vendor
59
- version_options[:vendor]
60
- end
61
-
62
- def error_headers
63
- cascade? ? { Grape::Http::Headers::X_CASCADE => 'pass' } : {}
64
- end
65
-
66
- def potential_version_match?(potential_version)
67
- versions.blank? || versions.any? { |v| v.to_s == potential_version }
68
- end
69
-
70
- def version_not_found!
71
- throw :error, status: 404, message: '404 API Version Not Found', headers: { Grape::Http::Headers::X_CASCADE => 'pass' }
72
- end
73
- end
74
- end
75
- end