paramore 3.2.0 → 3.6.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: b8620a326873694bcc720cd186b9f4998fde3ab3fc102e2cb81b55822accc1e1
4
- data.tar.gz: '07288ff15f31bb8480fc30662da17cd6aba34617afff96cd488c205b2c4c4660'
3
+ metadata.gz: 0e3e663f7752add2ed7c167643bdc789c5aec5421455440f094942b06ca49c57
4
+ data.tar.gz: 9ccdaec01fdd4e5ce1b337d3e8ca7a84c812acd38b817d015b980d279b0d43c9
5
5
  SHA512:
6
- metadata.gz: 753ede1706d8dc9563bfa8cfad77683586ac319aefd4f84f80b6247d0daa7054710809a4ae24f812196402a83628d0760992ba8f281de79197e9b69cd39f9570
7
- data.tar.gz: '078b73a5da242dc7fb75d1175232af4d52928d1cd5db1af9366ca2e95fec990c7ec0e37eaf48c3560e8f27f47a351d03bd448589354bd1f335cc3951763702f5'
6
+ metadata.gz: a571718b5125d6d7f6078b85cb0ef4d201c33731ad8a4eb4255550746562bdd6824a5207a11ec6a3a58a044e0cc5c5a78f0acd33246f7e419e1be1049f3c4eee
7
+ data.tar.gz: 3966ac01cadb45e454b001fbd0044778794dc437af95a6c3faeefe0663a9412a910ffa4fdede25b7508c4f029185ace67af5975630bde5d970b55311df7e1a38
@@ -9,7 +9,7 @@ module Paramore
9
9
 
10
10
  def cast(field, value, name = nil)
11
11
  if value.nil?
12
- if field.nullable? || field.default
12
+ if field.nullable? || field.default?
13
13
  return field.default
14
14
  else
15
15
  raise Paramore::NilParameter, name
@@ -18,32 +18,53 @@ module Paramore
18
18
 
19
19
  case field.type
20
20
  when Hash
21
- typecast_hash(field.type, value || {})
21
+ typecast_hash(field, value || {}, name)
22
22
  when Array
23
- typecast_array(field, value)
23
+ typecast_array(field, value, name)
24
24
  else
25
25
  if value == '' && !field.allow_empty? && field.nullable?
26
26
  nil
27
27
  else
28
- typecast_value(field.type, value)
28
+ typecast_value(field.type, value, name)
29
29
  end
30
30
  end
31
31
  end
32
32
 
33
- def typecast_hash(field, hash)
34
- field.to_h { |name, field| [name, cast(field, hash[name], name)] }
33
+ def typecast_hash(field, hash, name)
34
+ raise Paramore::HashExpected.new(name, hash) unless hash.is_a?(Hash)
35
+
36
+ result =
37
+ if field.wildly_keyed_hash?
38
+ value_field = field.type.values.first
39
+ key_type = field.type.keys.first
40
+ hash.to_h do |name, value|
41
+ [typecast_value(key_type, name, nil), cast(value_field, value, name)]
42
+ end
43
+ else
44
+ field
45
+ .type
46
+ .reject { |name, value_field| missing_and_optional?(hash, name, value_field) }
47
+ .to_h { |name, value_field| [name, cast(value_field, hash[name], name)] }
48
+ end
49
+
50
+
51
+ field.compact? ? result.compact : result
35
52
  end
36
53
 
37
- def typecast_array(field, array)
54
+ def typecast_array(field, array, name)
55
+ raise Paramore::ArrayExpected.new(name, array) unless array.is_a?(Array)
56
+
38
57
  array
39
58
  .reject { |unit| unit.to_s == '' && field.compact? }
40
- .map do |unit|
41
- cast(Paramore.field(field.type.first, null: true), unit)
42
- end
59
+ .map { |unit| cast(Paramore.field(field.type.first, null: true), unit) }
43
60
  end
44
61
 
45
- def typecast_value(type, value)
62
+ def typecast_value(type, value, name)
46
63
  type.send(Paramore.configuration.type_method_name, value)
47
64
  end
65
+
66
+ def missing_and_optional?(hash, name, field)
67
+ !hash.key?(name) && !field.required?
68
+ end
48
69
  end
49
70
  end
@@ -9,3 +9,21 @@ class Paramore::NonField < StandardError
9
9
  super("`#{param_name}` defined as a `#{type.class}`, expected a call of `Paramore.field()`! Perhaps you declared a plain hash instead of Paramore.field({})?")
10
10
  end
11
11
  end
12
+
13
+ class Paramore::HashExpected < StandardError
14
+ def initialize(param_name, param)
15
+ super("Expected `#{param_name}` to be a hash, received #{param.class} instead!")
16
+ end
17
+ end
18
+
19
+ class Paramore::ArrayExpected < StandardError
20
+ def initialize(param_name, param)
21
+ super("Expected `#{param_name}` to be an array, received #{param.class} instead!")
22
+ end
23
+ end
24
+
25
+ class Paramore::HashTooWild < StandardError
26
+ def initialize(hash)
27
+ super("A hash field with a type as key may not contain any more entries! (so, eg.: { String => field } is ok, but { String => field, user_id: field } is not)")
28
+ end
29
+ end
@@ -1,4 +1,3 @@
1
- require_relative 'validate'
2
1
  require_relative 'cast_parameters'
3
2
  require_relative 'permitted_parameter_argument'
4
3
 
@@ -8,6 +7,10 @@ module Paramore
8
7
  default
9
8
  ].freeze
10
9
 
10
+ def field(*args)
11
+ Paramore.field(*args)
12
+ end
13
+
11
14
  def param_schema(accessor_name, parameter_configuration)
12
15
  unless parameter_configuration.keys.size == 1
13
16
  raise ArgumentError,
@@ -17,8 +20,6 @@ module Paramore
17
20
  required_parameter_name = parameter_configuration.keys.first
18
21
  types_definition = parameter_configuration.values.first
19
22
 
20
- Paramore::Validate.run(types_definition) if types_definition.is_a?(Paramore::Field)
21
-
22
23
  permitted_parameter_argument =
23
24
  if types_definition.is_a?(Paramore::Field)
24
25
  Paramore::PermittedParameterArgument.parse(types_definition)
@@ -41,7 +42,7 @@ module Paramore
41
42
  parameter_values =
42
43
  if types_definition.is_a?(Paramore::Field)
43
44
  permitted_params.merge(
44
- Paramore::CastParameters.run(types_definition, permitted_params)
45
+ Paramore::CastParameters.run(types_definition, permitted_params.to_hash.with_indifferent_access)
45
46
  ).permit!
46
47
  else
47
48
  permitted_params.permit!
@@ -1,3 +1,5 @@
1
+ require_relative 'validate'
2
+
1
3
  module Paramore
2
4
  class Field
3
5
  DEFAULT_OPTIONS = {
@@ -5,22 +7,32 @@ module Paramore
5
7
  compact: false,
6
8
  default: nil,
7
9
  empty: true,
10
+ required: true,
8
11
  }.freeze
9
12
 
10
- def initialize(given_type, null:, compact:, default:, empty:)
13
+ def initialize(given_type, null:, compact:, default:, empty:, required:)
11
14
  @given_type = given_type
12
15
  @nullable = null
13
16
  @compact = compact
14
17
  @allow_empty = empty
15
18
  @default = default
19
+ @required = required
20
+ end
21
+
22
+ def required?
23
+ @required
16
24
  end
17
25
 
18
26
  def allow_empty?
19
27
  @allow_empty
20
28
  end
21
29
 
30
+ def default?
31
+ !@default.nil?
32
+ end
33
+
22
34
  def default
23
- @default
35
+ @default.is_a?(Proc) ? @default.call : @default
24
36
  end
25
37
 
26
38
  def compact?
@@ -34,5 +46,17 @@ module Paramore
34
46
  def type
35
47
  @given_type
36
48
  end
49
+
50
+ def wildly_keyed_hash?
51
+ type.is_a?(Hash) && self.class.wildly_keyed_hash?(type)
52
+ end
53
+
54
+ def validate!
55
+ Paramore::Validate.run(self)
56
+ end
57
+
58
+ def self.wildly_keyed_hash?(hash)
59
+ hash.keys.any? { |key| [Class, Module].include?(key.class) }
60
+ end
37
61
  end
38
62
  end
@@ -49,4 +49,11 @@ module Paramore
49
49
  Paramore::StrippedString[input].squeeze(' ')
50
50
  end
51
51
  end
52
+
53
+ module Date
54
+ module_function
55
+ def [](input)
56
+ input.to_date
57
+ end
58
+ end
52
59
  end
@@ -26,11 +26,23 @@ module Paramore
26
26
  end
27
27
 
28
28
  def hash_types(hash)
29
+ validate_wildly_keyed_hash!(hash)
30
+
29
31
  hash.flat_map do |param_name, field|
30
32
  raise Paramore::NonField.new(param_name, field) unless field.is_a?(Paramore::Field)
31
33
 
32
34
  field.type.is_a?(Hash) ? types(field.type) : field.type
33
35
  end.uniq
34
36
  end
37
+
38
+ def validate_wildly_keyed_hash!(hash)
39
+ if Paramore::Field.wildly_keyed_hash?(hash) && hash.keys.map(&:class).count > 1
40
+ raise Paramore::HashTooWild.new(hash)
41
+ end
42
+ end
43
+
44
+ def wildly_keyed_hash?(hash)
45
+ [Class, Module].include?(hash.keys.first.class)
46
+ end
35
47
  end
36
48
  end
data/lib/paramore.rb CHANGED
@@ -20,6 +20,6 @@ module Paramore
20
20
  Paramore::Field.new(
21
21
  given_type,
22
22
  **Paramore::Field::DEFAULT_OPTIONS.merge(options)
23
- )
23
+ ).validate!
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paramore
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukas Kairevičius
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-20 00:00:00.000000000 Z
11
+ date: 2021-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-rails
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rails
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -101,7 +115,7 @@ licenses:
101
115
  - MIT
102
116
  metadata: {}
103
117
  post_install_message: |
104
- Thank you for installing Paramore 3.2.0 !
118
+ Thank you for installing Paramore 3.6.0 !
105
119
  From the command line you can run `paramore` to generate a configuration file
106
120
 
107
121
  More details here : https://github.com/lumzdas/paramore/blob/master/README.md
@@ -120,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
134
  - !ruby/object:Gem::Version
121
135
  version: '0'
122
136
  requirements: []
123
- rubygems_version: 3.0.8
137
+ rubygems_version: 3.2.3
124
138
  signing_key:
125
139
  specification_version: 4
126
140
  summary: A declarative approach to Rails' strong parameter typing and sanitizing