camille 0.4.2 → 0.5.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: 1c6d8ec2d346e2ff02811be47d900bee304a82f5a96e213cbf5e1c9f96f3fe61
4
- data.tar.gz: 1a67d813067334b228caa09c9cc10411fa4a3b56eab57610b415c129616a4533
3
+ metadata.gz: acda60cf2aee3c70aadf0aa040f5b79832aa8fe44c8d92f8e305715a0edf7e36
4
+ data.tar.gz: 9c1b5c69c2638336c8341a2f9182d097f8276b8df21506365e69846aa71596f7
5
5
  SHA512:
6
- metadata.gz: 0d977978049f5c5589731135c24c360145c3145d3ded0be2d158ea67546eece82d8af7c07674e1895d03a3071418adc9b1a6a597e5246b22b96d0c7abb2123d3
7
- data.tar.gz: b4fd67e56fdd11db3c00d1e1ddee3a775c8e3d87ba2423cbe652729ed3dfb3460591d658a89bd1192385c45f0507fbeae5172a03acac65fcb3ad0880fe3b1aa7
6
+ metadata.gz: 4772765b95039fc3309e4eddd9a406cd0c1c94e9fca0c31e8dc283677ee9cc42620ba3acefbcc946818a44e1e78945eba798109e51bcf0ceccf6c858eff336a9
7
+ data.tar.gz: b90680ff5e4646237c856c26bc6c54bbccb3c2c38d69a670d95c81b7232d466ab95d27ffdd362829da985e204d648b9d81b7cfb83f51e989019324321fad4c9f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Changed
6
+
7
+ * Pick and Omit now use a new syntax, so it can handle snake to camel case conversion correctly
8
+
9
+ ## 0.4.3
10
+
11
+ ### Fixed
12
+
13
+ * Fixed the error that values not getting transformed in array/tuple/union types
14
+ * Fixed optional fields getting `nil` due to transformation
15
+
3
16
  ## 0.4.2
4
17
 
5
18
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- camille (0.4.2)
4
+ camille (0.4.3)
5
5
  rails (>= 6.1, < 8)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -158,9 +158,9 @@ params(
158
158
  string_literal: 'hello',
159
159
  # a custom type we defined above
160
160
  product: Product,
161
- # Pick and Omit use [] to enclose parameters instead of <>
162
- pick: Pick[{a: 1, b: 2}, 'a' | 'b'],
163
- omit: Omit[Product, 'id']
161
+ # Pick and Omit accepts a type and an array of symbols
162
+ pick: Pick[{a: 1, b: 2}, [:a, :b]],
163
+ omit: Omit[Product, [:id]]
164
164
  )
165
165
  ```
166
166
 
@@ -237,7 +237,7 @@ Camille will print the following error:
237
237
  ```
238
238
  object:
239
239
  array:
240
- [2]: Expected number, got "3".
240
+ array[2]: Expected number, got "3".
241
241
  ```
242
242
 
243
243
  ### Reloading
@@ -14,24 +14,14 @@ module Camille
14
14
  raise ArgumentError.new("Currently onle an object type or an alias of object type is supported in #{klass_name}. Got #{type.inspect}.")
15
15
  end
16
16
 
17
- @keys = Camille::Type.instance(keys)
18
- case
19
- when @keys.is_a?(Camille::Types::StringLiteral)
20
- @keys_array = [@keys.value].map(&:to_sym)
21
- when @keys.is_a?(Camille::Types::Union)
22
- unfolded = unfold_union(@keys).flatten
23
- if unfolded.all?{|x| x.is_a?(Camille::Types::StringLiteral)}
24
- @keys_array = unfolded.map(&:value).map(&:to_sym)
25
- else
26
- raise ArgumentError.new("The second argument of #{klass_name} has to be a string literal or an union of string literals. Got #{keys.inspect}.")
27
- end
28
- else
29
- raise ArgumentError.new("The second argument of #{klass_name} has to be a string literal or an union of string literals. Got #{keys.inspect}.")
17
+ unless keys.is_a?(::Array) && !keys.empty? && keys.all?{|x| x.is_a? Symbol}
18
+ raise ArgumentError.new("The second argument of #{klass_name} has to be an array of symbols. Got #{keys.inspect}.")
30
19
  end
20
+ @keys = keys
31
21
  end
32
22
 
33
23
  def literal
34
- "#{klass_name}<#{@type.literal}, #{@keys.literal}>"
24
+ "#{klass_name}<#{@type.literal}, #{keys_in_literal}>"
35
25
  end
36
26
 
37
27
  def self.[] type, keys
@@ -39,12 +29,8 @@ module Camille
39
29
  end
40
30
 
41
31
  private
42
- def unfold_union type
43
- if type.is_a?(Camille::Types::Union)
44
- [unfold_union(type.left), unfold_union(type.right)]
45
- else
46
- [type]
47
- end
32
+ def keys_in_literal
33
+ @keys.map{|k| "\"#{k.to_s.camelize(:lower)}\""}.join(' | ')
48
34
  end
49
35
 
50
36
  end
@@ -7,22 +7,26 @@ module Camille
7
7
  @content = Camille::Type.instance content
8
8
  end
9
9
 
10
- def check value
10
+ def transform_and_check value
11
11
  if value.is_a? ::Array
12
- errors = value.map.with_index{|e, i| ["array[#{i}]", @content.check(e)]}.select{|x| x[1]}
13
- unless errors.empty?
14
- Camille::TypeError.new(**errors.to_h)
12
+ transform_and_check_results = value.map.with_index do |element, index|
13
+ [index, @content.transform_and_check(element)]
14
+ end
15
+ errors = transform_and_check_results.map do |index, (error, transformed)|
16
+ ["array[#{index}]", error]
17
+ end.select{|x| x[1]}
18
+
19
+ if errors.empty?
20
+ transformed = transform_and_check_results.map{|_, (_, transformed)| transformed}
21
+ [nil, transformed]
22
+ else
23
+ [Camille::TypeError.new(**errors.to_h), nil]
15
24
  end
16
25
  else
17
- Camille::TypeError.new("Expected array, got #{value.inspect}.")
26
+ [Camille::TypeError.new("Expected array, got #{value.inspect}."), nil]
18
27
  end
19
28
  end
20
29
 
21
- def transform_and_check value
22
- transformed = value.map{|x| @content.transform x}
23
- [check(transformed), transformed]
24
- end
25
-
26
30
  def literal
27
31
  "#{@content.literal}[]"
28
32
  end
@@ -4,28 +4,20 @@ module Camille
4
4
  attr_reader :fields
5
5
 
6
6
  def initialize fields
7
+ @optional_keys = []
7
8
  @fields = normalize_fields fields
8
9
  end
9
10
 
10
- def check value
11
- if value.is_a? Hash
12
- errors = @fields.map do |key, type|
13
- [key.to_s, type.check(value[key])]
14
- end.select{|x| x[1]}
15
-
16
- unless errors.empty?
17
- Camille::TypeError.new(**errors.to_h)
18
- end
19
- else
20
- Camille::TypeError.new("Expected hash, got #{value.inspect}.")
21
- end
22
- end
23
-
24
11
  def transform_and_check value
25
12
  if value.is_a? Hash
26
13
  transform_and_check_results = @fields.map do |key, type|
27
- [key, type.transform_and_check(value[key])]
28
- end
14
+ error, transformed = type.transform_and_check(value[key])
15
+ if @optional_keys.include?(key) && !error && transformed.nil?
16
+ nil
17
+ else
18
+ [key, type.transform_and_check(value[key])]
19
+ end
20
+ end.compact
29
21
 
30
22
  errors = transform_and_check_results.map do |key, (error, transformed)|
31
23
  [key.to_s, error]
@@ -37,10 +29,10 @@ module Camille
37
29
  end.to_h
38
30
  [nil, transformed]
39
31
  else
40
- Camille::TypeError.new(**errors.to_h)
32
+ [Camille::TypeError.new(**errors.to_h), nil]
41
33
  end
42
34
  else
43
- Camille::TypeError.new("Expected hash, got #{value.inspect}.")
35
+ [Camille::TypeError.new("Expected hash, got #{value.inspect}."), nil]
44
36
  end
45
37
  end
46
38
 
@@ -54,6 +46,7 @@ module Camille
54
46
  type = Camille::Type.instance(value)
55
47
  if key.end_with?('?')
56
48
  new_key = remove_question_mark(key)
49
+ @optional_keys << new_key
57
50
  [new_key, type | Camille::Types::Undefined.new]
58
51
  else
59
52
  [key, type]
@@ -1,10 +1,6 @@
1
1
  module Camille
2
2
  module Types
3
3
  class Omit < PickAndOmit
4
- def check value
5
- processed_object.check(value)
6
- end
7
-
8
4
  def transform_and_check value
9
5
  processed_object.transform_and_check(value)
10
6
  end
@@ -15,7 +11,7 @@ module Camille
15
11
  end
16
12
 
17
13
  def processed_object
18
- fields = @target_object.fields.reject{|k, _| @keys_array.include?(k)}
14
+ fields = @target_object.fields.reject{|k, _| @keys.include?(k)}
19
15
  Camille::Types::Object.new(fields)
20
16
  end
21
17
 
@@ -1,10 +1,6 @@
1
1
  module Camille
2
2
  module Types
3
3
  class Pick < PickAndOmit
4
- def check value
5
- processed_object.check(value)
6
- end
7
-
8
4
  def transform_and_check value
9
5
  processed_object.transform_and_check(value)
10
6
  end
@@ -15,7 +11,7 @@ module Camille
15
11
  end
16
12
 
17
13
  def processed_object
18
- fields = @target_object.fields.select{|k, _| @keys_array.include?(k)}
14
+ fields = @target_object.fields.select{|k, _| @keys.include?(k)}
19
15
  Camille::Types::Object.new(fields)
20
16
  end
21
17
 
@@ -7,17 +7,24 @@ module Camille
7
7
  @elements = elements.map{|e| Camille::Type.instance e}
8
8
  end
9
9
 
10
- def check value
10
+ def transform_and_check value
11
11
  if value.is_a? ::Array
12
- errors = @elements.map.with_index do |type, index|
13
- ["tuple[#{index}]", type.check(value[index])]
12
+ transform_and_check_results = @elements.map.with_index do |type, index|
13
+ [index, type.transform_and_check(value[index])]
14
+ end
15
+
16
+ errors = transform_and_check_results.map do |index, (error, transformed)|
17
+ ["tuple[#{index}]", error]
14
18
  end.select{|x| x[1]}
15
19
 
16
- unless errors.empty?
17
- Camille::TypeError.new(**errors.to_h)
20
+ if errors.empty?
21
+ transformed = transform_and_check_results.map{|index, (error, transformed)| transformed}
22
+ [nil, transformed]
23
+ else
24
+ [Camille::TypeError.new(**errors.to_h), nil]
18
25
  end
19
26
  else
20
- Camille::TypeError.new("Expected array, got #{value.inspect}.")
27
+ [Camille::TypeError.new("Expected array, got #{value.inspect}."), nil]
21
28
  end
22
29
  end
23
30
 
@@ -8,29 +8,14 @@ module Camille
8
8
  @right = Camille::Type.instance right
9
9
  end
10
10
 
11
- def check value
12
- left_result = @left.check value
13
- if left_result
14
- right_result = @right.check value
15
- if right_result
16
- Camille::TypeError.new(
17
- 'union.left' => left_result,
18
- 'union.right' => right_result
19
- )
20
- end
21
- end
22
- end
23
-
24
11
  def transform_and_check value
25
- left_transformed = @left.transform value
26
- left_result = @left.check left_transformed
27
- if left_result
28
- right_transformed = @right.transform value
29
- right_result = @right.check right_transformed
30
- if right_result
12
+ left_error, left_transformed = @left.transform_and_check value
13
+ if left_error
14
+ right_error, right_transformed = @right.transform_and_check value
15
+ if right_error
31
16
  error = Camille::TypeError.new(
32
- 'union.left' => left_result,
33
- 'union.right' => right_result
17
+ 'union.left' => right_error,
18
+ 'union.right' => right_error
34
19
  )
35
20
  [error, nil]
36
21
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Camille
4
- VERSION = "0.4.2"
4
+ VERSION = "0.5.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: camille
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 辻彩
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-18 00:00:00.000000000 Z
11
+ date: 2023-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -52,7 +52,6 @@ files:
52
52
  - lib/camille/code_generator.rb
53
53
  - lib/camille/configuration.rb
54
54
  - lib/camille/controller_extension.rb
55
- - lib/camille/custom_types/date.rb
56
55
  - lib/camille/endpoint.rb
57
56
  - lib/camille/generators/install_generator.rb
58
57
  - lib/camille/generators/schema_generator.rb
@@ -111,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
110
  - !ruby/object:Gem::Version
112
111
  version: '0'
113
112
  requirements: []
114
- rubygems_version: 3.2.33
113
+ rubygems_version: 3.4.1
115
114
  signing_key:
116
115
  specification_version: 4
117
116
  summary: Typed API schema for Rails with TypeScript codegen
@@ -1,31 +0,0 @@
1
- require 'date'
2
-
3
- # This type is only for testing, to simulate the usage of transform.
4
- module Camille
5
- module CustomTypes
6
- class Date < Camille::Type
7
- include Camille::Types
8
-
9
- alias_of(
10
- type: 'Date',
11
- value: Number
12
- )
13
-
14
- def transform value
15
- case value
16
- when ::Date
17
- timestamp = value.to_time.to_i
18
- when ::Time
19
- timestamp = value.to_i
20
- end
21
- {
22
- type: 'Date',
23
- value: timestamp.to_i * 1000
24
- }
25
- end
26
-
27
- end
28
- end
29
- end
30
-
31
- Camille::Loader.loaded_types.delete(Camille::CustomTypes::Date)