typed_params 1.1.1 → 1.2.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +41 -1
- data/lib/typed_params/formatters/formatter.rb +1 -1
- data/lib/typed_params/formatters/jsonapi.rb +18 -8
- data/lib/typed_params/parameter.rb +10 -1
- data/lib/typed_params/parameterizer.rb +3 -3
- data/lib/typed_params/schema.rb +15 -5
- data/lib/typed_params/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 014c42e82286c1ffc175d08aca51e631da96a5b2aee8e9bbf575fc0bea7e1d57
|
4
|
+
data.tar.gz: 3a0ea8bac6b1021143b768767763899a6f5328f16bb6011a87b2f1ed694b6325
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c563758456e6359e37c75926124925141c59f535fc77070be23d46d3f86e0772f2cf2c52d2e57f165e2ba11f93717c6a0b15f90e61fcbe00baa19b3c1985f2a8
|
7
|
+
data.tar.gz: a277c1c13a5d0ac14ef293fbc9611bec82eba5df00686f9afaf8e324e89148aef7c49fa672bf025570a9482ec277e330edc1049a1e59051e41a559a31a4b6584
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.2.0
|
4
|
+
|
5
|
+
- Add `aliases:` keyword to `#param` to allow the schema to be accessible by different names.
|
6
|
+
- Add `polymorphic:` keyword to `#param` to define a polymorphic schema.
|
7
|
+
|
3
8
|
## 1.1.1
|
4
9
|
|
5
10
|
- Fix compatibility with Ruby 3.3.0 due to [#20091](https://bugs.ruby-lang.org/issues/20091).
|
data/README.md
CHANGED
@@ -436,6 +436,7 @@ Parameters can have validations, transforms, and more.
|
|
436
436
|
- [`:optional`](#optional-parameter)
|
437
437
|
- [`:if` and `:unless`](#conditional-parameter)
|
438
438
|
- [`:as`](#rename-parameter)
|
439
|
+
- [`:alias`](#alias-parameter)
|
439
440
|
- [`:noop`](#noop-parameter)
|
440
441
|
- [`:coerce`](#coerce-parameter)
|
441
442
|
- [`:allow_blank`](#allow-blank)
|
@@ -448,6 +449,7 @@ Parameters can have validations, transforms, and more.
|
|
448
449
|
- [`:length`](#length-validation)
|
449
450
|
- [`:transform`](#transform-parameter)
|
450
451
|
- [`:validate`](#validate-parameter)
|
452
|
+
- [`:polymorphic`](#polymorphic-parameter)
|
451
453
|
|
452
454
|
#### Parameter key
|
453
455
|
|
@@ -520,6 +522,17 @@ typed_params # => { user_id: 1 }
|
|
520
522
|
In this example, the parameter would be accepted as `:user`, but renamed
|
521
523
|
to `:user_id` for use inside of the controller.
|
522
524
|
|
525
|
+
#### Alias parameter
|
526
|
+
|
527
|
+
Allow a parameter to be provided via an alias.
|
528
|
+
|
529
|
+
```ruby
|
530
|
+
param :owner_id, type: :integer, alias: :user_id
|
531
|
+
```
|
532
|
+
|
533
|
+
In this example, the parameter would be accepted as both `:owner_id` and
|
534
|
+
`:user_id`, but accessible as `:owner_id` inside the controller.
|
535
|
+
|
523
536
|
#### Noop parameter
|
524
537
|
|
525
538
|
The parameter is accepted but immediately thrown out.
|
@@ -674,6 +687,33 @@ param :invalid, type: :string, validate: -> v {
|
|
674
687
|
}
|
675
688
|
```
|
676
689
|
|
690
|
+
#### Polymorphic parameter
|
691
|
+
|
692
|
+
***Currently, this option is only utilized by the JSONAPI formatter. Define
|
693
|
+
a polymorphic parameter, used when formatting JSONAPI relationships.***
|
694
|
+
|
695
|
+
```ruby
|
696
|
+
format :jsonapi
|
697
|
+
|
698
|
+
param :data, type: :hash do
|
699
|
+
param :relationships, type: :hash do
|
700
|
+
param :owner, type: :hash, polymorphic: true do
|
701
|
+
param :data, type: :hash do
|
702
|
+
param :type, type: :string, inclusion: { in: %w[users user] }
|
703
|
+
param :id, type: :integer
|
704
|
+
end
|
705
|
+
end
|
706
|
+
end
|
707
|
+
end
|
708
|
+
|
709
|
+
typed_params # => { owner_type: 'User', owner_id: 1 }
|
710
|
+
```
|
711
|
+
|
712
|
+
In this example, a polymorphic `:owner` relationship is defined. When run
|
713
|
+
through the JSONAPI formatter, instead of formatting the relationship
|
714
|
+
into the `:owner_id` key, it also includes the `:owner_type` key
|
715
|
+
for a polymorphic association.
|
716
|
+
|
677
717
|
### Shared options
|
678
718
|
|
679
719
|
You can define a set of options that will be applied to immediate
|
@@ -748,7 +788,7 @@ which may be a nested schema.
|
|
748
788
|
|
749
789
|
```ruby
|
750
790
|
# array of hashes
|
751
|
-
param :
|
791
|
+
param :endless_array, type: :array do
|
752
792
|
items type: :hash do
|
753
793
|
# ...
|
754
794
|
end
|
@@ -32,12 +32,16 @@ module TypedParams
|
|
32
32
|
# }
|
33
33
|
#
|
34
34
|
module JSONAPI
|
35
|
-
def self.call(params)
|
35
|
+
def self.call(params, schema:)
|
36
36
|
case params
|
37
37
|
in data: Array => data
|
38
|
-
|
38
|
+
child = schema.children.fetch(:data)
|
39
|
+
|
40
|
+
format_array_data(data, schema: child)
|
39
41
|
in data: Hash => data
|
40
|
-
|
42
|
+
child = schema.children.fetch(:data)
|
43
|
+
|
44
|
+
format_hash_data(data, schema: child)
|
41
45
|
else
|
42
46
|
params
|
43
47
|
end
|
@@ -45,11 +49,15 @@ module TypedParams
|
|
45
49
|
|
46
50
|
private
|
47
51
|
|
48
|
-
def self.format_array_data(data)
|
49
|
-
data.map
|
52
|
+
def self.format_array_data(data, schema:)
|
53
|
+
data.each_with_index.map do |value, i|
|
54
|
+
child = schema.children.fetch(i) { schema.endless? ? schema.children.first : nil }
|
55
|
+
|
56
|
+
format_hash_data(value, schema: child)
|
57
|
+
end
|
50
58
|
end
|
51
59
|
|
52
|
-
def self.format_hash_data(data)
|
60
|
+
def self.format_hash_data(data, schema:)
|
53
61
|
rels = data[:relationships]
|
54
62
|
attrs = data[:attributes]
|
55
63
|
res = data.except(
|
@@ -69,6 +77,8 @@ module TypedParams
|
|
69
77
|
# relationship data only contains :type and :id, otherwise it
|
70
78
|
# will use the x_attributes key.
|
71
79
|
rels&.each do |key, rel|
|
80
|
+
child = schema.children.dig(:relationships, key)
|
81
|
+
|
72
82
|
case rel
|
73
83
|
# FIXME(ezekg) We need https://bugs.ruby-lang.org/issues/18961 to
|
74
84
|
# clean this up (i.e. remove the if guard).
|
@@ -77,7 +87,7 @@ module TypedParams
|
|
77
87
|
in data: []
|
78
88
|
res[:"#{key.to_s.singularize}_ids"] = []
|
79
89
|
# FIXME(ezekg) Not sure how to make this cleaner, but this handles polymorphic relationships.
|
80
|
-
in data: { type:, id:, **nil } if key.to_s.underscore.classify != type.underscore.classify
|
90
|
+
in data: { type:, id:, **nil } if key.to_s.underscore.classify != type.underscore.classify && child.polymorphic?
|
81
91
|
res[:"#{key}_type"], res[:"#{key}_id"] = type.underscore.classify, id
|
82
92
|
in data: { type:, id:, **nil }
|
83
93
|
res[:"#{key}_id"] = id
|
@@ -86,7 +96,7 @@ module TypedParams
|
|
86
96
|
else
|
87
97
|
# NOTE(ezekg) Embedded relationships are non-standard as per the
|
88
98
|
# JSONAPI spec, but I don't really care. :)
|
89
|
-
res[:"#{key}_attributes"] = call(rel)
|
99
|
+
res[:"#{key}_attributes"] = call(rel, schema: child)
|
90
100
|
end
|
91
101
|
end
|
92
102
|
|
@@ -75,7 +75,16 @@ module TypedParams
|
|
75
75
|
if formatter.present?
|
76
76
|
v = case formatter.arity
|
77
77
|
when 2
|
78
|
-
formatter.
|
78
|
+
case formatter.parameters
|
79
|
+
in [[:req, *], [:keyreq | :key, :controller], [:keyreq | :key, :schema]]
|
80
|
+
formatter.call(v, controller:, schema:)
|
81
|
+
in [[:req, *], [:keyreq | :key, :schema], [:keyreq | :key, :controller]]
|
82
|
+
formatter.call(v, schema:, controller:)
|
83
|
+
in [[:req, *], [:keyreq | :key, :controller]]
|
84
|
+
formatter.call(v, controller:)
|
85
|
+
in [[:req, *], [:keyreq | :key, :schema]]
|
86
|
+
formatter.call(v, schema:)
|
87
|
+
end
|
79
88
|
when 1
|
80
89
|
formatter.call(v)
|
81
90
|
end
|
@@ -38,7 +38,7 @@ module TypedParams
|
|
38
38
|
|
39
39
|
value.each_with_index do |v, i|
|
40
40
|
unless schema.children.nil?
|
41
|
-
child = schema.children.fetch(i) { schema.
|
41
|
+
child = schema.children.fetch(i) { schema.endless? ? schema.children.first : nil }
|
42
42
|
if child.nil?
|
43
43
|
raise UnpermittedParameterError.new('unpermitted parameter', path: Path.new(*param.path.keys, i), source: schema.source) if
|
44
44
|
schema.strict?
|
@@ -63,7 +63,7 @@ module TypedParams
|
|
63
63
|
|
64
64
|
value.each do |k, v|
|
65
65
|
unless schema.children.nil?
|
66
|
-
child = schema.children.fetch(k) {
|
66
|
+
child = schema.children.fetch(k) { schema.children.values.find { _1.alias == k } }
|
67
67
|
if child.nil?
|
68
68
|
raise UnpermittedParameterError.new('unpermitted parameter', path: Path.new(*param.path.keys, k), source: schema.source) if
|
69
69
|
schema.strict?
|
@@ -71,7 +71,7 @@ module TypedParams
|
|
71
71
|
next
|
72
72
|
end
|
73
73
|
|
74
|
-
param[
|
74
|
+
param[child.key] = Parameterizer.new(schema: child, parent: param).call(key: child.key, value: v)
|
75
75
|
else
|
76
76
|
param[k] = Parameter.new(key: k, value: v, schema:, parent: param)
|
77
77
|
end
|
data/lib/typed_params/schema.rb
CHANGED
@@ -10,6 +10,7 @@ module TypedParams
|
|
10
10
|
:source,
|
11
11
|
:type,
|
12
12
|
:key,
|
13
|
+
:alias,
|
13
14
|
:if,
|
14
15
|
:unless
|
15
16
|
|
@@ -22,6 +23,7 @@ module TypedParams
|
|
22
23
|
key: nil,
|
23
24
|
optional: false,
|
24
25
|
coerce: false,
|
26
|
+
polymorphic: false,
|
25
27
|
allow_blank: false,
|
26
28
|
allow_nil: false,
|
27
29
|
allow_non_scalars: false,
|
@@ -36,6 +38,7 @@ module TypedParams
|
|
36
38
|
if: nil,
|
37
39
|
unless: nil,
|
38
40
|
as: nil,
|
41
|
+
alias: nil,
|
39
42
|
casing: TypedParams.config.key_transform,
|
40
43
|
&block
|
41
44
|
)
|
@@ -77,8 +80,10 @@ module TypedParams
|
|
77
80
|
@strict = strict
|
78
81
|
@parent = parent
|
79
82
|
@key = key
|
83
|
+
@alias = binding.local_variable_get(:alias)
|
80
84
|
@optional = optional
|
81
85
|
@coerce = coerce && @type.coercable?
|
86
|
+
@polymorphic = polymorphic
|
82
87
|
@allow_blank = key == ROOT || allow_blank
|
83
88
|
@allow_nil = allow_nil
|
84
89
|
@allow_non_scalars = allow_non_scalars
|
@@ -220,7 +225,7 @@ module TypedParams
|
|
220
225
|
Types.array?(children)
|
221
226
|
|
222
227
|
raise ArgumentError, "index #{key} has already been defined" if
|
223
|
-
children[key].present? ||
|
228
|
+
children[key].present? || endless?
|
224
229
|
|
225
230
|
children << Schema.new(**options, **kwargs, key:, type:, strict:, source:, casing:, parent: self, &block)
|
226
231
|
end
|
@@ -230,7 +235,7 @@ module TypedParams
|
|
230
235
|
def items(**kwargs, &)
|
231
236
|
item(0, **kwargs, &)
|
232
237
|
|
233
|
-
|
238
|
+
endless!
|
234
239
|
end
|
235
240
|
|
236
241
|
def path
|
@@ -261,12 +266,14 @@ module TypedParams
|
|
261
266
|
def optional? = !!@optional
|
262
267
|
def required? = !optional?
|
263
268
|
def coerce? = !!@coerce
|
269
|
+
def polymorphic? = !!@polymorphic
|
270
|
+
def aliased? = !!@alias
|
264
271
|
def allow_blank? = !!@allow_blank
|
265
272
|
def allow_nil? = !!@allow_nil
|
266
273
|
def allow_non_scalars? = !!@allow_non_scalars
|
267
274
|
def nilify_blanks? = !!@nilify_blanks
|
268
|
-
def
|
269
|
-
def indexed? = !
|
275
|
+
def endless? = !!@endless
|
276
|
+
def indexed? = !endless?
|
270
277
|
def if? = !@if.nil?
|
271
278
|
def unless? = !@unless.nil?
|
272
279
|
def array? = Types.array?(type)
|
@@ -278,6 +285,9 @@ module TypedParams
|
|
278
285
|
"#<#{self.class.name} key=#{key.inspect} type=#{type.inspect} children=#{children.inspect}>"
|
279
286
|
end
|
280
287
|
|
288
|
+
# @private
|
289
|
+
def dig(*keys) = children.dig(*keys)
|
290
|
+
|
281
291
|
private
|
282
292
|
|
283
293
|
attr_reader :controller,
|
@@ -285,6 +295,6 @@ module TypedParams
|
|
285
295
|
:strict,
|
286
296
|
:casing
|
287
297
|
|
288
|
-
def
|
298
|
+
def endless! = @endless = true
|
289
299
|
end
|
290
300
|
end
|
data/lib/typed_params/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typed_params
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zeke Gabrielse
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|