Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.1.0-alpha.39"
".": "0.1.0"
}
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## 0.1.0 (2025-04-08)

Full Changelog: [v0.1.0-alpha.39...v0.1.0](https://github.com/orbcorp/orb-ruby/compare/v0.1.0-alpha.39...v0.1.0)

### Bug Fixes

* raise connection error for errors that result from HTTP transports ([#244](https://github.com/orbcorp/orb-ruby/issues/244)) ([1213d2d](https://github.com/orbcorp/orb-ruby/commit/1213d2de5c7b0a80f1c96b8fed31a048ad57e2eb))


### Chores

* add README docs for using solargraph when installing gem from git ([#242](https://github.com/orbcorp/orb-ruby/issues/242)) ([48b892e](https://github.com/orbcorp/orb-ruby/commit/48b892e3b45412875d25c5683f0b7e1fd23d20ee))
* easier to read examples in README.md ([#240](https://github.com/orbcorp/orb-ruby/issues/240)) ([eb00ee4](https://github.com/orbcorp/orb-ruby/commit/eb00ee4e8564a44dad9320bf89f3a656764a38d9))
* **internal:** codegen related update ([#238](https://github.com/orbcorp/orb-ruby/issues/238)) ([fd54e32](https://github.com/orbcorp/orb-ruby/commit/fd54e32135d6ffbfbd3956b5505773169f5fca9f))
* **internal:** codegen related update ([#243](https://github.com/orbcorp/orb-ruby/issues/243)) ([edfc0bf](https://github.com/orbcorp/orb-ruby/commit/edfc0bfb29f6989cb5d249f9dcfd118c115a35a9))
* make client tests look prettier ([#241](https://github.com/orbcorp/orb-ruby/issues/241)) ([060c286](https://github.com/orbcorp/orb-ruby/commit/060c2864f0458bfc26030e97effa3340a0060dd0))

## 0.1.0-alpha.39 (2025-04-07)

Full Changelog: [v0.1.0-alpha.38...v0.1.0-alpha.39](https://github.com/orbcorp/orb-ruby/compare/v0.1.0-alpha.38...v0.1.0-alpha.39)
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ GIT
PATH
remote: .
specs:
orb-billing (0.1.0.pre.alpha.38)
orb-billing (0.1.0.pre.alpha.39)
connection_pool

GEM
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ To use this gem, install via Bundler by adding the following to your application
<!-- x-release-please-start-version -->

```ruby
gem "orb-billing", "~> 0.1.0.pre.alpha.38"
gem "orb-billing", "~> 0.1.0.pre.alpha.39"
```

<!-- x-release-please-end -->
Expand Down Expand Up @@ -148,6 +148,13 @@ After Solargraph is installed, **you must populate its index** either via the pr
bundle exec solargraph gems
```

Note: if you had installed the gem either using a `git:` or `github:` URL, or had vendored the gem using bundler, you will need to set up your [`.solargraph.yml`](https://solargraph.org/guides/configuration) to include the path to the gem's `lib` directory.

```yaml
include:
- 'vendor/bundle/ruby/*/gems/orb-billing-*/lib/**/*.rb'
```

Otherwise Solargraph will not be able to provide type information or auto-completion for any non-indexed libraries.

### Sorbet
Expand All @@ -161,7 +168,8 @@ Due to limitations with the Sorbet type system, where a method otherwise can tak
Please follow Sorbet's [setup guides](https://sorbet.org/docs/adopting) for best experience.

```ruby
params = Orb::Models::CustomerCreateParams.new(email: "example-customer@withorb.com", name: "My Customer")
params =
Orb::Models::CustomerCreateParams.new(email: "example-customer@withorb.com", name: "My Customer")

orb.customers.create(**params)
```
Expand Down
1 change: 1 addition & 0 deletions lib/orb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
require_relative "orb/internal/type/converter"
require_relative "orb/internal/type/unknown"
require_relative "orb/internal/type/boolean"
require_relative "orb/internal/type/io_like"
require_relative "orb/internal/type/enum"
require_relative "orb/internal/type/union"
require_relative "orb/internal/type/array_of"
Expand Down
2 changes: 1 addition & 1 deletion lib/orb/internal/transport/base_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def initialize(
in (400..) | Orb::Errors::APIConnectionError
self.class.reap_connection!(status, stream: stream)

delay = retry_delay(response, retry_count: retry_count)
delay = retry_delay(response || {}, retry_count: retry_count)
sleep(delay)

send_request(
Expand Down
19 changes: 14 additions & 5 deletions lib/orb/internal/transport/pooled_net_requester.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def calibrate_socket_timeout(conn, deadline)
# @param blk [Proc]
#
# @yieldparam [String]
# @return [Net::HTTPGenericRequest]
# @return [Array(Net::HTTPGenericRequest, Proc)]
def build_request(request, &blk)
method, url, headers, body = request.fetch_values(:method, :url, :headers, :body)
req = Net::HTTPGenericRequest.new(
Expand All @@ -75,12 +75,12 @@ def build_request(request, &blk)
in StringIO
req["content-length"] ||= body.size.to_s unless req["transfer-encoding"]
req.body_stream = Orb::Internal::Util::ReadIOAdapter.new(body, &blk)
in IO | Enumerator
in Pathname | IO | Enumerator
req["transfer-encoding"] ||= "chunked" unless req["content-length"]
req.body_stream = Orb::Internal::Util::ReadIOAdapter.new(body, &blk)
end

req
[req, req.body_stream&.method(:close)]
end
end

Expand Down Expand Up @@ -123,13 +123,17 @@ def build_request(request, &blk)
def execute(request)
url, deadline = request.fetch_values(:url, :deadline)

req = nil
eof = false
finished = false
closing = nil

# rubocop:disable Metrics/BlockLength
enum = Enumerator.new do |y|
with_pool(url, deadline: deadline) do |conn|
next if finished

req = self.class.build_request(request) do
req, closing = self.class.build_request(request) do
self.class.calibrate_socket_timeout(conn, deadline)
end

Expand All @@ -154,8 +158,11 @@ def execute(request)
end
end
rescue Timeout::Error
raise Orb::Errors::APITimeoutError
raise Orb::Errors::APITimeoutError.new(url: url, request: req)
rescue StandardError
raise Orb::Errors::APIConnectionError.new(url: url, request: req)
end
# rubocop:enable Metrics/BlockLength

conn, _, response = enum.next
body = Orb::Internal::Util.fused_enum(enum, external: true) do
Expand All @@ -165,7 +172,9 @@ def execute(request)
rescue StopIteration
nil
end
ensure
conn.finish if !eof && conn&.started?
closing&.call
end
[Integer(response.code), response, (response.body = body)]
end
Expand Down
14 changes: 12 additions & 2 deletions lib/orb/internal/type/array_of.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,20 @@ def coerce(value, state:)
#
# @param value [Array<Object>, Object]
#
# @param state [Hash{Symbol=>Object}] .
#
# @option state [Boolean] :can_retry
#
# @return [Array<Object>, Object]
def dump(value)
def dump(value, state:)
target = item_type
value.is_a?(Array) ? value.map { Orb::Internal::Type::Converter.dump(target, _1) } : super
if value.is_a?(Array)
value.map do
Orb::Internal::Type::Converter.dump(target, _1, state: state)
end
else
super
end
end

# @api private
Expand Down
14 changes: 9 additions & 5 deletions lib/orb/internal/type/base_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,12 @@ def coerce(value, state:)
#
# @param value [Orb::Internal::Type::BaseModel, Object]
#
# @param state [Hash{Symbol=>Object}] .
#
# @option state [Boolean] :can_retry
#
# @return [Hash{Object=>Object}, Object]
def dump(value)
def dump(value, state:)
unless (coerced = Orb::Internal::Util.coerce_hash(value)).is_a?(Hash)
return super
end
Expand All @@ -264,15 +268,15 @@ def dump(value)
name = key.is_a?(String) ? key.to_sym : key
case (field = known_fields[name])
in nil
acc.store(name, super(val))
acc.store(name, super(val, state: state))
else
api_name, mode, type_fn = field.fetch_values(:api_name, :mode, :type_fn)
case mode
in :coerce
next
else
target = type_fn.call
acc.store(api_name, Orb::Internal::Type::Converter.dump(target, val))
acc.store(api_name, Orb::Internal::Type::Converter.dump(target, val, state: state))
end
end
end
Expand Down Expand Up @@ -337,12 +341,12 @@ def deconstruct_keys(keys)
# @param a [Object]
#
# @return [String]
def to_json(*a) = self.class.dump(self).to_json(*a)
def to_json(*a) = Orb::Internal::Type::Converter.dump(self.class, self).to_json(*a)

# @param a [Object]
#
# @return [String]
def to_yaml(*a) = self.class.dump(self).to_yaml(*a)
def to_yaml(*a) = Orb::Internal::Type::Converter.dump(self.class, self).to_yaml(*a)

# Create a new instance of a model.
#
Expand Down
6 changes: 5 additions & 1 deletion lib/orb/internal/type/boolean.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,12 @@ def coerce(value, state:)
# #
# # @param value [Boolean, Object]
# #
# # @param state [Hash{Symbol=>Object}] .
# #
# # @option state [Boolean] :can_retry
# #
# # @return [Boolean, Object]
# def dump(value) = super
# def dump(value, state:) = super
end
end
end
Expand Down
35 changes: 26 additions & 9 deletions lib/orb/internal/type/converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,24 @@ def coerce(value, state:) = (raise NotImplementedError)
#
# @param value [Object]
#
# @param state [Hash{Symbol=>Object}] .
#
# @option state [Boolean] :can_retry
#
# @return [Object]
def dump(value)
def dump(value, state:)
case value
in Array
value.map { Orb::Internal::Type::Unknown.dump(_1) }
value.map { Orb::Internal::Type::Unknown.dump(_1, state: state) }
in Hash
value.transform_values { Orb::Internal::Type::Unknown.dump(_1) }
value.transform_values { Orb::Internal::Type::Unknown.dump(_1, state: state) }
in Orb::Internal::Type::BaseModel
value.class.dump(value)
value.class.dump(value, state: state)
in StringIO
value.string
in Pathname | IO
state[:can_retry] = false if value.is_a?(IO)
Orb::Internal::Util::SerializationAdapter.new(value)
else
value
end
Expand Down Expand Up @@ -182,7 +191,7 @@ def coerce(
rescue ArgumentError, TypeError => e
raise e if strictness == :strong
end
in -> { _1 <= IO } if value.is_a?(String)
in -> { _1 <= StringIO } if value.is_a?(String)
exactness[:yes] += 1
return StringIO.new(value.b)
else
Expand All @@ -207,13 +216,21 @@ def coerce(
# @api private
#
# @param target [Orb::Internal::Type::Converter, Class]
#
# @param value [Object]
#
# @param state [Hash{Symbol=>Object}] .
#
# @option state [Boolean] :can_retry
#
# @return [Object]
def dump(target, value)
# rubocop:disable Layout/LineLength
target.is_a?(Orb::Internal::Type::Converter) ? target.dump(value) : Orb::Internal::Type::Unknown.dump(value)
# rubocop:enable Layout/LineLength
def dump(target, value, state: {can_retry: true})
case target
in Orb::Internal::Type::Converter
target.dump(value, state: state)
else
Orb::Internal::Type::Unknown.dump(value, state: state)
end
end
end
end
Expand Down
6 changes: 5 additions & 1 deletion lib/orb/internal/type/enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,12 @@ def coerce(value, state:)
# #
# # @param value [Symbol, Object]
# #
# # @param state [Hash{Symbol=>Object}] .
# #
# # @option state [Boolean] :can_retry
# #
# # @return [Symbol, Object]
# def dump(value) = super
# def dump(value, state:) = super
end
end
end
Expand Down
8 changes: 6 additions & 2 deletions lib/orb/internal/type/hash_of.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,16 @@ def coerce(value, state:)
#
# @param value [Hash{Object=>Object}, Object]
#
# @param state [Hash{Symbol=>Object}] .
#
# @option state [Boolean] :can_retry
#
# @return [Hash{Symbol=>Object}, Object]
def dump(value)
def dump(value, state:)
target = item_type
if value.is_a?(Hash)
value.transform_values do
Orb::Internal::Type::Converter.dump(target, _1)
Orb::Internal::Type::Converter.dump(target, _1, state: state)
end
else
super
Expand Down
Loading