camille 0.5.13 → 0.5.15

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: d72196c6854c4c1354a55e5560b649753e49e23875a96d903b2d197dbae72581
4
- data.tar.gz: 43b711376dfa6e9311245463738d999ffe73abc8fa9c7eb9516100f0f778c018
3
+ metadata.gz: 61a549590ebc8eaaa9c8962ff9aee4b2e61c38eddd90bb03c6744bf8ef08b645
4
+ data.tar.gz: 3e93ad48715beae1a358c7f25201e9ed1a286b058fc1f387815bef1362878fcc
5
5
  SHA512:
6
- metadata.gz: 513b2edc45cf95615c6a0d6768a09b7a9ec40fdafb79756694db91b72ab7c614b49140ed6cd7e4cba1a0e8a033e39c5b50aec3ac20d8e5fac25f9ba169f958af
7
- data.tar.gz: '077171197c9aaea4b898ebe5157333d72b2f78297ec08b84605cf9da3615543e24af37f21d06d0a501bb1aa077aa21972e77c1f7c28967fff9274702578a22e1'
6
+ metadata.gz: 86fcb85d6c7730071e3448f12121deec1d585e1d1f615087adbd73b23736282cb5a986bf97b51e8deda8c4862c836d34b5fa5bb3bec9108200d055d69b4ffa1e
7
+ data.tar.gz: 427928b9da7d5665bd0e0874682afb4228a3ad8ceef13887c873baaacc8ec1becc45604988318b992b00db79897d3bd4727281072165e5e5d03fdb927655362c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.15
4
+
5
+ ### Added
6
+
7
+ * Added key conversion cache
8
+
9
+ ### Changed
10
+
11
+ * When generating TS, endpoints are now sorted by name
12
+
13
+ ## 0.5.14
14
+
15
+ ### Fixed
16
+
17
+ * Fixed support for `render json: false`
18
+
3
19
  ## 0.5.13
4
20
 
5
21
  ### Fixed
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- camille (0.5.12)
4
+ camille (0.5.14)
5
5
  rails (>= 6.1, < 8)
6
6
 
7
7
  GEM
@@ -75,11 +75,11 @@ GEM
75
75
  builder (3.2.4)
76
76
  concurrent-ruby (1.2.2)
77
77
  crass (1.0.6)
78
- date (3.3.3)
78
+ date (3.3.4)
79
79
  diff-lcs (1.5.0)
80
80
  erubi (1.12.0)
81
- globalid (1.1.0)
82
- activesupport (>= 5.0)
81
+ globalid (1.2.1)
82
+ activesupport (>= 6.1)
83
83
  i18n (1.12.0)
84
84
  concurrent-ruby (~> 1.0)
85
85
  loofah (2.19.1)
@@ -90,20 +90,20 @@ GEM
90
90
  net-imap
91
91
  net-pop
92
92
  net-smtp
93
- marcel (1.0.2)
93
+ marcel (1.0.4)
94
94
  method_source (1.0.0)
95
- mini_mime (1.1.2)
95
+ mini_mime (1.1.5)
96
96
  minitest (5.17.0)
97
- net-imap (0.3.4)
97
+ net-imap (0.4.16)
98
98
  date
99
99
  net-protocol
100
100
  net-pop (0.1.2)
101
101
  net-protocol
102
- net-protocol (0.2.1)
102
+ net-protocol (0.2.2)
103
103
  timeout
104
- net-smtp (0.3.3)
104
+ net-smtp (0.5.0)
105
105
  net-protocol
106
- nio4r (2.5.9)
106
+ nio4r (2.7.3)
107
107
  nokogiri (1.14.2-x86_64-linux)
108
108
  racc (~> 1.4)
109
109
  racc (1.6.2)
@@ -159,10 +159,10 @@ GEM
159
159
  rspec-support (~> 3.11)
160
160
  rspec-support (3.12.0)
161
161
  thor (1.2.1)
162
- timeout (0.3.2)
162
+ timeout (0.4.1)
163
163
  tzinfo (2.0.6)
164
164
  concurrent-ruby (~> 1.0)
165
- websocket-driver (0.7.5)
165
+ websocket-driver (0.7.6)
166
166
  websocket-extensions (>= 0.1.0)
167
167
  websocket-extensions (0.1.5)
168
168
  zeitwerk (2.6.7)
@@ -0,0 +1,94 @@
1
+ require "benchmark/ips"
2
+
3
+ def array_object
4
+ [1, 2, 3]
5
+ end
6
+
7
+ def hash_object
8
+ {
9
+ a: 1,
10
+ b: 2,
11
+ c: 3
12
+ }
13
+ end
14
+
15
+ class PlainObject
16
+ attr_reader :a, :b, :c
17
+
18
+ def initialize a, b, c
19
+ @a = a
20
+ @b = b
21
+ @c = c
22
+ end
23
+ end
24
+
25
+ def plain_object
26
+ PlainObject.new(1, 2, 3)
27
+ end
28
+
29
+ StructObject = Struct.new(:a, :b, :c)
30
+
31
+ def struct_object
32
+ StructObject.new(1, 2, 3)
33
+ end
34
+
35
+ DataObject = Data.define(:a, :b, :c)
36
+
37
+ def data_object
38
+ DataObject.new(1, 2, 3)
39
+ end
40
+
41
+ Benchmark.ips do |x|
42
+ x.report("parallel assignment") do
43
+ a, b, c = array_object
44
+ end
45
+
46
+ x.report("array access") do
47
+ arr = array_object
48
+ a = arr[0]
49
+ b = arr[1]
50
+ c = arr[2]
51
+ end
52
+
53
+ x.report("hash access") do
54
+ hsh = hash_object
55
+ a = hsh[:a]
56
+ b = hsh[:b]
57
+ c = hsh[:c]
58
+ end
59
+
60
+ x.report("hash destructuring") do
61
+ hash_object => {a:, b:, c:}
62
+ end
63
+
64
+ x.report("plain object") do
65
+ obj = plain_object
66
+ a = obj.a
67
+ b = obj.b
68
+ c = obj.c
69
+ end
70
+
71
+ x.report("struct object") do
72
+ obj = struct_object
73
+ a = obj.a
74
+ b = obj.b
75
+ c = obj.c
76
+ end
77
+
78
+ x.report("struct object destructuring") do
79
+ struct_object => {a:, b:, c:}
80
+ end
81
+
82
+ x.report("data object") do
83
+ obj = data_object
84
+ a = obj.a
85
+ b = obj.b
86
+ c = obj.c
87
+ end
88
+
89
+ x.report("data object destructuring") do
90
+ data_object => {a:, b:, c:}
91
+ end
92
+
93
+ x.compare!
94
+ end
@@ -2,21 +2,30 @@
2
2
  module Camille
3
3
  class Configuration
4
4
  class << self
5
- def ts_header= string
6
- @ts_header = string
7
- end
5
+ attr_reader :response_key_converter, :params_key_converter
6
+ attr_accessor :ts_header, :ts_location
7
+
8
+ def load_default_configurations
9
+ self.response_key_converter = lambda do |symbol|
10
+ symbol.to_s.camelize(:lower)
11
+ end
8
12
 
9
- def ts_header
10
- @ts_header
13
+ self.params_key_converter = lambda do |string|
14
+ string.underscore
15
+ end
11
16
  end
12
17
 
13
- def ts_location= string
14
- @ts_location = string
18
+ def response_key_converter= lambda
19
+ @response_key_converter = lambda
20
+ Camille::Type.define_method :convert_response_key, &lambda
15
21
  end
16
22
 
17
- def ts_location
18
- @ts_location
23
+ def params_key_converter= lambda
24
+ @params_key_converter = lambda
25
+ Camille::Type.define_method :convert_params_key, &lambda
19
26
  end
27
+
28
+ Camille::Configuration.load_default_configurations
20
29
  end
21
30
  end
22
31
  end
@@ -17,7 +17,8 @@ module Camille
17
17
  render_options = args.last
18
18
  intended_status = render_options[:status] || 200
19
19
  if intended_status == 200 || intended_status == :ok
20
- if value = render_options[:json]
20
+ if render_options.has_key? :json
21
+ value = render_options[:json]
21
22
  error, transformed = endpoint.response_type.transform_and_check(value)
22
23
  if error
23
24
  string_io = StringIO.new
@@ -25,7 +26,7 @@ module Camille
25
26
  raise TypeError.new("\nType check failed for response.\n#{string_io.string}")
26
27
  else
27
28
  if transformed.is_a? Hash
28
- transformed.deep_transform_keys!{|k| k.to_s.camelize(:lower)}
29
+ transformed.deep_transform_keys!{|k| Camille::KeyConverter.convert_response_key(k)}
29
30
  end
30
31
  super(json: transformed)
31
32
  end
@@ -44,7 +45,7 @@ module Camille
44
45
  Camille::Loader.check_and_raise_exception
45
46
  if endpoint = camille_endpoint
46
47
  begin
47
- params.deep_transform_keys!{|key| key.to_s.underscore}
48
+ params.deep_transform_keys!{|key| Camille::Configuration.params_key_converter.call(key.to_s)}
48
49
  result = super
49
50
  # When there's no `render` call, Rails will return status 204
50
51
  if response.status == 204
@@ -16,9 +16,9 @@ module Camille
16
16
  raise UnknownResponseError.new("Endpoint lacking a `response` definition.")
17
17
  end
18
18
  if @params_type
19
- "#{ActiveSupport::Inflector.camelize @name, false}(params: #{@params_type.literal}): Promise<#{@response_type.literal}>"
19
+ "#{Camille::Configuration.response_key_converter.call(@name)}(params: #{@params_type.literal}): Promise<#{@response_type.literal}>"
20
20
  else
21
- "#{ActiveSupport::Inflector.camelize @name, false}(): Promise<#{@response_type.literal}>"
21
+ "#{Camille::Configuration.response_key_converter.call(@name)}(): Promise<#{@response_type.literal}>"
22
22
  end
23
23
  end
24
24
 
@@ -0,0 +1,19 @@
1
+ module Camille
2
+ class KeyConverter
3
+ class << self
4
+ RESPONSE_KEY_CACHE = {}
5
+
6
+ def convert_response_key key
7
+ if in_cache = RESPONSE_KEY_CACHE[key]
8
+ in_cache
9
+ else
10
+ RESPONSE_KEY_CACHE[key] = Camille::Configuration.response_key_converter.call(key)
11
+ end
12
+ end
13
+
14
+ def convert_params_key key
15
+ Camille::Configuration.params_key_converter.call(key)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -30,7 +30,7 @@ module Camille
30
30
 
31
31
  private
32
32
  def keys_in_literal
33
- @keys.map{|k| "\"#{k.to_s.camelize(:lower)}\""}.join(' | ')
33
+ @keys.map{|k| "\"#{Camille::Configuration.response_key_converter.call(k)}\""}.join(' | ')
34
34
  end
35
35
 
36
36
  end
@@ -17,7 +17,7 @@ module Camille
17
17
  def self.literal_lines
18
18
  [
19
19
  Camille::Line.new('{'),
20
- *endpoints.map do |k, e|
20
+ *endpoints.sort_by{|k, e| k}.map do |k, e|
21
21
  Camille::Line.new("#{e.function},")
22
22
  end.map(&:do_indent),
23
23
  Camille::Line.new('}')
@@ -31,13 +31,13 @@ module Camille
31
31
  tree.map do |key, value|
32
32
  if value.is_a? ::Hash
33
33
  [
34
- Camille::Line.new("#{ActiveSupport::Inflector.camelize(key, false)}: {"),
34
+ Camille::Line.new("#{Camille::Configuration.response_key_converter.call(key)}: {"),
35
35
  tree_literal_lines(value).map(&:do_indent),
36
36
  Camille::Line.new('},')
37
37
  ]
38
38
  else
39
39
  value.literal_lines.tap do |lines|
40
- lines.first.prepend("#{ActiveSupport::Inflector.camelize(key, false)}: ")
40
+ lines.first.prepend("#{Camille::Configuration.response_key_converter.call(key)}: ")
41
41
  lines.last.append(',')
42
42
  end
43
43
  end
@@ -48,7 +48,7 @@ module Camille
48
48
  private
49
49
  def normalize_fields fields
50
50
  fields.map do |key, value|
51
- check_case_conversion_safe key
51
+ check_key_conversion_safe key
52
52
  type = Camille::Type.instance(value)
53
53
  if key.end_with?('?')
54
54
  new_key = remove_question_mark(key)
@@ -65,13 +65,13 @@ module Camille
65
65
  end
66
66
 
67
67
  def literal_key key
68
- "#{ActiveSupport::Inflector.camelize key.to_s, false}#{@optional_keys.include?(key) ? '?' : ''}"
68
+ "#{Camille::Configuration.response_key_converter.call(key)}#{@optional_keys.include?(key) ? '?' : ''}"
69
69
  end
70
70
 
71
- def check_case_conversion_safe sym
71
+ def check_key_conversion_safe sym
72
72
  str = sym.to_s
73
- if str != str.camelize.underscore
74
- raise ArgumentError.new("Only keys satisfying `key.to_s == key.to_s.camelize.underscore` can be used.")
73
+ if str != Camille::Configuration.params_key_converter.call(Camille::Configuration.response_key_converter.call(str))
74
+ raise ArgumentError.new("Only keys satisfying `key == key.to_s.camelize.underscore` can be used.")
75
75
  end
76
76
  end
77
77
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Camille
4
- VERSION = "0.5.13"
4
+ VERSION = "0.5.15"
5
5
  end
data/lib/camille.rb CHANGED
@@ -37,6 +37,7 @@ require_relative "camille/loader"
37
37
  require_relative "camille/configuration"
38
38
  require_relative "camille/code_generator"
39
39
  require_relative "camille/main_controller"
40
+ require_relative "camille/key_converter"
40
41
 
41
42
  require "rails/generators"
42
43
  require_relative "camille/generators/install_generator"
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.13
4
+ version: 0.5.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alyssa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-29 00:00:00.000000000 Z
11
+ date: 2024-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -43,6 +43,7 @@ files:
43
43
  - Gemfile.lock
44
44
  - README.md
45
45
  - Rakefile
46
+ - benchmarks/returning_multiple_values.rb
46
47
  - bin/console
47
48
  - bin/setup
48
49
  - gemfiles/rails-6.1
@@ -62,6 +63,7 @@ files:
62
63
  - lib/camille/generators/templates/schema_template.erb
63
64
  - lib/camille/generators/templates/type_template.erb
64
65
  - lib/camille/generators/type_generator.rb
66
+ - lib/camille/key_converter.rb
65
67
  - lib/camille/line.rb
66
68
  - lib/camille/loader.rb
67
69
  - lib/camille/main_controller.rb
@@ -113,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
115
  - !ruby/object:Gem::Version
114
116
  version: '0'
115
117
  requirements: []
116
- rubygems_version: 3.2.33
118
+ rubygems_version: 3.4.1
117
119
  signing_key:
118
120
  specification_version: 4
119
121
  summary: Typed API schema for Rails with TypeScript codegen