workato-connector-sdk 1.1.0 → 1.3.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/README.md +3 -2
- data/VERSION +1 -0
- data/lib/workato/cli/edit_command.rb +3 -1
- data/lib/workato/cli/exec_command.rb +103 -17
- data/lib/workato/cli/generate_command.rb +2 -2
- data/lib/workato/cli/main.rb +17 -10
- data/lib/workato/cli/multi_auth_selected_fallback.rb +33 -0
- data/lib/workato/cli/oauth2_command.rb +50 -12
- data/lib/workato/cli/push_command.rb +2 -2
- data/lib/workato/cli/schema_command.rb +2 -2
- data/lib/workato/connector/sdk/account_properties.rb +2 -2
- data/lib/workato/connector/sdk/action.rb +20 -70
- data/lib/workato/connector/sdk/block_invocation_refinements.rb +2 -10
- data/lib/workato/connector/sdk/connection.rb +115 -30
- data/lib/workato/connector/sdk/connector.rb +71 -81
- data/lib/workato/connector/sdk/core.rb +62 -0
- data/lib/workato/connector/sdk/dsl/aws.rb +8 -5
- data/lib/workato/connector/sdk/dsl/call.rb +1 -1
- data/lib/workato/connector/sdk/dsl/csv_package.rb +133 -0
- data/lib/workato/connector/sdk/dsl/execution_context.rb +45 -0
- data/lib/workato/connector/sdk/dsl/http.rb +1 -1
- data/lib/workato/connector/sdk/dsl/reinvoke_after.rb +84 -0
- data/lib/workato/connector/sdk/dsl/stream_package.rb +65 -0
- data/lib/workato/connector/sdk/dsl/time.rb +0 -14
- data/lib/workato/connector/sdk/dsl/workato_package.rb +146 -0
- data/lib/workato/connector/sdk/dsl.rb +64 -10
- data/lib/workato/connector/sdk/errors.rb +37 -9
- data/lib/workato/connector/sdk/lookup_tables.rb +3 -1
- data/lib/workato/connector/sdk/operation.rb +33 -10
- data/lib/workato/connector/sdk/request.rb +149 -69
- data/lib/workato/connector/sdk/schema/field/convertors.rb +2 -2
- data/lib/workato/connector/sdk/schema/type/unicode_string.rb +1 -1
- data/lib/workato/connector/sdk/schema.rb +12 -8
- data/lib/workato/connector/sdk/settings.rb +14 -3
- data/lib/workato/connector/sdk/stream.rb +243 -0
- data/lib/workato/connector/sdk/streams.rb +71 -0
- data/lib/workato/connector/sdk/summarize.rb +2 -2
- data/lib/workato/connector/sdk/trigger.rb +23 -15
- data/lib/workato/connector/sdk/version.rb +1 -1
- data/lib/workato/connector/sdk.rb +21 -47
- data/lib/workato/extension/array.rb +2 -0
- data/lib/workato/extension/case_sensitive_headers.rb +0 -26
- data/lib/workato/extension/content_encoding_decoder.rb +69 -0
- data/lib/workato/extension/currency/countries.rb +79 -0
- data/lib/workato/extension/currency/countries.yml +18433 -0
- data/lib/workato/extension/currency/currencies.rb +55 -0
- data/lib/workato/extension/currency/currencies.yml +479 -0
- data/lib/workato/extension/currency.rb +73 -5
- data/lib/workato/extension/enumerable.rb +2 -2
- data/lib/workato/extension/extra_chain_cert.rb +0 -14
- data/lib/workato/extension/hash_with_indifferent_access.rb +19 -0
- data/lib/workato/extension/metadata_fix_wrap_kw_args.rb +11 -0
- data/lib/workato/extension/string.rb +16 -112
- data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +2 -0
- data/lib/workato/types/binary.rb +55 -0
- data/lib/workato/{connector/sdk → utilities}/xml.rb +4 -4
- metadata +61 -64
- data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +0 -160
@@ -0,0 +1,243 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
using Workato::Extension::HashWithIndifferentAccess
|
5
|
+
|
6
|
+
module Workato
|
7
|
+
module Connector
|
8
|
+
module Sdk
|
9
|
+
module SorbetTypes
|
10
|
+
StreamProc = T.type_alias do
|
11
|
+
T.proc.params(
|
12
|
+
input: SorbetTypes::StreamInputHash,
|
13
|
+
from: Integer,
|
14
|
+
to: Integer,
|
15
|
+
frame_size: Integer
|
16
|
+
).returns(SorbetTypes::StreamOutput)
|
17
|
+
end
|
18
|
+
|
19
|
+
StreamInProc = T.type_alias do
|
20
|
+
T.proc.params(
|
21
|
+
data: T.untyped,
|
22
|
+
from: Integer,
|
23
|
+
to: T.nilable(Integer),
|
24
|
+
eof: T::Boolean,
|
25
|
+
next_from: T.nilable(Integer)
|
26
|
+
).void
|
27
|
+
end
|
28
|
+
|
29
|
+
StreamInputHash = T.type_alias { T::Hash[T.any(Symbol, String), T.untyped] }
|
30
|
+
|
31
|
+
StreamOutput = T.type_alias { [T.untyped, T::Boolean] }
|
32
|
+
end
|
33
|
+
|
34
|
+
class Stream < Operation
|
35
|
+
extend T::Sig
|
36
|
+
|
37
|
+
DEFAULT_FRAME_SIZE = T.let(10.megabytes, Integer)
|
38
|
+
|
39
|
+
using BlockInvocationRefinements
|
40
|
+
include Dsl::ReinvokeAfter
|
41
|
+
|
42
|
+
sig do
|
43
|
+
params(
|
44
|
+
stream: SorbetTypes::StreamProc,
|
45
|
+
methods: SorbetTypes::SourceHash,
|
46
|
+
connection: Connection
|
47
|
+
).void
|
48
|
+
end
|
49
|
+
def initialize(stream:, methods: {}, connection: Connection.new)
|
50
|
+
super(methods: methods, connection: connection)
|
51
|
+
@stream_proc = stream
|
52
|
+
end
|
53
|
+
|
54
|
+
sig do
|
55
|
+
params(
|
56
|
+
input: SorbetTypes::StreamInputHash,
|
57
|
+
from: Integer,
|
58
|
+
to: Integer,
|
59
|
+
frame_size: Integer
|
60
|
+
).returns(SorbetTypes::StreamOutput)
|
61
|
+
end
|
62
|
+
def chunk(input = {}, from = 0, to = from + DEFAULT_FRAME_SIZE, frame_size = DEFAULT_FRAME_SIZE)
|
63
|
+
raise "'frame_size' must be a positive integer number" unless frame_size.positive?
|
64
|
+
|
65
|
+
stream_proc = @stream_proc
|
66
|
+
execute(nil, { input: input, from: from, to: to, size: frame_size }) do |_, input| # rubocop:disable Lint/ShadowingOuterLocalVariable
|
67
|
+
T.unsafe(self).instance_exec(input['input'], input['from'], input['to'], input['size'], &stream_proc)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
sig { params(input: SorbetTypes::StreamInputHash, frame_size: Integer).returns(T.untyped) }
|
72
|
+
def invoke(input = {}, frame_size = DEFAULT_FRAME_SIZE)
|
73
|
+
proxy = Proxy.new(name: '', input: input, stream: self)
|
74
|
+
reader = Reader.new(stream: proxy, frame_size: frame_size)
|
75
|
+
data = T.let(nil, T.untyped)
|
76
|
+
reader.each_chunk do |chunk|
|
77
|
+
data = data.nil? ? chunk : data + chunk
|
78
|
+
end
|
79
|
+
data
|
80
|
+
end
|
81
|
+
|
82
|
+
class Reader
|
83
|
+
extend T::Sig
|
84
|
+
|
85
|
+
ProxyReadProc = T.type_alias do
|
86
|
+
T.proc.params(
|
87
|
+
data: T.untyped,
|
88
|
+
from: Integer,
|
89
|
+
eof: T::Boolean,
|
90
|
+
next_from: T.nilable(Integer)
|
91
|
+
).void
|
92
|
+
end
|
93
|
+
|
94
|
+
sig do
|
95
|
+
params(
|
96
|
+
stream: T.any(Proxy, T::Hash[T.untyped, T.untyped], String),
|
97
|
+
from: T.nilable(Integer),
|
98
|
+
frame_size: T.nilable(Integer)
|
99
|
+
).void
|
100
|
+
end
|
101
|
+
def initialize(stream:, from: nil, frame_size: nil)
|
102
|
+
@stream = T.let(
|
103
|
+
stream.is_a?(Hash) && stream[:__stream__] ? from_mock(stream) : stream,
|
104
|
+
T.any(Proxy, Mock, T::Hash[T.untyped, T.untyped], String)
|
105
|
+
)
|
106
|
+
@from = T.let(from || 0, Integer)
|
107
|
+
@frame_size = T.let(frame_size || DEFAULT_FRAME_SIZE, Integer)
|
108
|
+
end
|
109
|
+
|
110
|
+
sig { params(_blk: SorbetTypes::StreamInProc).void }
|
111
|
+
def each_chunk(&_blk)
|
112
|
+
case @stream
|
113
|
+
when Proxy, Mock
|
114
|
+
@stream.read(from: @from, frame_size: @frame_size) do |chunk, from, eof, next_from|
|
115
|
+
yield(chunk, from, calculate_byte_to(chunk, from), eof, next_from)
|
116
|
+
end
|
117
|
+
when Hash
|
118
|
+
chunk = @stream[:data][@from..]
|
119
|
+
yield(chunk, @from, calculate_byte_to(chunk, @from), @stream[:eof], nil)
|
120
|
+
else
|
121
|
+
chunk = @stream[@from..]
|
122
|
+
yield(@stream[@from..], @from, calculate_byte_to(chunk, @from), true, nil)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
sig { params(chunk: T.untyped, from: Integer).returns(T.nilable(Integer)) }
|
129
|
+
def calculate_byte_to(chunk, from)
|
130
|
+
(chunk_size = chunk.try(:bytesize) || 0).zero? ? nil : from + chunk_size - 1
|
131
|
+
end
|
132
|
+
|
133
|
+
sig { params(hash: T::Hash[T.untyped, T.untyped]).returns(T.any(Proxy, Mock)) }
|
134
|
+
def from_mock(hash)
|
135
|
+
case hash[:chunks]
|
136
|
+
when Proc
|
137
|
+
Proxy.new(
|
138
|
+
name: hash[:name],
|
139
|
+
input: HashWithIndifferentAccess.wrap(hash[:input] || {}),
|
140
|
+
stream: Stream.new(
|
141
|
+
stream: hash[:chunks],
|
142
|
+
connection: Connection.new(
|
143
|
+
connection: hash[:connection] || {},
|
144
|
+
settings: hash[:settings] || {}
|
145
|
+
)
|
146
|
+
)
|
147
|
+
)
|
148
|
+
when Hash
|
149
|
+
Mock.new(chunks: hash[:chunks])
|
150
|
+
else
|
151
|
+
raise 'Mock streams with Proc or Hash. Read spec/examples/stream/connector_spec.rb for examples'
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class Proxy
|
157
|
+
extend T::Sig
|
158
|
+
|
159
|
+
sig { params(name: String, input: SorbetTypes::StreamInputHash, stream: Stream).void }
|
160
|
+
def initialize(name:, input:, stream:)
|
161
|
+
@name = name
|
162
|
+
@input = input
|
163
|
+
@stream = stream
|
164
|
+
end
|
165
|
+
|
166
|
+
sig { params(_options: T.untyped).returns(T::Hash[String, T.untyped]) }
|
167
|
+
def as_json(_options = nil)
|
168
|
+
{
|
169
|
+
__stream__: true,
|
170
|
+
name: name,
|
171
|
+
input: input
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
sig { params(from: Integer, frame_size: Integer, _blk: Reader::ProxyReadProc).void }
|
176
|
+
def read(from:, frame_size:, &_blk)
|
177
|
+
next_from = from
|
178
|
+
loop do
|
179
|
+
res = read_chunk(next_from, frame_size)
|
180
|
+
yield(res.data, res.from, res.eof, res.next_from)
|
181
|
+
break if res.eof
|
182
|
+
|
183
|
+
next_from = T.must(res.next_from)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
private
|
188
|
+
|
189
|
+
sig { returns(String) }
|
190
|
+
attr_reader :name
|
191
|
+
|
192
|
+
sig { returns(SorbetTypes::StreamInputHash) }
|
193
|
+
attr_reader :input
|
194
|
+
|
195
|
+
class Chunk < T::Struct
|
196
|
+
const :data, T.untyped
|
197
|
+
const :from, Integer
|
198
|
+
const :eof, T::Boolean
|
199
|
+
const :next_from, T.nilable(Integer)
|
200
|
+
end
|
201
|
+
private_constant :Chunk
|
202
|
+
|
203
|
+
sig { params(from: Integer, frame_size: Integer).returns(Chunk) }
|
204
|
+
def read_chunk(from, frame_size)
|
205
|
+
data, eof = @stream.chunk(input, from, from + frame_size - 1, frame_size)
|
206
|
+
next_from = from + (data&.length || 0)
|
207
|
+
next_from = nil if eof
|
208
|
+
Chunk.new(data: data, from: from, eof: eof, next_from: next_from)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
class Mock
|
213
|
+
extend T::Sig
|
214
|
+
|
215
|
+
sig { params(chunks: T.untyped).void }
|
216
|
+
def initialize(chunks:)
|
217
|
+
@chunks = chunks
|
218
|
+
end
|
219
|
+
|
220
|
+
sig { params(from: Integer, frame_size: Integer, _blk: Reader::ProxyReadProc).void }
|
221
|
+
def read(from:, frame_size:, &_blk)
|
222
|
+
last_from = chunks.keys.last
|
223
|
+
chunks.each do |chunk_from, data|
|
224
|
+
next if chunk_from < from
|
225
|
+
|
226
|
+
eof = chunk_from == last_from
|
227
|
+
next_from = eof ? nil : chunk_from + frame_size
|
228
|
+
|
229
|
+
yield(data, chunk_from, eof, next_from)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
private
|
234
|
+
|
235
|
+
sig { returns(T.untyped) }
|
236
|
+
attr_reader :chunks
|
237
|
+
end
|
238
|
+
|
239
|
+
private_constant :Mock
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
using Workato::Extension::HashWithIndifferentAccess
|
5
|
+
|
6
|
+
module Workato
|
7
|
+
module Connector
|
8
|
+
module Sdk
|
9
|
+
class Streams
|
10
|
+
extend T::Sig
|
11
|
+
|
12
|
+
sig do
|
13
|
+
params(
|
14
|
+
streams: SorbetTypes::SourceHash,
|
15
|
+
methods: SorbetTypes::SourceHash,
|
16
|
+
connection: Connection
|
17
|
+
).void
|
18
|
+
end
|
19
|
+
def initialize(streams: {}, methods: {}, connection: Connection.new)
|
20
|
+
@methods_source = methods
|
21
|
+
@connection = connection
|
22
|
+
@streams = T.let({}, T::Hash[T.any(Symbol, String), Stream])
|
23
|
+
@streams_source = streams
|
24
|
+
define_action_methods(streams)
|
25
|
+
end
|
26
|
+
|
27
|
+
sig { params(stream: T.any(String, Symbol)).returns(Stream) }
|
28
|
+
def [](stream)
|
29
|
+
@streams[stream] ||= Stream.new(
|
30
|
+
stream: @streams_source.fetch(stream),
|
31
|
+
methods: methods_source,
|
32
|
+
connection: connection
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
sig { params(streams_source: SorbetTypes::SourceHash).void }
|
39
|
+
def define_action_methods(streams_source)
|
40
|
+
streams_source.each do |stream, _stream_proc|
|
41
|
+
define_singleton_method(stream) do |input = {}, from = 0, to = nil, frame_size = Stream::DEFAULT_FRAME_SIZE|
|
42
|
+
to ||= from + frame_size
|
43
|
+
self[stream].chunk(input, from, to, frame_size)
|
44
|
+
end
|
45
|
+
|
46
|
+
define_singleton_method("#{stream}!") do |input = {}, frame_size = Stream::DEFAULT_FRAME_SIZE|
|
47
|
+
self[stream].invoke(input, frame_size)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
sig { returns(SorbetTypes::SourceHash) }
|
53
|
+
attr_reader :methods_source
|
54
|
+
|
55
|
+
sig { returns(Connection) }
|
56
|
+
attr_reader :connection
|
57
|
+
end
|
58
|
+
|
59
|
+
class ProhibitedStreams < Streams
|
60
|
+
extend T::Sig
|
61
|
+
|
62
|
+
sig { void }
|
63
|
+
def initialize
|
64
|
+
@streams = Hash.new do
|
65
|
+
raise 'Streams are not available in this context. Access streams in actions or triggers'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -34,8 +34,8 @@ module Workato
|
|
34
34
|
attr_reader :paths
|
35
35
|
|
36
36
|
def above_summarization_limit?(candidate)
|
37
|
-
candidate.is_a?(::Array) && candidate.length > ARRAY_SUMMARIZATION_LIMIT ||
|
38
|
-
candidate.is_a?(::String) && candidate.length > STRING_SUMMARIZATION_LIMIT
|
37
|
+
(candidate.is_a?(::Array) && candidate.length > ARRAY_SUMMARIZATION_LIMIT) ||
|
38
|
+
(candidate.is_a?(::String) && candidate.length > STRING_SUMMARIZATION_LIMIT)
|
39
39
|
end
|
40
40
|
|
41
41
|
def apply_summarization_limit(summarized, steps)
|
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
require 'securerandom'
|
5
5
|
|
6
|
+
using Workato::Extension::HashWithIndifferentAccess
|
7
|
+
|
6
8
|
module Workato
|
7
9
|
module Connector
|
8
10
|
module Sdk
|
@@ -32,15 +34,18 @@ module Workato
|
|
32
34
|
trigger: SorbetTypes::SourceHash,
|
33
35
|
methods: SorbetTypes::SourceHash,
|
34
36
|
connection: Connection,
|
35
|
-
object_definitions: T.nilable(ObjectDefinitions)
|
37
|
+
object_definitions: T.nilable(ObjectDefinitions),
|
38
|
+
streams: Streams
|
36
39
|
).void
|
37
40
|
end
|
38
|
-
def initialize(trigger:, methods: {}, connection: Connection.new, object_definitions: nil
|
41
|
+
def initialize(trigger:, methods: {}, connection: Connection.new, object_definitions: nil,
|
42
|
+
streams: ProhibitedStreams.new)
|
39
43
|
super(
|
40
44
|
operation: trigger,
|
41
45
|
connection: connection,
|
42
46
|
methods: methods,
|
43
|
-
object_definitions: object_definitions
|
47
|
+
object_definitions: object_definitions,
|
48
|
+
streams: streams
|
44
49
|
)
|
45
50
|
end
|
46
51
|
|
@@ -66,7 +71,6 @@ module Workato
|
|
66
71
|
) do |connection, payload, eis, eos|
|
67
72
|
instance_exec(connection, payload[:input], payload[:closure], eis, eos, &poll_proc)
|
68
73
|
end
|
69
|
-
output.with_indifferent_access
|
70
74
|
output[:events] = Array.wrap(output[:events])
|
71
75
|
.reverse!
|
72
76
|
.map! { |event| ::Hash.try_convert(event) || event }
|
@@ -117,7 +121,7 @@ module Workato
|
|
117
121
|
headers: T::Hash[T.any(String, Symbol), T.untyped],
|
118
122
|
params: T::Hash[T.any(String, Symbol), T.untyped],
|
119
123
|
settings: T.nilable(SorbetTypes::SettingsHash),
|
120
|
-
webhook_subscribe_output: SorbetTypes::WebhookSubscribeOutputHash
|
124
|
+
webhook_subscribe_output: T.nilable(SorbetTypes::WebhookSubscribeOutputHash)
|
121
125
|
).returns(
|
122
126
|
SorbetTypes::WebhookNotificationOutputHash
|
123
127
|
)
|
@@ -133,16 +137,15 @@ module Workato
|
|
133
137
|
webhook_subscribe_output = {}
|
134
138
|
)
|
135
139
|
connection.merge_settings!(settings) if settings
|
136
|
-
output =
|
137
|
-
|
138
|
-
input.with_indifferent_access,
|
140
|
+
output = global_dsl_context.execute(
|
141
|
+
HashWithIndifferentAccess.wrap(input),
|
139
142
|
payload,
|
140
|
-
Array.wrap(extended_input_schema).map(
|
141
|
-
Array.wrap(extended_output_schema).map(
|
142
|
-
headers
|
143
|
-
params
|
143
|
+
Array.wrap(extended_input_schema).map { |i| HashWithIndifferentAccess.wrap(i) },
|
144
|
+
Array.wrap(extended_output_schema).map { |i| HashWithIndifferentAccess.wrap(i) },
|
145
|
+
HashWithIndifferentAccess.wrap(headers),
|
146
|
+
HashWithIndifferentAccess.wrap(params),
|
144
147
|
connection.settings,
|
145
|
-
webhook_subscribe_output
|
148
|
+
HashWithIndifferentAccess.wrap(webhook_subscribe_output),
|
146
149
|
&trigger[:webhook_notification]
|
147
150
|
)
|
148
151
|
if output.is_a?(::Array)
|
@@ -162,7 +165,7 @@ module Workato
|
|
162
165
|
SorbetTypes::WebhookSubscribeOutputHash
|
163
166
|
)
|
164
167
|
end
|
165
|
-
def webhook_subscribe(webhook_url = '', settings = nil, input = {}, recipe_id =
|
168
|
+
def webhook_subscribe(webhook_url = '', settings = nil, input = {}, recipe_id = recipe_id!)
|
166
169
|
webhook_subscribe_proc = trigger[:webhook_subscribe]
|
167
170
|
execute(settings, { input: input, webhook_url: webhook_url, recipe_id: recipe_id }) do |connection, payload|
|
168
171
|
instance_exec(
|
@@ -189,7 +192,7 @@ module Workato
|
|
189
192
|
payload: T::Hash[T.any(String, Symbol), T.untyped],
|
190
193
|
headers: T::Hash[T.any(String, Symbol), T.untyped],
|
191
194
|
params: T::Hash[T.any(String, Symbol), T.untyped],
|
192
|
-
webhook_subscribe_output: SorbetTypes::WebhookSubscribeOutputHash
|
195
|
+
webhook_subscribe_output: T.nilable(SorbetTypes::WebhookSubscribeOutputHash)
|
193
196
|
).returns(
|
194
197
|
T.any(SorbetTypes::WebhookNotificationOutputHash, SorbetTypes::PollOutputHash)
|
195
198
|
)
|
@@ -231,6 +234,11 @@ module Workato
|
|
231
234
|
def webhook_notification?
|
232
235
|
trigger[:webhook_notification].present?
|
233
236
|
end
|
237
|
+
|
238
|
+
sig { returns(Dsl::WithDsl) }
|
239
|
+
def global_dsl_context
|
240
|
+
Dsl::WithDsl.new(connection, streams)
|
241
|
+
end
|
234
242
|
end
|
235
243
|
end
|
236
244
|
end
|
@@ -2,48 +2,22 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'sorbet-runtime'
|
5
|
-
::Method.prepend(T::CompatibilityPatches::MethodExtensions)
|
6
|
-
|
7
|
-
module Workato
|
8
|
-
module Connector
|
9
|
-
module Sdk
|
10
|
-
DEFAULT_MASTER_KEY_ENV = 'WORKATO_CONNECTOR_MASTER_KEY'
|
11
|
-
DEFAULT_MASTER_KEY_PATH = 'master.key'
|
12
|
-
|
13
|
-
DEFAULT_CONNECTOR_PATH = 'connector.rb'
|
14
|
-
|
15
|
-
DEFAULT_SETTINGS_PATH = 'settings.yaml'
|
16
|
-
DEFAULT_ENCRYPTED_SETTINGS_PATH = 'settings.yaml.enc'
|
17
|
-
|
18
|
-
DEFAULT_ACCOUNT_PROPERTIES_PATH = 'account_properties.yaml'
|
19
|
-
DEFAULT_ENCRYPTED_ACCOUNT_PROPERTIES_PATH = 'account_properties.yaml.enc'
|
20
|
-
|
21
|
-
DEFAULT_LOOKUP_TABLES_PATH = 'lookup_tables.yaml'
|
22
|
-
|
23
|
-
DEFAULT_TIME_ZONE = 'Pacific Time (US & Canada)'
|
24
|
-
|
25
|
-
DEFAULT_SCHEMAS_PATH = 'workato_schemas.json'
|
26
|
-
|
27
|
-
WORKATO_API_EMAIL_ENV = 'WORKATO_API_EMAIL'
|
28
|
-
WORKATO_API_TOKEN_ENV = 'WORKATO_API_TOKEN'
|
29
|
-
|
30
|
-
WORKATO_BASE_URL_ENV = 'WORKATO_BASE_URL'
|
31
|
-
DEFAULT_WORKATO_BASE_URL = 'https://app.workato.com'
|
32
|
-
WORKATO_BASE_URL = T.let(ENV.fetch(WORKATO_BASE_URL_ENV, DEFAULT_WORKATO_BASE_URL), String)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
5
|
|
37
6
|
# Global libs and monkey patches
|
38
7
|
require 'active_support/all'
|
39
8
|
require 'active_support/json'
|
9
|
+
|
10
|
+
require_relative '../types/binary'
|
11
|
+
|
40
12
|
require_relative '../extension/array'
|
41
13
|
require_relative '../extension/case_sensitive_headers'
|
14
|
+
require_relative '../extension/content_encoding_decoder'
|
42
15
|
require_relative '../extension/currency'
|
43
16
|
require_relative '../extension/date'
|
44
17
|
require_relative '../extension/enumerable'
|
45
18
|
require_relative '../extension/extra_chain_cert'
|
46
19
|
require_relative '../extension/hash'
|
20
|
+
require_relative '../extension/hash_with_indifferent_access'
|
47
21
|
require_relative '../extension/integer'
|
48
22
|
require_relative '../extension/nil_class'
|
49
23
|
require_relative '../extension/object'
|
@@ -52,19 +26,19 @@ require_relative '../extension/string'
|
|
52
26
|
require_relative '../extension/symbol'
|
53
27
|
require_relative '../extension/time'
|
54
28
|
|
55
|
-
require_relative './sdk/
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
29
|
+
require_relative './sdk/core'
|
30
|
+
|
31
|
+
begin
|
32
|
+
tz = ENV.fetch('TZ', nil)
|
33
|
+
if tz.present? && tz != 'UTC'
|
34
|
+
warn "WARNING: TZ environment variable is set to '#{tz}'. Set TZ=UTC for consistency with Workato platform'"
|
35
|
+
else
|
36
|
+
ENV['TZ'] = 'UTC'
|
37
|
+
end
|
38
|
+
Time.zone = Workato::Connector::Sdk::DEFAULT_TIME_ZONE
|
39
|
+
rescue TZInfo::DataSourceNotFound
|
40
|
+
puts ''
|
41
|
+
puts "tzinfo-data is not present. Please install gem 'tzinfo-data' by 'gem install tzinfo-data'"
|
42
|
+
puts ''
|
43
|
+
exit!
|
44
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# typed: false
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require 'rest-client'
|
5
4
|
require 'net/http'
|
6
5
|
|
7
6
|
module Workato
|
@@ -22,31 +21,6 @@ module Workato
|
|
22
21
|
|
23
22
|
::Net::HTTPHeader.prepend Net::HTTPHeader
|
24
23
|
::Net::HTTPGenericRequest.prepend Net::HTTPHeader
|
25
|
-
|
26
|
-
module RestClient
|
27
|
-
module Request
|
28
|
-
attr_accessor :case_sensitive_headers
|
29
|
-
|
30
|
-
def processed_headers
|
31
|
-
return @processed_headers if case_sensitive_headers.blank?
|
32
|
-
return case_sensitive_headers if @processed_headers.blank?
|
33
|
-
|
34
|
-
@processed_headers.merge(case_sensitive_headers)
|
35
|
-
end
|
36
|
-
|
37
|
-
def execute(&block)
|
38
|
-
# With 2.0.0+, net/http accepts URI objects in requests and handles wrapping
|
39
|
-
# IPv6 addresses in [] for use in the Host request header.
|
40
|
-
net_http_request = net_http_request_class(method).new(uri, processed_headers)
|
41
|
-
net_http_request.case_sensitive_headers = case_sensitive_headers
|
42
|
-
transmit(uri, net_http_request, payload, &block)
|
43
|
-
ensure
|
44
|
-
payload&.close
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
::RestClient::Request.prepend RestClient::Request
|
50
24
|
end
|
51
25
|
end
|
52
26
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'rest-client'
|
5
|
+
|
6
|
+
module Workato
|
7
|
+
module Extension
|
8
|
+
module ContentEncodingDecoder
|
9
|
+
module RestClient
|
10
|
+
module Response
|
11
|
+
def create(body, net_http_res, request, start_time)
|
12
|
+
body = decode_content_encoding(net_http_res, body)
|
13
|
+
super(body, net_http_res, request, start_time)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def decode_content_encoding(response, body)
|
19
|
+
content_encoding = response['content-encoding']
|
20
|
+
|
21
|
+
case content_encoding&.downcase
|
22
|
+
when 'deflate', 'gzip', 'x-gzip'
|
23
|
+
response.delete 'content-encoding'
|
24
|
+
return body if body.blank?
|
25
|
+
|
26
|
+
deflate_string(body).force_encoding(Encoding.default_external)
|
27
|
+
when 'none', 'identity'
|
28
|
+
response.delete 'content-encoding'
|
29
|
+
body
|
30
|
+
else
|
31
|
+
body
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def deflate_string(body)
|
36
|
+
# Decodes all deflate, gzip or x-gzip
|
37
|
+
zstream = Zlib::Inflate.new(Zlib::MAX_WBITS + 32)
|
38
|
+
|
39
|
+
zstream.inflate(body) + zstream.finish
|
40
|
+
rescue Zlib::DataError
|
41
|
+
# No luck with Zlib decompression. Let's try with raw deflate,
|
42
|
+
# like some broken web servers do. This part isn't compatible with Net::HTTP content-decoding
|
43
|
+
zstream.close
|
44
|
+
|
45
|
+
zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
46
|
+
zstream.inflate(body) + zstream.finish
|
47
|
+
ensure
|
48
|
+
zstream.close
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
::RestClient::Response.singleton_class.prepend(RestClient::Response)
|
54
|
+
|
55
|
+
::RestClient::Request.prepend(
|
56
|
+
Module.new do
|
57
|
+
def default_headers
|
58
|
+
# Should pass this header to be compatible with rest-client 2.0.2 version
|
59
|
+
# and rely on decode_content_encoding patch
|
60
|
+
# since net/http does not decompress response body if Content-Range is specified
|
61
|
+
# (see https://github.com/ruby/ruby/blob/27f6ad737b13062339df0a0c80449cf0dbc92ba5/lib/net/http/response.rb#L254)
|
62
|
+
# while the previous version of rest-client does.
|
63
|
+
super.tap { |headers| headers[:accept_encoding] = 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3' }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|