modern_treasury 0.1.0.pre.alpha.17 → 0.1.0.pre.alpha.18
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/.ignore +2 -0
- data/CHANGELOG.md +635 -0
- data/README.md +37 -12
- data/SECURITY.md +27 -0
- data/lib/modern_treasury/client.rb +3 -2
- data/lib/modern_treasury/internal/page.rb +27 -23
- data/lib/modern_treasury/internal/transport/base_client.rb +19 -5
- data/lib/modern_treasury/internal/transport/pooled_net_requester.rb +20 -7
- data/lib/modern_treasury/internal/type/array_of.rb +23 -4
- data/lib/modern_treasury/internal/type/base_model.rb +45 -10
- data/lib/modern_treasury/internal/type/base_page.rb +1 -0
- data/lib/modern_treasury/internal/type/boolean.rb +7 -1
- data/lib/modern_treasury/internal/type/converter.rb +66 -17
- data/lib/modern_treasury/internal/type/enum.rb +24 -4
- data/lib/modern_treasury/internal/type/hash_of.rb +23 -4
- data/lib/modern_treasury/internal/type/io_like.rb +77 -0
- data/lib/modern_treasury/internal/type/request_parameters.rb +11 -2
- data/lib/modern_treasury/internal/type/union.rb +30 -6
- data/lib/modern_treasury/internal/type/unknown.rb +7 -1
- data/lib/modern_treasury/internal/util.rb +115 -29
- data/lib/modern_treasury/internal.rb +5 -1
- data/lib/modern_treasury/models/document_create_params.rb +3 -3
- data/lib/modern_treasury/models/payment_order_create_params.rb +3 -3
- data/lib/modern_treasury/resources/documents.rb +1 -1
- data/lib/modern_treasury/version.rb +1 -1
- data/lib/modern_treasury.rb +1 -0
- data/rbi/lib/modern_treasury/client.rbi +3 -2
- data/rbi/lib/modern_treasury/internal/page.rbi +1 -0
- data/rbi/lib/modern_treasury/internal/transport/base_client.rbi +1 -0
- data/rbi/lib/modern_treasury/internal/transport/pooled_net_requester.rbi +1 -1
- data/rbi/lib/modern_treasury/internal/type/array_of.rbi +18 -12
- data/rbi/lib/modern_treasury/internal/type/base_model.rbi +13 -3
- data/rbi/lib/modern_treasury/internal/type/boolean.rbi +16 -12
- data/rbi/lib/modern_treasury/internal/type/converter.rbi +24 -8
- data/rbi/lib/modern_treasury/internal/type/enum.rbi +15 -5
- data/rbi/lib/modern_treasury/internal/type/hash_of.rbi +18 -12
- data/rbi/lib/modern_treasury/internal/type/io_like.rbi +46 -0
- data/rbi/lib/modern_treasury/internal/type/union.rbi +11 -3
- data/rbi/lib/modern_treasury/internal/type/unknown.rbi +10 -7
- data/rbi/lib/modern_treasury/internal/util.rbi +50 -4
- data/rbi/lib/modern_treasury/internal.rbi +1 -1
- data/rbi/lib/modern_treasury/models/document_create_params.rbi +3 -3
- data/rbi/lib/modern_treasury/models/payment_order_create_params.rbi +3 -3
- data/rbi/lib/modern_treasury/resources/documents.rbi +1 -1
- data/sig/modern_treasury/internal/transport/pooled_net_requester.rbs +1 -1
- data/sig/modern_treasury/internal/type/array_of.rbs +7 -2
- data/sig/modern_treasury/internal/type/base_model.rbs +7 -2
- data/sig/modern_treasury/internal/type/boolean.rbs +5 -2
- data/sig/modern_treasury/internal/type/converter.rbs +15 -5
- data/sig/modern_treasury/internal/type/enum.rbs +7 -2
- data/sig/modern_treasury/internal/type/hash_of.rbs +7 -2
- data/sig/modern_treasury/internal/type/io_like.rbs +23 -0
- data/sig/modern_treasury/internal/type/union.rbs +7 -2
- data/sig/modern_treasury/internal/type/unknown.rbs +5 -2
- data/sig/modern_treasury/internal/util.rbs +19 -2
- data/sig/modern_treasury/internal.rbs +1 -1
- data/sig/modern_treasury/models/document_create_params.rbs +3 -3
- data/sig/modern_treasury/models/payment_order_create_params.rbs +3 -3
- data/sig/modern_treasury/resources/documents.rbs +1 -1
- metadata +8 -2
@@ -58,9 +58,9 @@ module ModernTreasury
|
|
58
58
|
#
|
59
59
|
# @return [Boolean]
|
60
60
|
def ==(other)
|
61
|
-
# rubocop:disable
|
62
|
-
|
63
|
-
# rubocop:enable
|
61
|
+
# rubocop:disable Style/CaseEquality
|
62
|
+
ModernTreasury::Internal::Type::Enum === other && other.values.to_set == values.to_set
|
63
|
+
# rubocop:enable Style/CaseEquality
|
64
64
|
end
|
65
65
|
|
66
66
|
# @api private
|
@@ -97,8 +97,28 @@ module ModernTreasury
|
|
97
97
|
# #
|
98
98
|
# # @param value [Symbol, Object]
|
99
99
|
# #
|
100
|
+
# # @param state [Hash{Symbol=>Object}] .
|
101
|
+
# #
|
102
|
+
# # @option state [Boolean] :can_retry
|
103
|
+
# #
|
100
104
|
# # @return [Symbol, Object]
|
101
|
-
# def dump(value) = super
|
105
|
+
# def dump(value, state:) = super
|
106
|
+
|
107
|
+
# @api private
|
108
|
+
#
|
109
|
+
# @param depth [Integer]
|
110
|
+
#
|
111
|
+
# @return [String]
|
112
|
+
def inspect(depth: 0)
|
113
|
+
if depth.positive?
|
114
|
+
return is_a?(Module) ? super() : self.class.name
|
115
|
+
end
|
116
|
+
|
117
|
+
members = values.map { ModernTreasury::Internal::Type::Converter.inspect(_1, depth: depth.succ) }
|
118
|
+
prefix = is_a?(Module) ? name : self.class.name
|
119
|
+
|
120
|
+
"#{prefix}[#{members.join(' | ')}]"
|
121
|
+
end
|
102
122
|
end
|
103
123
|
end
|
104
124
|
end
|
@@ -13,6 +13,10 @@ module ModernTreasury
|
|
13
13
|
class HashOf
|
14
14
|
include ModernTreasury::Internal::Type::Converter
|
15
15
|
|
16
|
+
private_class_method :new
|
17
|
+
|
18
|
+
# @overload [](type_info, spec = {})
|
19
|
+
#
|
16
20
|
# @param type_info [Hash{Symbol=>Object}, Proc, ModernTreasury::Internal::Type::Converter, Class]
|
17
21
|
#
|
18
22
|
# @param spec [Hash{Symbol=>Object}] .
|
@@ -24,7 +28,7 @@ module ModernTreasury
|
|
24
28
|
# @option spec [Proc] :union
|
25
29
|
#
|
26
30
|
# @option spec [Boolean] :"nil?"
|
27
|
-
def self.[](
|
31
|
+
def self.[](...) = new(...)
|
28
32
|
|
29
33
|
# @param other [Object]
|
30
34
|
#
|
@@ -99,12 +103,16 @@ module ModernTreasury
|
|
99
103
|
#
|
100
104
|
# @param value [Hash{Object=>Object}, Object]
|
101
105
|
#
|
106
|
+
# @param state [Hash{Symbol=>Object}] .
|
107
|
+
#
|
108
|
+
# @option state [Boolean] :can_retry
|
109
|
+
#
|
102
110
|
# @return [Hash{Symbol=>Object}, Object]
|
103
|
-
def dump(value)
|
111
|
+
def dump(value, state:)
|
104
112
|
target = item_type
|
105
113
|
if value.is_a?(Hash)
|
106
114
|
value.transform_values do
|
107
|
-
ModernTreasury::Internal::Type::Converter.dump(target, _1)
|
115
|
+
ModernTreasury::Internal::Type::Converter.dump(target, _1, state: state)
|
108
116
|
end
|
109
117
|
else
|
110
118
|
super
|
@@ -136,7 +144,18 @@ module ModernTreasury
|
|
136
144
|
# @option spec [Boolean] :"nil?"
|
137
145
|
def initialize(type_info, spec = {})
|
138
146
|
@item_type_fn = ModernTreasury::Internal::Type::Converter.type_info(type_info || spec)
|
139
|
-
@nilable = spec
|
147
|
+
@nilable = spec.fetch(:nil?, false)
|
148
|
+
end
|
149
|
+
|
150
|
+
# @api private
|
151
|
+
#
|
152
|
+
# @param depth [Integer]
|
153
|
+
#
|
154
|
+
# @return [String]
|
155
|
+
def inspect(depth: 0)
|
156
|
+
items = ModernTreasury::Internal::Type::Converter.inspect(item_type, depth: depth.succ)
|
157
|
+
|
158
|
+
"#{self.class}[#{[items, nilable? ? 'nil' : nil].compact.join(' | ')}]"
|
140
159
|
end
|
141
160
|
end
|
142
161
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ModernTreasury
|
4
|
+
module Internal
|
5
|
+
module Type
|
6
|
+
# @api private
|
7
|
+
#
|
8
|
+
# @abstract
|
9
|
+
#
|
10
|
+
# Either `Pathname` or `StringIO`.
|
11
|
+
class IOLike
|
12
|
+
extend ModernTreasury::Internal::Type::Converter
|
13
|
+
|
14
|
+
private_class_method :new
|
15
|
+
|
16
|
+
# @param other [Object]
|
17
|
+
#
|
18
|
+
# @return [Boolean]
|
19
|
+
def self.===(other)
|
20
|
+
case other
|
21
|
+
in StringIO | Pathname | IO
|
22
|
+
true
|
23
|
+
else
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param other [Object]
|
29
|
+
#
|
30
|
+
# @return [Boolean]
|
31
|
+
def self.==(other) = other.is_a?(Class) && other <= ModernTreasury::Internal::Type::IOLike
|
32
|
+
|
33
|
+
class << self
|
34
|
+
# @api private
|
35
|
+
#
|
36
|
+
# @param value [StringIO, String, Object]
|
37
|
+
#
|
38
|
+
# @param state [Hash{Symbol=>Object}] .
|
39
|
+
#
|
40
|
+
# @option state [Boolean, :strong] :strictness
|
41
|
+
#
|
42
|
+
# @option state [Hash{Symbol=>Object}] :exactness
|
43
|
+
#
|
44
|
+
# @option state [Integer] :branched
|
45
|
+
#
|
46
|
+
# @return [StringIO, Object]
|
47
|
+
def coerce(value, state:)
|
48
|
+
exactness = state.fetch(:exactness)
|
49
|
+
case value
|
50
|
+
in String
|
51
|
+
exactness[:yes] += 1
|
52
|
+
StringIO.new(value)
|
53
|
+
in StringIO
|
54
|
+
exactness[:yes] += 1
|
55
|
+
value
|
56
|
+
else
|
57
|
+
exactness[:no] += 1
|
58
|
+
value
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# @!parse
|
63
|
+
# # @api private
|
64
|
+
# #
|
65
|
+
# # @param value [Pathname, StringIO, IO, String, Object]
|
66
|
+
# #
|
67
|
+
# # @param state [Hash{Symbol=>Object}] .
|
68
|
+
# #
|
69
|
+
# # @option state [Boolean] :can_retry
|
70
|
+
# #
|
71
|
+
# # @return [Pathname, StringIO, IO, String, Object]
|
72
|
+
# def dump(value, state:) = super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -26,9 +26,18 @@ module ModernTreasury
|
|
26
26
|
#
|
27
27
|
# @return [Array(Object, Hash{Symbol=>Object})]
|
28
28
|
def dump_request(params)
|
29
|
-
|
29
|
+
state = {can_retry: true}
|
30
|
+
case (dumped = dump(params, state: state))
|
30
31
|
in Hash
|
31
|
-
|
32
|
+
options = ModernTreasury::Internal::Util.coerce_hash(dumped[:request_options])
|
33
|
+
request_options =
|
34
|
+
case [options, state.fetch(:can_retry)]
|
35
|
+
in [Hash | nil, false]
|
36
|
+
{**options.to_h, max_retries: 0}
|
37
|
+
else
|
38
|
+
options
|
39
|
+
end
|
40
|
+
[dumped.except(:request_options), request_options]
|
32
41
|
else
|
33
42
|
[dumped, nil]
|
34
43
|
end
|
@@ -111,9 +111,7 @@ module ModernTreasury
|
|
111
111
|
#
|
112
112
|
# @return [Boolean]
|
113
113
|
def ==(other)
|
114
|
-
|
115
|
-
other.is_a?(Module) && other.singleton_class <= ModernTreasury::Internal::Type::Union && other.derefed_variants == derefed_variants
|
116
|
-
# rubocop:enable Layout/LineLength
|
114
|
+
ModernTreasury::Internal::Type::Union === other && other.derefed_variants == derefed_variants
|
117
115
|
end
|
118
116
|
|
119
117
|
# @api private
|
@@ -176,15 +174,25 @@ module ModernTreasury
|
|
176
174
|
#
|
177
175
|
# @param value [Object]
|
178
176
|
#
|
177
|
+
# @param state [Hash{Symbol=>Object}] .
|
178
|
+
#
|
179
|
+
# @option state [Boolean] :can_retry
|
180
|
+
#
|
179
181
|
# @return [Object]
|
180
|
-
def dump(value)
|
182
|
+
def dump(value, state:)
|
181
183
|
if (target = resolve_variant(value))
|
182
|
-
return ModernTreasury::Internal::Type::Converter.dump(target, value)
|
184
|
+
return ModernTreasury::Internal::Type::Converter.dump(target, value, state: state)
|
183
185
|
end
|
184
186
|
|
185
187
|
known_variants.each do
|
186
188
|
target = _2.call
|
187
|
-
|
189
|
+
if target === value
|
190
|
+
return ModernTreasury::Internal::Type::Converter.dump(
|
191
|
+
target,
|
192
|
+
value,
|
193
|
+
state: state
|
194
|
+
)
|
195
|
+
end
|
188
196
|
end
|
189
197
|
|
190
198
|
super
|
@@ -192,6 +200,22 @@ module ModernTreasury
|
|
192
200
|
|
193
201
|
# rubocop:enable Style/CaseEquality
|
194
202
|
# rubocop:enable Style/HashEachMethods
|
203
|
+
|
204
|
+
# @api private
|
205
|
+
#
|
206
|
+
# @param depth [Integer]
|
207
|
+
#
|
208
|
+
# @return [String]
|
209
|
+
def inspect(depth: 0)
|
210
|
+
if depth.positive?
|
211
|
+
return is_a?(Module) ? super() : self.class.name
|
212
|
+
end
|
213
|
+
|
214
|
+
members = variants.map { ModernTreasury::Internal::Type::Converter.inspect(_1, depth: depth.succ) }
|
215
|
+
prefix = is_a?(Module) ? name : self.class.name
|
216
|
+
|
217
|
+
"#{prefix}[#{members.join(' | ')}]"
|
218
|
+
end
|
195
219
|
end
|
196
220
|
end
|
197
221
|
end
|
@@ -13,6 +13,8 @@ module ModernTreasury
|
|
13
13
|
|
14
14
|
# rubocop:disable Lint/UnusedMethodArgument
|
15
15
|
|
16
|
+
private_class_method :new
|
17
|
+
|
16
18
|
# @param other [Object]
|
17
19
|
#
|
18
20
|
# @return [Boolean]
|
@@ -47,8 +49,12 @@ module ModernTreasury
|
|
47
49
|
# #
|
48
50
|
# # @param value [Object]
|
49
51
|
# #
|
52
|
+
# # @param state [Hash{Symbol=>Object}] .
|
53
|
+
# #
|
54
|
+
# # @option state [Boolean] :can_retry
|
55
|
+
# #
|
50
56
|
# # @return [Object]
|
51
|
-
# def dump(value) = super
|
57
|
+
# def dump(value, state:) = super
|
52
58
|
end
|
53
59
|
|
54
60
|
# rubocop:enable Lint/UnusedMethodArgument
|
@@ -122,7 +122,7 @@ module ModernTreasury
|
|
122
122
|
# @return [Hash{Object=>Object}, Object]
|
123
123
|
def coerce_hash(input)
|
124
124
|
case input
|
125
|
-
in NilClass | Array | Set | Enumerator
|
125
|
+
in NilClass | Array | Set | Enumerator | StringIO | IO
|
126
126
|
input
|
127
127
|
else
|
128
128
|
input.respond_to?(:to_h) ? input.to_h : input
|
@@ -348,10 +348,47 @@ module ModernTreasury
|
|
348
348
|
end
|
349
349
|
end
|
350
350
|
|
351
|
+
# @api private
|
352
|
+
class SerializationAdapter
|
353
|
+
# @return [Pathname, IO]
|
354
|
+
attr_reader :inner
|
355
|
+
|
356
|
+
# @param a [Object]
|
357
|
+
#
|
358
|
+
# @return [String]
|
359
|
+
def to_json(*a) = (inner.is_a?(IO) ? inner.read : inner.read(binmode: true)).to_json(*a)
|
360
|
+
|
361
|
+
# @param a [Object]
|
362
|
+
#
|
363
|
+
# @return [String]
|
364
|
+
def to_yaml(*a) = (inner.is_a?(IO) ? inner.read : inner.read(binmode: true)).to_yaml(*a)
|
365
|
+
|
366
|
+
# @api private
|
367
|
+
#
|
368
|
+
# @param inner [Pathname, IO]
|
369
|
+
def initialize(inner) = @inner = inner
|
370
|
+
end
|
371
|
+
|
351
372
|
# @api private
|
352
373
|
#
|
353
374
|
# An adapter that satisfies the IO interface required by `::IO.copy_stream`
|
354
375
|
class ReadIOAdapter
|
376
|
+
# @api private
|
377
|
+
#
|
378
|
+
# @return [Boolean, nil]
|
379
|
+
def close? = @closing
|
380
|
+
|
381
|
+
# @api private
|
382
|
+
def close
|
383
|
+
case @stream
|
384
|
+
in Enumerator
|
385
|
+
ModernTreasury::Internal::Util.close_fused!(@stream)
|
386
|
+
in IO if close?
|
387
|
+
@stream.close
|
388
|
+
else
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
355
392
|
# @api private
|
356
393
|
#
|
357
394
|
# @param max_len [Integer, nil]
|
@@ -396,13 +433,22 @@ module ModernTreasury
|
|
396
433
|
|
397
434
|
# @api private
|
398
435
|
#
|
399
|
-
# @param
|
436
|
+
# @param src [String, Pathname, StringIO, Enumerable<String>]
|
400
437
|
# @param blk [Proc]
|
401
438
|
#
|
402
439
|
# @yieldparam [String]
|
403
|
-
def initialize(
|
404
|
-
@stream =
|
405
|
-
|
440
|
+
def initialize(src, &blk)
|
441
|
+
@stream =
|
442
|
+
case src
|
443
|
+
in String
|
444
|
+
StringIO.new(src)
|
445
|
+
in Pathname
|
446
|
+
@closing = true
|
447
|
+
src.open(binmode: true)
|
448
|
+
else
|
449
|
+
src
|
450
|
+
end
|
451
|
+
@buf = String.new
|
406
452
|
@blk = blk
|
407
453
|
end
|
408
454
|
end
|
@@ -414,9 +460,10 @@ module ModernTreasury
|
|
414
460
|
# @return [Enumerable<String>]
|
415
461
|
def writable_enum(&blk)
|
416
462
|
Enumerator.new do |y|
|
463
|
+
buf = String.new
|
417
464
|
y.define_singleton_method(:write) do
|
418
|
-
self << _1
|
419
|
-
|
465
|
+
self << buf.replace(_1)
|
466
|
+
buf.bytesize
|
420
467
|
end
|
421
468
|
|
422
469
|
blk.call(y)
|
@@ -431,29 +478,39 @@ module ModernTreasury
|
|
431
478
|
# @param boundary [String]
|
432
479
|
# @param key [Symbol, String]
|
433
480
|
# @param val [Object]
|
434
|
-
|
481
|
+
# @param closing [Array<Proc>]
|
482
|
+
private def write_multipart_chunk(y, boundary:, key:, val:, closing:)
|
483
|
+
val = val.inner if val.is_a?(ModernTreasury::Internal::Util::SerializationAdapter)
|
484
|
+
|
435
485
|
y << "--#{boundary}\r\n"
|
436
486
|
y << "Content-Disposition: form-data"
|
437
487
|
unless key.nil?
|
438
488
|
name = ERB::Util.url_encode(key.to_s)
|
439
489
|
y << "; name=\"#{name}\""
|
440
490
|
end
|
441
|
-
|
491
|
+
case val
|
492
|
+
in Pathname | IO
|
442
493
|
filename = ERB::Util.url_encode(File.basename(val.to_path))
|
443
494
|
y << "; filename=\"#{filename}\""
|
495
|
+
else
|
444
496
|
end
|
445
497
|
y << "\r\n"
|
446
498
|
case val
|
499
|
+
in Pathname
|
500
|
+
y << "Content-Type: application/octet-stream\r\n\r\n"
|
501
|
+
io = val.open(binmode: true)
|
502
|
+
closing << io.method(:close)
|
503
|
+
IO.copy_stream(io, y)
|
447
504
|
in IO
|
448
505
|
y << "Content-Type: application/octet-stream\r\n\r\n"
|
449
|
-
IO.copy_stream(val
|
506
|
+
IO.copy_stream(val, y)
|
450
507
|
in StringIO
|
451
508
|
y << "Content-Type: application/octet-stream\r\n\r\n"
|
452
509
|
y << val.string
|
453
510
|
in String
|
454
511
|
y << "Content-Type: application/octet-stream\r\n\r\n"
|
455
512
|
y << val.to_s
|
456
|
-
in
|
513
|
+
in _ if primitive?(val)
|
457
514
|
y << "Content-Type: text/plain\r\n\r\n"
|
458
515
|
y << val.to_s
|
459
516
|
else
|
@@ -471,6 +528,7 @@ module ModernTreasury
|
|
471
528
|
private def encode_multipart_streaming(body)
|
472
529
|
boundary = SecureRandom.urlsafe_base64(60)
|
473
530
|
|
531
|
+
closing = []
|
474
532
|
strio = writable_enum do |y|
|
475
533
|
case body
|
476
534
|
in Hash
|
@@ -478,19 +536,20 @@ module ModernTreasury
|
|
478
536
|
case val
|
479
537
|
in Array if val.all? { primitive?(_1) }
|
480
538
|
val.each do |v|
|
481
|
-
write_multipart_chunk(y, boundary: boundary, key: key, val: v)
|
539
|
+
write_multipart_chunk(y, boundary: boundary, key: key, val: v, closing: closing)
|
482
540
|
end
|
483
541
|
else
|
484
|
-
write_multipart_chunk(y, boundary: boundary, key: key, val: val)
|
542
|
+
write_multipart_chunk(y, boundary: boundary, key: key, val: val, closing: closing)
|
485
543
|
end
|
486
544
|
end
|
487
545
|
else
|
488
|
-
write_multipart_chunk(y, boundary: boundary, key: nil, val: body)
|
546
|
+
write_multipart_chunk(y, boundary: boundary, key: nil, val: body, closing: closing)
|
489
547
|
end
|
490
548
|
y << "--#{boundary}--\r\n"
|
491
549
|
end
|
492
550
|
|
493
|
-
|
551
|
+
fused_io = fused_enum(strio) { closing.each(&:call) }
|
552
|
+
[boundary, fused_io]
|
494
553
|
end
|
495
554
|
|
496
555
|
# @api private
|
@@ -501,21 +560,21 @@ module ModernTreasury
|
|
501
560
|
# @return [Object]
|
502
561
|
def encode_content(headers, body)
|
503
562
|
content_type = headers["content-type"]
|
563
|
+
body = body.inner if body.is_a?(ModernTreasury::Internal::Util::SerializationAdapter)
|
564
|
+
|
504
565
|
case [content_type, body]
|
505
|
-
in [%r{^application/(?:vnd\.api\+)?json},
|
566
|
+
in [%r{^application/(?:vnd\.api\+)?json}, Hash | Array | -> { primitive?(_1) }]
|
506
567
|
[headers, JSON.fast_generate(body)]
|
507
|
-
in [%r{^application/(?:x-)?jsonl}, Enumerable]
|
568
|
+
in [%r{^application/(?:x-)?jsonl}, Enumerable] unless body.is_a?(StringIO) || body.is_a?(IO)
|
508
569
|
[headers, body.lazy.map { JSON.fast_generate(_1) }]
|
509
|
-
in [%r{^multipart/form-data}, Hash |
|
570
|
+
in [%r{^multipart/form-data}, Hash | Pathname | StringIO | IO]
|
510
571
|
boundary, strio = encode_multipart_streaming(body)
|
511
572
|
headers = {**headers, "content-type" => "#{content_type}; boundary=#{boundary}"}
|
512
573
|
[headers, strio]
|
513
|
-
in [_, IO]
|
514
|
-
[headers, body.tap(&:rewind)]
|
515
|
-
in [_, StringIO]
|
516
|
-
[headers, body.string]
|
517
574
|
in [_, Symbol | Numeric]
|
518
575
|
[headers, body.to_s]
|
576
|
+
in [_, StringIO]
|
577
|
+
[headers, body.string]
|
519
578
|
else
|
520
579
|
[headers, body]
|
521
580
|
end
|
@@ -523,6 +582,27 @@ module ModernTreasury
|
|
523
582
|
|
524
583
|
# @api private
|
525
584
|
#
|
585
|
+
# https://www.iana.org/assignments/character-sets/character-sets.xhtml
|
586
|
+
#
|
587
|
+
# @param content_type [String]
|
588
|
+
# @param text [String]
|
589
|
+
def force_charset!(content_type, text:)
|
590
|
+
charset = /charset=([^;\s]+)/.match(content_type)&.captures&.first
|
591
|
+
|
592
|
+
return unless charset
|
593
|
+
|
594
|
+
begin
|
595
|
+
encoding = Encoding.find(charset)
|
596
|
+
text.force_encoding(encoding)
|
597
|
+
rescue ArgumentError
|
598
|
+
nil
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
# @api private
|
603
|
+
#
|
604
|
+
# Assumes each chunk in stream has `Encoding::BINARY`.
|
605
|
+
#
|
526
606
|
# @param headers [Hash{String=>String}, Net::HTTPHeader]
|
527
607
|
# @param stream [Enumerable<String>]
|
528
608
|
# @param suppress_error [Boolean]
|
@@ -530,7 +610,7 @@ module ModernTreasury
|
|
530
610
|
# @raise [JSON::ParserError]
|
531
611
|
# @return [Object]
|
532
612
|
def decode_content(headers, stream:, suppress_error: false)
|
533
|
-
case headers["content-type"]
|
613
|
+
case (content_type = headers["content-type"])
|
534
614
|
in %r{^application/(?:vnd\.api\+)?json}
|
535
615
|
json = stream.to_a.join
|
536
616
|
begin
|
@@ -547,11 +627,10 @@ module ModernTreasury
|
|
547
627
|
in %r{^text/event-stream}
|
548
628
|
lines = decode_lines(stream)
|
549
629
|
decode_sse(lines)
|
550
|
-
in %r{^text/}
|
551
|
-
stream.to_a.join
|
552
630
|
else
|
553
|
-
|
554
|
-
|
631
|
+
text = stream.to_a.join
|
632
|
+
force_charset!(content_type, text: text)
|
633
|
+
StringIO.new(text)
|
555
634
|
end
|
556
635
|
end
|
557
636
|
end
|
@@ -616,12 +695,17 @@ module ModernTreasury
|
|
616
695
|
class << self
|
617
696
|
# @api private
|
618
697
|
#
|
698
|
+
# Assumes Strings have been forced into having `Encoding::BINARY`.
|
699
|
+
#
|
700
|
+
# This decoder is responsible for reassembling lines split across multiple
|
701
|
+
# fragments.
|
702
|
+
#
|
619
703
|
# @param enum [Enumerable<String>]
|
620
704
|
#
|
621
705
|
# @return [Enumerable<String>]
|
622
706
|
def decode_lines(enum)
|
623
707
|
re = /(\r\n|\r|\n)/
|
624
|
-
buffer = String.new
|
708
|
+
buffer = String.new
|
625
709
|
cr_seen = nil
|
626
710
|
|
627
711
|
chain_fused(enum) do |y|
|
@@ -652,6 +736,8 @@ module ModernTreasury
|
|
652
736
|
#
|
653
737
|
# https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream
|
654
738
|
#
|
739
|
+
# Assumes that `lines` has been decoded with `#decode_lines`.
|
740
|
+
#
|
655
741
|
# @param lines [Enumerable<String>]
|
656
742
|
#
|
657
743
|
# @return [Enumerable<Hash{Symbol=>Object}>]
|
@@ -675,7 +761,7 @@ module ModernTreasury
|
|
675
761
|
in "event"
|
676
762
|
current.merge!(event: value)
|
677
763
|
in "data"
|
678
|
-
(current[:data] ||= String.new
|
764
|
+
(current[:data] ||= String.new) << (value << "\n")
|
679
765
|
in "id" unless value.include?("\0")
|
680
766
|
current.merge!(id: value)
|
681
767
|
in "retry" if /^\d+$/ =~ value
|
@@ -21,8 +21,8 @@ module ModernTreasury
|
|
21
21
|
|
22
22
|
# @!attribute file
|
23
23
|
#
|
24
|
-
# @return [
|
25
|
-
required :file,
|
24
|
+
# @return [Pathname, StringIO]
|
25
|
+
required :file, ModernTreasury::Internal::Type::IOLike
|
26
26
|
|
27
27
|
# @!attribute [r] document_type
|
28
28
|
# A category given to the document, can be `null`.
|
@@ -37,7 +37,7 @@ module ModernTreasury
|
|
37
37
|
# @!parse
|
38
38
|
# # @param documentable_id [String]
|
39
39
|
# # @param documentable_type [Symbol, ModernTreasury::Models::DocumentCreateParams::DocumentableType]
|
40
|
-
# # @param file [
|
40
|
+
# # @param file [Pathname, StringIO]
|
41
41
|
# # @param document_type [String]
|
42
42
|
# # @param request_options [ModernTreasury::RequestOptions, Hash{Symbol=>Object}]
|
43
43
|
# #
|
@@ -496,8 +496,8 @@ module ModernTreasury
|
|
496
496
|
|
497
497
|
# @!attribute file
|
498
498
|
#
|
499
|
-
# @return [
|
500
|
-
required :file,
|
499
|
+
# @return [Pathname, StringIO]
|
500
|
+
required :file, ModernTreasury::Internal::Type::IOLike
|
501
501
|
|
502
502
|
# @!attribute [r] document_type
|
503
503
|
# A category given to the document, can be `null`.
|
@@ -512,7 +512,7 @@ module ModernTreasury
|
|
512
512
|
# @!parse
|
513
513
|
# # @param documentable_id [String]
|
514
514
|
# # @param documentable_type [Symbol, ModernTreasury::Models::PaymentOrderCreateParams::Document::DocumentableType]
|
515
|
-
# # @param file [
|
515
|
+
# # @param file [Pathname, StringIO]
|
516
516
|
# # @param document_type [String]
|
517
517
|
# #
|
518
518
|
# def initialize(documentable_id:, documentable_type:, file:, document_type: nil, **) = super
|
@@ -9,7 +9,7 @@ module ModernTreasury
|
|
9
9
|
#
|
10
10
|
# @param documentable_id [String]
|
11
11
|
# @param documentable_type [Symbol, ModernTreasury::Models::DocumentCreateParams::DocumentableType]
|
12
|
-
# @param file [
|
12
|
+
# @param file [Pathname, StringIO]
|
13
13
|
# @param document_type [String]
|
14
14
|
# @param request_options [ModernTreasury::RequestOptions, Hash{Symbol=>Object}, nil]
|
15
15
|
#
|
data/lib/modern_treasury.rb
CHANGED
@@ -40,6 +40,7 @@ require_relative "modern_treasury/internal/util"
|
|
40
40
|
require_relative "modern_treasury/internal/type/converter"
|
41
41
|
require_relative "modern_treasury/internal/type/unknown"
|
42
42
|
require_relative "modern_treasury/internal/type/boolean"
|
43
|
+
require_relative "modern_treasury/internal/type/io_like"
|
43
44
|
require_relative "modern_treasury/internal/type/enum"
|
44
45
|
require_relative "modern_treasury/internal/type/union"
|
45
46
|
require_relative "modern_treasury/internal/type/array_of"
|
@@ -160,8 +160,9 @@ module ModernTreasury
|
|
160
160
|
api_key: ENV["MODERN_TREASURY_API_KEY"],
|
161
161
|
# Defaults to `ENV["MODERN_TREASURY_ORGANIZATION_ID"]`
|
162
162
|
organization_id: ENV["MODERN_TREASURY_ORGANIZATION_ID"],
|
163
|
-
# Override the default base URL for the API, e.g.,
|
164
|
-
|
163
|
+
# Override the default base URL for the API, e.g.,
|
164
|
+
# `"https://api.example.com/v2/"`. Defaults to `ENV["MODERN_TREASURY_BASE_URL"]`
|
165
|
+
base_url: ENV["MODERN_TREASURY_BASE_URL"],
|
165
166
|
# Max number of retries to attempt after a failed retryable request.
|
166
167
|
max_retries: DEFAULT_MAX_RETRIES,
|
167
168
|
timeout: DEFAULT_TIMEOUT_IN_SECONDS,
|