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.3.2"
".": "0.4.0"
}
7 changes: 6 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ AllCops:
- "bin/*"
NewCops: enable
SuggestExtensions: false
TargetRubyVersion: 3.1.0
TargetRubyVersion: 3.2.0

# Whether MFA is required or not should be left to the token configuration.
Gemspec/RequireMFA:
Expand Down Expand Up @@ -112,6 +112,8 @@ Metrics/AbcSize:
Metrics/BlockLength:
AllowedPatterns:
- assert_pattern
- type_alias
- define_sorbet_constant!
Exclude:
- "**/*.rbi"

Expand Down Expand Up @@ -182,6 +184,9 @@ Style/ClassAndModuleChildren:
Exclude:
- "test/**/*"

Style/CommentAnnotation:
Enabled: false

# We should go back and add these docs, but ignore for now.
Style/Documentation:
Enabled: false
Expand Down
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## 0.4.0 (2025-05-13)

Full Changelog: [v0.3.2...v0.4.0](https://github.com/orbcorp/orb-ruby/compare/v0.3.2...v0.4.0)

### Features

* expose base client options as read only attributes ([1f638b6](https://github.com/orbcorp/orb-ruby/commit/1f638b60ad1679bc7969f441650ba61fb9a65e8a))
* expose recursive `#to_h` conversion ([cfd49a1](https://github.com/orbcorp/orb-ruby/commit/cfd49a15d805ffaa5828249c5b91565661ae7e52))
* support sorbet aliases at the runtime ([786d1e3](https://github.com/orbcorp/orb-ruby/commit/786d1e3dd882054bd298e33a448a194f1d68bac4))


### Bug Fixes

* **internal:** update gemspec name ([852ab56](https://github.com/orbcorp/orb-ruby/commit/852ab562ee4948d3fe4de8dd877f9301f36c8a4b))


### Chores

* fix misc linting / minor issues ([0e7dd84](https://github.com/orbcorp/orb-ruby/commit/0e7dd846c906cc2e72827f5477a93e4799ab9482))
* **internal:** version bump ([359839c](https://github.com/orbcorp/orb-ruby/commit/359839c734c4bcf8051490b1e8723674ef634753))

## 0.3.2 (2025-05-07)

Full Changelog: [v0.3.1...v0.3.2](https://github.com/orbcorp/orb-ruby/compare/v0.3.1...v0.3.2)
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.3.1)
orb-billing (0.3.2)
connection_pool

GEM
Expand Down
2 changes: 1 addition & 1 deletion 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.3.2"
gem "orb-billing", "~> 0.4.0"
```

<!-- x-release-please-end -->
Expand Down
4 changes: 2 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ desc("Lint `*.rb(i)`")
multitask(:"lint:rubocop") do
find = %w[find ./lib ./test ./rbi -type f -and ( -name *.rb -or -name *.rbi ) -print0]

rubocop = %w[rubocop --fail-level E]
rubocop = %w[rubocop]
rubocop += %w[--format github] if ENV.key?("CI")

# some lines cannot be shortened
Expand Down Expand Up @@ -147,7 +147,7 @@ multitask(:"build:gem") do
sig/*
GLOB

sh(*%w[gem build -- openai.gemspec])
sh(*%w[gem build -- orb.gemspec])
rm_rf(ignore_file)
end

Expand Down
2 changes: 2 additions & 0 deletions lib/orb.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

# Standard libraries.
# rubocop:disable Lint/RedundantRequireStatement
require "English"
require "cgi"
require "date"
Expand All @@ -15,6 +16,7 @@
require "stringio"
require "time"
require "uri"
# rubocop:enable Lint/RedundantRequireStatement

# We already ship the preferred sorbet manifests in the package itself.
# `tapioca` currently does not offer us a way to opt out of unnecessary compilation.
Expand Down
2 changes: 1 addition & 1 deletion lib/orb/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class APIStatusError < Orb::Errors::APIError
# @param response [nil]
# @param message [String, nil]
#
# @return [Orb::Errors::APIStatusError]
# @return [self]
def self.for(url:, status:, body:, request:, response:, message: nil)
key = Orb::Internal::Util.dig(body, :type)
kwargs = {
Expand Down
6 changes: 6 additions & 0 deletions lib/orb/internal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

module Orb
module Internal
extend Orb::Internal::Util::SorbetRuntimeSupport

OMIT =
Object.new.tap do
_1.define_singleton_method(:inspect) { "#<#{Orb::Internal}::OMIT>" }
end
.freeze

define_sorbet_constant!(:AnyHash) do
T.type_alias { T::Hash[Symbol, T.anything] }
end
end
end
79 changes: 74 additions & 5 deletions lib/orb/internal/transport/base_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ module Transport
#
# @abstract
class BaseClient
extend Orb::Internal::Util::SorbetRuntimeSupport

# from whatwg fetch spec
MAX_REDIRECTS = 20

Expand Down Expand Up @@ -151,6 +153,27 @@ def reap_connection!(status, stream:)
end
end

# @return [URI::Generic]
attr_reader :base_url

# @return [Float]
attr_reader :timeout

# @return [Integer]
attr_reader :max_retries

# @return [Float]
attr_reader :initial_retry_delay

# @return [Float]
attr_reader :max_retry_delay

# @return [Hash{String=>String}]
attr_reader :headers

# @return [String, nil]
attr_reader :idempotency_header

# @api private
# @return [Orb::Internal::Transport::PooledNetRequester]
attr_reader :requester
Expand Down Expand Up @@ -182,10 +205,11 @@ def initialize(
},
headers
)
@base_url = Orb::Internal::Util.parse_uri(base_url)
@base_url_components = Orb::Internal::Util.parse_uri(base_url)
@base_url = Orb::Internal::Util.unparse_uri(@base_url_components)
@idempotency_header = idempotency_header&.to_s&.downcase
@max_retries = max_retries
@timeout = timeout
@max_retries = max_retries
@initial_retry_delay = initial_retry_delay
@max_retry_delay = max_retry_delay
end
Expand Down Expand Up @@ -276,10 +300,11 @@ def initialize(
Orb::Internal::Util.deep_merge(*[req[:body], opts[:extra_body]].compact)
end

url = Orb::Internal::Util.join_parsed_uri(@base_url_components, {**req, path: path, query: query})
headers, encoded = Orb::Internal::Util.encode_content(headers, body)
{
method: method,
url: Orb::Internal::Util.join_parsed_uri(@base_url, {**req, path: path, query: query}),
url: url,
headers: headers,
body: encoded,
max_retries: opts.fetch(:max_retries, @max_retries),
Expand Down Expand Up @@ -473,10 +498,54 @@ def request(req)
# @return [String]
def inspect
# rubocop:disable Layout/LineLength
base_url = Orb::Internal::Util.unparse_uri(@base_url)
"#<#{self.class.name}:0x#{object_id.to_s(16)} base_url=#{base_url} max_retries=#{@max_retries} timeout=#{@timeout}>"
"#<#{self.class.name}:0x#{object_id.to_s(16)} base_url=#{@base_url} max_retries=#{@max_retries} timeout=#{@timeout}>"
# rubocop:enable Layout/LineLength
end

define_sorbet_constant!(:RequestComponents) do
T.type_alias do
{
method: Symbol,
path: T.any(String, T::Array[String]),
query: T.nilable(T::Hash[String, T.nilable(T.any(T::Array[String], String))]),
headers: T.nilable(
T::Hash[String,
T.nilable(
T.any(
String,
Integer,
T::Array[T.nilable(T.any(String, Integer))]
)
)]
),
body: T.nilable(T.anything),
unwrap: T.nilable(
T.any(
Symbol,
Integer,
T::Array[T.any(Symbol, Integer)],
T.proc.params(arg0: T.anything).returns(T.anything)
)
),
page: T.nilable(T::Class[Orb::Internal::Type::BasePage[Orb::Internal::Type::BaseModel]]),
stream: T.nilable(T::Class[T.anything]),
model: T.nilable(Orb::Internal::Type::Converter::Input),
options: T.nilable(Orb::RequestOptions::OrHash)
}
end
end
define_sorbet_constant!(:RequestInput) do
T.type_alias do
{
method: Symbol,
url: URI::Generic,
headers: T::Hash[String, String],
body: T.anything,
max_retries: Integer,
timeout: Float
}
end
end
end
end
end
Expand Down
14 changes: 14 additions & 0 deletions lib/orb/internal/transport/pooled_net_requester.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ module Internal
module Transport
# @api private
class PooledNetRequester
extend Orb::Internal::Util::SorbetRuntimeSupport

# from the golang stdlib
# https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49
KEEP_ALIVE_TIMEOUT = 30
Expand Down Expand Up @@ -187,6 +189,18 @@ def initialize(size: Etc.nprocessors)
@size = size
@pools = {}
end

define_sorbet_constant!(:Request) do
T.type_alias do
{
method: Symbol,
url: URI::Generic,
headers: T::Hash[String, String],
body: T.anything,
deadline: Float
}
end
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/orb/internal/type/array_of.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ArrayOf
#
# @option spec [Boolean] :"nil?"
#
# @return [Orb::Internal::Type::ArrayOf]
# @return [self]
def self.[](...) = new(...)

# @api public
Expand Down
Loading