workato-connector-sdk 1.2.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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/VERSION +1 -0
  4. data/lib/workato/cli/edit_command.rb +3 -1
  5. data/lib/workato/cli/exec_command.rb +76 -10
  6. data/lib/workato/cli/generate_command.rb +2 -2
  7. data/lib/workato/cli/main.rb +17 -10
  8. data/lib/workato/cli/oauth2_command.rb +4 -4
  9. data/lib/workato/cli/push_command.rb +2 -2
  10. data/lib/workato/cli/schema_command.rb +2 -2
  11. data/lib/workato/connector/sdk/account_properties.rb +2 -2
  12. data/lib/workato/connector/sdk/action.rb +20 -70
  13. data/lib/workato/connector/sdk/block_invocation_refinements.rb +2 -10
  14. data/lib/workato/connector/sdk/connection.rb +36 -19
  15. data/lib/workato/connector/sdk/connector.rb +65 -77
  16. data/lib/workato/connector/sdk/core.rb +62 -0
  17. data/lib/workato/connector/sdk/dsl/aws.rb +3 -3
  18. data/lib/workato/connector/sdk/dsl/call.rb +1 -1
  19. data/lib/workato/connector/sdk/dsl/csv_package.rb +133 -0
  20. data/lib/workato/connector/sdk/dsl/execution_context.rb +1 -0
  21. data/lib/workato/connector/sdk/dsl/http.rb +1 -1
  22. data/lib/workato/connector/sdk/dsl/reinvoke_after.rb +84 -0
  23. data/lib/workato/connector/sdk/dsl/stream_package.rb +65 -0
  24. data/lib/workato/connector/sdk/dsl/time.rb +0 -14
  25. data/lib/workato/connector/sdk/dsl/workato_package.rb +146 -0
  26. data/lib/workato/connector/sdk/dsl.rb +63 -10
  27. data/lib/workato/connector/sdk/errors.rb +28 -11
  28. data/lib/workato/connector/sdk/operation.rb +9 -2
  29. data/lib/workato/connector/sdk/request.rb +63 -25
  30. data/lib/workato/connector/sdk/schema/field/convertors.rb +2 -2
  31. data/lib/workato/connector/sdk/schema/type/unicode_string.rb +1 -1
  32. data/lib/workato/connector/sdk/schema.rb +7 -5
  33. data/lib/workato/connector/sdk/settings.rb +10 -1
  34. data/lib/workato/connector/sdk/stream.rb +243 -0
  35. data/lib/workato/connector/sdk/streams.rb +71 -0
  36. data/lib/workato/connector/sdk/summarize.rb +2 -2
  37. data/lib/workato/connector/sdk/trigger.rb +14 -7
  38. data/lib/workato/connector/sdk/version.rb +1 -1
  39. data/lib/workato/connector/sdk.rb +19 -46
  40. data/lib/workato/extension/array.rb +2 -0
  41. data/lib/workato/extension/case_sensitive_headers.rb +0 -1
  42. data/lib/workato/extension/content_encoding_decoder.rb +2 -0
  43. data/lib/workato/extension/currency/countries.rb +79 -0
  44. data/lib/workato/extension/currency/countries.yml +18433 -0
  45. data/lib/workato/extension/currency/currencies.rb +55 -0
  46. data/lib/workato/extension/currency/currencies.yml +479 -0
  47. data/lib/workato/extension/currency.rb +73 -5
  48. data/lib/workato/extension/enumerable.rb +2 -2
  49. data/lib/workato/extension/metadata_fix_wrap_kw_args.rb +11 -0
  50. data/lib/workato/extension/string.rb +14 -111
  51. data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +2 -0
  52. data/lib/workato/types/binary.rb +55 -0
  53. metadata +46 -61
  54. data/lib/workato/connector/sdk/dsl/csv.rb +0 -125
  55. data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +0 -167
@@ -7,6 +7,7 @@ require 'json'
7
7
  require 'gyoku'
8
8
  require 'net/http'
9
9
  require 'net/http/digest_auth'
10
+ require 'active_support/json'
10
11
 
11
12
  require 'workato/utilities/encoding'
12
13
  require 'workato/utilities/xml'
@@ -37,18 +38,20 @@ module Workato
37
38
  @callstack_before_request = Array.wrap(Kernel.caller)
38
39
  end
39
40
 
40
- def method_missing(*args, &block)
41
- execute!.send(*args, &block)
41
+ def method_missing(...)
42
+ execute!.send(...)
42
43
  end
43
44
 
44
45
  def execute!
45
46
  __getobj__ || __setobj__(response)
47
+ rescue RestClient::Exceptions::Timeout => e
48
+ Kernel.raise RequestTimeoutError, e
46
49
  rescue RestClient::Exception => e
47
50
  if after_error_response_matches?(e)
48
51
  return apply_after_error_response(e)
49
52
  end
50
53
 
51
- Kernel.raise RequestError.new(
54
+ Kernel.raise RequestFailedError.new(
52
55
  response: e.response,
53
56
  message: e.message,
54
57
  method: current_verb,
@@ -250,8 +253,8 @@ module Workato
250
253
  ::Kernel.puts(*args)
251
254
  end
252
255
 
253
- def try(*args, &block)
254
- execute!.try(*args, &block)
256
+ def try(...)
257
+ execute!.try(...)
255
258
  end
256
259
 
257
260
  private
@@ -275,9 +278,9 @@ module Workato
275
278
  request = RestClientRequest.new(rest_request_params)
276
279
  response = execute_request(request)
277
280
  end
278
- detect_error!(response.body)
281
+ detect_auth_error!(response.body)
279
282
  parsed_response = @parse_response.call(response)
280
- detect_error!(parsed_response)
283
+ detect_auth_error!(parsed_response)
281
284
  apply_after_response(response.code, parsed_response, response.headers)
282
285
  end
283
286
  end
@@ -322,7 +325,7 @@ module Workato
322
325
 
323
326
  def build_url
324
327
  uri = if @base_uri
325
- URI.parse(@base_uri).merge(@uri)
328
+ merge_uris(@base_uri, @uri)
326
329
  else
327
330
  URI.parse(@uri)
328
331
  end
@@ -347,9 +350,13 @@ module Workato
347
350
  uri.to_s
348
351
  end
349
352
 
353
+ def merge_uris(uri1, uri2)
354
+ (uri1.is_a?(::String) ? URI.parse(uri1) : uri1).merge(uri2)
355
+ end
356
+
350
357
  def build_headers
351
358
  headers = @headers
352
- if @content_type_header.present? && headers.keys.none? { |key| /^content[\-_]type$/i =~ key }
359
+ if @content_type_header.present? && headers.keys.none? { |key| /^content[-_]type$/i =~ key }
353
360
  headers[:content_type] = @content_type_header
354
361
  end
355
362
  if @accept_header && headers.keys.none? { |key| /^accept$/i =~ key }
@@ -358,13 +365,13 @@ module Workato
358
365
  headers.compact
359
366
  end
360
367
 
361
- def detect_error!(response)
368
+ def detect_auth_error!(response)
362
369
  return unless authorized?
363
370
 
364
371
  error_patterns = connection.authorization.detect_on
365
372
  return unless error_patterns.any? { |pattern| pattern === response rescue false }
366
373
 
367
- Kernel.raise(CustomRequestError, response.to_s)
374
+ Kernel.raise(DetectOnUnauthorizedRequestError, response.to_s)
368
375
  end
369
376
 
370
377
  def after_error_response_matches?(exception)
@@ -399,8 +406,8 @@ module Workato
399
406
  within_action_context(code, parsed_response, encoded_headers, &@after_response)
400
407
  end
401
408
 
402
- def within_action_context(*args, &block)
403
- (@action || self).instance_exec(*args, &block)
409
+ def within_action_context(...)
410
+ (@action || self).instance_exec(...)
404
411
  end
405
412
 
406
413
  sig { returns(T::Boolean) }
@@ -418,14 +425,14 @@ module Workato
418
425
  begin
419
426
  settings = connection.settings
420
427
  if connection.authorization.oauth2?
421
- instance_exec(settings, settings[:access_token], @auth_type, &apply)
428
+ apply_oauth2(settings, settings[:access_token], @auth_type, &apply)
422
429
  else
423
- instance_exec(settings, @auth_type, &apply)
430
+ apply_custom_auth(settings, @auth_type, &apply)
424
431
  end
425
432
  yield
426
- rescue RestClient::Exception, CustomRequestError => e
433
+ rescue RestClient::Exception, DetectOnUnauthorizedRequestError => e
427
434
  Kernel.raise e unless first
428
- Kernel.raise e unless refresh_authorization!(e.try(:http_code), e.try(:http_body), e.message)
435
+ Kernel.raise e unless refresh_authorization!(settings, e.try(:http_code), e.try(:http_body), e.message)
429
436
 
430
437
  first = false
431
438
  retry
@@ -434,16 +441,49 @@ module Workato
434
441
 
435
442
  sig do
436
443
  params(
444
+ settings: HashWithIndifferentAccess,
445
+ access_token: T.untyped,
446
+ auth_type: T.untyped,
447
+ apply_proc: T.proc.params(
448
+ settings: HashWithIndifferentAccess,
449
+ access_token: T.untyped,
450
+ auth_type: T.untyped
451
+ ).void
452
+ ).void
453
+ end
454
+ def apply_oauth2(settings, access_token, auth_type, &apply_proc)
455
+ instance_exec(settings, access_token, auth_type, &apply_proc)
456
+ end
457
+
458
+ sig do
459
+ params(
460
+ settings: HashWithIndifferentAccess,
461
+ auth_type: T.untyped,
462
+ apply_proc: T.proc.params(
463
+ settings: HashWithIndifferentAccess,
464
+ auth_type: T.untyped
465
+ ).void
466
+ ).void
467
+ end
468
+ def apply_custom_auth(settings, auth_type, &apply_proc)
469
+ instance_exec(settings, auth_type, &apply_proc)
470
+ end
471
+
472
+ sig do
473
+ params(
474
+ settings_before: HashWithIndifferentAccess,
437
475
  http_code: T.nilable(Integer),
438
476
  http_body: T.nilable(String),
439
477
  exception: T.nilable(String)
440
478
  ).returns(T::Boolean)
441
479
  end
442
- def refresh_authorization!(http_code, http_body, exception)
480
+ def refresh_authorization!(settings_before, http_code, http_body, exception)
443
481
  return false unless connection.authorization.refresh?(http_code, http_body, exception)
444
482
 
445
- connection.update_settings!("Refresh token triggered on response \"#{exception}\"") do
446
- connection.authorization.refresh!(connection.settings)
483
+ connection.update_settings!("Refresh token triggered on response \"#{exception}\"", settings_before) do
484
+ next connection.settings unless connection.settings == settings_before
485
+
486
+ connection.authorization.refresh!(settings_before)
447
487
  end
448
488
  end
449
489
 
@@ -454,11 +494,9 @@ module Workato
454
494
 
455
495
  def lambda_with_error_wrap(error_type, &block)
456
496
  Kernel.lambda do |payload|
457
- begin
458
- block.call(payload)
459
- rescue StandardError => e
460
- Kernel.raise error_type.new(e)
461
- end
497
+ block.call(payload)
498
+ rescue StandardError => e
499
+ Kernel.raise error_type.new(e)
462
500
  end
463
501
  end
464
502
 
@@ -26,7 +26,7 @@ module Workato
26
26
  end
27
27
 
28
28
  def integer_conversion(value)
29
- value.try(:is_number?) && value.to_i || value
29
+ (value.try(:is_number?) && value.to_i) || value
30
30
  end
31
31
 
32
32
  def boolean_conversion(value)
@@ -34,7 +34,7 @@ module Workato
34
34
  end
35
35
 
36
36
  def float_conversion(value)
37
- value.try(:is_number?) && value.to_f || value
37
+ (value.try(:is_number?) && value.to_f) || value
38
38
  end
39
39
 
40
40
  def item_array_wrap(items)
@@ -8,7 +8,7 @@ module Workato
8
8
  module Type
9
9
  class UnicodeString < ::String
10
10
  def initialize(str)
11
- super(str, {})
11
+ super(str, **{})
12
12
  encode!('UTF-8')
13
13
  end
14
14
 
@@ -101,14 +101,14 @@ module Workato
101
101
  return Type::Time.from_date_time(value)
102
102
  when ::Date
103
103
  return value.to_date
104
- when ::Numeric, ::TrueClass, ::FalseClass, Workato::Extension::Binary, Type::UnicodeString,
105
- ::Array, ::Hash
104
+ when ::Numeric, ::TrueClass, ::FalseClass, Workato::Types::Binary, Type::UnicodeString,
105
+ ::Array, ::Hash, Stream::Proxy
106
106
  return value
107
107
  when Extension::Array::ArrayWhere
108
108
  return value.to_a
109
109
  when ::String
110
110
  if value.encoding == Encoding::ASCII_8BIT
111
- return Workato::Extension::Binary.new(value)
111
+ return Workato::Types::Binary.new(value)
112
112
  end
113
113
 
114
114
  return Type::UnicodeString.new(value)
@@ -119,7 +119,7 @@ module Workato
119
119
 
120
120
  if value.respond_to?(:read) && value.respond_to?(:rewind)
121
121
  value.rewind
122
- return Workato::Extension::Binary.new(value.read.force_encoding(Encoding::ASCII_8BIT))
122
+ return Workato::Types::Binary.new(value.read.force_encoding(Encoding::ASCII_8BIT))
123
123
  end
124
124
  end
125
125
 
@@ -178,7 +178,9 @@ module Workato
178
178
 
179
179
  def clean_values(field)
180
180
  field.transform_values! do |value|
181
- value.presence && (value.is_a?(::Symbol) && value.to_s || value)
181
+ next value if value.is_a?(FalseClass)
182
+
183
+ value.presence && ((value.is_a?(::Symbol) && value.to_s) || value)
182
184
  end
183
185
  field.compact!
184
186
  field
@@ -123,7 +123,7 @@ module Workato
123
123
  end
124
124
 
125
125
  def encrypted_configuration
126
- @encrypted_configuration ||= ActiveSupport::EncryptedConfiguration.new(
126
+ @encrypted_configuration ||= FixedEncryptedConfiguration.new(
127
127
  config_path: path,
128
128
  key_path: key_path || DEFAULT_MASTER_KEY_PATH,
129
129
  env_key: DEFAULT_MASTER_KEY_ENV,
@@ -135,6 +135,15 @@ module Workato
135
135
  YAML.dump(settings.to_hash)
136
136
  end
137
137
  end
138
+
139
+ class FixedEncryptedConfiguration < ActiveSupport::EncryptedConfiguration
140
+ private
141
+
142
+ def handle_missing_key
143
+ # Original methods incorectly passes constructor params
144
+ raise MissingKeyError.new(key_path: key_path, env_key: env_key) if raise_if_missing_key
145
+ end
146
+ end
138
147
  end
139
148
  end
140
149
  end
@@ -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)
@@ -34,15 +34,18 @@ module Workato
34
34
  trigger: SorbetTypes::SourceHash,
35
35
  methods: SorbetTypes::SourceHash,
36
36
  connection: Connection,
37
- object_definitions: T.nilable(ObjectDefinitions)
37
+ object_definitions: T.nilable(ObjectDefinitions),
38
+ streams: Streams
38
39
  ).void
39
40
  end
40
- 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)
41
43
  super(
42
44
  operation: trigger,
43
45
  connection: connection,
44
46
  methods: methods,
45
- object_definitions: object_definitions
47
+ object_definitions: object_definitions,
48
+ streams: streams
46
49
  )
47
50
  end
48
51
 
@@ -118,7 +121,7 @@ module Workato
118
121
  headers: T::Hash[T.any(String, Symbol), T.untyped],
119
122
  params: T::Hash[T.any(String, Symbol), T.untyped],
120
123
  settings: T.nilable(SorbetTypes::SettingsHash),
121
- webhook_subscribe_output: SorbetTypes::WebhookSubscribeOutputHash
124
+ webhook_subscribe_output: T.nilable(SorbetTypes::WebhookSubscribeOutputHash)
122
125
  ).returns(
123
126
  SorbetTypes::WebhookNotificationOutputHash
124
127
  )
@@ -134,8 +137,7 @@ module Workato
134
137
  webhook_subscribe_output = {}
135
138
  )
136
139
  connection.merge_settings!(settings) if settings
137
- output = Dsl::WithDsl.execute(
138
- connection,
140
+ output = global_dsl_context.execute(
139
141
  HashWithIndifferentAccess.wrap(input),
140
142
  payload,
141
143
  Array.wrap(extended_input_schema).map { |i| HashWithIndifferentAccess.wrap(i) },
@@ -190,7 +192,7 @@ module Workato
190
192
  payload: T::Hash[T.any(String, Symbol), T.untyped],
191
193
  headers: T::Hash[T.any(String, Symbol), T.untyped],
192
194
  params: T::Hash[T.any(String, Symbol), T.untyped],
193
- webhook_subscribe_output: SorbetTypes::WebhookSubscribeOutputHash
195
+ webhook_subscribe_output: T.nilable(SorbetTypes::WebhookSubscribeOutputHash)
194
196
  ).returns(
195
197
  T.any(SorbetTypes::WebhookNotificationOutputHash, SorbetTypes::PollOutputHash)
196
198
  )
@@ -232,6 +234,11 @@ module Workato
232
234
  def webhook_notification?
233
235
  trigger[:webhook_notification].present?
234
236
  end
237
+
238
+ sig { returns(Dsl::WithDsl) }
239
+ def global_dsl_context
240
+ Dsl::WithDsl.new(connection, streams)
241
+ end
235
242
  end
236
243
  end
237
244
  end
@@ -4,7 +4,7 @@
4
4
  module Workato
5
5
  module Connector
6
6
  module Sdk
7
- VERSION = '1.2.0'
7
+ VERSION = T.let(File.read(File.expand_path('../../../../VERSION', __dir__)).strip, String)
8
8
  end
9
9
  end
10
10
  end