paramore 0.2.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78c8a8c6985a0f9044fa608f0473cbd6ce872c5ff7f9626a2fb6e49f39c67f69
4
- data.tar.gz: c6c18de5f2dd039d06044ba58f7c4bfc38dda160fd6730213748c883529f8823
3
+ metadata.gz: 2a45a04ffeaabb270fd7b57a2e27e195205a26ad281c46d69561040d71fb6961
4
+ data.tar.gz: 0df60483be44946c6e1fedb711039d5a915787c54e46c5f841c73172393e35f9
5
5
  SHA512:
6
- metadata.gz: e406c95c757d7c583fb5d962f4b453c8dbda6dc141ad581169aab7ba767e2903723eb31c830ef8f55b98e5a12606feb578644141800e64a154217c0cd2f886e0
7
- data.tar.gz: 9061803ea9cdcccd492bb58f280d0037e01870c61d7dd30d8fad1d1ceabcb580f0e715531cf71ceff6fb8f875f60810ec95d7cfbedb14594f6fc65e85d491a1e
6
+ metadata.gz: f0f3ed2da9f139467f5d4f6db3d7cbc7f0b29c3c1385a4eb8835d0cbffced915d0c77700d69722d11807984624e611856b2acd36462fe6ea4cb577736f8c6255
7
+ data.tar.gz: decf8bc3cbaa99c75ce7070b59f58f4e84d5cd0b3d22681836ae56f61596a600f3777e58c929d9db31a698689ea07a7b00330d45f54a9706262b512734b07393
data/README.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # Paramore
2
2
 
3
3
  Paramore is a small gem intended to make strong parameter definitions declarative
4
- and provide a unified way to format and sanitize their values outside of controllers.
4
+ and provide a unified way to typecast and sanitize their values outside of controllers.
5
5
 
6
6
  # Installation
7
7
 
8
-
9
8
  In your Gemfile:
10
9
  ```ruby
11
10
  gem 'paramore'
@@ -18,14 +17,14 @@ $ bundle
18
17
 
19
18
  # Usage
20
19
 
21
- <h3>Without formatting/sanitizing</h3>
20
+ <h3>Without typing</h3>
22
21
 
23
22
  ```ruby
24
- declare_params :item_params
23
+ paramorize :item_params,
25
24
  item: [:name, :description, :for_sale, :price, metadata: [tags: []]]
26
25
  ```
27
26
 
28
- This is completely equivalent (including return type) to
27
+ This is completely equivalent (including the return type) to
29
28
 
30
29
  ```ruby
31
30
  def item_params
@@ -35,10 +34,10 @@ def item_params
35
34
  end
36
35
  ```
37
36
 
38
- <h3>With formatting/sanitizing</h3>
37
+ <h3>With typing</h3>
39
38
 
40
39
  A common problem in app development is untrustworthy input given by clients.
41
- That input needs to be sanitized and potentially formatted and type-cast for further processing.
40
+ That input needs to be sanitized and typecast for further processing.
42
41
  A naive approach could be:
43
42
 
44
43
  ```ruby
@@ -48,7 +47,7 @@ def item_params
48
47
  @item_params ||= begin
49
48
  _params = params
50
49
  .require(:item)
51
- .permit(:name, :description, :price, metadata: [tags: []])
50
+ .permit(:name, :description, :for_sale, :price, metadata: [tags: []])
52
51
 
53
52
  _params[:name] = _params[:name].strip.squeeze(' ') if _params[:name]
54
53
  _params[:description] = _params[:description].strip.squeeze(' ') if _params[:description]
@@ -70,69 +69,42 @@ The next logical step is extracting those procedures - this is where Paramore st
70
69
  ```ruby
71
70
  # app/controllers/items_controller.rb
72
71
 
73
- declare_params :item_params
74
- item: [:name, :description, :price, metadata: [tags: []]],
75
- format: {
76
- name: :Text,
77
- description: :Text,
78
- for_sale: :Boolean,
79
- price: :Decimal,
80
- metadata: {
81
- tags: :ItemTags
82
- }
83
- }
84
- ```
85
-
86
- ```ruby
87
- # app/formatter/text.rb
88
-
89
- module Formatter::Text
90
- module_function
91
- def run(input)
92
- input.strip.squeeze(' ')
72
+ class ItemsController < ApplicationController
73
+ def create
74
+ Item.create(item_params)
93
75
  end
94
- end
95
- ```
96
- ```ruby
97
- # app/formatter/boolean.rb
98
76
 
99
- module Formatter::Boolean
100
- TRUTHY_TEXT_VALUES = %w[t true 1]
101
-
102
- module_function
103
- def run(input)
104
- input.in?(TRUTHY_TEXT_VALUES)
105
- end
77
+ paramorize :item_params,
78
+ item: {
79
+ name: Paratype[Paramore::SanitizedString],
80
+ description: Paratype[Paramore::StrippedString, null: true],
81
+ for_sale: Paratype[Paramore::Boolean],
82
+ price: Paratype[Paramore::Decimal],
83
+ metadata: Paratype[{
84
+ tags: Paratype[[Types::ItemTag], compact: true]
85
+ }]
86
+ }
106
87
  end
107
88
  ```
108
- ```ruby
109
- # app/formatter/decimal.rb
110
89
 
111
- module Formatter::Decimal
112
- module_function
113
- def run(input)
114
- input.to_d
115
- end
116
- end
117
- ```
90
+ `Types::ItemTag` could be your own type:
118
91
  ```ruby
119
- # app/formatter/item_tags.rb
92
+ # app/types/item_tag.rb
120
93
 
121
- module Formatter::ItemTags
94
+ module Types::ItemTag
122
95
  module_function
123
- def run(input)
124
- input.map { |tag_id| Item.tags[tag_id.to_i] }
96
+ def [](input)
97
+ Item.tags[input.to_i]
125
98
  end
126
99
  end
127
100
  ```
128
101
 
129
-
130
102
  Now, given `params` are:
131
103
  ```ruby
132
104
  <ActionController::Parameters {
133
105
  "unpermitted"=>"parameter",
134
106
  "name"=>"Shoe \n",
135
- "description"=>"Black, with laces",
107
+ "description"=>" Black, with laces",
136
108
  "for_sale"=>"true",
137
109
  "price"=>"39.99",
138
110
  "metadata"=><ActionController::Parameters { "tags"=>["38", "112"] } permitted: false>
@@ -142,7 +114,7 @@ Calling `item_params` will return:
142
114
  ```ruby
143
115
  <ActionController::Parameters {
144
116
  "name"=>"Shoe",
145
- "description"=>"Black, with laces",
117
+ "description"=>"Black, with laces",
146
118
  "for_sale"=>true,
147
119
  "price"=>39.99,
148
120
  "metadata"=><ActionController::Parameters { "tags"=>[:shoe, :new] } permitted: true>
@@ -150,22 +122,30 @@ Calling `item_params` will return:
150
122
  ```
151
123
 
152
124
  This is useful when the values are not used with Rails models, but are passed to simple functions for processing.
153
- The formatters can also be easily reused anywhere in the app,
154
- since they are completely decoupled from Rails.
125
+ The types can also be easily reused anywhere in the app, since they are completely decoupled from Rails.
126
+
127
+ Notice that the `Paramore::StrippedString` does not perform `.squeeze(' ')`, only `Paramore::SanitizedString` does.
128
+
129
+ <h3>nil</h3>
130
+
131
+ Types are non-nullable by default and raise exceptions if the param hash misses any.
132
+ This can be disabled for any type by declaring `Paratype[Paramore::Int, null: true]`.
133
+
134
+ nils will usually not reach any of the type classes - if some parameter is nullable, the class will not be called.
135
+ If a parameter is non-nullable, then a `Paramore::NilParameter` error will be raised before calling the class.
136
+ If a, say, `item_ids` array is non-nullable, but the received parameter is `['1', '', '3']`, only the `'1'` and `'2'` will get passed to type classes, and the resulting array will contain a nil, eg.: `['1', nil, '3']`.
137
+ nils inside arrays can still be passed to type classes by declaring `Paratype[[Paramore::Int], empty: true]`.
138
+ If you wish to get rid of empty array elements, declare `Paratype[Paramore::Int, compact: true]`.
155
139
 
156
140
  <h3>Configuration</h3>
157
141
 
158
142
  Running `$ paramore` will generate a configuration file located in `config/initializers/paramore.rb`.
159
- - `config.formatter_namespace` - default is `Formatter`. Set to `nil` to have top level named formatters
160
- (this also allows specifying the formatter object itself, eg.: `name: Formatter::Text`).
161
- - `config.formatter_method_name` - default is `run`. Don't set to `nil` :D
143
+ - `config.type_method_name` - default is `[]`, to allow using, for example, `SuperString["foo"]` syntax. Note that changing this value will preclude you from using built in types.
162
144
 
163
145
  <h3>Safety</h3>
164
146
 
165
- - Formatters will not be called if their parameter is missing (no key in the param hash)
166
- - Formatters are validated - all given formatter names must match actual modules/classes defined in the app
167
- and must respond to the configured `formatter_method_name`.
168
- This means that all used formatters are loaded when the controller is loaded.
147
+ - Types will not be called if their parameter is missing (no key in the param hash)
148
+ - All given types must respond to the configured `type_method_name` and an error will be raised when controllers are loaded if they don't.
169
149
 
170
150
  # License
171
151
 
@@ -0,0 +1,65 @@
1
+ require_relative 'errors'
2
+
3
+ module Paramore
4
+ module CastParameters
5
+ module_function
6
+ def run(types_definition, permitted_params)
7
+ recursive_merge(
8
+ recursive_typecast(
9
+ types_definition, permitted_params
10
+ )
11
+ )
12
+ end
13
+
14
+ def recursive_merge(nested_hash_array)
15
+ nested_hash_array.reduce(:merge).map do |param_name, value|
16
+ if value.is_a?(Array) && value.all? { |_value| _value.is_a?(Hash) }
17
+ { param_name => recursive_merge(value) }
18
+ else
19
+ { param_name => value }
20
+ end
21
+ end.reduce(:merge)
22
+ end
23
+
24
+ def recursive_typecast(types_definition, permitted_params)
25
+ types_definition.map do |param_name, definition|
26
+ value = permitted_params[param_name]
27
+
28
+ if value.nil?
29
+ if definition.nullable?
30
+ next { param_name => nil }
31
+ else
32
+ raise Paramore::NilParameter, param_name
33
+ end
34
+ end
35
+
36
+ { param_name => cast(definition, value) }
37
+ end
38
+ end
39
+
40
+ def cast(definition, value)
41
+ case definition.type
42
+ when Hash
43
+ recursive_typecast(definition.type, value || {})
44
+ when Array
45
+ typecast_array(definition, value)
46
+ else
47
+ typecast_value(definition.type, value)
48
+ end
49
+ end
50
+
51
+ def typecast_array(definition, array)
52
+ array
53
+ .reject { |unit| unit.to_s == '' && definition.compact? }
54
+ .map do |unit|
55
+ if unit.to_s != '' || definition.use_empty_strings?
56
+ typecast_value(definition.type.first, unit)
57
+ end
58
+ end
59
+ end
60
+
61
+ def typecast_value(type, value)
62
+ type.send(Paramore.configuration.type_method_name, value)
63
+ end
64
+ end
65
+ end
data/lib/paramore/cli.rb CHANGED
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Paramore
4
2
  module Cli
5
3
  module_function
@@ -12,15 +10,9 @@ module Paramore
12
10
  end
13
11
 
14
12
  File.write(config_file_path, <<~CONF)
15
- # frozen_string_literal: true
16
-
17
13
  Paramore.configure do |config|
18
- # change this to any level you need, eg.: `'A::B'` for doubly nested formatters
19
- # or `nil` for top level formatters
20
- # config.formatter_namespace = 'Formatter'
21
-
22
- # what method name to call formatters with
23
- # config.formatter_method_name = 'run'
14
+ # what method name to call types with
15
+ # config.type_method_name = :[]
24
16
  end
25
17
  CONF
26
18
 
@@ -1,15 +1,11 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Paramore
4
2
  class Configuration
5
- DEFAULT_FORMATTER_NAMESPACE = 'Formatter'
6
- DEFAULT_FORMATTER_METHOD_NAME = 'run'
3
+ DEFAULT_TYPE_METHOD_NAME = :[]
7
4
 
8
- attr_accessor :formatter_namespace, :formatter_method_name
5
+ attr_accessor :type_method_name
9
6
 
10
7
  def initialize
11
- @formatter_namespace = DEFAULT_FORMATTER_NAMESPACE
12
- @formatter_method_name = DEFAULT_FORMATTER_METHOD_NAME
8
+ @type_method_name = DEFAULT_TYPE_METHOD_NAME
13
9
  end
14
10
  end
15
11
  end
@@ -0,0 +1,11 @@
1
+ class Paramore::NilParameter < StandardError
2
+ def initialize(param_name)
3
+ super("Received a nil `#{param_name}`, but it's type is non nullable!")
4
+ end
5
+ end
6
+
7
+ class Paramore::NonParatype < StandardError
8
+ def initialize(param_name, type)
9
+ super("`#{param_name}` defined as a `#{type.class}`, expected `Paratype`! Perhaps you declared a plain hash instead of Paratype[{}]?")
10
+ end
11
+ end
@@ -1,27 +1,55 @@
1
- # frozen_string_literal: true
2
-
3
1
  require_relative 'validate'
4
- require_relative 'format'
2
+ require_relative 'cast_parameters'
3
+ require_relative 'permitted_parameter_argument'
5
4
 
6
5
  module Paramore
7
6
  module Extension
8
- def declare_params(accessor_name, param_definition)
9
- format_definition = param_definition.delete(:format)
7
+ OPTIONS = %i[
8
+ default
9
+ ].freeze
10
+
11
+ def paramorize(accessor_name, configuration)
12
+ parameter_configuration = configuration.except(*OPTIONS)
13
+
14
+ unless parameter_configuration.keys.size == 1
15
+ raise ArgumentError,
16
+ "Paramore: exactly one required attribute allowed! Given: #{parameter_configuration.keys}"
17
+ end
10
18
 
11
- Validate.run(param_definition, format_definition)
19
+ required_parameter_name = parameter_configuration.keys.first
20
+ types_definition = parameter_configuration.values.first
12
21
 
13
- required = param_definition.keys.first
14
- permitted = param_definition.values.first
22
+ Paramore::Validate.run(types_definition) if types_definition.is_a?(Hash)
23
+
24
+ permitted_parameter_argument =
25
+ if types_definition.is_a?(Hash)
26
+ Paramore::PermittedParameterArgument.parse(types_definition)
27
+ else
28
+ types_definition
29
+ end
15
30
 
16
31
  define_method(accessor_name) do |rails_parameters = params|
17
32
  return instance_variable_get("@#{accessor_name}") if instance_variable_defined?("@#{accessor_name}")
18
33
 
19
- permitted_params = rails_parameters.require(required).permit(permitted)
34
+ if rails_parameters[required_parameter_name].nil? && configuration[:default]
35
+ instance_variable_set("@#{accessor_name}", configuration[:default])
36
+ return instance_variable_get("@#{accessor_name}")
37
+ end
38
+
39
+ permitted_params = rails_parameters
40
+ .require(required_parameter_name)
41
+ .permit(permitted_parameter_argument)
42
+
43
+ parameter_values =
44
+ if types_definition.is_a?(Hash)
45
+ permitted_params.merge(
46
+ Paramore::CastParameters.run(types_definition, permitted_params)
47
+ ).permit!
48
+ else
49
+ permitted_params.permit!
50
+ end
20
51
 
21
- instance_variable_set(
22
- "@#{accessor_name}",
23
- permitted_params.merge(Format.run(format_definition, permitted_params)).permit!
24
- )
52
+ instance_variable_set("@#{accessor_name}", parameter_values)
25
53
  end
26
54
  end
27
55
  end
@@ -0,0 +1,37 @@
1
+ module Paramore
2
+ module PermittedParameterArgument
3
+ module_function
4
+
5
+ def parse(types_definition)
6
+ merge_hashes(
7
+ types_definition.map do |key, definition|
8
+ case definition
9
+ when Hash
10
+ { key => merge_hashes(parse(definition)) }
11
+ when Paratype
12
+ case definition.type
13
+ when Array
14
+ { key => [] }
15
+ when Hash
16
+ { key => merge_hashes(parse(definition.type)) }
17
+ else
18
+ key
19
+ end
20
+ end
21
+ end
22
+ )
23
+ end
24
+
25
+ def merge_hashes(parsed)
26
+ (flat_parameters(parsed) + nested_parameters(parsed)).compact
27
+ end
28
+
29
+ def flat_parameters(parsed)
30
+ parsed.select { |arg| arg.is_a?(Symbol) }
31
+ end
32
+
33
+ def nested_parameters(parsed)
34
+ [parsed.reject { |arg| arg.is_a?(Symbol) }.reduce(:merge)]
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require_relative 'extension'
4
2
 
5
3
  return unless defined?(Rails)
@@ -0,0 +1,52 @@
1
+ module Paramore
2
+ module BigDecimal
3
+ module_function
4
+ def [](input)
5
+ BigDecimal(input)
6
+ end
7
+ end
8
+
9
+ module Boolean
10
+ TRUTHY_TEXT_VALUES = %w[t true 1]
11
+
12
+ module_function
13
+ def [](input)
14
+ input.in?(TRUTHY_TEXT_VALUES)
15
+ end
16
+ end
17
+
18
+ module Float
19
+ module_function
20
+ def [](input)
21
+ input.to_f
22
+ end
23
+ end
24
+
25
+ module Int
26
+ module_function
27
+ def [](input)
28
+ input.to_i
29
+ end
30
+ end
31
+
32
+ module String
33
+ module_function
34
+ def [](input)
35
+ input.to_s
36
+ end
37
+ end
38
+
39
+ module StrippedString
40
+ module_function
41
+ def [](input)
42
+ input.to_s.strip
43
+ end
44
+ end
45
+
46
+ module SanitizedString
47
+ module_function
48
+ def [](input)
49
+ Paramore::StrippedString[input].squeeze(' ')
50
+ end
51
+ end
52
+ end
@@ -1,39 +1,24 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Paramore
4
2
  module Validate
5
3
  module_function
6
- def run(param_definition, format_definition)
7
- unless param_definition.keys.size == 1
8
- raise ArgumentError,
9
- "Paramore: exactly one required attribute allowed! Given: #{param_definition.keys}"
10
- end
11
-
12
- return unless format_definition
13
4
 
14
- formatter_names(format_definition).each do |formatter_name|
15
- formatter =
16
- begin
17
- Paramore::Format.formatter_for(formatter_name)
18
- rescue NameError => e
19
- raise NameError, "Paramore: formatter `#{formatter_name}` is undefined! #{e}"
20
- end
21
-
22
- unless formatter.respond_to?(Paramore.configuration.formatter_method_name)
23
- raise NoMethodError,
24
- "Paramore: formatter `#{formatter_name}` does not respond to " +
25
- "`#{Paramore.configuration.formatter_method_name}`!"
26
- end
5
+ def run(types_definition)
6
+ types(types_definition).each do |type|
7
+ unless type.respond_to?(Paramore.configuration.type_method_name)
8
+ raise NoMethodError,
9
+ "Paramore: type `#{type}` does not respond to " +
10
+ "`#{Paramore.configuration.type_method_name}`!"
11
+ end
27
12
  end
28
13
  end
29
14
 
30
- def formatter_names(format_definition)
31
- format_definition.flat_map do |_, value|
32
- if value.kind_of?(Hash)
33
- formatter_names(value)
34
- else
35
- value
15
+ def types(types_definition)
16
+ types_definition.flat_map do |param_name, paratype|
17
+ unless paratype.is_a?(Paratype)
18
+ raise Paramore::NonParatype.new(param_name, paratype)
36
19
  end
20
+
21
+ paratype.type.is_a?(Hash) ? types(paratype.type) : paratype.type
37
22
  end.uniq
38
23
  end
39
24
  end
data/lib/paramore.rb CHANGED
@@ -1,7 +1,7 @@
1
- # frozen_string_literal: true
2
-
3
1
  require_relative 'paramore/configuration'
4
2
  require_relative 'paramore/railtie'
3
+ require_relative 'paramore/types'
4
+ require_relative 'paratype'
5
5
 
6
6
  module Paramore
7
7
  class << self
data/lib/paratype.rb ADDED
@@ -0,0 +1,32 @@
1
+ class Paratype
2
+ def self.[](given_type, null: false, empty: false, compact: false)
3
+ self.new(given_type, null: null, empty: empty, compact: compact)
4
+ end
5
+
6
+ def initialize(given_type, null:, empty:, compact:)
7
+ @given_type = given_type
8
+ @nullable = null
9
+ @empty = empty
10
+ @compact = compact
11
+ end
12
+
13
+ def compact?
14
+ compact
15
+ end
16
+
17
+ def nullable?
18
+ nullable
19
+ end
20
+
21
+ def use_empty_strings?
22
+ empty
23
+ end
24
+
25
+ def type
26
+ given_type
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :given_type, :nullable, :empty, :compact
32
+ end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paramore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.1.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: 2019-09-09 00:00:00.000000000 Z
11
+ date: 2021-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rspec
14
+ name: rspec-rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
@@ -39,22 +39,42 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rails
42
+ name: combustion
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
46
60
  - !ruby/object:Gem::Version
47
61
  version: '5.0'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '7'
48
65
  type: :runtime
49
66
  prerelease: false
50
67
  version_requirements: !ruby/object:Gem::Requirement
51
68
  requirements:
52
- - - "~>"
69
+ - - ">="
53
70
  - !ruby/object:Gem::Version
54
71
  version: '5.0'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '7'
55
75
  description: |
56
76
  Paramore lets you declare which parameters are permitted and what object is responsible
57
- for formatting/sanitizing/type-casting them before they passed along to your models/processors.
77
+ for typing/sanitizing/type-casting them before they are passed along to your models/domain.
58
78
  It is intended to reduce the amount of imperative code in controllers.
59
79
  email: lukas.kairevicius9@gmail.com
60
80
  executables:
@@ -66,18 +86,22 @@ files:
66
86
  - README.md
67
87
  - bin/paramore
68
88
  - lib/paramore.rb
89
+ - lib/paramore/cast_parameters.rb
69
90
  - lib/paramore/cli.rb
70
91
  - lib/paramore/configuration.rb
92
+ - lib/paramore/errors.rb
71
93
  - lib/paramore/extension.rb
72
- - lib/paramore/format.rb
94
+ - lib/paramore/permitted_parameter_argument.rb
73
95
  - lib/paramore/railtie.rb
96
+ - lib/paramore/types.rb
74
97
  - lib/paramore/validate.rb
98
+ - lib/paratype.rb
75
99
  homepage: https://github.com/lumzdas/paramore
76
100
  licenses:
77
101
  - MIT
78
102
  metadata: {}
79
103
  post_install_message: |
80
- Thank you for installing Paramore 0.2.0 !
104
+ Thank you for installing Paramore 1.1.0 !
81
105
  From the command line you can run `paramore` to generate a configuration file
82
106
 
83
107
  More details here : https://github.com/lumzdas/paramore/blob/master/README.md
@@ -96,8 +120,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
120
  - !ruby/object:Gem::Version
97
121
  version: '0'
98
122
  requirements: []
99
- rubygems_version: 3.0.3
123
+ rubygems_version: 3.0.8
100
124
  signing_key:
101
125
  specification_version: 4
102
- summary: A declarative approach to Rails' strong parameter formatting and sanitizing
126
+ summary: A declarative approach to Rails' strong parameter typing and sanitizing
103
127
  test_files: []
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Paramore
4
- module Format
5
- module_function
6
- def run(format_definition, permitted_params)
7
- return {} unless format_definition
8
-
9
- recursive_merge(
10
- recursive_format(
11
- format_definition, permitted_params
12
- )
13
- )
14
- end
15
-
16
- def recursive_merge(nested_hash_array)
17
- nested_hash_array.reduce(:merge).map do |param_name, value|
18
- if value.kind_of?(Array) && value.all? { |_value| _value.kind_of?(Hash) }
19
- { param_name => recursive_merge(value) }
20
- else
21
- { param_name => value }
22
- end
23
- end.reduce(:merge)
24
- end
25
-
26
- def recursive_format(format_definition, permitted_params)
27
- format_definition.map do |param_name, value|
28
- next {} unless permitted_params[param_name]
29
-
30
- if value.kind_of?(Hash)
31
- { param_name => recursive_format(value, permitted_params[param_name]) }
32
- else
33
- { param_name => formatted_value(permitted_params[param_name], formatter_for(value)) }
34
- end
35
- end
36
- end
37
-
38
- def formatted_value(value, formatter)
39
- formatter.send(Paramore.configuration.formatter_method_name, value)
40
- end
41
-
42
- def formatter_for(formatter_name)
43
- Object.const_get(
44
- [Paramore.configuration.formatter_namespace, formatter_name].compact.join('::'),
45
- false # inherit=false - only get exact match
46
- )
47
- end
48
- end
49
- end