camille 0.5.7 → 0.5.9

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: 3ff47e3a7fdcb5ef28cca7bc5ce3989900c82d7eb0d94af77a00e0b0c4ac9b3d
4
- data.tar.gz: 7885520d31b5b0a4f339cc24e5993ea1d8e1d637029a018b5dcb144060e72965
3
+ metadata.gz: fd8f26b87f7ddf2f3c951a19a24610abfe1bfac4f4da041568883cc371090895
4
+ data.tar.gz: bbecf051c37ec9da1eae0920a6ec42c09d159feef1f2be734beaef2871af7410
5
5
  SHA512:
6
- metadata.gz: 5c990d3326e3271092647bd2ccdbc9ddf213e0f6200c872f0d398c4fb5306670c7e9993e4e48c82dab84a97ea4a8b3200ad100475c4a9243758e94ea211df681
7
- data.tar.gz: c21e9542119b194dac81e446574c582fcf16a98a7fbeaeeba33e083518b3070b826a4db20596ff22fb5b18f1b8e64161056e10f71309a3309ab3213c8da9ba4d
6
+ metadata.gz: 53bb5fd170e71b21687dadba5ab1ce6c5a81bcb1a4ede09e280103cd81693fb8e9f41a3a15af630b2d48b62f150f29c1f222d8308fff2636135c5653d9ca3da3
7
+ data.tar.gz: 47c9621bfdeb542e625f2115eb96b7d1d14fdecfd5f6cefe62bd6f92be2703d7e3e7518e96df26af3c692fb5887ac08ebe26db38eaeae8a8cfb059eeb07de839
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.9
4
+
5
+ ### Added
6
+
7
+ * Added intersection type
8
+ * Added #print to Camille::TypeError
9
+
10
+ ### Changed
11
+
12
+ * Typecheck will no longer remove fields from a hash if those fields are not presented in type schema
13
+
14
+ ### Fixed
15
+
16
+ * Fixed the wrong literal generated by an array of unions
17
+
18
+ ## 0.5.8
19
+
20
+ ### Added
21
+
22
+ * `render` call with a status code other than 200 will skip the typecheck
23
+
24
+ ### Fixed
25
+
26
+ * `head 401` will no longer raise Camille::Controller::MissingRenderError
27
+
3
28
  ## 0.5.7
4
29
 
5
30
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- camille (0.5.7)
4
+ camille (0.5.9)
5
5
  rails (>= 6.1, < 8)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -153,6 +153,8 @@ params(
153
153
  }[]
154
154
  # a union type is two types connected by '|'
155
155
  union: Number | String,
156
+ # an intersection type is two types connected by '&'
157
+ intersection: { id: Number } & { name: String },
156
158
  # a tuple type is several types put inside '[]'
157
159
  tuple: [Number, String, Boolean],
158
160
  # a field followed by '?' is optional, the same as in TypeScript
@@ -7,6 +7,10 @@ module Camille
7
7
  Camille::Types::Union.new(self, other)
8
8
  end
9
9
 
10
+ def & other
11
+ Camille::Types::Intersection.new(self, other)
12
+ end
13
+
10
14
  def []
11
15
  Camille::Types::Array.new(self)
12
16
  end
@@ -24,6 +28,10 @@ module Camille
24
28
  Camille::Type.instance(self) | other
25
29
  end
26
30
 
31
+ def self.& other
32
+ Camille::Type.instance(self) & other
33
+ end
34
+
27
35
  def self.[]
28
36
  Camille::Type.instance(self)[]
29
37
  end
@@ -15,21 +15,25 @@ module Camille
15
15
  def render *args
16
16
  if endpoint = camille_endpoint
17
17
  render_options = args.last
18
- if value = render_options[:json]
19
- error, transformed = endpoint.response_type.transform_and_check(value)
20
- if error
21
- string_io = StringIO.new
22
- Camille::TypeErrorPrinter.new(error).print(string_io)
23
- raise TypeError.new("\nType check failed for response.\n#{string_io.string}")
24
- else
25
- if transformed.is_a? Hash
26
- transformed.deep_transform_keys!{|k| k.to_s.camelize(:lower)}
18
+ intended_status = render_options[:status] || 200
19
+ if intended_status == 200 || intended_status == :ok
20
+ if value = render_options[:json]
21
+ error, transformed = endpoint.response_type.transform_and_check(value)
22
+ if error
23
+ string_io = StringIO.new
24
+ Camille::TypeErrorPrinter.new(error).print(string_io)
25
+ raise TypeError.new("\nType check failed for response.\n#{string_io.string}")
26
+ else
27
+ if transformed.is_a? Hash
28
+ transformed.deep_transform_keys!{|k| k.to_s.camelize(:lower)}
29
+ end
30
+ super(json: transformed)
27
31
  end
28
- @camille_rendered = true
29
- super(json: transformed)
32
+ else
33
+ raise ArgumentError.new("Expected key :json for `render` call.")
30
34
  end
31
35
  else
32
- raise ArgumentError.new("Expected key :json for `render` call.")
36
+ super
33
37
  end
34
38
  else
35
39
  super
@@ -42,7 +46,8 @@ module Camille
42
46
  begin
43
47
  params.deep_transform_keys!{|key| key.to_s.underscore}
44
48
  result = super
45
- unless @camille_rendered
49
+ # When there's no `render` call, Rails will return status 204
50
+ if response.status == 204
46
51
  raise_missing_render_error
47
52
  end
48
53
  result
@@ -17,5 +17,9 @@ module Camille
17
17
  def basic?
18
18
  !!@message
19
19
  end
20
+
21
+ def print io = STDOUT
22
+ Camille::TypeErrorPrinter.new(self).print io
23
+ end
20
24
  end
21
25
  end
@@ -0,0 +1,39 @@
1
+ module Camille
2
+ module Types
3
+ class Intersection < Camille::BasicType
4
+ class ArgumentError < ::ArgumentError; end
5
+
6
+ attr_reader :left, :right
7
+
8
+ def initialize left, right
9
+ @left = Camille::Type.instance left
10
+ @right = Camille::Type.instance right
11
+ end
12
+
13
+ def transform_and_check value
14
+ left_error, left_transformed = @left.transform_and_check value
15
+ if left_error
16
+ error = Camille::TypeError.new(
17
+ 'intersection.left' => left_error
18
+ )
19
+ [error, nil]
20
+ else
21
+ right_error, right_transformed = @right.transform_and_check left_transformed
22
+ if right_error
23
+ error = Camille::TypeError.new(
24
+ 'intersection.right' => right_error
25
+ )
26
+ [error, nil]
27
+ else
28
+ [nil, right_transformed]
29
+ end
30
+ end
31
+ end
32
+
33
+ def literal
34
+ "(#{@left.literal} & #{@right.literal})"
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -11,12 +11,17 @@ module Camille
11
11
 
12
12
  def transform_and_check value
13
13
  if value.is_a? Hash
14
- transform_and_check_results = @fields.map do |key, type|
15
- error, transformed = type.transform_and_check(value[key])
16
- if @optional_keys.include?(key) && !error && transformed.nil?
17
- nil
14
+ keys = (@fields.keys + value.keys).uniq
15
+ transform_and_check_results = keys.map do |key|
16
+ if type = @fields[key]
17
+ error, transformed = type.transform_and_check(value[key])
18
+ if @optional_keys.include?(key) && !error && transformed.nil?
19
+ nil
20
+ else
21
+ [key, [error, transformed]]
22
+ end
18
23
  else
19
- [key, type.transform_and_check(value[key])]
24
+ [key, [nil, value[key]]]
20
25
  end
21
26
  end.compact
22
27
 
@@ -63,7 +68,7 @@ module Camille
63
68
  def check_case_conversion_safe sym
64
69
  str = sym.to_s
65
70
  if str != str.camelize.underscore
66
- raise ArgumentError.new("Only keys satisfying `key.to_s == key.to_s.caamelize.underscore` can be used.")
71
+ raise ArgumentError.new("Only keys satisfying `key.to_s == key.to_s.camelize.underscore` can be used.")
67
72
  end
68
73
  end
69
74
  end
@@ -27,7 +27,7 @@ module Camille
27
27
  end
28
28
 
29
29
  def literal
30
- "#{@left.literal} | #{@right.literal}"
30
+ "(#{@left.literal} | #{@right.literal})"
31
31
  end
32
32
  end
33
33
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Camille
4
- VERSION = "0.5.7"
4
+ VERSION = "0.5.9"
5
5
  end
data/lib/camille.rb CHANGED
@@ -13,6 +13,7 @@ require_relative "camille/types/object"
13
13
  require_relative "camille/types/null"
14
14
  require_relative "camille/types/undefined"
15
15
  require_relative "camille/types/union"
16
+ require_relative "camille/types/intersection"
16
17
  require_relative "camille/types/tuple"
17
18
  require_relative "camille/types/any"
18
19
  require_relative "camille/types/number_literal"
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.5.7
4
+ version: 0.5.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - 辻彩
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-22 00:00:00.000000000 Z
11
+ date: 2023-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -78,6 +78,7 @@ files:
78
78
  - lib/camille/types/array.rb
79
79
  - lib/camille/types/boolean.rb
80
80
  - lib/camille/types/boolean_literal.rb
81
+ - lib/camille/types/intersection.rb
81
82
  - lib/camille/types/null.rb
82
83
  - lib/camille/types/number.rb
83
84
  - lib/camille/types/number_literal.rb