Skip to content

Commit 7203b6f

Browse files
authored
Merge pull request #274 from orbcorp/release-please--branches--main--changes--next
release: 1.1.0
2 parents d6a331f + d3cf934 commit 7203b6f

File tree

133 files changed

+2033
-611
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

133 files changed

+2033
-611
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ on:
77
- 'integrated/**'
88
- 'stl-preview-head/**'
99
- 'stl-preview-base/**'
10+
pull_request:
11+
branches-ignore:
12+
- 'stl-preview-head/**'
13+
- 'stl-preview-base/**'
1014

1115
jobs:
1216
lint:

.github/workflows/publish-gem.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This workflow is triggered when a GitHub release is created.
22
# It can also be run manually to re-publish to rubygems.org in case it failed for some reason.
3-
# You can run this workflow by navigating to https://www.github.com/orbcorp/orb-python/actions/workflows/publish-gem.yml
3+
# You can run this workflow by navigating to https://www.github.com/orbcorp/orb-ruby/actions/workflows/publish-gem.yml
44
name: Publish Gem
55
on:
66
workflow_dispatch:

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "1.0.1"
2+
".": "1.1.0"
33
}

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 116
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-c2a4808c828c8288c5c8dfe2fdfa51d4d7c1bcc33cacc6b859d0cf4b35ce95cc.yml
3-
openapi_spec_hash: a2b5a1bfabbd03dd1b411791576eb502
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-9d6e0a988df83c0e2baa559ef57ec96981669a7a294de2188adb2cd6bbc0be8a.yml
3+
openapi_spec_hash: 7f5e7221872d7ee799141f546c394f48
44
config_hash: 3c3524be9607afb24d2139ce26ce5389

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
# Changelog
22

3+
## 1.1.0 (2025-06-18)
4+
5+
Full Changelog: [v1.0.1...v1.1.0](https://github.com/orbcorp/orb-ruby/compare/v1.0.1...v1.1.0)
6+
7+
### Features
8+
9+
* **api:** api update ([c557aa7](https://github.com/orbcorp/orb-ruby/commit/c557aa72779ba1d99e5983b8b3bedb9d4ea6f53a))
10+
* **api:** api update ([9d2ed65](https://github.com/orbcorp/orb-ruby/commit/9d2ed65a2ee93d7138f9ee4e7e0cf375f2b78b67))
11+
* **api:** api update ([1d97f15](https://github.com/orbcorp/orb-ruby/commit/1d97f159f6fc72e33037b8ac8775ae48fa5a75d9))
12+
13+
14+
### Bug Fixes
15+
16+
* issue where we cannot mutate arrays on base model derivatives ([b53b6cc](https://github.com/orbcorp/orb-ruby/commit/b53b6cce364fc3bc4fead546b889e58e12f8862a))
17+
18+
19+
### Chores
20+
21+
* **ci:** enable for pull requests ([0d16f9f](https://github.com/orbcorp/orb-ruby/commit/0d16f9f5a238d651c9e5f68a5368a1835d22604f))
22+
* **ci:** link to correct github repo ([0d079fe](https://github.com/orbcorp/orb-ruby/commit/0d079fe8e8a6b862ea6a33ba091478011658252d))
23+
* **internal:** version bump ([4956d97](https://github.com/orbcorp/orb-ruby/commit/4956d97d24d4a2e388e4c417e18e09eef1361dad))
24+
325
## 1.0.1 (2025-06-09)
426

527
Full Changelog: [v1.0.0...v1.0.1](https://github.com/orbcorp/orb-ruby/compare/v1.0.0...v1.0.1)

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ GIT
1111
PATH
1212
remote: .
1313
specs:
14-
orb-billing (1.0.0)
14+
orb-billing (1.0.1)
1515
connection_pool
1616

1717
GEM

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ To use this gem, install via Bundler by adding the following to your application
1515
<!-- x-release-please-start-version -->
1616

1717
```ruby
18-
gem "orb-billing", "~> 1.0.1"
18+
gem "orb-billing", "~> 1.1.0"
1919
```
2020

2121
<!-- x-release-please-end -->

lib/orb/errors.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,28 @@ class Error < StandardError
99
end
1010

1111
class ConversionError < Orb::Errors::Error
12+
# @return [StandardError, nil]
13+
def cause = @cause.nil? ? super : @cause
14+
15+
# @api private
16+
#
17+
# @param on [Class<StandardError>]
18+
# @param method [Symbol]
19+
# @param target [Object]
20+
# @param value [Object]
21+
# @param cause [StandardError, nil]
22+
def initialize(on:, method:, target:, value:, cause: nil)
23+
cls = on.name.split("::").last
24+
25+
message = [
26+
"Failed to parse #{cls}.#{method} from #{value.class} to #{target.inspect}.",
27+
"To get the unparsed API response, use #{cls}[#{method.inspect}].",
28+
cause && "Cause: #{cause.message}"
29+
].filter(&:itself).join(" ")
30+
31+
@cause = cause
32+
super(message)
33+
end
1234
end
1335

1436
class APIError < Orb::Errors::Error

lib/orb/internal/type/array_of.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,14 @@ def hash = [self.class, item_type].hash
6262
#
6363
# @param state [Hash{Symbol=>Object}] .
6464
#
65-
# @option state [Boolean, :strong] :strictness
65+
# @option state [Boolean] :translate_names
66+
#
67+
# @option state [Boolean] :strictness
6668
#
6769
# @option state [Hash{Symbol=>Object}] :exactness
6870
#
71+
# @option state [Class<StandardError>] :error
72+
#
6973
# @option state [Integer] :branched
7074
#
7175
# @return [Array<Object>, Object]
@@ -74,6 +78,7 @@ def coerce(value, state:)
7478

7579
unless value.is_a?(Array)
7680
exactness[:no] += 1
81+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{Array}")
7782
return value
7883
end
7984

lib/orb/internal/type/base_model.rb

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def fields
6060
[Orb::Internal::Type::Converter.type_info(type_info), type_info]
6161
end
6262

63-
setter = "#{name_sym}="
63+
setter = :"#{name_sym}="
6464
api_name = info.fetch(:api_name, name_sym)
6565
nilable = info.fetch(:nil?, false)
6666
const = required && !nilable ? info.fetch(:const, Orb::Internal::OMIT) : Orb::Internal::OMIT
@@ -77,30 +77,63 @@ def fields
7777
type_fn: type_fn
7878
}
7979

80-
define_method(setter) { @data.store(name_sym, _1) }
80+
define_method(setter) do |value|
81+
target = type_fn.call
82+
state = Orb::Internal::Type::Converter.new_coerce_state(translate_names: false)
83+
coerced = Orb::Internal::Type::Converter.coerce(target, value, state: state)
84+
status = @coerced.store(name_sym, state.fetch(:error) || true)
85+
stored =
86+
case [target, status]
87+
in [Orb::Internal::Type::Converter | Symbol, true]
88+
coerced
89+
else
90+
value
91+
end
92+
@data.store(name_sym, stored)
93+
end
8194

95+
# rubocop:disable Style/CaseEquality
96+
# rubocop:disable Metrics/BlockLength
8297
define_method(name_sym) do
8398
target = type_fn.call
84-
value = @data.fetch(name_sym) { const == Orb::Internal::OMIT ? nil : const }
85-
state = {strictness: :strong, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0}
86-
if (nilable || !required) && value.nil?
87-
nil
88-
else
89-
Orb::Internal::Type::Converter.coerce(
90-
target,
91-
value,
92-
state: state
99+
100+
case @coerced[name_sym]
101+
in true | false if Orb::Internal::Type::Converter === target
102+
@data.fetch(name_sym)
103+
in ::StandardError => e
104+
raise Orb::Errors::ConversionError.new(
105+
on: self.class,
106+
method: __method__,
107+
target: target,
108+
value: @data.fetch(name_sym),
109+
cause: e
93110
)
111+
else
112+
Kernel.then do
113+
value = @data.fetch(name_sym) { const == Orb::Internal::OMIT ? nil : const }
114+
state = Orb::Internal::Type::Converter.new_coerce_state(translate_names: false)
115+
if (nilable || !required) && value.nil?
116+
nil
117+
else
118+
Orb::Internal::Type::Converter.coerce(
119+
target,
120+
value,
121+
state: state
122+
)
123+
end
124+
rescue StandardError => e
125+
raise Orb::Errors::ConversionError.new(
126+
on: self.class,
127+
method: __method__,
128+
target: target,
129+
value: value,
130+
cause: e
131+
)
132+
end
94133
end
95-
rescue StandardError => e
96-
cls = self.class.name.split("::").last
97-
message = [
98-
"Failed to parse #{cls}.#{__method__} from #{value.class} to #{target.inspect}.",
99-
"To get the unparsed API response, use #{cls}[#{__method__.inspect}].",
100-
"Cause: #{e.message}"
101-
].join(" ")
102-
raise Orb::Errors::ConversionError.new(message)
103134
end
135+
# rubocop:enable Metrics/BlockLength
136+
# rubocop:enable Style/CaseEquality
104137
end
105138

106139
# @api private
@@ -200,37 +233,44 @@ class << self
200233
#
201234
# @param state [Hash{Symbol=>Object}] .
202235
#
203-
# @option state [Boolean, :strong] :strictness
236+
# @option state [Boolean] :translate_names
237+
#
238+
# @option state [Boolean] :strictness
204239
#
205240
# @option state [Hash{Symbol=>Object}] :exactness
206241
#
242+
# @option state [Class<StandardError>] :error
243+
#
207244
# @option state [Integer] :branched
208245
#
209246
# @return [self, Object]
210247
def coerce(value, state:)
211248
exactness = state.fetch(:exactness)
212249

213-
if value.is_a?(self.class)
250+
if value.is_a?(self)
214251
exactness[:yes] += 1
215252
return value
216253
end
217254

218255
unless (val = Orb::Internal::Util.coerce_hash(value)).is_a?(Hash)
219256
exactness[:no] += 1
257+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{Hash}")
220258
return value
221259
end
222260
exactness[:yes] += 1
223261

224262
keys = val.keys.to_set
225263
instance = new
226264
data = instance.to_h
265+
status = instance.instance_variable_get(:@coerced)
227266

228267
# rubocop:disable Metrics/BlockLength
229268
fields.each do |name, field|
230269
mode, required, target = field.fetch_values(:mode, :required, :type)
231270
api_name, nilable, const = field.fetch_values(:api_name, :nilable, :const)
271+
src_name = state.fetch(:translate_names) ? api_name : name
232272

233-
unless val.key?(api_name)
273+
unless val.key?(src_name)
234274
if required && mode != :dump && const == Orb::Internal::OMIT
235275
exactness[nilable ? :maybe : :no] += 1
236276
else
@@ -239,9 +279,10 @@ def coerce(value, state:)
239279
next
240280
end
241281

242-
item = val.fetch(api_name)
243-
keys.delete(api_name)
282+
item = val.fetch(src_name)
283+
keys.delete(src_name)
244284

285+
state[:error] = nil
245286
converted =
246287
if item.nil? && (nilable || !required)
247288
exactness[nilable ? :yes : :maybe] += 1
@@ -255,6 +296,8 @@ def coerce(value, state:)
255296
item
256297
end
257298
end
299+
300+
status.store(name, state.fetch(:error) || true)
258301
data.store(name, converted)
259302
end
260303
# rubocop:enable Metrics/BlockLength
@@ -430,7 +473,18 @@ def to_yaml(*a) = Orb::Internal::Type::Converter.dump(self.class, self).to_yaml(
430473
# Create a new instance of a model.
431474
#
432475
# @param data [Hash{Symbol=>Object}, self]
433-
def initialize(data = {}) = (@data = Orb::Internal::Util.coerce_hash!(data).to_h)
476+
def initialize(data = {})
477+
@data = {}
478+
@coerced = {}
479+
Orb::Internal::Util.coerce_hash!(data).each do
480+
if self.class.known_fields.key?(_1)
481+
public_send(:"#{_1}=", _2)
482+
else
483+
@data.store(_1, _2)
484+
@coerced.store(_1, false)
485+
end
486+
end
487+
end
434488

435489
class << self
436490
# @api private

0 commit comments

Comments
 (0)