validate-params 0.11.0 → 0.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40dd463b2500f9e2ab704d35c033763aaf80299e71796104889cc5850aaa1c50
4
- data.tar.gz: f0ba27d4568a6dab4e3770cd967085654701fcdd24d74e15519e2d5302c5dce0
3
+ metadata.gz: 29df4493a4e78d2a93b953b423b01a87870e49e9178720971eba9174aa0a5e1e
4
+ data.tar.gz: 6368b7cbf5240ff8d05ef54a402fc52ec800e181a6104f4219bae02270745b62
5
5
  SHA512:
6
- metadata.gz: 9c9b40b0a3f57659b9b5c86713888d0ef8d294bbe21505cc065a406548e032626d1a625a72e72236a895dddc9ea03288c62668de03b437d06d0f1c67f76fc467
7
- data.tar.gz: 728615aee1a6082e3816bde334fa064ef7462a9bef9833f029d330ebd98409807a367988def4f4c5c984a2afecdd80e2839296ecf12f351c7647d1a0a54f8434
6
+ metadata.gz: 63379593455a6bf06bb6d8633b8387d170bc602114e53cd5107cbc7e9e5fee524cb66c86d5e7675a9d4e300cc380d982be8cf8739cf34e59e3d4bc76b1c26d0e
7
+ data.tar.gz: 371f096da45f2eeed375607d1181e227b843b18241c43a9601db90bf8d0357939f65c1413814a7ee031472b504acd776ca72c3d8f1b184a1a05254d938d7de9c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- validate-params (0.11.0)
4
+ validate-params (0.12.0)
5
5
  activesupport (>= 6.1.0)
6
6
  i18n (>= 1.6)
7
7
 
@@ -3,27 +3,60 @@
3
3
  module ValidateParams
4
4
  module Validatable
5
5
  class ParamBuilder
6
- def initialize(parent_field: nil, validations:)
7
- @parent_field = parent_field
8
- @validations = validations
9
- end
6
+ Validation = Struct.new(:field, :type, :options, :children, :parent) do
7
+ def valid?(value, errors)
8
+ ParamValidator.call(
9
+ validation: self,
10
+ value: value,
11
+ errors: errors
12
+ )
10
13
 
11
- def param(field, type, options = {}, &block)
12
- if block
13
- yield(ParamBuilder.new(parent_field: field, validations: @validations))
14
- else
15
- @validations << build_config(field, type, options)
14
+ if children.any?
15
+ case type.to_s
16
+ when "Hash"
17
+ # Skip in case hash is configured and string is passed
18
+ if !value.is_a?(String)
19
+ children.each { |c| c.valid?(value&.[](c.field), errors) }
20
+ end
21
+ when "Array"
22
+ values = value ? Array.wrap(value) : [nil]
23
+ values.each do |item|
24
+ children.each do |child|
25
+ child_value = item[child.field] if item.is_a?(Hash) || item.is_a?(Array)
26
+ child.valid?(child_value, errors)
27
+ end
28
+ end
29
+ else
30
+ raise "Unexpected type: #{type}"
31
+ end
32
+ end
33
+
34
+ errors.empty?
16
35
  end
17
36
  end
18
37
 
19
- private
20
- def build_config(field, type, options)
21
- if @parent_field.nil?
22
- { field: field, type: type, options: options }
23
- else
24
- { field: { @parent_field => field }, type: type, options: options }
38
+ def initialize(parent: nil, validations: [])
39
+ @parent = parent
40
+ @validations = validations
41
+ end
42
+
43
+ def param(field, type, options = {})
44
+ validation = Validation.new(field, type, options, [], @parent)
45
+
46
+ if block_given?
47
+ if ![Array, Hash].include?(type)
48
+ raise "#{type} type cannot have nested definitions, only Array or Hash are supported"
25
49
  end
50
+
51
+ yield ParamBuilder.new(parent: validation)
26
52
  end
53
+
54
+ if @parent
55
+ @parent.children << validation
56
+ else
57
+ @validations << validation
58
+ end
59
+ end
27
60
  end
28
61
  end
29
62
  end
@@ -9,12 +9,13 @@ module ValidateParams
9
9
  new(**args).call
10
10
  end
11
11
 
12
- def initialize(type:, field:, value:, errors:, options: {})
13
- @type = type
14
- @field = field
12
+ attr_reader :validation
13
+
14
+ def initialize(validation:, value:, errors:)
15
+ @validation = validation
15
16
  @value = value
16
17
  @errors = errors
17
- @options = options
18
+ @options = validation.options.presence || {}
18
19
  end
19
20
 
20
21
  def call
@@ -25,7 +26,7 @@ module ValidateParams
25
26
  return
26
27
  end
27
28
 
28
- send(@type.to_s.underscore)
29
+ send(validation.type.to_s.underscore)
29
30
  end
30
31
 
31
32
  private
@@ -129,18 +130,15 @@ module ValidateParams
129
130
  end
130
131
 
131
132
  def error_param_name
132
- case @field
133
- when Array
134
- "#{@field[0]}[#{@field[1]}]"
135
- when Hash
136
- @field.map { |k, v| "#{k}[#{v}]" }.first
133
+ if validation.parent
134
+ "#{validation.parent.field}[#{validation.field}]"
137
135
  else
138
- @field
136
+ validation.field
139
137
  end
140
138
  end
141
139
 
142
140
  def error_message
143
- I18n.t("validate_params.invalid_type", param: error_param_name, type: @type)
141
+ I18n.t("validate_params.invalid_type", param: error_param_name, type: validation.type)
144
142
  end
145
143
 
146
144
  def required_error_message
@@ -3,7 +3,7 @@
3
3
  module ValidateParams
4
4
  class Types
5
5
  class Array
6
- def self.valid?(value, of: String, reject_blank: false, **)
6
+ def self.valid?(value, of: ::String, reject_blank: false, **)
7
7
  return false unless value.is_a?(::Array)
8
8
 
9
9
  val = value
@@ -16,12 +16,14 @@ module ValidateParams
16
16
  val.all? { |item| Types::Float.valid?(item) }
17
17
  when "String"
18
18
  val.all? { |item| item.is_a?(::String) }
19
+ when "Hash"
20
+ val.all? { |item| item.is_a?(::Hash) }
19
21
  else
20
22
  true
21
23
  end
22
24
  end
23
25
 
24
- def self.cast(raw_value, of: String, reject_blank: false, **)
26
+ def self.cast(raw_value, of: ::String, reject_blank: false, **)
25
27
  value = raw_value
26
28
  value.reject!(&:blank?) if reject_blank
27
29
 
@@ -23,14 +23,17 @@ module ValidateParams
23
23
  class_methods do
24
24
  attr_reader :params_validations
25
25
 
26
- def validate_params_for(action, options = {}, &block)
26
+ def validate_params_for(action, options = {})
27
27
  options[:format] ||= :json
28
28
  @params_validations ||= {}
29
29
 
30
30
  Array(action).each do |act|
31
31
  @params_validations[act] ||= { options: options, validations: [] }
32
32
 
33
- yield(ParamBuilder.new(validations: @params_validations[act][:validations])) if block
33
+ if block_given?
34
+ param_builder = ParamBuilder.new(validations: @params_validations[act][:validations])
35
+ yield(param_builder)
36
+ end
34
37
  end
35
38
  end
36
39
  end
@@ -47,29 +50,15 @@ module ValidateParams
47
50
  config = params_validations[action_name.to_sym]
48
51
 
49
52
  config[:validations].each do |validation|
50
- apply_default_values(validation)
51
-
52
- next if validation[:field].is_a?(Hash) &&
53
- params[validation[:field].keys.first].is_a?(String)
54
-
55
- parameter_value = if validation[:field].is_a? Hash
56
- params.dig(validation[:field].keys.first,
57
- validation[:field][validation[:field].keys.first])
58
- else
59
- params[validation[:field]]
60
- end
61
-
62
- ParamValidator.call(
63
- type: validation[:type],
64
- field: validation[:field],
65
- value: parameter_value,
66
- errors: errors,
67
- options: validation[:options]
68
- )
53
+ apply_default_values(params, validation)
54
+ validation.valid?(params[validation.field], errors)
69
55
  end
70
56
 
71
57
  if errors.empty?
72
- cast_param_values(config[:validations])
58
+ config[:validations].each do |validation|
59
+ cast_param_values(params, validation)
60
+ end
61
+
73
62
  return
74
63
  end
75
64
 
@@ -81,57 +70,57 @@ module ValidateParams
81
70
  end
82
71
  end
83
72
 
84
- def apply_default_values(validation)
85
- return unless validation[:options].key?(:default)
73
+ def apply_default_values(params, validation)
74
+ validation.children.each do |sub_validation|
75
+ next if sub_validation.options.blank?
86
76
 
87
- if validation[:field].is_a?(Hash)
88
- validation[:field].each_key do |key|
77
+ if validation.type == Array
78
+ Array(params[validation.field]).each do |sub_params|
79
+ apply_default_values(sub_params, sub_validation)
80
+ end
81
+ elsif validation.type == Hash
89
82
  # Skip in case hash is configured and string is passed
90
- next if hashlike?(params[key])
91
- next if params.dig(key, validation[:field][key])
92
-
93
- value = if validation[:options][:default].is_a?(Proc)
94
- validation[:options][:default].call
95
- else
96
- validation[:options][:default]
97
- end
83
+ next if params[validation.field].is_a?(String)
98
84
 
99
- params[key] ||= {}
100
- params[key][validation[:field][key]] = value
85
+ params[validation.field] ||= {}
86
+ apply_default_values(params[validation.field], sub_validation)
87
+ else
88
+ apply_default_values(params, sub_validation)
101
89
  end
102
- else
103
- value = if validation[:options][:default].is_a?(Proc)
104
- validation[:options][:default].call
105
- else
106
- validation[:options][:default]
107
- end
108
-
109
- params[validation[:field]] ||= value
110
90
  end
91
+
92
+ return if validation.children.any?
93
+
94
+ options = validation.options.presence || {}
95
+ return if !options.key?(:default)
96
+
97
+ value = options[:default].is_a?(Proc) ? options[:default].call : options[:default]
98
+ params[validation.field] ||= value
111
99
  end
112
100
 
113
- def cast_param_values(validations)
114
- validations.each do |validation|
115
- if validation[:field].is_a?(Hash)
116
- validation[:field].each_key do |key|
117
- next unless hashlike?(params[key])
101
+ def cast_param_values(params, validation)
102
+ return unless params
118
103
 
119
- value = params.dig(key, validation[:field][key])
120
- next if value.blank?
104
+ validation.children.each do |sub_validation|
105
+ if validation.type == Hash
106
+ # Skip in case hash is configured and string is passed
107
+ next if params[validation.field].is_a?(String)
121
108
 
122
- params[key][validation[:field][key]] = Types.const_get(validation[:type].name).cast(value, **validation.fetch(:options, {}))
109
+ cast_param_values(params[validation.field], sub_validation)
110
+ elsif validation.type == Array
111
+ params[validation.field].each do |sub_params|
112
+ cast_param_values(sub_params, sub_validation)
123
113
  end
124
- else
125
- value = params[validation[:field]]
126
- next if value.blank?
127
-
128
- params[validation[:field]] = Types.const_get(validation[:type].name).cast(value, **validation.fetch(:options, {}))
129
114
  end
130
115
  end
131
- end
132
116
 
133
- def hashlike?(obj)
134
- obj.is_a?(Hash) || obj.is_a?(ActionController::Parameters)
117
+ return if validation.children.any?
118
+
119
+ value = params[validation.field]
120
+ return if value.blank?
121
+
122
+ options = validation.options.presence || {}
123
+ params[validation.field] = Types.const_get(validation.type.name).cast(value, **options)
135
124
  end
136
125
  end
137
126
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ValidateParams
4
- VERSION = "0.11.0"
4
+ VERSION = "0.12.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validate-params
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dcherevatenko
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-06 00:00:00.000000000 Z
11
+ date: 2024-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack