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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/VERSION +1 -0
  4. data/lib/workato/cli/edit_command.rb +3 -1
  5. data/lib/workato/cli/exec_command.rb +103 -17
  6. data/lib/workato/cli/generate_command.rb +2 -2
  7. data/lib/workato/cli/main.rb +17 -10
  8. data/lib/workato/cli/multi_auth_selected_fallback.rb +33 -0
  9. data/lib/workato/cli/oauth2_command.rb +50 -12
  10. data/lib/workato/cli/push_command.rb +2 -2
  11. data/lib/workato/cli/schema_command.rb +2 -2
  12. data/lib/workato/connector/sdk/account_properties.rb +2 -2
  13. data/lib/workato/connector/sdk/action.rb +20 -70
  14. data/lib/workato/connector/sdk/block_invocation_refinements.rb +2 -10
  15. data/lib/workato/connector/sdk/connection.rb +115 -30
  16. data/lib/workato/connector/sdk/connector.rb +71 -81
  17. data/lib/workato/connector/sdk/core.rb +62 -0
  18. data/lib/workato/connector/sdk/dsl/aws.rb +8 -5
  19. data/lib/workato/connector/sdk/dsl/call.rb +1 -1
  20. data/lib/workato/connector/sdk/dsl/csv_package.rb +133 -0
  21. data/lib/workato/connector/sdk/dsl/execution_context.rb +45 -0
  22. data/lib/workato/connector/sdk/dsl/http.rb +1 -1
  23. data/lib/workato/connector/sdk/dsl/reinvoke_after.rb +84 -0
  24. data/lib/workato/connector/sdk/dsl/stream_package.rb +65 -0
  25. data/lib/workato/connector/sdk/dsl/time.rb +0 -14
  26. data/lib/workato/connector/sdk/dsl/workato_package.rb +146 -0
  27. data/lib/workato/connector/sdk/dsl.rb +64 -10
  28. data/lib/workato/connector/sdk/errors.rb +37 -9
  29. data/lib/workato/connector/sdk/lookup_tables.rb +3 -1
  30. data/lib/workato/connector/sdk/operation.rb +33 -10
  31. data/lib/workato/connector/sdk/request.rb +149 -69
  32. data/lib/workato/connector/sdk/schema/field/convertors.rb +2 -2
  33. data/lib/workato/connector/sdk/schema/type/unicode_string.rb +1 -1
  34. data/lib/workato/connector/sdk/schema.rb +12 -8
  35. data/lib/workato/connector/sdk/settings.rb +14 -3
  36. data/lib/workato/connector/sdk/stream.rb +243 -0
  37. data/lib/workato/connector/sdk/streams.rb +71 -0
  38. data/lib/workato/connector/sdk/summarize.rb +2 -2
  39. data/lib/workato/connector/sdk/trigger.rb +23 -15
  40. data/lib/workato/connector/sdk/version.rb +1 -1
  41. data/lib/workato/connector/sdk.rb +21 -47
  42. data/lib/workato/extension/array.rb +2 -0
  43. data/lib/workato/extension/case_sensitive_headers.rb +0 -26
  44. data/lib/workato/extension/content_encoding_decoder.rb +69 -0
  45. data/lib/workato/extension/currency/countries.rb +79 -0
  46. data/lib/workato/extension/currency/countries.yml +18433 -0
  47. data/lib/workato/extension/currency/currencies.rb +55 -0
  48. data/lib/workato/extension/currency/currencies.yml +479 -0
  49. data/lib/workato/extension/currency.rb +73 -5
  50. data/lib/workato/extension/enumerable.rb +2 -2
  51. data/lib/workato/extension/extra_chain_cert.rb +0 -14
  52. data/lib/workato/extension/hash_with_indifferent_access.rb +19 -0
  53. data/lib/workato/extension/metadata_fix_wrap_kw_args.rb +11 -0
  54. data/lib/workato/extension/string.rb +16 -112
  55. data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +2 -0
  56. data/lib/workato/types/binary.rb +55 -0
  57. data/lib/workato/{connector/sdk → utilities}/xml.rb +4 -4
  58. metadata +61 -64
  59. 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 = Dsl::WithDsl.execute(
137
- connection,
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(&:with_indifferent_access),
141
- Array.wrap(extended_output_schema).map(&:with_indifferent_access),
142
- headers.with_indifferent_access,
143
- params.with_indifferent_access,
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.with_indifferent_access,
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 = SecureRandom.uuid)
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
@@ -4,7 +4,7 @@
4
4
  module Workato
5
5
  module Connector
6
6
  module Sdk
7
- VERSION = '1.1.0'
7
+ VERSION = T.let(File.read(File.expand_path('../../../../VERSION', __dir__)).strip, String)
8
8
  end
9
9
  end
10
10
  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/account_properties'
56
- require_relative './sdk/action'
57
- require_relative './sdk/connection'
58
- require_relative './sdk/connector'
59
- require_relative './sdk/dsl'
60
- require_relative './sdk/errors'
61
- require_relative './sdk/lookup_tables'
62
- require_relative './sdk/object_definitions'
63
- require_relative './sdk/operation'
64
- require_relative './sdk/request'
65
- require_relative './sdk/settings'
66
- require_relative './sdk/summarize'
67
- require_relative './sdk/trigger'
68
- require_relative './sdk/version'
69
- require_relative './sdk/workato_schemas'
70
- require_relative './sdk/xml'
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,6 +1,8 @@
1
1
  # typed: false
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'delegate'
5
+
4
6
  module Workato
5
7
  module Extension
6
8
  module Array
@@ -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