lithic 0.1.0.pre.alpha.11 → 0.1.0.pre.alpha.12

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/README.md +3 -3
  4. data/lib/lithic/client.rb +5 -11
  5. data/lib/lithic/internal/cursor_page.rb +25 -25
  6. data/lib/lithic/internal/single_page.rb +25 -25
  7. data/lib/lithic/internal/transport/base_client.rb +13 -3
  8. data/lib/lithic/internal/transport/pooled_net_requester.rb +6 -2
  9. data/lib/lithic/internal/type/array_of.rb +17 -2
  10. data/lib/lithic/internal/type/base_model.rb +33 -5
  11. data/lib/lithic/internal/type/base_page.rb +1 -0
  12. data/lib/lithic/internal/type/boolean.rb +2 -0
  13. data/lib/lithic/internal/type/converter.rb +24 -0
  14. data/lib/lithic/internal/type/enum.rb +19 -3
  15. data/lib/lithic/internal/type/hash_of.rb +17 -2
  16. data/lib/lithic/internal/type/io_like.rb +2 -0
  17. data/lib/lithic/internal/type/union.rb +17 -3
  18. data/lib/lithic/internal/type/unknown.rb +2 -0
  19. data/lib/lithic/internal/util.rb +36 -9
  20. data/lib/lithic/internal.rb +5 -1
  21. data/lib/lithic/version.rb +1 -1
  22. data/rbi/lib/lithic/client.rbi +3 -2
  23. data/rbi/lib/lithic/internal/cursor_page.rbi +1 -0
  24. data/rbi/lib/lithic/internal/single_page.rbi +1 -0
  25. data/rbi/lib/lithic/internal/transport/base_client.rbi +1 -0
  26. data/rbi/lib/lithic/internal/type/array_of.rbi +12 -9
  27. data/rbi/lib/lithic/internal/type/base_model.rbi +7 -0
  28. data/rbi/lib/lithic/internal/type/boolean.rbi +4 -5
  29. data/rbi/lib/lithic/internal/type/converter.rbi +8 -0
  30. data/rbi/lib/lithic/internal/type/enum.rbi +4 -0
  31. data/rbi/lib/lithic/internal/type/hash_of.rbi +12 -9
  32. data/rbi/lib/lithic/internal/type/io_like.rbi +4 -5
  33. data/rbi/lib/lithic/internal/type/union.rbi +4 -0
  34. data/rbi/lib/lithic/internal/type/unknown.rbi +4 -5
  35. data/rbi/lib/lithic/internal/util.rbi +15 -0
  36. data/rbi/lib/lithic/internal.rbi +1 -1
  37. data/sig/lithic/internal/type/array_of.rbs +2 -0
  38. data/sig/lithic/internal/type/base_model.rbs +2 -0
  39. data/sig/lithic/internal/type/converter.rbs +4 -0
  40. data/sig/lithic/internal/type/enum.rbs +2 -0
  41. data/sig/lithic/internal/type/hash_of.rbs +2 -0
  42. data/sig/lithic/internal/type/union.rbs +2 -0
  43. data/sig/lithic/internal/util.rbs +2 -0
  44. data/sig/lithic/internal.rbs +1 -1
  45. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8345e32a155e6a1e033d160c478dbc15e245cf60f62f03e21dbc56db982e44e
4
- data.tar.gz: 9e5cbced2f15565f0c0dc8b0f80f3d87034c546d07fff2a4076128d389b91ddd
3
+ metadata.gz: 488e7e7c02bda44d666c79ab398ee65c00d5994049f4aa48439bdb344330fbb6
4
+ data.tar.gz: 7ff630d6290e4abe4304cc2bde7325650d83d2e7b710ac1b93536e22ce8e1351
5
5
  SHA512:
6
- metadata.gz: 11cc54d6e196f755a4ac4bf058799851a598a6c8d25f33989b5f0b6d4e11af50eb2199d61d0aa411ef998ebb0a85b6ee723490b721e38e59ec1e14ba5998ca72
7
- data.tar.gz: 99cc29235b0673eea35abd9bd020c57f009b9307ef4d184029944f6ab066a15358a8347617d06e5fd9816e2b07aadaedd7b5a9d14a2476bada3548474f5d8f64
6
+ metadata.gz: b88593452a1e5a38014849baf782b3030d41bce4fb0b19c3656172590fc381a12892dc7c597d6e9a718560be4be2c083a5d2967140f463aafcf43e493af48d3f
7
+ data.tar.gz: c72e9785ce3b02549023b34b8d8e2a5c3616928ae0bf964f85c8ed7e25e3f2bfa88e97830af80ae7e1c9a107b918eeab7a534c3576360267657d1300fafca04f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.12 (2025-04-17)
4
+
5
+ Full Changelog: [v0.1.0-alpha.11...v0.1.0-alpha.12](https://github.com/lithic-com/lithic-ruby/compare/v0.1.0-alpha.11...v0.1.0-alpha.12)
6
+
7
+ ### Features
8
+
9
+ * **client:** enable setting base URL from environment variable ([4f4585e](https://github.com/lithic-com/lithic-ruby/commit/4f4585e1557f60480629b83e6e2850f6b4a5dc98))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * **client:** send correct HTTP path ([743cdc2](https://github.com/lithic-com/lithic-ruby/commit/743cdc28a16b5cfd724bf5b66cd699c840af8bad))
15
+
16
+
17
+ ### Chores
18
+
19
+ * **internal:** always run post-processing when formatting when syntax_tree ([cfb9196](https://github.com/lithic-com/lithic-ruby/commit/cfb9196cccd8dea098fc52678e0eb2c777b0f900))
20
+ * **internal:** codegen related update ([c743e5d](https://github.com/lithic-com/lithic-ruby/commit/c743e5dd161480e7d3bf5305fb1135137b55d7de))
21
+ * **internal:** loosen internal type restrictions ([be1ae99](https://github.com/lithic-com/lithic-ruby/commit/be1ae999e5f9c36ed16367dfd9a9d0be4115b108))
22
+ * **internal:** minor touch ups on sdk internals ([a9ff4a6](https://github.com/lithic-com/lithic-ruby/commit/a9ff4a6e7da32387c68195b1bdbfe683f63435ff))
23
+ * **internal:** mostly README touch ups ([95ec3f1](https://github.com/lithic-com/lithic-ruby/commit/95ec3f10b027ca3be7dce6ffa2c45b9f8ba0b258))
24
+ * **internal:** protect SSE parsing pipeline from broken UTF-8 characters ([810686a](https://github.com/lithic-com/lithic-ruby/commit/810686a28f0a1d4710c632be010912b2ae41316f))
25
+ * make internal types pretty print ([eb5f0d9](https://github.com/lithic-com/lithic-ruby/commit/eb5f0d9f11b86370cfdca97b4a4716565a20c140))
26
+
27
+
28
+ ### Documentation
29
+
30
+ * update documentation links to be more uniform ([6d246be](https://github.com/lithic-com/lithic-ruby/commit/6d246be6b7a3d16f4e8fb88980d2f53b45d85346))
31
+
3
32
  ## 0.1.0-alpha.11 (2025-04-11)
4
33
 
5
34
  Full Changelog: [v0.1.0-alpha.10...v0.1.0-alpha.11](https://github.com/lithic-com/lithic-ruby/compare/v0.1.0-alpha.10...v0.1.0-alpha.11)
data/README.md CHANGED
@@ -4,9 +4,9 @@ The Lithic Ruby library provides convenient access to the Lithic REST API from a
4
4
 
5
5
  ## Documentation
6
6
 
7
- Documentation for released of this gem can be found [on RubyDoc](https://gemdocs.org/gems/lithic).
7
+ Documentation for releases of this gem can be found [on RubyDoc](https://gemdocs.org/gems/lithic).
8
8
 
9
- The underlying REST API documentation can be found on [docs.lithic.com](https://docs.lithic.com).
9
+ The REST API documentation can be found on [docs.lithic.com](https://docs.lithic.com).
10
10
 
11
11
  ## Installation
12
12
 
@@ -15,7 +15,7 @@ To use this gem, install via Bundler by adding the following to your application
15
15
  <!-- x-release-please-start-version -->
16
16
 
17
17
  ```ruby
18
- gem "lithic", "~> 0.1.0.pre.alpha.11"
18
+ gem "lithic", "~> 0.1.0.pre.alpha.12"
19
19
  ```
20
20
 
21
21
  <!-- x-release-please-end -->
data/lib/lithic/client.rb CHANGED
@@ -134,7 +134,8 @@ module Lithic
134
134
  # - `production` corresponds to `https://api.lithic.com`
135
135
  # - `sandbox` corresponds to `https://sandbox.lithic.com`
136
136
  #
137
- # @param base_url [String, nil] Override the default base URL for the API, e.g., `"https://api.example.com/v2/"`
137
+ # @param base_url [String, nil] Override the default base URL for the API, e.g.,
138
+ # `"https://api.example.com/v2/"`. Defaults to `ENV["LITHIC_BASE_URL"]`
138
139
  #
139
140
  # @param max_retries [Integer] Max number of retries to attempt after a failed retryable request.
140
141
  #
@@ -146,21 +147,14 @@ module Lithic
146
147
  def initialize(
147
148
  api_key: ENV["LITHIC_API_KEY"],
148
149
  environment: nil,
149
- base_url: nil,
150
+ base_url: ENV["LITHIC_BASE_URL"],
150
151
  max_retries: DEFAULT_MAX_RETRIES,
151
152
  timeout: DEFAULT_TIMEOUT_IN_SECONDS,
152
153
  initial_retry_delay: DEFAULT_INITIAL_RETRY_DELAY,
153
154
  max_retry_delay: DEFAULT_MAX_RETRY_DELAY
154
155
  )
155
- case [environment, base_url]
156
- in [Symbol | String, String]
157
- raise ArgumentError.new("both environment and base_url given, expected only one")
158
- in [Symbol | String, nil]
159
- base_url = ENVIRONMENTS.fetch(environment.to_sym) do
160
- raise ArgumentError.new("environment must be one of #{ENVIRONMENTS.keys}, got #{environment}")
161
- end
162
- else
163
- base_url ||= ENVIRONMENTS.fetch(:production)
156
+ base_url ||= ENVIRONMENTS.fetch(environment || :production) do
157
+ raise ArgumentError.new("environment must be one of #{ENVIRONMENTS.keys}, got #{environment}")
164
158
  end
165
159
 
166
160
  if api_key.nil?
@@ -22,29 +22,6 @@ module Lithic
22
22
  # @return [Boolean]
23
23
  attr_accessor :has_more
24
24
 
25
- # @api private
26
- #
27
- # @param client [Lithic::Internal::Transport::BaseClient]
28
- # @param req [Hash{Symbol=>Object}]
29
- # @param headers [Hash{String=>String}, Net::HTTPHeader]
30
- # @param page_data [Hash{Symbol=>Object}]
31
- def initialize(client:, req:, headers:, page_data:)
32
- super
33
- model = req.fetch(:model)
34
-
35
- case page_data
36
- in {data: Array | nil => data}
37
- @data = data&.map { Lithic::Internal::Type::Converter.coerce(model, _1) }
38
- else
39
- end
40
-
41
- case page_data
42
- in {has_more: true | false => has_more}
43
- @has_more = has_more
44
- else
45
- end
46
- end
47
-
48
25
  # @return [Boolean]
49
26
  def next_page?
50
27
  has_more
@@ -69,17 +46,40 @@ module Lithic
69
46
  unless block_given?
70
47
  raise ArgumentError.new("A block must be given to ##{__method__}")
71
48
  end
49
+
72
50
  page = self
73
51
  loop do
74
- page.data&.each { blk.call(_1) }
52
+ page.data&.each(&blk)
53
+
75
54
  break unless page.next_page?
76
55
  page = page.next_page
77
56
  end
78
57
  end
79
58
 
59
+ # @api private
60
+ #
61
+ # @param client [Lithic::Internal::Transport::BaseClient]
62
+ # @param req [Hash{Symbol=>Object}]
63
+ # @param headers [Hash{String=>String}, Net::HTTPHeader]
64
+ # @param page_data [Hash{Symbol=>Object}]
65
+ def initialize(client:, req:, headers:, page_data:)
66
+ super
67
+
68
+ case page_data
69
+ in {data: Array | nil => data}
70
+ @data = data&.map { Lithic::Internal::Type::Converter.coerce(@model, _1) }
71
+ else
72
+ end
73
+ @has_more = page_data[:has_more]
74
+ end
75
+
76
+ # @api private
77
+ #
80
78
  # @return [String]
81
79
  def inspect
82
- "#<#{self.class}:0x#{object_id.to_s(16)} data=#{data.inspect} has_more=#{has_more.inspect}>"
80
+ model = Lithic::Internal::Type::Converter.inspect(@model, depth: 1)
81
+
82
+ "#<#{self.class}[#{model}]:0x#{object_id.to_s(16)} has_more=#{has_more.inspect}>"
83
83
  end
84
84
  end
85
85
  end
@@ -22,29 +22,6 @@ module Lithic
22
22
  # @return [Boolean]
23
23
  attr_accessor :has_more
24
24
 
25
- # @api private
26
- #
27
- # @param client [Lithic::Internal::Transport::BaseClient]
28
- # @param req [Hash{Symbol=>Object}]
29
- # @param headers [Hash{String=>String}, Net::HTTPHeader]
30
- # @param page_data [Array<Object>]
31
- def initialize(client:, req:, headers:, page_data:)
32
- super
33
- model = req.fetch(:model)
34
-
35
- case page_data
36
- in {data: Array | nil => data}
37
- @data = data&.map { Lithic::Internal::Type::Converter.coerce(model, _1) }
38
- else
39
- end
40
-
41
- case page_data
42
- in {has_more: true | false => has_more}
43
- @has_more = has_more
44
- else
45
- end
46
- end
47
-
48
25
  # @return [Boolean]
49
26
  def next_page?
50
27
  has_more
@@ -63,17 +40,40 @@ module Lithic
63
40
  unless block_given?
64
41
  raise ArgumentError.new("A block must be given to ##{__method__}")
65
42
  end
43
+
66
44
  page = self
67
45
  loop do
68
- page.data&.each { blk.call(_1) }
46
+ page.data&.each(&blk)
47
+
69
48
  break unless page.next_page?
70
49
  page = page.next_page
71
50
  end
72
51
  end
73
52
 
53
+ # @api private
54
+ #
55
+ # @param client [Lithic::Internal::Transport::BaseClient]
56
+ # @param req [Hash{Symbol=>Object}]
57
+ # @param headers [Hash{String=>String}, Net::HTTPHeader]
58
+ # @param page_data [Array<Object>]
59
+ def initialize(client:, req:, headers:, page_data:)
60
+ super
61
+
62
+ case page_data
63
+ in {data: Array | nil => data}
64
+ @data = data&.map { Lithic::Internal::Type::Converter.coerce(@model, _1) }
65
+ else
66
+ end
67
+ @has_more = page_data[:has_more]
68
+ end
69
+
70
+ # @api private
71
+ #
74
72
  # @return [String]
75
73
  def inspect
76
- "#<#{self.class}:0x#{object_id.to_s(16)} data=#{data.inspect} has_more=#{has_more.inspect}>"
74
+ model = Lithic::Internal::Type::Converter.inspect(@model, depth: 1)
75
+
76
+ "#<#{self.class}[#{model}]:0x#{object_id.to_s(16)} has_more=#{has_more.inspect}>"
77
77
  end
78
78
  end
79
79
  end
@@ -93,7 +93,11 @@ module Lithic
93
93
  URI.join(url, response_headers["location"])
94
94
  rescue ArgumentError
95
95
  message = "Server responded with status #{status} but no valid location header."
96
- raise Lithic::Errors::APIConnectionError.new(url: url, message: message)
96
+ raise Lithic::Errors::APIConnectionError.new(
97
+ url: url,
98
+ response: response_headers,
99
+ message: message
100
+ )
97
101
  end
98
102
 
99
103
  request = {**request, url: location}
@@ -101,7 +105,11 @@ module Lithic
101
105
  case [url.scheme, location.scheme]
102
106
  in ["https", "http"]
103
107
  message = "Tried to redirect to a insecure URL"
104
- raise Lithic::Errors::APIConnectionError.new(url: url, message: message)
108
+ raise Lithic::Errors::APIConnectionError.new(
109
+ url: url,
110
+ response: response_headers,
111
+ message: message
112
+ )
105
113
  else
106
114
  nil
107
115
  end
@@ -350,7 +358,7 @@ module Lithic
350
358
  self.class.reap_connection!(status, stream: stream)
351
359
 
352
360
  message = "Failed to complete the request within #{self.class::MAX_REDIRECTS} redirects."
353
- raise Lithic::Errors::APIConnectionError.new(url: url, message: message)
361
+ raise Lithic::Errors::APIConnectionError.new(url: url, response: response, message: message)
354
362
  in 300..399
355
363
  self.class.reap_connection!(status, stream: stream)
356
364
 
@@ -460,6 +468,8 @@ module Lithic
460
468
  end
461
469
  end
462
470
 
471
+ # @api private
472
+ #
463
473
  # @return [String]
464
474
  def inspect
465
475
  # rubocop:disable Layout/LineLength
@@ -57,11 +57,15 @@ module Lithic
57
57
  # @return [Array(Net::HTTPGenericRequest, Proc)]
58
58
  def build_request(request, &blk)
59
59
  method, url, headers, body = request.fetch_values(:method, :url, :headers, :body)
60
+
61
+ # ensure we construct a URI class of the right scheme
62
+ url = URI(url.to_s)
63
+
60
64
  req = Net::HTTPGenericRequest.new(
61
65
  method.to_s.upcase,
62
66
  !body.nil?,
63
67
  method != :head,
64
- url.to_s
68
+ url
65
69
  )
66
70
 
67
71
  headers.each { req[_1] = _2 }
@@ -149,7 +153,7 @@ module Lithic
149
153
  break if finished
150
154
 
151
155
  rsp.read_body do |bytes|
152
- y << bytes
156
+ y << bytes.force_encoding(Encoding::BINARY)
153
157
  break if finished
154
158
 
155
159
  self.class.calibrate_socket_timeout(conn, deadline)
@@ -13,6 +13,10 @@ module Lithic
13
13
  class ArrayOf
14
14
  include Lithic::Internal::Type::Converter
15
15
 
16
+ private_class_method :new
17
+
18
+ # @overload [](type_info, spec = {})
19
+ #
16
20
  # @param type_info [Hash{Symbol=>Object}, Proc, Lithic::Internal::Type::Converter, Class]
17
21
  #
18
22
  # @param spec [Hash{Symbol=>Object}] .
@@ -24,7 +28,7 @@ module Lithic
24
28
  # @option spec [Proc] :union
25
29
  #
26
30
  # @option spec [Boolean] :"nil?"
27
- def self.[](type_info, spec = {}) = new(type_info, spec)
31
+ def self.[](...) = new(...)
28
32
 
29
33
  # @param other [Object]
30
34
  #
@@ -120,7 +124,18 @@ module Lithic
120
124
  # @option spec [Boolean] :"nil?"
121
125
  def initialize(type_info, spec = {})
122
126
  @item_type_fn = Lithic::Internal::Type::Converter.type_info(type_info || spec)
123
- @nilable = spec[:nil?]
127
+ @nilable = spec.fetch(:nil?, false)
128
+ end
129
+
130
+ # @api private
131
+ #
132
+ # @param depth [Integer]
133
+ #
134
+ # @return [String]
135
+ def inspect(depth: 0)
136
+ items = Lithic::Internal::Type::Converter.inspect(item_type, depth: depth.succ)
137
+
138
+ "#{self.class}[#{[items, nilable? ? 'nil' : nil].compact.join(' | ')}]"
124
139
  end
125
140
  end
126
141
  end
@@ -63,7 +63,7 @@ module Lithic
63
63
 
64
64
  setter = "#{name_sym}="
65
65
  api_name = info.fetch(:api_name, name_sym)
66
- nilable = info[:nil?]
66
+ nilable = info.fetch(:nil?, false)
67
67
  const = required && !nilable ? info.fetch(:const, Lithic::Internal::OMIT) : Lithic::Internal::OMIT
68
68
 
69
69
  [name_sym, setter].each { undef_method(_1) } if known_fields.key?(name_sym)
@@ -361,14 +361,42 @@ module Lithic
361
361
  end
362
362
  end
363
363
 
364
+ class << self
365
+ # @api private
366
+ #
367
+ # @param depth [Integer]
368
+ #
369
+ # @return [String]
370
+ def inspect(depth: 0)
371
+ return super() if depth.positive?
372
+
373
+ depth = depth.succ
374
+ deferred = fields.transform_values do |field|
375
+ type, required, nilable = field.fetch_values(:type, :required, :nilable)
376
+ -> do
377
+ [
378
+ Lithic::Internal::Type::Converter.inspect(type, depth: depth),
379
+ !required || nilable ? "nil" : nil
380
+ ].compact.join(" | ")
381
+ end
382
+ .tap { _1.define_singleton_method(:inspect) { call } }
383
+ end
384
+
385
+ "#{name}[#{deferred.inspect}]"
386
+ end
387
+ end
388
+
389
+ # @api private
390
+ #
364
391
  # @return [String]
365
392
  def inspect
366
- rows = self.class.known_fields.keys.map do
367
- "#{_1}=#{@data.key?(_1) ? public_send(_1) : ''}"
393
+ rows = @data.map do
394
+ "#{_1}=#{self.class.known_fields.key?(_1) ? public_send(_1).inspect : ''}"
368
395
  rescue Lithic::Errors::ConversionError
369
- "#{_1}=#{@data.fetch(_1)}"
396
+ "#{_1}=#{_2.inspect}"
370
397
  end
371
- "#<#{self.class.name}:0x#{object_id.to_s(16)} #{rows.join(' ')}>"
398
+
399
+ "#<#{self.class}:0x#{object_id.to_s(16)} #{rows.join(' ')}>"
372
400
  end
373
401
  end
374
402
  end
@@ -36,6 +36,7 @@ module Lithic
36
36
  def initialize(client:, req:, headers:, page_data:)
37
37
  @client = client
38
38
  @req = req
39
+ @model = req.fetch(:model)
39
40
  super()
40
41
  end
41
42
 
@@ -11,6 +11,8 @@ module Lithic
11
11
  class Boolean
12
12
  extend Lithic::Internal::Type::Converter
13
13
 
14
+ private_class_method :new
15
+
14
16
  # @param other [Object]
15
17
  #
16
18
  # @return [Boolean]
@@ -49,6 +49,15 @@ module Lithic
49
49
  end
50
50
  end
51
51
 
52
+ # @api private
53
+ #
54
+ # @param depth [Integer]
55
+ #
56
+ # @return [String]
57
+ def inspect(depth: 0)
58
+ super()
59
+ end
60
+
52
61
  # rubocop:enable Lint/UnusedMethodArgument
53
62
 
54
63
  class << self
@@ -240,6 +249,21 @@ module Lithic
240
249
  Lithic::Internal::Type::Unknown.dump(value, state: state)
241
250
  end
242
251
  end
252
+
253
+ # @api private
254
+ #
255
+ # @param target [Object]
256
+ # @param depth [Integer]
257
+ #
258
+ # @return [String]
259
+ def inspect(target, depth:)
260
+ case target
261
+ in Lithic::Internal::Type::Converter
262
+ target.inspect(depth: depth.succ)
263
+ else
264
+ target.inspect
265
+ end
266
+ end
243
267
  end
244
268
  end
245
269
  end
@@ -58,9 +58,9 @@ module Lithic
58
58
  #
59
59
  # @return [Boolean]
60
60
  def ==(other)
61
- # rubocop:disable Layout/LineLength
62
- other.is_a?(Module) && other.singleton_class <= Lithic::Internal::Type::Enum && other.values.to_set == values.to_set
63
- # rubocop:enable Layout/LineLength
61
+ # rubocop:disable Style/CaseEquality
62
+ Lithic::Internal::Type::Enum === other && other.values.to_set == values.to_set
63
+ # rubocop:enable Style/CaseEquality
64
64
  end
65
65
 
66
66
  # @api private
@@ -103,6 +103,22 @@ module Lithic
103
103
  # #
104
104
  # # @return [Symbol, Object]
105
105
  # def dump(value, state:) = super
106
+
107
+ # @api private
108
+ #
109
+ # @param depth [Integer]
110
+ #
111
+ # @return [String]
112
+ def inspect(depth: 0)
113
+ if depth.positive?
114
+ return is_a?(Module) ? super() : self.class.name
115
+ end
116
+
117
+ members = values.map { Lithic::Internal::Type::Converter.inspect(_1, depth: depth.succ) }
118
+ prefix = is_a?(Module) ? name : self.class.name
119
+
120
+ "#{prefix}[#{members.join(' | ')}]"
121
+ end
106
122
  end
107
123
  end
108
124
  end
@@ -13,6 +13,10 @@ module Lithic
13
13
  class HashOf
14
14
  include Lithic::Internal::Type::Converter
15
15
 
16
+ private_class_method :new
17
+
18
+ # @overload [](type_info, spec = {})
19
+ #
16
20
  # @param type_info [Hash{Symbol=>Object}, Proc, Lithic::Internal::Type::Converter, Class]
17
21
  #
18
22
  # @param spec [Hash{Symbol=>Object}] .
@@ -24,7 +28,7 @@ module Lithic
24
28
  # @option spec [Proc] :union
25
29
  #
26
30
  # @option spec [Boolean] :"nil?"
27
- def self.[](type_info, spec = {}) = new(type_info, spec)
31
+ def self.[](...) = new(...)
28
32
 
29
33
  # @param other [Object]
30
34
  #
@@ -140,7 +144,18 @@ module Lithic
140
144
  # @option spec [Boolean] :"nil?"
141
145
  def initialize(type_info, spec = {})
142
146
  @item_type_fn = Lithic::Internal::Type::Converter.type_info(type_info || spec)
143
- @nilable = spec[:nil?]
147
+ @nilable = spec.fetch(:nil?, false)
148
+ end
149
+
150
+ # @api private
151
+ #
152
+ # @param depth [Integer]
153
+ #
154
+ # @return [String]
155
+ def inspect(depth: 0)
156
+ items = Lithic::Internal::Type::Converter.inspect(item_type, depth: depth.succ)
157
+
158
+ "#{self.class}[#{[items, nilable? ? 'nil' : nil].compact.join(' | ')}]"
144
159
  end
145
160
  end
146
161
  end
@@ -11,6 +11,8 @@ module Lithic
11
11
  class IOLike
12
12
  extend Lithic::Internal::Type::Converter
13
13
 
14
+ private_class_method :new
15
+
14
16
  # @param other [Object]
15
17
  #
16
18
  # @return [Boolean]
@@ -111,9 +111,7 @@ module Lithic
111
111
  #
112
112
  # @return [Boolean]
113
113
  def ==(other)
114
- # rubocop:disable Layout/LineLength
115
- other.is_a?(Module) && other.singleton_class <= Lithic::Internal::Type::Union && other.derefed_variants == derefed_variants
116
- # rubocop:enable Layout/LineLength
114
+ Lithic::Internal::Type::Union === other && other.derefed_variants == derefed_variants
117
115
  end
118
116
 
119
117
  # @api private
@@ -196,6 +194,22 @@ module Lithic
196
194
 
197
195
  # rubocop:enable Style/CaseEquality
198
196
  # rubocop:enable Style/HashEachMethods
197
+
198
+ # @api private
199
+ #
200
+ # @param depth [Integer]
201
+ #
202
+ # @return [String]
203
+ def inspect(depth: 0)
204
+ if depth.positive?
205
+ return is_a?(Module) ? super() : self.class.name
206
+ end
207
+
208
+ members = variants.map { Lithic::Internal::Type::Converter.inspect(_1, depth: depth.succ) }
209
+ prefix = is_a?(Module) ? name : self.class.name
210
+
211
+ "#{prefix}[#{members.join(' | ')}]"
212
+ end
199
213
  end
200
214
  end
201
215
  end
@@ -13,6 +13,8 @@ module Lithic
13
13
 
14
14
  # rubocop:disable Lint/UnusedMethodArgument
15
15
 
16
+ private_class_method :new
17
+
16
18
  # @param other [Object]
17
19
  #
18
20
  # @return [Boolean]
@@ -448,7 +448,7 @@ module Lithic
448
448
  else
449
449
  src
450
450
  end
451
- @buf = String.new.b
451
+ @buf = String.new
452
452
  @blk = blk
453
453
  end
454
454
  end
@@ -460,7 +460,7 @@ module Lithic
460
460
  # @return [Enumerable<String>]
461
461
  def writable_enum(&blk)
462
462
  Enumerator.new do |y|
463
- buf = String.new.b
463
+ buf = String.new
464
464
  y.define_singleton_method(:write) do
465
465
  self << buf.replace(_1)
466
466
  buf.bytesize
@@ -582,6 +582,27 @@ module Lithic
582
582
 
583
583
  # @api private
584
584
  #
585
+ # https://www.iana.org/assignments/character-sets/character-sets.xhtml
586
+ #
587
+ # @param content_type [String]
588
+ # @param text [String]
589
+ def force_charset!(content_type, text:)
590
+ charset = /charset=([^;\s]+)/.match(content_type)&.captures&.first
591
+
592
+ return unless charset
593
+
594
+ begin
595
+ encoding = Encoding.find(charset)
596
+ text.force_encoding(encoding)
597
+ rescue ArgumentError
598
+ nil
599
+ end
600
+ end
601
+
602
+ # @api private
603
+ #
604
+ # Assumes each chunk in stream has `Encoding::BINARY`.
605
+ #
585
606
  # @param headers [Hash{String=>String}, Net::HTTPHeader]
586
607
  # @param stream [Enumerable<String>]
587
608
  # @param suppress_error [Boolean]
@@ -589,7 +610,7 @@ module Lithic
589
610
  # @raise [JSON::ParserError]
590
611
  # @return [Object]
591
612
  def decode_content(headers, stream:, suppress_error: false)
592
- case headers["content-type"]
613
+ case (content_type = headers["content-type"])
593
614
  in %r{^application/(?:vnd\.api\+)?json}
594
615
  json = stream.to_a.join
595
616
  begin
@@ -606,11 +627,10 @@ module Lithic
606
627
  in %r{^text/event-stream}
607
628
  lines = decode_lines(stream)
608
629
  decode_sse(lines)
609
- in %r{^text/}
610
- stream.to_a.join
611
630
  else
612
- # TODO: parsing other response types
613
- StringIO.new(stream.to_a.join)
631
+ text = stream.to_a.join
632
+ force_charset!(content_type, text: text)
633
+ StringIO.new(text)
614
634
  end
615
635
  end
616
636
  end
@@ -675,12 +695,17 @@ module Lithic
675
695
  class << self
676
696
  # @api private
677
697
  #
698
+ # Assumes Strings have been forced into having `Encoding::BINARY`.
699
+ #
700
+ # This decoder is responsible for reassembling lines split across multiple
701
+ # fragments.
702
+ #
678
703
  # @param enum [Enumerable<String>]
679
704
  #
680
705
  # @return [Enumerable<String>]
681
706
  def decode_lines(enum)
682
707
  re = /(\r\n|\r|\n)/
683
- buffer = String.new.b
708
+ buffer = String.new
684
709
  cr_seen = nil
685
710
 
686
711
  chain_fused(enum) do |y|
@@ -711,6 +736,8 @@ module Lithic
711
736
  #
712
737
  # https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream
713
738
  #
739
+ # Assumes that `lines` has been decoded with `#decode_lines`.
740
+ #
714
741
  # @param lines [Enumerable<String>]
715
742
  #
716
743
  # @return [Enumerable<Hash{Symbol=>Object}>]
@@ -734,7 +761,7 @@ module Lithic
734
761
  in "event"
735
762
  current.merge!(event: value)
736
763
  in "data"
737
- (current[:data] ||= String.new.b) << (value << "\n")
764
+ (current[:data] ||= String.new) << (value << "\n")
738
765
  in "id" unless value.include?("\0")
739
766
  current.merge!(id: value)
740
767
  in "retry" if /^\d+$/ =~ value
@@ -3,6 +3,10 @@
3
3
  module Lithic
4
4
  # @api private
5
5
  module Internal
6
- OMIT = Object.new.freeze
6
+ OMIT =
7
+ Object.new.tap do
8
+ _1.define_singleton_method(:inspect) { "#<#{Lithic::Internal}::OMIT>" }
9
+ end
10
+ .freeze
7
11
  end
8
12
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lithic
4
- VERSION = "0.1.0.pre.alpha.11"
4
+ VERSION = "0.1.0.pre.alpha.12"
5
5
  end
@@ -128,8 +128,9 @@ module Lithic
128
128
  # - `production` corresponds to `https://api.lithic.com`
129
129
  # - `sandbox` corresponds to `https://sandbox.lithic.com`
130
130
  environment: nil,
131
- # Override the default base URL for the API, e.g., `"https://api.example.com/v2/"`
132
- base_url: nil,
131
+ # Override the default base URL for the API, e.g.,
132
+ # `"https://api.example.com/v2/"`. Defaults to `ENV["LITHIC_BASE_URL"]`
133
+ base_url: ENV["LITHIC_BASE_URL"],
133
134
  # Max number of retries to attempt after a failed retryable request.
134
135
  max_retries: DEFAULT_MAX_RETRIES,
135
136
  timeout: DEFAULT_TIMEOUT_IN_SECONDS,
@@ -13,6 +13,7 @@ module Lithic
13
13
  sig { returns(T::Boolean) }
14
14
  attr_accessor :has_more
15
15
 
16
+ # @api private
16
17
  sig { returns(String) }
17
18
  def inspect; end
18
19
  end
@@ -13,6 +13,7 @@ module Lithic
13
13
  sig { returns(T::Boolean) }
14
14
  attr_accessor :has_more
15
15
 
16
+ # @api private
16
17
  sig { returns(String) }
17
18
  def inspect; end
18
19
  end
@@ -190,6 +190,7 @@ module Lithic
190
190
  model: Lithic::Internal::Type::Unknown,
191
191
  options: {}
192
192
  ); end
193
+ # @api private
193
194
  sig { returns(String) }
194
195
  def inspect; end
195
196
  end
@@ -10,11 +10,10 @@ module Lithic
10
10
  include Lithic::Internal::Type::Converter
11
11
 
12
12
  abstract!
13
- final!
14
13
 
15
14
  Elem = type_member(:out)
16
15
 
17
- sig(:final) do
16
+ sig do
18
17
  params(
19
18
  type_info: T.any(
20
19
  Lithic::Internal::AnyHash,
@@ -27,14 +26,14 @@ module Lithic
27
26
  end
28
27
  def self.[](type_info, spec = {}); end
29
28
 
30
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
29
+ sig { params(other: T.anything).returns(T::Boolean) }
31
30
  def ===(other); end
32
31
 
33
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
32
+ sig { params(other: T.anything).returns(T::Boolean) }
34
33
  def ==(other); end
35
34
 
36
35
  # @api private
37
- sig(:final) do
36
+ sig do
38
37
  override
39
38
  .params(
40
39
  value: T.any(T::Array[T.anything], T.anything),
@@ -45,7 +44,7 @@ module Lithic
45
44
  def coerce(value, state:); end
46
45
 
47
46
  # @api private
48
- sig(:final) do
47
+ sig do
49
48
  override
50
49
  .params(
51
50
  value: T.any(T::Array[T.anything], T.anything),
@@ -56,15 +55,15 @@ module Lithic
56
55
  def dump(value, state:); end
57
56
 
58
57
  # @api private
59
- sig(:final) { returns(Elem) }
58
+ sig { returns(Elem) }
60
59
  protected def item_type; end
61
60
 
62
61
  # @api private
63
- sig(:final) { returns(T::Boolean) }
62
+ sig { returns(T::Boolean) }
64
63
  protected def nilable?; end
65
64
 
66
65
  # @api private
67
- sig(:final) do
66
+ sig do
68
67
  params(
69
68
  type_info: T.any(
70
69
  Lithic::Internal::AnyHash,
@@ -76,6 +75,10 @@ module Lithic
76
75
  .void
77
76
  end
78
77
  def initialize(type_info, spec = {}); end
78
+
79
+ # @api private
80
+ sig { params(depth: Integer).returns(String) }
81
+ def inspect(depth: 0); end
79
82
  end
80
83
  end
81
84
  end
@@ -185,6 +185,13 @@ module Lithic
185
185
  sig { params(data: T.any(T::Hash[Symbol, T.anything], T.self_type)).returns(T.attached_class) }
186
186
  def self.new(data = {}); end
187
187
 
188
+ class << self
189
+ # @api private
190
+ sig { params(depth: Integer).returns(String) }
191
+ def inspect(depth: 0); end
192
+ end
193
+
194
+ # @api private
188
195
  sig { returns(String) }
189
196
  def inspect; end
190
197
  end
@@ -10,17 +10,16 @@ module Lithic
10
10
  extend Lithic::Internal::Type::Converter
11
11
 
12
12
  abstract!
13
- final!
14
13
 
15
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
14
+ sig { params(other: T.anything).returns(T::Boolean) }
16
15
  def self.===(other); end
17
16
 
18
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
17
+ sig { params(other: T.anything).returns(T::Boolean) }
19
18
  def self.==(other); end
20
19
 
21
20
  class << self
22
21
  # @api private
23
- sig(:final) do
22
+ sig do
24
23
  override
25
24
  .params(value: T.any(
26
25
  T::Boolean,
@@ -32,7 +31,7 @@ module Lithic
32
31
  def coerce(value, state:); end
33
32
 
34
33
  # @api private
35
- sig(:final) do
34
+ sig do
36
35
  override
37
36
  .params(value: T.any(
38
37
  T::Boolean,
@@ -34,6 +34,10 @@ module Lithic
34
34
  end
35
35
  def dump(value, state:); end
36
36
 
37
+ # @api private
38
+ sig { params(depth: Integer).returns(String) }
39
+ def inspect(depth: 0); end
40
+
37
41
  class << self
38
42
  # @api private
39
43
  sig do
@@ -105,6 +109,10 @@ module Lithic
105
109
  .returns(T.anything)
106
110
  end
107
111
  def self.dump(target, value, state: {can_retry: true}); end
112
+
113
+ # @api private
114
+ sig { params(target: T.anything, depth: Integer).returns(String) }
115
+ def self.inspect(target, depth:); end
108
116
  end
109
117
  end
110
118
  end
@@ -57,6 +57,10 @@ module Lithic
57
57
  .returns(T.any(Symbol, T.anything))
58
58
  end
59
59
  def dump(value, state:); end
60
+
61
+ # @api private
62
+ sig { params(depth: Integer).returns(String) }
63
+ def inspect(depth: 0); end
60
64
  end
61
65
  end
62
66
  end
@@ -10,11 +10,10 @@ module Lithic
10
10
  include Lithic::Internal::Type::Converter
11
11
 
12
12
  abstract!
13
- final!
14
13
 
15
14
  Elem = type_member(:out)
16
15
 
17
- sig(:final) do
16
+ sig do
18
17
  params(
19
18
  type_info: T.any(
20
19
  Lithic::Internal::AnyHash,
@@ -27,14 +26,14 @@ module Lithic
27
26
  end
28
27
  def self.[](type_info, spec = {}); end
29
28
 
30
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
29
+ sig { params(other: T.anything).returns(T::Boolean) }
31
30
  def ===(other); end
32
31
 
33
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
32
+ sig { params(other: T.anything).returns(T::Boolean) }
34
33
  def ==(other); end
35
34
 
36
35
  # @api private
37
- sig(:final) do
36
+ sig do
38
37
  override
39
38
  .params(
40
39
  value: T.any(T::Hash[T.anything, T.anything], T.anything),
@@ -45,7 +44,7 @@ module Lithic
45
44
  def coerce(value, state:); end
46
45
 
47
46
  # @api private
48
- sig(:final) do
47
+ sig do
49
48
  override
50
49
  .params(
51
50
  value: T.any(T::Hash[T.anything, T.anything], T.anything),
@@ -56,15 +55,15 @@ module Lithic
56
55
  def dump(value, state:); end
57
56
 
58
57
  # @api private
59
- sig(:final) { returns(Elem) }
58
+ sig { returns(Elem) }
60
59
  protected def item_type; end
61
60
 
62
61
  # @api private
63
- sig(:final) { returns(T::Boolean) }
62
+ sig { returns(T::Boolean) }
64
63
  protected def nilable?; end
65
64
 
66
65
  # @api private
67
- sig(:final) do
66
+ sig do
68
67
  params(
69
68
  type_info: T.any(
70
69
  Lithic::Internal::AnyHash,
@@ -76,6 +75,10 @@ module Lithic
76
75
  .void
77
76
  end
78
77
  def initialize(type_info, spec = {}); end
78
+
79
+ # @api private
80
+ sig { params(depth: Integer).returns(String) }
81
+ def inspect(depth: 0); end
79
82
  end
80
83
  end
81
84
  end
@@ -10,17 +10,16 @@ module Lithic
10
10
  extend Lithic::Internal::Type::Converter
11
11
 
12
12
  abstract!
13
- final!
14
13
 
15
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
14
+ sig { params(other: T.anything).returns(T::Boolean) }
16
15
  def self.===(other); end
17
16
 
18
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
17
+ sig { params(other: T.anything).returns(T::Boolean) }
19
18
  def self.==(other); end
20
19
 
21
20
  class << self
22
21
  # @api private
23
- sig(:final) do
22
+ sig do
24
23
  override
25
24
  .params(value: T.any(
26
25
  StringIO,
@@ -33,7 +32,7 @@ module Lithic
33
32
  def coerce(value, state:); end
34
33
 
35
34
  # @api private
36
- sig(:final) do
35
+ sig do
37
36
  override
38
37
  .params(
39
38
  value: T.any(Pathname, StringIO, IO, String, T.anything),
@@ -63,6 +63,10 @@ module Lithic
63
63
  ).returns(T.anything)
64
64
  end
65
65
  def dump(value, state:); end
66
+
67
+ # @api private
68
+ sig { params(depth: Integer).returns(String) }
69
+ def inspect(depth: 0); end
66
70
  end
67
71
  end
68
72
  end
@@ -10,17 +10,16 @@ module Lithic
10
10
  extend Lithic::Internal::Type::Converter
11
11
 
12
12
  abstract!
13
- final!
14
13
 
15
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
14
+ sig { params(other: T.anything).returns(T::Boolean) }
16
15
  def self.===(other); end
17
16
 
18
- sig(:final) { params(other: T.anything).returns(T::Boolean) }
17
+ sig { params(other: T.anything).returns(T::Boolean) }
19
18
  def self.==(other); end
20
19
 
21
20
  class << self
22
21
  # @api private
23
- sig(:final) do
22
+ sig do
24
23
  override
25
24
  .params(value: T.anything, state: Lithic::Internal::Type::Converter::CoerceState)
26
25
  .returns(T.anything)
@@ -28,7 +27,7 @@ module Lithic
28
27
  def coerce(value, state:); end
29
28
 
30
29
  # @api private
31
- sig(:final) do
30
+ sig do
32
31
  override.params(
33
32
  value: T.anything,
34
33
  state: Lithic::Internal::Type::Converter::DumpState
@@ -215,6 +215,14 @@ module Lithic
215
215
  def encode_content(headers, body); end
216
216
 
217
217
  # @api private
218
+ #
219
+ # https://www.iana.org/assignments/character-sets/character-sets.xhtml
220
+ sig { params(content_type: String, text: String).void }
221
+ def force_charset!(content_type, text:); end
222
+
223
+ # @api private
224
+ #
225
+ # Assumes each chunk in stream has `Encoding::BINARY`.
218
226
  sig do
219
227
  params(
220
228
  headers: T.any(T::Hash[String, String], Net::HTTPHeader),
@@ -263,12 +271,19 @@ module Lithic
263
271
 
264
272
  class << self
265
273
  # @api private
274
+ #
275
+ # Assumes Strings have been forced into having `Encoding::BINARY`.
276
+ #
277
+ # This decoder is responsible for reassembling lines split across multiple
278
+ # fragments.
266
279
  sig { params(enum: T::Enumerable[String]).returns(T::Enumerable[String]) }
267
280
  def decode_lines(enum); end
268
281
 
269
282
  # @api private
270
283
  #
271
284
  # https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream
285
+ #
286
+ # Assumes that `lines` has been decoded with `#decode_lines`.
272
287
  sig do
273
288
  params(lines: T::Enumerable[String]).returns(T::Enumerable[Lithic::Internal::Util::ServerSentEvent])
274
289
  end
@@ -7,6 +7,6 @@ module Lithic
7
7
  # this alias might be refined in the future.
8
8
  AnyHash = T.type_alias { T::Hash[Symbol, T.anything] }
9
9
 
10
- OMIT = T.let(T.anything, T.anything)
10
+ OMIT = T.let(Object.new.freeze, T.anything)
11
11
  end
12
12
  end
@@ -35,6 +35,8 @@ module Lithic
35
35
  | Lithic::Internal::Type::Converter::input type_info,
36
36
  ?::Hash[Symbol, top] spec
37
37
  ) -> void
38
+
39
+ def inspect: (?depth: Integer) -> String
38
40
  end
39
41
  end
40
42
  end
@@ -75,6 +75,8 @@ module Lithic
75
75
 
76
76
  def initialize: (?::Hash[Symbol, top] | self data) -> void
77
77
 
78
+ def self.inspect: (?depth: Integer) -> String
79
+
78
80
  def inspect: -> String
79
81
  end
80
82
  end
@@ -23,6 +23,8 @@ module Lithic
23
23
  state: Lithic::Internal::Type::Converter::dump_state
24
24
  ) -> top
25
25
 
26
+ def inspect: (?depth: Integer) -> String
27
+
26
28
  def self.type_info: (
27
29
  {
28
30
  const: (nil | bool | Integer | Float | Symbol)?,
@@ -44,6 +46,8 @@ module Lithic
44
46
  top value,
45
47
  ?state: Lithic::Internal::Type::Converter::dump_state
46
48
  ) -> top
49
+
50
+ def self.inspect: (top target, depth: Integer) -> String
47
51
  end
48
52
  end
49
53
  end
@@ -21,6 +21,8 @@ module Lithic
21
21
  Symbol | top value,
22
22
  state: Lithic::Internal::Type::Converter::dump_state
23
23
  ) -> (Symbol | top)
24
+
25
+ def inspect: (?depth: Integer) -> String
24
26
  end
25
27
  end
26
28
  end
@@ -35,6 +35,8 @@ module Lithic
35
35
  | Lithic::Internal::Type::Converter::input type_info,
36
36
  ?::Hash[Symbol, top] spec
37
37
  ) -> void
38
+
39
+ def inspect: (?depth: Integer) -> String
38
40
  end
39
41
  end
40
42
  end
@@ -39,6 +39,8 @@ module Lithic
39
39
  top value,
40
40
  state: Lithic::Internal::Type::Converter::dump_state
41
41
  ) -> top
42
+
43
+ def inspect: (?depth: Integer) -> String
42
44
  end
43
45
  end
44
46
  end
@@ -120,6 +120,8 @@ module Lithic
120
120
  top body
121
121
  ) -> top
122
122
 
123
+ def self?.force_charset!: (String content_type, text: String) -> void
124
+
123
125
  def self?.decode_content: (
124
126
  ::Hash[String, String] headers,
125
127
  stream: Enumerable[String],
@@ -1,5 +1,5 @@
1
1
  module Lithic
2
2
  module Internal
3
- OMIT: top
3
+ OMIT: Object
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lithic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre.alpha.11
4
+ version: 0.1.0.pre.alpha.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lithic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-11 00:00:00.000000000 Z
11
+ date: 2025-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool