orb-billing 0.1.3 → 0.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/.ignore +2 -0
- data/CHANGELOG.md +31 -0
- data/README.md +3 -3
- data/lib/orb/client.rb +3 -2
- data/lib/orb/internal/page.rb +33 -31
- data/lib/orb/internal/transport/base_client.rb +14 -4
- data/lib/orb/internal/transport/pooled_net_requester.rb +1 -1
- data/lib/orb/internal/type/array_of.rb +17 -2
- data/lib/orb/internal/type/base_model.rb +52 -8
- data/lib/orb/internal/type/base_page.rb +1 -0
- data/lib/orb/internal/type/boolean.rb +2 -0
- data/lib/orb/internal/type/converter.rb +24 -0
- data/lib/orb/internal/type/enum.rb +19 -3
- data/lib/orb/internal/type/hash_of.rb +17 -2
- data/lib/orb/internal/type/io_like.rb +2 -0
- data/lib/orb/internal/type/union.rb +17 -3
- data/lib/orb/internal/type/unknown.rb +2 -0
- data/lib/orb/internal/util.rb +36 -9
- data/lib/orb/internal.rb +5 -1
- data/lib/orb/version.rb +1 -1
- data/rbi/lib/orb/client.rbi +3 -2
- data/rbi/lib/orb/internal/page.rbi +1 -0
- data/rbi/lib/orb/internal/transport/base_client.rbi +1 -0
- data/rbi/lib/orb/internal/type/array_of.rbi +12 -9
- data/rbi/lib/orb/internal/type/base_model.rbi +16 -0
- data/rbi/lib/orb/internal/type/boolean.rbi +4 -5
- data/rbi/lib/orb/internal/type/converter.rbi +8 -0
- data/rbi/lib/orb/internal/type/enum.rbi +4 -0
- data/rbi/lib/orb/internal/type/hash_of.rbi +12 -9
- data/rbi/lib/orb/internal/type/io_like.rbi +4 -5
- data/rbi/lib/orb/internal/type/union.rbi +4 -0
- data/rbi/lib/orb/internal/type/unknown.rbi +4 -5
- data/rbi/lib/orb/internal/util.rbi +15 -0
- data/rbi/lib/orb/internal.rbi +1 -1
- data/sig/orb/internal/type/array_of.rbs +2 -0
- data/sig/orb/internal/type/base_model.rbs +8 -0
- data/sig/orb/internal/type/converter.rbs +4 -0
- data/sig/orb/internal/type/enum.rbs +2 -0
- data/sig/orb/internal/type/hash_of.rbs +2 -0
- data/sig/orb/internal/type/union.rbs +2 -0
- data/sig/orb/internal/util.rbs +2 -0
- data/sig/orb/internal.rbs +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b20102d8611954dcd1c5682addb7eb5d7b54314f2a38a14ac662e61fdd3084d5
|
4
|
+
data.tar.gz: '0857f6afda9adda33b5370837b17c5ab08e2bead3d708a3554e0c23c4398c2de'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2641bfb912356b7b5458ffa63da5c444a75c651dc14984a863badfb4b461e1b06da20ac25153dfa4d1e8176411268b541777f631cf75300b1704dfc0316a417
|
7
|
+
data.tar.gz: 51816a9538c1d9e475afd9bc3e027aa4ef09874850ebb0d12d0c3b662c63315ef1a61e28e3d271ad83e3c529d8dddb545eace95b2fafa4c6e6689edbd63cb2a2
|
data/.ignore
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,36 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.2.0 (2025-04-17)
|
4
|
+
|
5
|
+
Full Changelog: [v0.1.3...v0.2.0](https://github.com/orbcorp/orb-ruby/compare/v0.1.3...v0.2.0)
|
6
|
+
|
7
|
+
### Features
|
8
|
+
|
9
|
+
* **client:** enable setting base URL from environment variable ([a472f4c](https://github.com/orbcorp/orb-ruby/commit/a472f4cdee0d969b7e240a9519acccd3877f3de6))
|
10
|
+
|
11
|
+
|
12
|
+
### Bug Fixes
|
13
|
+
|
14
|
+
* always send idempotency header when specified as a request option ([f570e93](https://github.com/orbcorp/orb-ruby/commit/f570e93e8fe1a2f6d6df495021ea1152aeaf1e58))
|
15
|
+
|
16
|
+
|
17
|
+
### Chores
|
18
|
+
|
19
|
+
* **internal:** always run post-processing when formatting when syntax_tree ([9df6d63](https://github.com/orbcorp/orb-ruby/commit/9df6d6382e67f6f28f1cedff4ee1c949ffd70237))
|
20
|
+
* **internal:** codegen related update ([202fff4](https://github.com/orbcorp/orb-ruby/commit/202fff413ad9e9be16b67a07270dd4ac2c4f14e4))
|
21
|
+
* **internal:** codegen related update ([2b99ae2](https://github.com/orbcorp/orb-ruby/commit/2b99ae2ea108ad4e6227bd5ab7e9a7dd064a8ded))
|
22
|
+
* **internal:** contribute.md and contributor QoL improvements ([cb204de](https://github.com/orbcorp/orb-ruby/commit/cb204de43549ee6aa9ead2d1e071ec5df0c58cb2))
|
23
|
+
* **internal:** loosen internal type restrictions ([9dc6b52](https://github.com/orbcorp/orb-ruby/commit/9dc6b52d1bfa57e3fab328bf8673872522ab7f25))
|
24
|
+
* **internal:** minor touch ups on sdk internals ([9297be8](https://github.com/orbcorp/orb-ruby/commit/9297be8eaa459f14cb0b4118066ecd59877686ab))
|
25
|
+
* **internal:** protect SSE parsing pipeline from broken UTF-8 characters ([bb2243a](https://github.com/orbcorp/orb-ruby/commit/bb2243a19fbd077687be4b2a4a001e4b7381c54d))
|
26
|
+
* **internal:** version bump ([c664f2f](https://github.com/orbcorp/orb-ruby/commit/c664f2fb5019cabca07ce026410d6951f9412d69))
|
27
|
+
* refine `#inspect` and `#to_s` for model classes ([86f8280](https://github.com/orbcorp/orb-ruby/commit/86f8280e1126e5bd4013f4c1e5ddd09190044fa3))
|
28
|
+
|
29
|
+
|
30
|
+
### Documentation
|
31
|
+
|
32
|
+
* update documentation links to be more uniform ([a0bfe42](https://github.com/orbcorp/orb-ruby/commit/a0bfe42c34e09819e4948069670cfdf895cb51af))
|
33
|
+
|
3
34
|
## 0.1.3 (2025-04-11)
|
4
35
|
|
5
36
|
Full Changelog: [v0.1.2...v0.1.3](https://github.com/orbcorp/orb-ruby/compare/v0.1.2...v0.1.3)
|
data/README.md
CHANGED
@@ -4,9 +4,9 @@ The Orb Ruby library provides convenient access to the Orb REST API from any Rub
|
|
4
4
|
|
5
5
|
## Documentation
|
6
6
|
|
7
|
-
Documentation for
|
7
|
+
Documentation for releases of this gem can be found [on RubyDoc](https://gemdocs.org/gems/orb-billing).
|
8
8
|
|
9
|
-
The
|
9
|
+
The REST API documentation can be found on [docs.withorb.com](https://docs.withorb.com/reference/api-reference).
|
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 "orb-billing", "~> 0.
|
18
|
+
gem "orb-billing", "~> 0.2.0"
|
19
19
|
```
|
20
20
|
|
21
21
|
<!-- x-release-please-end -->
|
data/lib/orb/client.rb
CHANGED
@@ -76,7 +76,8 @@ module Orb
|
|
76
76
|
#
|
77
77
|
# @param api_key [String, nil] Defaults to `ENV["ORB_API_KEY"]`
|
78
78
|
#
|
79
|
-
# @param base_url [String, nil] Override the default base URL for the API, e.g.,
|
79
|
+
# @param base_url [String, nil] Override the default base URL for the API, e.g.,
|
80
|
+
# `"https://api.example.com/v2/"`. Defaults to `ENV["ORB_BASE_URL"]`
|
80
81
|
#
|
81
82
|
# @param max_retries [Integer] Max number of retries to attempt after a failed retryable request.
|
82
83
|
#
|
@@ -89,7 +90,7 @@ module Orb
|
|
89
90
|
# @param idempotency_header [String]
|
90
91
|
def initialize(
|
91
92
|
api_key: ENV["ORB_API_KEY"],
|
92
|
-
base_url:
|
93
|
+
base_url: ENV["ORB_BASE_URL"],
|
93
94
|
max_retries: DEFAULT_MAX_RETRIES,
|
94
95
|
timeout: DEFAULT_TIMEOUT_IN_SECONDS,
|
95
96
|
initial_retry_delay: DEFAULT_INITIAL_RETRY_DELAY,
|
data/lib/orb/internal/page.rb
CHANGED
@@ -22,33 +22,6 @@ module Orb
|
|
22
22
|
# @return [PaginationMetadata]
|
23
23
|
attr_accessor :pagination_metadata
|
24
24
|
|
25
|
-
# @api private
|
26
|
-
#
|
27
|
-
# @param client [Orb::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 { Orb::Internal::Type::Converter.coerce(model, _1) }
|
38
|
-
else
|
39
|
-
end
|
40
|
-
|
41
|
-
case page_data
|
42
|
-
in {pagination_metadata: Hash | nil => pagination_metadata}
|
43
|
-
@pagination_metadata =
|
44
|
-
Orb::Internal::Type::Converter.coerce(
|
45
|
-
Orb::Internal::Page::PaginationMetadata,
|
46
|
-
pagination_metadata
|
47
|
-
)
|
48
|
-
else
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
25
|
# @return [Boolean]
|
53
26
|
def next_page?
|
54
27
|
!pagination_metadata&.next_cursor.nil?
|
@@ -73,19 +46,48 @@ module Orb
|
|
73
46
|
unless block_given?
|
74
47
|
raise ArgumentError.new("A block must be given to ##{__method__}")
|
75
48
|
end
|
49
|
+
|
76
50
|
page = self
|
77
51
|
loop do
|
78
|
-
page.data&.each
|
52
|
+
page.data&.each(&blk)
|
53
|
+
|
79
54
|
break unless page.next_page?
|
80
55
|
page = page.next_page
|
81
56
|
end
|
82
57
|
end
|
83
58
|
|
59
|
+
# @api private
|
60
|
+
#
|
61
|
+
# @param client [Orb::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 { Orb::Internal::Type::Converter.coerce(@model, _1) }
|
71
|
+
else
|
72
|
+
end
|
73
|
+
case page_data
|
74
|
+
in {pagination_metadata: Hash | nil => pagination_metadata}
|
75
|
+
@pagination_metadata =
|
76
|
+
Orb::Internal::Type::Converter.coerce(
|
77
|
+
Orb::Internal::Page::PaginationMetadata,
|
78
|
+
pagination_metadata
|
79
|
+
)
|
80
|
+
else
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# @api private
|
85
|
+
#
|
84
86
|
# @return [String]
|
85
87
|
def inspect
|
86
|
-
|
87
|
-
|
88
|
-
#
|
88
|
+
model = Orb::Internal::Type::Converter.inspect(@model, depth: 1)
|
89
|
+
|
90
|
+
"#<#{self.class}[#{model}]:0x#{object_id.to_s(16)}>"
|
89
91
|
end
|
90
92
|
|
91
93
|
class PaginationMetadata < Orb::Internal::Type::BaseModel
|
@@ -93,7 +93,11 @@ module Orb
|
|
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 Orb::Errors::APIConnectionError.new(
|
96
|
+
raise Orb::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 Orb
|
|
101
105
|
case [url.scheme, location.scheme]
|
102
106
|
in ["https", "http"]
|
103
107
|
message = "Tried to redirect to a insecure URL"
|
104
|
-
raise Orb::Errors::APIConnectionError.new(
|
108
|
+
raise Orb::Errors::APIConnectionError.new(
|
109
|
+
url: url,
|
110
|
+
response: response_headers,
|
111
|
+
message: message
|
112
|
+
)
|
105
113
|
else
|
106
114
|
nil
|
107
115
|
end
|
@@ -245,7 +253,7 @@ module Orb
|
|
245
253
|
|
246
254
|
if @idempotency_header &&
|
247
255
|
!headers.key?(@idempotency_header) &&
|
248
|
-
!Net::HTTP::IDEMPOTENT_METHODS_.include?(method.to_s.upcase)
|
256
|
+
(!Net::HTTP::IDEMPOTENT_METHODS_.include?(method.to_s.upcase) || opts.key?(:idempotency_key))
|
249
257
|
headers[@idempotency_header] = opts.fetch(:idempotency_key) { generate_idempotency_key }
|
250
258
|
end
|
251
259
|
|
@@ -350,7 +358,7 @@ module Orb
|
|
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 Orb::Errors::APIConnectionError.new(url: url, message: message)
|
361
|
+
raise Orb::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 Orb
|
|
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
|
@@ -13,6 +13,10 @@ module Orb
|
|
13
13
|
class ArrayOf
|
14
14
|
include Orb::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, Orb::Internal::Type::Converter, Class]
|
17
21
|
#
|
18
22
|
# @param spec [Hash{Symbol=>Object}] .
|
@@ -24,7 +28,7 @@ module Orb
|
|
24
28
|
# @option spec [Proc] :union
|
25
29
|
#
|
26
30
|
# @option spec [Boolean] :"nil?"
|
27
|
-
def self.[](
|
31
|
+
def self.[](...) = new(...)
|
28
32
|
|
29
33
|
# @param other [Object]
|
30
34
|
#
|
@@ -120,7 +124,18 @@ module Orb
|
|
120
124
|
# @option spec [Boolean] :"nil?"
|
121
125
|
def initialize(type_info, spec = {})
|
122
126
|
@item_type_fn = Orb::Internal::Type::Converter.type_info(type_info || spec)
|
123
|
-
@nilable = spec
|
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 = Orb::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 Orb
|
|
63
63
|
|
64
64
|
setter = "#{name_sym}="
|
65
65
|
api_name = info.fetch(:api_name, name_sym)
|
66
|
-
nilable = info
|
66
|
+
nilable = info.fetch(:nil?, false)
|
67
67
|
const = required && !nilable ? info.fetch(:const, Orb::Internal::OMIT) : Orb::Internal::OMIT
|
68
68
|
|
69
69
|
[name_sym, setter].each { undef_method(_1) } if known_fields.key?(name_sym)
|
@@ -338,6 +338,27 @@ module Orb
|
|
338
338
|
.to_h
|
339
339
|
end
|
340
340
|
|
341
|
+
class << self
|
342
|
+
# @param model [Orb::Internal::Type::BaseModel]
|
343
|
+
#
|
344
|
+
# @return [Hash{Symbol=>Object}]
|
345
|
+
def walk(model)
|
346
|
+
walk = ->(x) do
|
347
|
+
case x
|
348
|
+
in Orb::Internal::Type::BaseModel
|
349
|
+
walk.call(x.to_h)
|
350
|
+
in Hash
|
351
|
+
x.transform_values(&walk)
|
352
|
+
in Array
|
353
|
+
x.map(&walk)
|
354
|
+
else
|
355
|
+
x
|
356
|
+
end
|
357
|
+
end
|
358
|
+
walk.call(model)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
341
362
|
# @param a [Object]
|
342
363
|
#
|
343
364
|
# @return [String]
|
@@ -361,15 +382,38 @@ module Orb
|
|
361
382
|
end
|
362
383
|
end
|
363
384
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
385
|
+
class << self
|
386
|
+
# @api private
|
387
|
+
#
|
388
|
+
# @param depth [Integer]
|
389
|
+
#
|
390
|
+
# @return [String]
|
391
|
+
def inspect(depth: 0)
|
392
|
+
return super() if depth.positive?
|
393
|
+
|
394
|
+
depth = depth.succ
|
395
|
+
deferred = fields.transform_values do |field|
|
396
|
+
type, required, nilable = field.fetch_values(:type, :required, :nilable)
|
397
|
+
inspected = [
|
398
|
+
Orb::Internal::Type::Converter.inspect(type, depth: depth),
|
399
|
+
!required || nilable ? "nil" : nil
|
400
|
+
].compact.join(" | ")
|
401
|
+
-> { inspected }.tap { _1.define_singleton_method(:inspect) { call } }
|
402
|
+
end
|
403
|
+
|
404
|
+
"#{name}[#{deferred.inspect}]"
|
370
405
|
end
|
371
|
-
"#<#{self.class.name}:0x#{object_id.to_s(16)} #{rows.join(' ')}>"
|
372
406
|
end
|
407
|
+
|
408
|
+
# @api private
|
409
|
+
#
|
410
|
+
# @return [String]
|
411
|
+
def to_s = self.class.walk(@data).to_s
|
412
|
+
|
413
|
+
# @api private
|
414
|
+
#
|
415
|
+
# @return [String]
|
416
|
+
def inspect = "#<#{self.class}:0x#{object_id.to_s(16)} #{self}>"
|
373
417
|
end
|
374
418
|
end
|
375
419
|
end
|
@@ -49,6 +49,15 @@ module Orb
|
|
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 Orb
|
|
240
249
|
Orb::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 Orb::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 Orb
|
|
58
58
|
#
|
59
59
|
# @return [Boolean]
|
60
60
|
def ==(other)
|
61
|
-
# rubocop:disable
|
62
|
-
|
63
|
-
# rubocop:enable
|
61
|
+
# rubocop:disable Style/CaseEquality
|
62
|
+
Orb::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 Orb
|
|
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 { Orb::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 Orb
|
|
13
13
|
class HashOf
|
14
14
|
include Orb::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, Orb::Internal::Type::Converter, Class]
|
17
21
|
#
|
18
22
|
# @param spec [Hash{Symbol=>Object}] .
|
@@ -24,7 +28,7 @@ module Orb
|
|
24
28
|
# @option spec [Proc] :union
|
25
29
|
#
|
26
30
|
# @option spec [Boolean] :"nil?"
|
27
|
-
def self.[](
|
31
|
+
def self.[](...) = new(...)
|
28
32
|
|
29
33
|
# @param other [Object]
|
30
34
|
#
|
@@ -140,7 +144,18 @@ module Orb
|
|
140
144
|
# @option spec [Boolean] :"nil?"
|
141
145
|
def initialize(type_info, spec = {})
|
142
146
|
@item_type_fn = Orb::Internal::Type::Converter.type_info(type_info || spec)
|
143
|
-
@nilable = spec
|
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 = Orb::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
|
@@ -140,9 +140,7 @@ module Orb
|
|
140
140
|
#
|
141
141
|
# @return [Boolean]
|
142
142
|
def ==(other)
|
143
|
-
|
144
|
-
other.is_a?(Module) && other.singleton_class <= Orb::Internal::Type::Union && other.derefed_variants == derefed_variants
|
145
|
-
# rubocop:enable Layout/LineLength
|
143
|
+
Orb::Internal::Type::Union === other && other.derefed_variants == derefed_variants
|
146
144
|
end
|
147
145
|
|
148
146
|
# @api private
|
@@ -225,6 +223,22 @@ module Orb
|
|
225
223
|
|
226
224
|
# rubocop:enable Style/CaseEquality
|
227
225
|
# rubocop:enable Style/HashEachMethods
|
226
|
+
|
227
|
+
# @api private
|
228
|
+
#
|
229
|
+
# @param depth [Integer]
|
230
|
+
#
|
231
|
+
# @return [String]
|
232
|
+
def inspect(depth: 0)
|
233
|
+
if depth.positive?
|
234
|
+
return is_a?(Module) ? super() : self.class.name
|
235
|
+
end
|
236
|
+
|
237
|
+
members = variants.map { Orb::Internal::Type::Converter.inspect(_1, depth: depth.succ) }
|
238
|
+
prefix = is_a?(Module) ? name : self.class.name
|
239
|
+
|
240
|
+
"#{prefix}[#{members.join(' | ')}]"
|
241
|
+
end
|
228
242
|
end
|
229
243
|
end
|
230
244
|
end
|
data/lib/orb/internal/util.rb
CHANGED
@@ -448,7 +448,7 @@ module Orb
|
|
448
448
|
else
|
449
449
|
src
|
450
450
|
end
|
451
|
-
@buf = String.new
|
451
|
+
@buf = String.new
|
452
452
|
@blk = blk
|
453
453
|
end
|
454
454
|
end
|
@@ -460,7 +460,7 @@ module Orb
|
|
460
460
|
# @return [Enumerable<String>]
|
461
461
|
def writable_enum(&blk)
|
462
462
|
Enumerator.new do |y|
|
463
|
-
buf = String.new
|
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 Orb
|
|
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 Orb
|
|
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 Orb
|
|
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
|
-
|
613
|
-
|
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 Orb
|
|
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
|
708
|
+
buffer = String.new
|
684
709
|
cr_seen = nil
|
685
710
|
|
686
711
|
chain_fused(enum) do |y|
|
@@ -711,6 +736,8 @@ module Orb
|
|
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 Orb
|
|
734
761
|
in "event"
|
735
762
|
current.merge!(event: value)
|
736
763
|
in "data"
|
737
|
-
(current[:data] ||= String.new
|
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
|
data/lib/orb/internal.rb
CHANGED
data/lib/orb/version.rb
CHANGED
data/rbi/lib/orb/client.rbi
CHANGED
@@ -78,8 +78,9 @@ module Orb
|
|
78
78
|
def self.new(
|
79
79
|
# Defaults to `ENV["ORB_API_KEY"]`
|
80
80
|
api_key: ENV["ORB_API_KEY"],
|
81
|
-
# Override the default base URL for the API, e.g.,
|
82
|
-
|
81
|
+
# Override the default base URL for the API, e.g.,
|
82
|
+
# `"https://api.example.com/v2/"`. Defaults to `ENV["ORB_BASE_URL"]`
|
83
|
+
base_url: ENV["ORB_BASE_URL"],
|
83
84
|
# Max number of retries to attempt after a failed retryable request.
|
84
85
|
max_retries: DEFAULT_MAX_RETRIES,
|
85
86
|
timeout: DEFAULT_TIMEOUT_IN_SECONDS,
|
@@ -10,11 +10,10 @@ module Orb
|
|
10
10
|
include Orb::Internal::Type::Converter
|
11
11
|
|
12
12
|
abstract!
|
13
|
-
final!
|
14
13
|
|
15
14
|
Elem = type_member(:out)
|
16
15
|
|
17
|
-
sig
|
16
|
+
sig do
|
18
17
|
params(
|
19
18
|
type_info: T.any(
|
20
19
|
Orb::Internal::AnyHash,
|
@@ -27,14 +26,14 @@ module Orb
|
|
27
26
|
end
|
28
27
|
def self.[](type_info, spec = {}); end
|
29
28
|
|
30
|
-
sig
|
29
|
+
sig { params(other: T.anything).returns(T::Boolean) }
|
31
30
|
def ===(other); end
|
32
31
|
|
33
|
-
sig
|
32
|
+
sig { params(other: T.anything).returns(T::Boolean) }
|
34
33
|
def ==(other); end
|
35
34
|
|
36
35
|
# @api private
|
37
|
-
sig
|
36
|
+
sig do
|
38
37
|
override
|
39
38
|
.params(value: T.any(
|
40
39
|
T::Array[T.anything],
|
@@ -46,7 +45,7 @@ module Orb
|
|
46
45
|
def coerce(value, state:); end
|
47
46
|
|
48
47
|
# @api private
|
49
|
-
sig
|
48
|
+
sig do
|
50
49
|
override
|
51
50
|
.params(value: T.any(
|
52
51
|
T::Array[T.anything],
|
@@ -58,15 +57,15 @@ module Orb
|
|
58
57
|
def dump(value, state:); end
|
59
58
|
|
60
59
|
# @api private
|
61
|
-
sig
|
60
|
+
sig { returns(Elem) }
|
62
61
|
protected def item_type; end
|
63
62
|
|
64
63
|
# @api private
|
65
|
-
sig
|
64
|
+
sig { returns(T::Boolean) }
|
66
65
|
protected def nilable?; end
|
67
66
|
|
68
67
|
# @api private
|
69
|
-
sig
|
68
|
+
sig do
|
70
69
|
params(
|
71
70
|
type_info: T.any(
|
72
71
|
Orb::Internal::AnyHash,
|
@@ -78,6 +77,10 @@ module Orb
|
|
78
77
|
.void
|
79
78
|
end
|
80
79
|
def initialize(type_info, spec = {}); end
|
80
|
+
|
81
|
+
# @api private
|
82
|
+
sig { params(depth: Integer).returns(String) }
|
83
|
+
def inspect(depth: 0); end
|
81
84
|
end
|
82
85
|
end
|
83
86
|
end
|
@@ -175,6 +175,11 @@ module Orb
|
|
175
175
|
sig { params(keys: T.nilable(T::Array[Symbol])).returns(Orb::Internal::AnyHash) }
|
176
176
|
def deconstruct_keys(keys); end
|
177
177
|
|
178
|
+
class << self
|
179
|
+
sig { params(model: Orb::Internal::Type::BaseModel).returns(Orb::Internal::AnyHash) }
|
180
|
+
def walk(model); end
|
181
|
+
end
|
182
|
+
|
178
183
|
sig { params(a: T.anything).returns(String) }
|
179
184
|
def to_json(*a); end
|
180
185
|
|
@@ -185,6 +190,17 @@ module Orb
|
|
185
190
|
sig { params(data: T.any(T::Hash[Symbol, T.anything], T.self_type)).returns(T.attached_class) }
|
186
191
|
def self.new(data = {}); end
|
187
192
|
|
193
|
+
class << self
|
194
|
+
# @api private
|
195
|
+
sig { params(depth: Integer).returns(String) }
|
196
|
+
def inspect(depth: 0); end
|
197
|
+
end
|
198
|
+
|
199
|
+
# @api private
|
200
|
+
sig { returns(String) }
|
201
|
+
def to_s; end
|
202
|
+
|
203
|
+
# @api private
|
188
204
|
sig { returns(String) }
|
189
205
|
def inspect; end
|
190
206
|
end
|
@@ -10,17 +10,16 @@ module Orb
|
|
10
10
|
extend Orb::Internal::Type::Converter
|
11
11
|
|
12
12
|
abstract!
|
13
|
-
final!
|
14
13
|
|
15
|
-
sig
|
14
|
+
sig { params(other: T.anything).returns(T::Boolean) }
|
16
15
|
def self.===(other); end
|
17
16
|
|
18
|
-
sig
|
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
|
22
|
+
sig do
|
24
23
|
override
|
25
24
|
.params(value: T.any(
|
26
25
|
T::Boolean,
|
@@ -32,7 +31,7 @@ module Orb
|
|
32
31
|
def coerce(value, state:); end
|
33
32
|
|
34
33
|
# @api private
|
35
|
-
sig
|
34
|
+
sig do
|
36
35
|
override
|
37
36
|
.params(value: T.any(T::Boolean, T.anything), state: Orb::Internal::Type::Converter::DumpState)
|
38
37
|
.returns(T.any(T::Boolean, T.anything))
|
@@ -35,6 +35,10 @@ module Orb
|
|
35
35
|
end
|
36
36
|
def dump(value, state:); end
|
37
37
|
|
38
|
+
# @api private
|
39
|
+
sig { params(depth: Integer).returns(String) }
|
40
|
+
def inspect(depth: 0); end
|
41
|
+
|
38
42
|
class << self
|
39
43
|
# @api private
|
40
44
|
sig do
|
@@ -106,6 +110,10 @@ module Orb
|
|
106
110
|
.returns(T.anything)
|
107
111
|
end
|
108
112
|
def self.dump(target, value, state: {can_retry: true}); end
|
113
|
+
|
114
|
+
# @api private
|
115
|
+
sig { params(target: T.anything, depth: Integer).returns(String) }
|
116
|
+
def self.inspect(target, depth:); end
|
109
117
|
end
|
110
118
|
end
|
111
119
|
end
|
@@ -10,11 +10,10 @@ module Orb
|
|
10
10
|
include Orb::Internal::Type::Converter
|
11
11
|
|
12
12
|
abstract!
|
13
|
-
final!
|
14
13
|
|
15
14
|
Elem = type_member(:out)
|
16
15
|
|
17
|
-
sig
|
16
|
+
sig do
|
18
17
|
params(
|
19
18
|
type_info: T.any(
|
20
19
|
Orb::Internal::AnyHash,
|
@@ -27,14 +26,14 @@ module Orb
|
|
27
26
|
end
|
28
27
|
def self.[](type_info, spec = {}); end
|
29
28
|
|
30
|
-
sig
|
29
|
+
sig { params(other: T.anything).returns(T::Boolean) }
|
31
30
|
def ===(other); end
|
32
31
|
|
33
|
-
sig
|
32
|
+
sig { params(other: T.anything).returns(T::Boolean) }
|
34
33
|
def ==(other); end
|
35
34
|
|
36
35
|
# @api private
|
37
|
-
sig
|
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 Orb
|
|
45
44
|
def coerce(value, state:); end
|
46
45
|
|
47
46
|
# @api private
|
48
|
-
sig
|
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 Orb
|
|
56
55
|
def dump(value, state:); end
|
57
56
|
|
58
57
|
# @api private
|
59
|
-
sig
|
58
|
+
sig { returns(Elem) }
|
60
59
|
protected def item_type; end
|
61
60
|
|
62
61
|
# @api private
|
63
|
-
sig
|
62
|
+
sig { returns(T::Boolean) }
|
64
63
|
protected def nilable?; end
|
65
64
|
|
66
65
|
# @api private
|
67
|
-
sig
|
66
|
+
sig do
|
68
67
|
params(
|
69
68
|
type_info: T.any(
|
70
69
|
Orb::Internal::AnyHash,
|
@@ -76,6 +75,10 @@ module Orb
|
|
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 Orb
|
|
10
10
|
extend Orb::Internal::Type::Converter
|
11
11
|
|
12
12
|
abstract!
|
13
|
-
final!
|
14
13
|
|
15
|
-
sig
|
14
|
+
sig { params(other: T.anything).returns(T::Boolean) }
|
16
15
|
def self.===(other); end
|
17
16
|
|
18
|
-
sig
|
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
|
22
|
+
sig do
|
24
23
|
override
|
25
24
|
.params(value: T.any(
|
26
25
|
StringIO,
|
@@ -33,7 +32,7 @@ module Orb
|
|
33
32
|
def coerce(value, state:); end
|
34
33
|
|
35
34
|
# @api private
|
36
|
-
sig
|
35
|
+
sig do
|
37
36
|
override
|
38
37
|
.params(
|
39
38
|
value: T.any(Pathname, StringIO, IO, String, T.anything),
|
@@ -10,17 +10,16 @@ module Orb
|
|
10
10
|
extend Orb::Internal::Type::Converter
|
11
11
|
|
12
12
|
abstract!
|
13
|
-
final!
|
14
13
|
|
15
|
-
sig
|
14
|
+
sig { params(other: T.anything).returns(T::Boolean) }
|
16
15
|
def self.===(other); end
|
17
16
|
|
18
|
-
sig
|
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
|
22
|
+
sig do
|
24
23
|
override.params(
|
25
24
|
value: T.anything,
|
26
25
|
state: Orb::Internal::Type::Converter::CoerceState
|
@@ -29,7 +28,7 @@ module Orb
|
|
29
28
|
def coerce(value, state:); end
|
30
29
|
|
31
30
|
# @api private
|
32
|
-
sig
|
31
|
+
sig do
|
33
32
|
override.params(
|
34
33
|
value: T.anything,
|
35
34
|
state: Orb::Internal::Type::Converter::DumpState
|
@@ -215,6 +215,14 @@ module Orb
|
|
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 Orb
|
|
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[Orb::Internal::Util::ServerSentEvent])
|
274
289
|
end
|
data/rbi/lib/orb/internal.rbi
CHANGED
@@ -69,12 +69,20 @@ module Orb
|
|
69
69
|
|
70
70
|
def deconstruct_keys: (::Array[Symbol]? keys) -> ::Hash[Symbol, top]
|
71
71
|
|
72
|
+
def self.walk: (
|
73
|
+
Orb::Internal::Type::BaseModel model
|
74
|
+
) -> ::Hash[Symbol, top]
|
75
|
+
|
72
76
|
def to_json: (*top a) -> String
|
73
77
|
|
74
78
|
def to_yaml: (*top a) -> String
|
75
79
|
|
76
80
|
def initialize: (?::Hash[Symbol, top] | self data) -> void
|
77
81
|
|
82
|
+
def self.inspect: (?depth: Integer) -> String
|
83
|
+
|
84
|
+
def to_s: -> String
|
85
|
+
|
78
86
|
def inspect: -> String
|
79
87
|
end
|
80
88
|
end
|
@@ -23,6 +23,8 @@ module Orb
|
|
23
23
|
state: Orb::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 Orb
|
|
44
46
|
top value,
|
45
47
|
?state: Orb::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
|
data/sig/orb/internal/util.rbs
CHANGED
data/sig/orb/internal.rbs
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orb-billing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Orb
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-04-
|
11
|
+
date: 2025-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: connection_pool
|
@@ -31,6 +31,7 @@ extensions: []
|
|
31
31
|
extra_rdoc_files:
|
32
32
|
- README.md
|
33
33
|
files:
|
34
|
+
- ".ignore"
|
34
35
|
- CHANGELOG.md
|
35
36
|
- README.md
|
36
37
|
- SECURITY.md
|