Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a865cea
feat(api): api update
stainless-app[bot] Mar 4, 2026
8a52368
fix(client): add types for path params, and update structure of union…
stainless-app[bot] Mar 5, 2026
b7ef3b3
chore(test): do not count install time for mock server timeout
stainless-app[bot] Mar 5, 2026
eb40fda
feat(api): api update
stainless-app[bot] Mar 5, 2026
751628a
feat(api): api update
stainless-app[bot] Mar 7, 2026
21805c5
chore(ci): skip uploading artifacts on stainless-internal branches
stainless-app[bot] Mar 7, 2026
f434716
feat(client): add webhook support
stainless-app[bot] Mar 11, 2026
337be04
feat(api): api update
stainless-app[bot] Mar 13, 2026
2e5e97f
chore(tests): update mock server to steady
stainless-app[bot] Mar 13, 2026
6692611
chore(internal): tweak CI branches
stainless-app[bot] Mar 16, 2026
27b02b6
feat(api): api update
stainless-app[bot] Mar 19, 2026
e63158f
chore(tests): bump steady to v0.19.4
stainless-app[bot] Mar 20, 2026
d82e274
chore(tests): bump steady to v0.19.5
stainless-app[bot] Mar 20, 2026
7ad9ec0
chore(internal): update gitignore
stainless-app[bot] Mar 23, 2026
aad19ff
chore(tests): bump steady to v0.19.6
stainless-app[bot] Mar 23, 2026
a2caac3
chore(ci): skip lint on metadata-only changes
stainless-app[bot] Mar 24, 2026
3c90c75
chore(tests): bump steady to v0.19.7
stainless-app[bot] Mar 24, 2026
029ba18
feat(api): api update
stainless-app[bot] Mar 24, 2026
f696c0a
codegen metadata
stainless-app[bot] Mar 25, 2026
efb1b4a
fix(internal): correct multipart form field name encoding
stainless-app[bot] Mar 26, 2026
37edebe
chore(ci): support opting out of skipping builds on metadata-only com…
stainless-app[bot] Mar 27, 2026
7da3249
chore(tests): bump steady to v0.20.1
stainless-app[bot] Mar 31, 2026
15de2fa
codegen metadata
stainless-app[bot] Mar 31, 2026
34a56cf
chore(tests): bump steady to v0.20.2
stainless-app[bot] Mar 31, 2026
6ed82a7
fix: variable name typo
stainless-app[bot] Mar 31, 2026
21d02ec
fix: align path encoding with RFC 3986 section 3.3
stainless-app[bot] Mar 31, 2026
d185f3d
feat(api): api update
stainless-app[bot] Apr 3, 2026
aff6ad8
fix: multipart encoding for file arrays
stainless-app[bot] Apr 8, 2026
1d58c25
release: 1.14.0
stainless-app[bot] Apr 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
24 changes: 15 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
name: CI
on:
push:
branches-ignore:
- 'generated'
- 'codegen/**'
- 'integrated/**'
- 'stl-preview-head/**'
- 'stl-preview-base/**'
branches:
- '**'
- '!integrated/**'
- '!stl-preview-head/**'
- '!stl-preview-base/**'
- '!generated'
- '!codegen/**'
- 'codegen/stl/**'
pull_request:
branches-ignore:
- 'stl-preview-head/**'
Expand All @@ -22,7 +24,7 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/orb-ruby' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: |-
github.repository == 'stainless-sdks/orb-ruby' &&
(github.event_name == 'push' || github.event.pull_request.head.repo.fork)
(github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
Expand All @@ -33,14 +35,18 @@ jobs:
bundle install

- name: Get GitHub OIDC Token
if: github.repository == 'stainless-sdks/orb-ruby'
if: |-
github.repository == 'stainless-sdks/orb-ruby' &&
!startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
uses: actions/github-script@v8
with:
script: core.setOutput('github_token', await core.getIDToken());

- name: Build and upload gem artifacts
if: github.repository == 'stainless-sdks/orb-ruby'
if: |-
github.repository == 'stainless-sdks/orb-ruby' &&
!startsWith(github.ref, 'refs/heads/stl/')
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.idea/
.ignore
.prism.log
.stdy.log
.ruby-lsp/
.yardoc/
bin/tapioca
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.13.0"
".": "1.14.0"
}
6 changes: 3 additions & 3 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 139
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-5bb582f84f0b4cf7bef84833fefd48a5f2734dc25805da2028fd8a6f1198da07.yml
openapi_spec_hash: ced0e30dc67faa2414df511819408f12
config_hash: 3279841440b02d4e8303c961d6983492
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-1ca41c4b1d872cf2a198c8cf5edeeeddac012259a7cf211b102bf137c05b8240.yml
openapi_spec_hash: 955066d4865fc42440cd81e40f5f79cd
config_hash: c01c1191b1cd696c7ca855ff6d28a8df
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@
# Changelog

## 1.14.0 (2026-04-08)

Full Changelog: [v1.13.0...v1.14.0](https://github.com/orbcorp/orb-ruby/compare/v1.13.0...v1.14.0)

### Features

* **api:** api update ([d185f3d](https://github.com/orbcorp/orb-ruby/commit/d185f3dde0afc117b2a5df5608fc7aeedbec6f49))
* **api:** api update ([029ba18](https://github.com/orbcorp/orb-ruby/commit/029ba18854d6ef34ee3a8b30d8b54d4b28be2a77))
* **api:** api update ([27b02b6](https://github.com/orbcorp/orb-ruby/commit/27b02b67cdeb02fd1083a30f8b450be96ac4d0fb))
* **api:** api update ([337be04](https://github.com/orbcorp/orb-ruby/commit/337be04c7a4f8abe058b0ca27becf8124badc168))
* **api:** api update ([751628a](https://github.com/orbcorp/orb-ruby/commit/751628a1843a653fdd0a8e718ed431d8ce518c24))
* **api:** api update ([eb40fda](https://github.com/orbcorp/orb-ruby/commit/eb40fdad4ce17f70dc2f315c000f0bd8c0118055))
* **api:** api update ([a865cea](https://github.com/orbcorp/orb-ruby/commit/a865cea3435365ca97c336a991cdf2c632604b24))
* **client:** add webhook support ([f434716](https://github.com/orbcorp/orb-ruby/commit/f434716cc961eae629f626c95be963e89b712c90))


### Bug Fixes

* align path encoding with RFC 3986 section 3.3 ([21d02ec](https://github.com/orbcorp/orb-ruby/commit/21d02eccd03e5cd37b5a20b0718fa6dbd1803302))
* **client:** add types for path params, and update structure of unions nested in params ([8a52368](https://github.com/orbcorp/orb-ruby/commit/8a523686305ffbee12c8f2643a37d3cab4edb5d5))
* **internal:** correct multipart form field name encoding ([efb1b4a](https://github.com/orbcorp/orb-ruby/commit/efb1b4ab5d45ab2c965a41bab4b99fa5370679d0))
* multipart encoding for file arrays ([aff6ad8](https://github.com/orbcorp/orb-ruby/commit/aff6ad82926b24962cc913c73a5663ee8776a271))
* variable name typo ([6ed82a7](https://github.com/orbcorp/orb-ruby/commit/6ed82a7f6b83f9da113a37be4cb6c84665b1deeb))


### Chores

* **ci:** skip lint on metadata-only changes ([a2caac3](https://github.com/orbcorp/orb-ruby/commit/a2caac38daaabff98fb29618628dee0558afd973))
* **ci:** skip uploading artifacts on stainless-internal branches ([21805c5](https://github.com/orbcorp/orb-ruby/commit/21805c52bfa86ecf544fdc3c5828003638d5938d))
* **ci:** support opting out of skipping builds on metadata-only commits ([37edebe](https://github.com/orbcorp/orb-ruby/commit/37edebe2c123b23eb923ae53f18e732d3369a9d5))
* **internal:** tweak CI branches ([6692611](https://github.com/orbcorp/orb-ruby/commit/6692611801c9e7402ec21d5e7eb07f46d0b61951))
* **internal:** update gitignore ([7ad9ec0](https://github.com/orbcorp/orb-ruby/commit/7ad9ec089de88e0adfd67f94e1f5d073f75e90be))
* **test:** do not count install time for mock server timeout ([b7ef3b3](https://github.com/orbcorp/orb-ruby/commit/b7ef3b3c4e1054a2a5db603476b57c9d3a64b860))
* **tests:** bump steady to v0.19.4 ([e63158f](https://github.com/orbcorp/orb-ruby/commit/e63158f62d06ab361c7c2dfc544298decb85f1ca))
* **tests:** bump steady to v0.19.5 ([d82e274](https://github.com/orbcorp/orb-ruby/commit/d82e2748e8ee154e43745d7b1bfe5bf2a3827284))
* **tests:** bump steady to v0.19.6 ([aad19ff](https://github.com/orbcorp/orb-ruby/commit/aad19ff345ca22d148ca36ccb7f7850c8f1d14f0))
* **tests:** bump steady to v0.19.7 ([3c90c75](https://github.com/orbcorp/orb-ruby/commit/3c90c7514ee8f9f38e405e8ca38599d73bb354a3))
* **tests:** bump steady to v0.20.1 ([7da3249](https://github.com/orbcorp/orb-ruby/commit/7da32497ce4e9cde8f282082e05abb1d23a86b51))
* **tests:** bump steady to v0.20.2 ([34a56cf](https://github.com/orbcorp/orb-ruby/commit/34a56cfdd242cb2c2fba7ccc3e93f7c11c166010))
* **tests:** update mock server to steady ([2e5e97f](https://github.com/orbcorp/orb-ruby/commit/2e5e97f7a3cf18ad23ecef601edde222bfc62bbd))

## 1.13.0 (2026-03-03)

Full Changelog: [v1.12.0...v1.13.0](https://github.com/orbcorp/orb-ruby/compare/v1.12.0...v1.13.0)
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ $ bundle exec rake

## Running tests

Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.
Most tests require you to [set up a mock server](https://github.com/dgellow/steady) against the OpenAPI spec to run the tests.

```sh
$ ./scripts/mock
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 (1.13.0)
orb-billing (1.14.0)
cgi
connection_pool

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", "~> 1.13.0"
gem "orb-billing", "~> 1.14.0"
```

<!-- x-release-please-end -->
Expand Down
7 changes: 7 additions & 0 deletions lib/orb/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class Client < Orb::Internal::Transport::BaseClient
# @return [String]
attr_reader :api_key

# @return [String, nil]
attr_reader :webhook_secret

# @return [Orb::Resources::TopLevel]
attr_reader :top_level

Expand Down Expand Up @@ -160,6 +163,8 @@ class Client < Orb::Internal::Transport::BaseClient
#
# @param api_key [String, nil] Defaults to `ENV["ORB_API_KEY"]`
#
# @param webhook_secret [String, nil] Defaults to `ENV["ORB_WEBHOOK_SECRET"]`
#
# @param base_url [String, nil] Override the default base URL for the API, e.g.,
# `"https://api.example.com/v2/"`. Defaults to `ENV["ORB_BASE_URL"]`
#
Expand All @@ -174,6 +179,7 @@ class Client < Orb::Internal::Transport::BaseClient
# @param idempotency_header [String]
def initialize(
api_key: ENV["ORB_API_KEY"],
webhook_secret: ENV["ORB_WEBHOOK_SECRET"],
base_url: ENV["ORB_BASE_URL"],
max_retries: self.class::DEFAULT_MAX_RETRIES,
timeout: self.class::DEFAULT_TIMEOUT_IN_SECONDS,
Expand All @@ -188,6 +194,7 @@ def initialize(
end

@api_key = api_key.to_s
@webhook_secret = webhook_secret&.to_s

super(
base_url: base_url,
Expand Down
29 changes: 22 additions & 7 deletions lib/orb/internal/util.rb
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def coerce_hash!(input)
in Hash | nil => coerced
coerced
else
message = "Expected a #{Hash} or #{Orb::Internal::Type::BaseModel}, got #{data.inspect}"
message = "Expected a #{Hash} or #{Orb::Internal::Type::BaseModel}, got #{input.inspect}"
raise ArgumentError.new(message)
end
end
Expand Down Expand Up @@ -237,6 +237,11 @@ def dig(data, pick, &blk)
end
end

# @type [Regexp]
#
# https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3
RFC_3986_NOT_PCHARS = /[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/

class << self
# @api private
#
Expand All @@ -247,6 +252,15 @@ def uri_origin(uri)
"#{uri.scheme}://#{uri.host}#{":#{uri.port}" unless uri.port == uri.default_port}"
end

# @api private
#
# @param path [String, Integer]
#
# @return [String]
def encode_path(path)
path.to_s.gsub(Orb::Internal::Util::RFC_3986_NOT_PCHARS) { ERB::Util.url_encode(_1) }
end

# @api private
#
# @param path [String, Array<String>]
Expand All @@ -259,7 +273,7 @@ def interpolate_path(path)
in []
""
in [String => p, *interpolations]
encoded = interpolations.map { ERB::Util.url_encode(_1) }
encoded = interpolations.map { encode_path(_1) }
format(p, *encoded)
end
end
Expand Down Expand Up @@ -571,16 +585,15 @@ def encode_query_params(query)
y << "Content-Disposition: form-data"

unless key.nil?
name = ERB::Util.url_encode(key.to_s)
y << "; name=\"#{name}\""
y << "; name=\"#{key}\""
end

case val
in Orb::FilePart unless val.filename.nil?
filename = ERB::Util.url_encode(val.filename)
filename = encode_path(val.filename)
y << "; filename=\"#{filename}\""
in Pathname | IO
filename = ERB::Util.url_encode(::File.basename(val.to_path))
filename = encode_path(::File.basename(val.to_path))
y << "; filename=\"#{filename}\""
else
end
Expand All @@ -597,6 +610,7 @@ def encode_query_params(query)
#
# @return [Array(String, Enumerable<String>)]
private def encode_multipart_streaming(body)
# rubocop:disable Style/CaseEquality
# RFC 1521 Section 7.2.1 says we should have 70 char maximum for boundary length
boundary = SecureRandom.urlsafe_base64(46)

Expand All @@ -606,7 +620,7 @@ def encode_query_params(query)
in Hash
body.each do |key, val|
case val
in Array if val.all? { primitive?(_1) }
in Array if val.all? { primitive?(_1) || Orb::Internal::Type::FileInput === _1 }
val.each do |v|
write_multipart_chunk(y, boundary: boundary, key: key, val: v, closing: closing)
end
Expand All @@ -622,6 +636,7 @@ def encode_query_params(query)

fused_io = fused_enum(strio) { closing.each(&:call) }
[boundary, fused_io]
# rubocop:enable Style/CaseEquality
end

# @api private
Expand Down
11 changes: 10 additions & 1 deletion lib/orb/models/alert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,20 @@ class Alert < Orb::Internal::Type::BaseModel
-> { Orb::Internal::Type::ArrayOf[Orb::Alert::BalanceAlertStatus] },
nil?: true

# @!attribute grouping_keys
# The property keys to group cost alerts by. Only present for cost alerts with
# grouping enabled.
#
# @return [Array<String>, nil]
optional :grouping_keys, Orb::Internal::Type::ArrayOf[String], nil?: true

# @!attribute license_type
# Minified license type for alert serialization.
#
# @return [Orb::Models::Alert::LicenseType, nil]
optional :license_type, -> { Orb::Alert::LicenseType }, nil?: true

# @!method initialize(id:, created_at:, currency:, customer:, enabled:, metric:, plan:, subscription:, thresholds:, type:, balance_alert_status: nil, license_type: nil)
# @!method initialize(id:, created_at:, currency:, customer:, enabled:, metric:, plan:, subscription:, thresholds:, type:, balance_alert_status: nil, grouping_keys: nil, license_type: nil)
# Some parameter documentations has been truncated, see {Orb::Models::Alert} for
# more details.
#
Expand Down Expand Up @@ -112,6 +119,8 @@ class Alert < Orb::Internal::Type::BaseModel
#
# @param balance_alert_status [Array<Orb::Models::Alert::BalanceAlertStatus>, nil] The current status of the alert. This field is only present for credit balance a
#
# @param grouping_keys [Array<String>, nil] The property keys to group cost alerts by. Only present for cost alerts with gro
#
# @param license_type [Orb::Models::Alert::LicenseType, nil] Minified license type for alert serialization.

# @see Orb::Models::Alert#metric
Expand Down
9 changes: 8 additions & 1 deletion lib/orb/models/alert_create_for_customer_params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ class AlertCreateForCustomerParams < Orb::Internal::Type::BaseModel
extend Orb::Internal::Type::RequestParameters::Converter
include Orb::Internal::Type::RequestParameters

# @!attribute customer_id
#
# @return [String]
required :customer_id, String

# @!attribute currency
# The case sensitive currency or custom pricing unit to use for this alert.
#
Expand All @@ -25,7 +30,9 @@ class AlertCreateForCustomerParams < Orb::Internal::Type::BaseModel
# @return [Array<Orb::Models::Threshold>, nil]
optional :thresholds, -> { Orb::Internal::Type::ArrayOf[Orb::Threshold] }, nil?: true

# @!method initialize(currency:, type:, thresholds: nil, request_options: {})
# @!method initialize(customer_id:, currency:, type:, thresholds: nil, request_options: {})
# @param customer_id [String]
#
# @param currency [String] The case sensitive currency or custom pricing unit to use for this alert.
#
# @param type [Symbol, Orb::Models::AlertCreateForCustomerParams::Type] The type of alert to create. This must be a valid alert type.
Expand Down
9 changes: 8 additions & 1 deletion lib/orb/models/alert_create_for_external_customer_params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ class AlertCreateForExternalCustomerParams < Orb::Internal::Type::BaseModel
extend Orb::Internal::Type::RequestParameters::Converter
include Orb::Internal::Type::RequestParameters

# @!attribute external_customer_id
#
# @return [String]
required :external_customer_id, String

# @!attribute currency
# The case sensitive currency or custom pricing unit to use for this alert.
#
Expand All @@ -25,7 +30,9 @@ class AlertCreateForExternalCustomerParams < Orb::Internal::Type::BaseModel
# @return [Array<Orb::Models::Threshold>, nil]
optional :thresholds, -> { Orb::Internal::Type::ArrayOf[Orb::Threshold] }, nil?: true

# @!method initialize(currency:, type:, thresholds: nil, request_options: {})
# @!method initialize(external_customer_id:, currency:, type:, thresholds: nil, request_options: {})
# @param external_customer_id [String]
#
# @param currency [String] The case sensitive currency or custom pricing unit to use for this alert.
#
# @param type [Symbol, Orb::Models::AlertCreateForExternalCustomerParams::Type] The type of alert to create. This must be a valid alert type.
Expand Down
Loading
Loading