orb-billing 1.0.0 → 1.1.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/CHANGELOG.md +30 -0
- data/README.md +1 -1
- data/lib/orb/errors.rb +22 -0
- data/lib/orb/internal/type/array_of.rb +6 -1
- data/lib/orb/internal/type/base_model.rb +79 -25
- data/lib/orb/internal/type/boolean.rb +7 -1
- data/lib/orb/internal/type/converter.rb +42 -34
- data/lib/orb/internal/type/enum.rb +10 -2
- data/lib/orb/internal/type/file_input.rb +6 -1
- data/lib/orb/internal/type/hash_of.rb +6 -1
- data/lib/orb/internal/type/union.rb +12 -7
- data/lib/orb/internal/type/unknown.rb +7 -1
- data/lib/orb/models/customers/credits/ledger_create_entry_by_external_id_params.rb +4 -4
- data/lib/orb/models/customers/credits/ledger_create_entry_params.rb +4 -4
- data/lib/orb/models/invoice.rb +4 -1
- data/lib/orb/models/invoice_fetch_upcoming_response.rb +4 -1
- data/lib/orb/models/invoice_line_item_create_response.rb +4 -1
- data/lib/orb/models/new_plan_bps_price.rb +10 -1
- data/lib/orb/models/new_plan_bulk_bps_price.rb +10 -1
- data/lib/orb/models/new_plan_bulk_price.rb +10 -1
- data/lib/orb/models/new_plan_bulk_with_proration_price.rb +10 -1
- data/lib/orb/models/new_plan_cumulative_grouped_bulk_price.rb +10 -1
- data/lib/orb/models/new_plan_grouped_allocation_price.rb +10 -1
- data/lib/orb/models/new_plan_grouped_tiered_package_price.rb +10 -1
- data/lib/orb/models/new_plan_grouped_tiered_price.rb +10 -1
- data/lib/orb/models/new_plan_grouped_with_metered_minimum_price.rb +10 -1
- data/lib/orb/models/new_plan_grouped_with_prorated_minimum_price.rb +10 -1
- data/lib/orb/models/new_plan_matrix_price.rb +10 -1
- data/lib/orb/models/new_plan_matrix_with_allocation_price.rb +10 -1
- data/lib/orb/models/new_plan_matrix_with_display_name_price.rb +10 -1
- data/lib/orb/models/new_plan_max_group_tiered_package_price.rb +10 -1
- data/lib/orb/models/new_plan_package_price.rb +10 -1
- data/lib/orb/models/new_plan_package_with_allocation_price.rb +10 -1
- data/lib/orb/models/new_plan_scalable_matrix_with_tiered_pricing_price.rb +10 -1
- data/lib/orb/models/new_plan_scalable_matrix_with_unit_pricing_price.rb +10 -1
- data/lib/orb/models/new_plan_threshold_total_amount_price.rb +10 -1
- data/lib/orb/models/new_plan_tier_with_proration_price.rb +10 -1
- data/lib/orb/models/new_plan_tiered_bps_price.rb +10 -1
- data/lib/orb/models/new_plan_tiered_package_price.rb +10 -1
- data/lib/orb/models/new_plan_tiered_package_with_minimum_price.rb +10 -1
- data/lib/orb/models/new_plan_tiered_price.rb +10 -1
- data/lib/orb/models/new_plan_tiered_with_minimum_price.rb +10 -1
- data/lib/orb/models/new_plan_unit_price.rb +10 -1
- data/lib/orb/models/new_plan_unit_with_percent_price.rb +10 -1
- data/lib/orb/models/new_plan_unit_with_proration_price.rb +10 -1
- data/lib/orb/models/plan_create_params.rb +185 -37
- data/lib/orb/resources/customers/credits/ledger.rb +6 -6
- data/lib/orb/resources/plans.rb +6 -2
- data/lib/orb/version.rb +1 -1
- data/rbi/orb/errors.rbi +16 -0
- data/rbi/orb/internal/type/boolean.rbi +2 -0
- data/rbi/orb/internal/type/converter.rbi +15 -15
- data/rbi/orb/internal/type/union.rbi +5 -0
- data/rbi/orb/internal/type/unknown.rbi +2 -0
- data/rbi/orb/models/customers/credits/ledger_create_entry_by_external_id_params.rbi +3 -3
- data/rbi/orb/models/customers/credits/ledger_create_entry_params.rbi +3 -3
- data/rbi/orb/models/invoice.rbi +2 -0
- data/rbi/orb/models/invoice_fetch_upcoming_response.rbi +2 -0
- data/rbi/orb/models/invoice_line_item_create_response.rbi +2 -0
- data/rbi/orb/models/new_plan_bps_price.rbi +13 -3
- data/rbi/orb/models/new_plan_bulk_bps_price.rbi +13 -3
- data/rbi/orb/models/new_plan_bulk_price.rbi +13 -3
- data/rbi/orb/models/new_plan_bulk_with_proration_price.rbi +13 -3
- data/rbi/orb/models/new_plan_cumulative_grouped_bulk_price.rbi +13 -3
- data/rbi/orb/models/new_plan_grouped_allocation_price.rbi +13 -3
- data/rbi/orb/models/new_plan_grouped_tiered_package_price.rbi +13 -3
- data/rbi/orb/models/new_plan_grouped_tiered_price.rbi +13 -3
- data/rbi/orb/models/new_plan_grouped_with_metered_minimum_price.rbi +13 -3
- data/rbi/orb/models/new_plan_grouped_with_prorated_minimum_price.rbi +13 -3
- data/rbi/orb/models/new_plan_matrix_price.rbi +13 -3
- data/rbi/orb/models/new_plan_matrix_with_allocation_price.rbi +13 -3
- data/rbi/orb/models/new_plan_matrix_with_display_name_price.rbi +13 -3
- data/rbi/orb/models/new_plan_max_group_tiered_package_price.rbi +13 -3
- data/rbi/orb/models/new_plan_package_price.rbi +13 -3
- data/rbi/orb/models/new_plan_package_with_allocation_price.rbi +13 -3
- data/rbi/orb/models/new_plan_scalable_matrix_with_tiered_pricing_price.rbi +13 -3
- data/rbi/orb/models/new_plan_scalable_matrix_with_unit_pricing_price.rbi +13 -3
- data/rbi/orb/models/new_plan_threshold_total_amount_price.rbi +13 -3
- data/rbi/orb/models/new_plan_tier_with_proration_price.rbi +13 -3
- data/rbi/orb/models/new_plan_tiered_bps_price.rbi +13 -3
- data/rbi/orb/models/new_plan_tiered_package_price.rbi +13 -3
- data/rbi/orb/models/new_plan_tiered_package_with_minimum_price.rbi +13 -3
- data/rbi/orb/models/new_plan_tiered_price.rbi +13 -3
- data/rbi/orb/models/new_plan_tiered_with_minimum_price.rbi +13 -3
- data/rbi/orb/models/new_plan_unit_price.rbi +13 -3
- data/rbi/orb/models/new_plan_unit_with_percent_price.rbi +13 -3
- data/rbi/orb/models/new_plan_unit_with_proration_price.rbi +13 -3
- data/rbi/orb/models/plan_create_params.rbi +415 -135
- data/rbi/orb/resources/customers/credits/ledger.rbi +6 -6
- data/rbi/orb/resources/plans.rbi +11 -33
- data/sig/orb/errors.rbs +9 -0
- data/sig/orb/internal/type/converter.rbs +7 -1
- data/sig/orb/models/customers/credits/ledger_create_entry_by_external_id_params.rbs +1 -1
- data/sig/orb/models/customers/credits/ledger_create_entry_params.rbs +1 -1
- data/sig/orb/models/new_plan_bps_price.rbs +8 -3
- data/sig/orb/models/new_plan_bulk_bps_price.rbs +8 -3
- data/sig/orb/models/new_plan_bulk_price.rbs +8 -3
- data/sig/orb/models/new_plan_bulk_with_proration_price.rbs +8 -3
- data/sig/orb/models/new_plan_cumulative_grouped_bulk_price.rbs +8 -3
- data/sig/orb/models/new_plan_grouped_allocation_price.rbs +8 -3
- data/sig/orb/models/new_plan_grouped_tiered_package_price.rbs +8 -3
- data/sig/orb/models/new_plan_grouped_tiered_price.rbs +8 -3
- data/sig/orb/models/new_plan_grouped_with_metered_minimum_price.rbs +8 -3
- data/sig/orb/models/new_plan_grouped_with_prorated_minimum_price.rbs +8 -3
- data/sig/orb/models/new_plan_matrix_price.rbs +8 -3
- data/sig/orb/models/new_plan_matrix_with_allocation_price.rbs +8 -3
- data/sig/orb/models/new_plan_matrix_with_display_name_price.rbs +8 -3
- data/sig/orb/models/new_plan_max_group_tiered_package_price.rbs +8 -3
- data/sig/orb/models/new_plan_package_price.rbs +8 -3
- data/sig/orb/models/new_plan_package_with_allocation_price.rbs +8 -3
- data/sig/orb/models/new_plan_scalable_matrix_with_tiered_pricing_price.rbs +8 -3
- data/sig/orb/models/new_plan_scalable_matrix_with_unit_pricing_price.rbs +8 -3
- data/sig/orb/models/new_plan_threshold_total_amount_price.rbs +8 -3
- data/sig/orb/models/new_plan_tier_with_proration_price.rbs +8 -3
- data/sig/orb/models/new_plan_tiered_bps_price.rbs +8 -3
- data/sig/orb/models/new_plan_tiered_package_price.rbs +8 -3
- data/sig/orb/models/new_plan_tiered_package_with_minimum_price.rbs +8 -3
- data/sig/orb/models/new_plan_tiered_price.rbs +8 -3
- data/sig/orb/models/new_plan_tiered_with_minimum_price.rbs +8 -3
- data/sig/orb/models/new_plan_unit_price.rbs +8 -3
- data/sig/orb/models/new_plan_unit_with_percent_price.rbs +8 -3
- data/sig/orb/models/new_plan_unit_with_proration_price.rbs +8 -3
- data/sig/orb/models/plan_create_params.rbs +156 -37
- data/sig/orb/resources/customers/credits/ledger.rbs +2 -2
- data/sig/orb/resources/plans.rbs +3 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72bf8cc708079b89812a37a34a92505d31c7a8e4fb7be72449ef1cefa3a68433
|
4
|
+
data.tar.gz: c94583819d1a3c5e6544dc35378a645f5b823e6591a6fc8a18e0a02c070e68da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3955626d5164c7909179bd3d87b0bdea7660cc532390ecff4586642a79072014f039fe0e1ecf05a9c1a52ed2a5088800bac24bea9ae02fe0110692c6579cf0f1
|
7
|
+
data.tar.gz: b440576069f58911b5fb0640bdd8e92a0210b8027b9cf7640aee6c2094d94ff56b8285e3e870630c825684b3902f8eb4085ec8b79a233b5eb4d3ca9557e9f898
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,35 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
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
|
+
|
25
|
+
## 1.0.1 (2025-06-09)
|
26
|
+
|
27
|
+
Full Changelog: [v1.0.0...v1.0.1](https://github.com/orbcorp/orb-ruby/compare/v1.0.0...v1.0.1)
|
28
|
+
|
29
|
+
### Chores
|
30
|
+
|
31
|
+
* **internal:** version bump ([c8f2c89](https://github.com/orbcorp/orb-ruby/commit/c8f2c89c4cd20fba8ead7e483b25a4496b9064eb))
|
32
|
+
|
3
33
|
## 1.0.0 (2025-06-09)
|
4
34
|
|
5
35
|
Full Changelog: [v0.12.0...v1.0.0](https://github.com/orbcorp/orb-ruby/compare/v0.12.0...v1.0.0)
|
data/README.md
CHANGED
data/lib/orb/errors.rb
CHANGED
@@ -9,6 +9,28 @@ module Orb
|
|
9
9
|
end
|
10
10
|
|
11
11
|
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
|
12
34
|
end
|
13
35
|
|
14
36
|
class APIError < Orb::Errors::Error
|
@@ -62,10 +62,14 @@ module Orb
|
|
62
62
|
#
|
63
63
|
# @param state [Hash{Symbol=>Object}] .
|
64
64
|
#
|
65
|
-
# @option state [Boolean
|
65
|
+
# @option state [Boolean] :translate_names
|
66
|
+
#
|
67
|
+
# @option state [Boolean] :strictness
|
66
68
|
#
|
67
69
|
# @option state [Hash{Symbol=>Object}] :exactness
|
68
70
|
#
|
71
|
+
# @option state [Class<StandardError>] :error
|
72
|
+
#
|
69
73
|
# @option state [Integer] :branched
|
70
74
|
#
|
71
75
|
# @return [Array<Object>, Object]
|
@@ -74,6 +78,7 @@ module Orb
|
|
74
78
|
|
75
79
|
unless value.is_a?(Array)
|
76
80
|
exactness[:no] += 1
|
81
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{Array}")
|
77
82
|
return value
|
78
83
|
end
|
79
84
|
|
@@ -60,7 +60,7 @@ module Orb
|
|
60
60
|
[Orb::Internal::Type::Converter.type_info(type_info), type_info]
|
61
61
|
end
|
62
62
|
|
63
|
-
setter = "#{name_sym}="
|
63
|
+
setter = :"#{name_sym}="
|
64
64
|
api_name = info.fetch(:api_name, name_sym)
|
65
65
|
nilable = info.fetch(:nil?, false)
|
66
66
|
const = required && !nilable ? info.fetch(:const, Orb::Internal::OMIT) : Orb::Internal::OMIT
|
@@ -77,30 +77,63 @@ module Orb
|
|
77
77
|
type_fn: type_fn
|
78
78
|
}
|
79
79
|
|
80
|
-
define_method(setter)
|
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
|
81
94
|
|
95
|
+
# rubocop:disable Style/CaseEquality
|
96
|
+
# rubocop:disable Metrics/BlockLength
|
82
97
|
define_method(name_sym) do
|
83
98
|
target = type_fn.call
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
Orb::
|
90
|
-
|
91
|
-
|
92
|
-
|
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
|
93
110
|
)
|
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
|
94
133
|
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)
|
103
134
|
end
|
135
|
+
# rubocop:enable Metrics/BlockLength
|
136
|
+
# rubocop:enable Style/CaseEquality
|
104
137
|
end
|
105
138
|
|
106
139
|
# @api private
|
@@ -200,23 +233,28 @@ module Orb
|
|
200
233
|
#
|
201
234
|
# @param state [Hash{Symbol=>Object}] .
|
202
235
|
#
|
203
|
-
# @option state [Boolean
|
236
|
+
# @option state [Boolean] :translate_names
|
237
|
+
#
|
238
|
+
# @option state [Boolean] :strictness
|
204
239
|
#
|
205
240
|
# @option state [Hash{Symbol=>Object}] :exactness
|
206
241
|
#
|
242
|
+
# @option state [Class<StandardError>] :error
|
243
|
+
#
|
207
244
|
# @option state [Integer] :branched
|
208
245
|
#
|
209
246
|
# @return [self, Object]
|
210
247
|
def coerce(value, state:)
|
211
248
|
exactness = state.fetch(:exactness)
|
212
249
|
|
213
|
-
if value.is_a?(self
|
250
|
+
if value.is_a?(self)
|
214
251
|
exactness[:yes] += 1
|
215
252
|
return value
|
216
253
|
end
|
217
254
|
|
218
255
|
unless (val = Orb::Internal::Util.coerce_hash(value)).is_a?(Hash)
|
219
256
|
exactness[:no] += 1
|
257
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{Hash}")
|
220
258
|
return value
|
221
259
|
end
|
222
260
|
exactness[:yes] += 1
|
@@ -224,13 +262,15 @@ module Orb
|
|
224
262
|
keys = val.keys.to_set
|
225
263
|
instance = new
|
226
264
|
data = instance.to_h
|
265
|
+
status = instance.instance_variable_get(:@coerced)
|
227
266
|
|
228
267
|
# rubocop:disable Metrics/BlockLength
|
229
268
|
fields.each do |name, field|
|
230
269
|
mode, required, target = field.fetch_values(:mode, :required, :type)
|
231
270
|
api_name, nilable, const = field.fetch_values(:api_name, :nilable, :const)
|
271
|
+
src_name = state.fetch(:translate_names) ? api_name : name
|
232
272
|
|
233
|
-
unless val.key?(
|
273
|
+
unless val.key?(src_name)
|
234
274
|
if required && mode != :dump && const == Orb::Internal::OMIT
|
235
275
|
exactness[nilable ? :maybe : :no] += 1
|
236
276
|
else
|
@@ -239,9 +279,10 @@ module Orb
|
|
239
279
|
next
|
240
280
|
end
|
241
281
|
|
242
|
-
item = val.fetch(
|
243
|
-
keys.delete(
|
282
|
+
item = val.fetch(src_name)
|
283
|
+
keys.delete(src_name)
|
244
284
|
|
285
|
+
state[:error] = nil
|
245
286
|
converted =
|
246
287
|
if item.nil? && (nilable || !required)
|
247
288
|
exactness[nilable ? :yes : :maybe] += 1
|
@@ -255,6 +296,8 @@ module Orb
|
|
255
296
|
item
|
256
297
|
end
|
257
298
|
end
|
299
|
+
|
300
|
+
status.store(name, state.fetch(:error) || true)
|
258
301
|
data.store(name, converted)
|
259
302
|
end
|
260
303
|
# rubocop:enable Metrics/BlockLength
|
@@ -430,7 +473,18 @@ module Orb
|
|
430
473
|
# Create a new instance of a model.
|
431
474
|
#
|
432
475
|
# @param data [Hash{Symbol=>Object}, self]
|
433
|
-
def initialize(data = {})
|
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
|
434
488
|
|
435
489
|
class << self
|
436
490
|
# @api private
|
@@ -31,14 +31,20 @@ module Orb
|
|
31
31
|
class << self
|
32
32
|
# @api private
|
33
33
|
#
|
34
|
+
# Coerce value to Boolean if possible, otherwise return the original value.
|
35
|
+
#
|
34
36
|
# @param value [Boolean, Object]
|
35
37
|
#
|
36
38
|
# @param state [Hash{Symbol=>Object}] .
|
37
39
|
#
|
38
|
-
# @option state [Boolean
|
40
|
+
# @option state [Boolean] :translate_names
|
41
|
+
#
|
42
|
+
# @option state [Boolean] :strictness
|
39
43
|
#
|
40
44
|
# @option state [Hash{Symbol=>Object}] :exactness
|
41
45
|
#
|
46
|
+
# @option state [Class<StandardError>] :error
|
47
|
+
#
|
42
48
|
# @option state [Integer] :branched
|
43
49
|
#
|
44
50
|
# @return [Boolean, Object]
|
@@ -15,10 +15,14 @@ module Orb
|
|
15
15
|
#
|
16
16
|
# @param state [Hash{Symbol=>Object}] .
|
17
17
|
#
|
18
|
-
# @option state [Boolean
|
18
|
+
# @option state [Boolean] :translate_names
|
19
|
+
#
|
20
|
+
# @option state [Boolean] :strictness
|
19
21
|
#
|
20
22
|
# @option state [Hash{Symbol=>Object}] :exactness
|
21
23
|
#
|
24
|
+
# @option state [Class<StandardError>] :error
|
25
|
+
#
|
22
26
|
# @option state [Integer] :branched
|
23
27
|
#
|
24
28
|
# @return [Object]
|
@@ -94,6 +98,21 @@ module Orb
|
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
101
|
+
# @api private
|
102
|
+
#
|
103
|
+
# @param translate_names [Boolean]
|
104
|
+
#
|
105
|
+
# @return [Hash{Symbol=>Object}]
|
106
|
+
def new_coerce_state(translate_names: true)
|
107
|
+
{
|
108
|
+
translate_names: translate_names,
|
109
|
+
strictness: true,
|
110
|
+
exactness: {yes: 0, no: 0, maybe: 0},
|
111
|
+
error: nil,
|
112
|
+
branched: 0
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
97
116
|
# @api private
|
98
117
|
#
|
99
118
|
# Based on `target`, transform `value` into `target`, to the extent possible:
|
@@ -110,14 +129,11 @@ module Orb
|
|
110
129
|
#
|
111
130
|
# @param value [Object]
|
112
131
|
#
|
113
|
-
# @param state [Hash{Symbol=>Object}] The `strictness` is one of `true`, `false
|
114
|
-
#
|
115
|
-
# targets:
|
132
|
+
# @param state [Hash{Symbol=>Object}] The `strictness` is one of `true`, `false`. This informs the coercion strategy
|
133
|
+
# when we have to decide between multiple possible conversion targets:
|
116
134
|
#
|
117
135
|
# - `true`: the conversion must be exact, with minimum coercion.
|
118
136
|
# - `false`: the conversion can be approximate, with some coercion.
|
119
|
-
# - `:strong`: the conversion must be exact, with no coercion, and raise an error
|
120
|
-
# if not possible.
|
121
137
|
#
|
122
138
|
# The `exactness` is `Hash` with keys being one of `yes`, `no`, or `maybe`. For
|
123
139
|
# any given conversion attempt, the exactness will be updated based on how closely
|
@@ -130,21 +146,20 @@ module Orb
|
|
130
146
|
#
|
131
147
|
# See implementation below for more details.
|
132
148
|
#
|
133
|
-
# @option state [Boolean
|
149
|
+
# @option state [Boolean] :translate_names
|
150
|
+
#
|
151
|
+
# @option state [Boolean] :strictness
|
134
152
|
#
|
135
153
|
# @option state [Hash{Symbol=>Object}] :exactness
|
136
154
|
#
|
155
|
+
# @option state [Class<StandardError>] :error
|
156
|
+
#
|
137
157
|
# @option state [Integer] :branched
|
138
158
|
#
|
139
159
|
# @return [Object]
|
140
|
-
def coerce(
|
141
|
-
target,
|
142
|
-
value,
|
143
|
-
state: {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0}
|
144
|
-
)
|
145
|
-
# rubocop:disable Lint/SuppressedException
|
160
|
+
def coerce(target, value, state: Orb::Internal::Type::Converter.new_coerce_state)
|
146
161
|
# rubocop:disable Metrics/BlockNesting
|
147
|
-
|
162
|
+
exactness = state.fetch(:exactness)
|
148
163
|
|
149
164
|
case target
|
150
165
|
in Orb::Internal::Type::Converter
|
@@ -160,29 +175,26 @@ module Orb
|
|
160
175
|
exactness[value.nil? ? :yes : :maybe] += 1
|
161
176
|
return nil
|
162
177
|
in -> { _1 <= Integer }
|
163
|
-
|
178
|
+
case value
|
179
|
+
in Integer
|
164
180
|
exactness[:yes] += 1
|
165
181
|
return value
|
166
|
-
elsif strictness == :strong && Integer(value, exception: false) != value
|
167
|
-
message = "no implicit conversion of #{value.class} into #{target.inspect}"
|
168
|
-
raise value.is_a?(Numeric) ? ArgumentError.new(message) : TypeError.new(message)
|
169
182
|
else
|
170
183
|
Kernel.then do
|
171
184
|
return Integer(value).tap { exactness[:maybe] += 1 }
|
172
|
-
rescue ArgumentError, TypeError
|
185
|
+
rescue ArgumentError, TypeError => e
|
186
|
+
state[:error] = e
|
173
187
|
end
|
174
188
|
end
|
175
189
|
in -> { _1 <= Float }
|
176
190
|
if value.is_a?(Numeric)
|
177
191
|
exactness[:yes] += 1
|
178
192
|
return Float(value)
|
179
|
-
elsif strictness == :strong
|
180
|
-
message = "no implicit conversion of #{value.class} into #{target.inspect}"
|
181
|
-
raise TypeError.new(message)
|
182
193
|
else
|
183
194
|
Kernel.then do
|
184
195
|
return Float(value).tap { exactness[:maybe] += 1 }
|
185
|
-
rescue ArgumentError, TypeError
|
196
|
+
rescue ArgumentError, TypeError => e
|
197
|
+
state[:error] = e
|
186
198
|
end
|
187
199
|
end
|
188
200
|
in -> { _1 <= String }
|
@@ -194,16 +206,13 @@ module Orb
|
|
194
206
|
exactness[:yes] += 1
|
195
207
|
return value.string
|
196
208
|
else
|
197
|
-
|
198
|
-
message = "no implicit conversion of #{value.class} into #{target.inspect}"
|
199
|
-
raise TypeError.new(message)
|
200
|
-
end
|
209
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{String}")
|
201
210
|
end
|
202
211
|
in -> { _1 <= Date || _1 <= Time }
|
203
212
|
Kernel.then do
|
204
213
|
return target.parse(value).tap { exactness[:yes] += 1 }
|
205
214
|
rescue ArgumentError, TypeError => e
|
206
|
-
|
215
|
+
state[:error] = e
|
207
216
|
end
|
208
217
|
in -> { _1 <= StringIO } if value.is_a?(String)
|
209
218
|
exactness[:yes] += 1
|
@@ -221,10 +230,8 @@ module Orb
|
|
221
230
|
return value
|
222
231
|
end
|
223
232
|
else
|
224
|
-
|
225
|
-
|
226
|
-
raise ArgumentError.new(message)
|
227
|
-
end
|
233
|
+
message = "cannot convert non-matching #{value.class} into #{target.inspect}"
|
234
|
+
state[:error] = ArgumentError.new(message)
|
228
235
|
end
|
229
236
|
else
|
230
237
|
end
|
@@ -232,7 +239,6 @@ module Orb
|
|
232
239
|
exactness[:no] += 1
|
233
240
|
value
|
234
241
|
# rubocop:enable Metrics/BlockNesting
|
235
|
-
# rubocop:enable Lint/SuppressedException
|
236
242
|
end
|
237
243
|
|
238
244
|
# @api private
|
@@ -277,8 +283,10 @@ module Orb
|
|
277
283
|
define_sorbet_constant!(:CoerceState) do
|
278
284
|
T.type_alias do
|
279
285
|
{
|
280
|
-
|
286
|
+
translate_names: T::Boolean,
|
287
|
+
strictness: T::Boolean,
|
281
288
|
exactness: {yes: Integer, no: Integer, maybe: Integer},
|
289
|
+
error: T::Class[StandardError],
|
282
290
|
branched: Integer
|
283
291
|
}
|
284
292
|
end
|
@@ -77,10 +77,14 @@ module Orb
|
|
77
77
|
#
|
78
78
|
# @param state [Hash{Symbol=>Object}] .
|
79
79
|
#
|
80
|
-
# @option state [Boolean
|
80
|
+
# @option state [Boolean] :translate_names
|
81
|
+
#
|
82
|
+
# @option state [Boolean] :strictness
|
81
83
|
#
|
82
84
|
# @option state [Hash{Symbol=>Object}] :exactness
|
83
85
|
#
|
86
|
+
# @option state [Class<StandardError>] :error
|
87
|
+
#
|
84
88
|
# @option state [Integer] :branched
|
85
89
|
#
|
86
90
|
# @return [Symbol, Object]
|
@@ -91,8 +95,12 @@ module Orb
|
|
91
95
|
if values.include?(val)
|
92
96
|
exactness[:yes] += 1
|
93
97
|
val
|
98
|
+
elsif values.first&.class == val.class
|
99
|
+
exactness[:maybe] += 1
|
100
|
+
value
|
94
101
|
else
|
95
|
-
exactness[
|
102
|
+
exactness[:no] += 1
|
103
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{self}")
|
96
104
|
value
|
97
105
|
end
|
98
106
|
end
|
@@ -44,10 +44,14 @@ module Orb
|
|
44
44
|
#
|
45
45
|
# @param state [Hash{Symbol=>Object}] .
|
46
46
|
#
|
47
|
-
# @option state [Boolean
|
47
|
+
# @option state [Boolean] :translate_names
|
48
|
+
#
|
49
|
+
# @option state [Boolean] :strictness
|
48
50
|
#
|
49
51
|
# @option state [Hash{Symbol=>Object}] :exactness
|
50
52
|
#
|
53
|
+
# @option state [Class<StandardError>] :error
|
54
|
+
#
|
51
55
|
# @option state [Integer] :branched
|
52
56
|
#
|
53
57
|
# @return [StringIO, Object]
|
@@ -61,6 +65,7 @@ module Orb
|
|
61
65
|
exactness[:yes] += 1
|
62
66
|
value
|
63
67
|
else
|
68
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{StringIO}")
|
64
69
|
exactness[:no] += 1
|
65
70
|
value
|
66
71
|
end
|
@@ -77,10 +77,14 @@ module Orb
|
|
77
77
|
#
|
78
78
|
# @param state [Hash{Symbol=>Object}] .
|
79
79
|
#
|
80
|
-
# @option state [Boolean
|
80
|
+
# @option state [Boolean] :translate_names
|
81
|
+
#
|
82
|
+
# @option state [Boolean] :strictness
|
81
83
|
#
|
82
84
|
# @option state [Hash{Symbol=>Object}] :exactness
|
83
85
|
#
|
86
|
+
# @option state [Class<StandardError>] :error
|
87
|
+
#
|
84
88
|
# @option state [Integer] :branched
|
85
89
|
#
|
86
90
|
# @return [Hash{Symbol=>Object}, Object]
|
@@ -89,6 +93,7 @@ module Orb
|
|
89
93
|
|
90
94
|
unless value.is_a?(Hash)
|
91
95
|
exactness[:no] += 1
|
96
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{Hash}")
|
92
97
|
return value
|
93
98
|
end
|
94
99
|
|
@@ -150,14 +150,23 @@ module Orb
|
|
150
150
|
|
151
151
|
# @api private
|
152
152
|
#
|
153
|
+
# Tries to efficiently coerce the given value to one of the known variants.
|
154
|
+
#
|
155
|
+
# If the value cannot match any of the known variants, the coercion is considered
|
156
|
+
# non-viable and returns the original value.
|
157
|
+
#
|
153
158
|
# @param value [Object]
|
154
159
|
#
|
155
160
|
# @param state [Hash{Symbol=>Object}] .
|
156
161
|
#
|
157
|
-
# @option state [Boolean
|
162
|
+
# @option state [Boolean] :translate_names
|
163
|
+
#
|
164
|
+
# @option state [Boolean] :strictness
|
158
165
|
#
|
159
166
|
# @option state [Hash{Symbol=>Object}] :exactness
|
160
167
|
#
|
168
|
+
# @option state [Class<StandardError>] :error
|
169
|
+
#
|
161
170
|
# @option state [Integer] :branched
|
162
171
|
#
|
163
172
|
# @return [Object]
|
@@ -168,7 +177,6 @@ module Orb
|
|
168
177
|
|
169
178
|
strictness = state.fetch(:strictness)
|
170
179
|
exactness = state.fetch(:exactness)
|
171
|
-
state[:strictness] = strictness == :strong ? true : strictness
|
172
180
|
|
173
181
|
alternatives = []
|
174
182
|
known_variants.each do |_, variant_fn|
|
@@ -187,13 +195,10 @@ module Orb
|
|
187
195
|
end
|
188
196
|
end
|
189
197
|
|
190
|
-
case alternatives.sort_by(&:first)
|
198
|
+
case alternatives.sort_by!(&:first)
|
191
199
|
in []
|
192
200
|
exactness[:no] += 1
|
193
|
-
|
194
|
-
message = "no possible conversion of #{value.class} into a variant of #{target.inspect}"
|
195
|
-
raise ArgumentError.new(message)
|
196
|
-
end
|
201
|
+
state[:error] = ArgumentError.new("no matching variant for #{value.inspect}")
|
197
202
|
value
|
198
203
|
in [[_, exact, coerced], *]
|
199
204
|
exact.each { exactness[_1] += _2 }
|
@@ -33,14 +33,20 @@ module Orb
|
|
33
33
|
class << self
|
34
34
|
# @api private
|
35
35
|
#
|
36
|
+
# No coercion needed for Unknown type.
|
37
|
+
#
|
36
38
|
# @param value [Object]
|
37
39
|
#
|
38
40
|
# @param state [Hash{Symbol=>Object}] .
|
39
41
|
#
|
40
|
-
# @option state [Boolean
|
42
|
+
# @option state [Boolean] :translate_names
|
43
|
+
#
|
44
|
+
# @option state [Boolean] :strictness
|
41
45
|
#
|
42
46
|
# @option state [Hash{Symbol=>Object}] :exactness
|
43
47
|
#
|
48
|
+
# @option state [Class<StandardError>] :error
|
49
|
+
#
|
44
50
|
# @option state [Integer] :branched
|
45
51
|
#
|
46
52
|
# @return [Object]
|
@@ -50,7 +50,7 @@ module Orb
|
|
50
50
|
# An ISO 8601 format date that identifies the origination credit block to expire
|
51
51
|
#
|
52
52
|
# @return [Time, nil]
|
53
|
-
|
53
|
+
optional :expiry_date, Time, nil?: true
|
54
54
|
|
55
55
|
# @!attribute invoice_settings
|
56
56
|
# Passing `invoice_settings` automatically generates an invoice for the newly
|
@@ -100,7 +100,7 @@ module Orb
|
|
100
100
|
enum: -> { Orb::Customers::Credits::LedgerCreateEntryByExternalIDParams::VoidReason },
|
101
101
|
nil?: true
|
102
102
|
|
103
|
-
# @!method initialize(amount:, entry_type:,
|
103
|
+
# @!method initialize(amount:, entry_type:, target_expiry_date:, block_id:, currency: nil, description: nil, effective_date: nil, expiry_date: nil, invoice_settings: nil, metadata: nil, per_unit_cost_basis: nil, void_reason: nil, request_options: {})
|
104
104
|
# Some parameter documentations has been truncated, see
|
105
105
|
# {Orb::Models::Customers::Credits::LedgerCreateEntryByExternalIDParams} for more
|
106
106
|
# details.
|
@@ -109,8 +109,6 @@ module Orb
|
|
109
109
|
#
|
110
110
|
# @param entry_type [Symbol, Orb::Models::Customers::Credits::LedgerCreateEntryByExternalIDParams::EntryType]
|
111
111
|
#
|
112
|
-
# @param expiry_date [Time, nil] An ISO 8601 format date that identifies the origination credit block to expire
|
113
|
-
#
|
114
112
|
# @param target_expiry_date [Date] A future date (specified in YYYY-MM-DD format) used for expiration change, denot
|
115
113
|
#
|
116
114
|
# @param block_id [String] The ID of the block to reverse a decrement from.
|
@@ -121,6 +119,8 @@ module Orb
|
|
121
119
|
#
|
122
120
|
# @param effective_date [Time, nil] An ISO 8601 format date that denotes when this credit balance should become avai
|
123
121
|
#
|
122
|
+
# @param expiry_date [Time, nil] An ISO 8601 format date that identifies the origination credit block to expire
|
123
|
+
#
|
124
124
|
# @param invoice_settings [Orb::Models::Customers::Credits::LedgerCreateEntryByExternalIDParams::InvoiceSettings, nil] Passing `invoice_settings` automatically generates an invoice for the newly adde
|
125
125
|
#
|
126
126
|
# @param metadata [Hash{Symbol=>String, nil}, nil] User-specified key/value pairs for the resource. Individual keys can be removed
|