workato-connector-sdk 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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,65 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Workato
5
+ module Connector
6
+ module Sdk
7
+ module Dsl
8
+ class StreamPackage
9
+ extend T::Sig
10
+
11
+ sig { params(streams: Streams, connection: Connection).void }
12
+ def initialize(streams:, connection:)
13
+ @streams = streams
14
+ @connection = connection
15
+ end
16
+
17
+ sig do
18
+ params(
19
+ stream: T.any(Stream::Proxy, String, T::Hash[T.untyped, T.untyped]),
20
+ from: T.nilable(Integer),
21
+ frame_size: T.nilable(Integer),
22
+ blk: SorbetTypes::StreamInProc
23
+ ).returns(T.untyped)
24
+ end
25
+ def in(stream, from: nil, frame_size: nil, &blk)
26
+ if stream.is_a?(Hash) && stream[:__stream__] && stream[:chunks].nil?
27
+ stream = out(stream[:name], stream[:input] || {})
28
+ end
29
+
30
+ Stream::Reader.new(
31
+ stream: stream,
32
+ from: from,
33
+ frame_size: frame_size
34
+ ).each_chunk do |chunk, byte_from, byte_to, eof, next_from|
35
+ blk.call(chunk, byte_from, byte_to, eof, next_from)
36
+ end
37
+ end
38
+
39
+ sig { params(stream_name: String, input: SorbetTypes::StreamInputHash).returns(Stream::Proxy) }
40
+ def out(stream_name, input = {})
41
+ Stream::Proxy.new(input: input, name: stream_name, stream: streams[stream_name])
42
+ end
43
+
44
+ private
45
+
46
+ T::Sig::WithoutRuntime.sig { params(symbol: T.any(String, Symbol), _args: T.untyped).void }
47
+ def method_missing(symbol, *_args)
48
+ raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato.stream')
49
+ end
50
+
51
+ T::Sig::WithoutRuntime.sig { params(_args: T.untyped).returns(T::Boolean) }
52
+ def respond_to_missing?(*_args)
53
+ false
54
+ end
55
+
56
+ sig { returns(Connection) }
57
+ attr_reader :connection
58
+
59
+ sig { returns(Streams) }
60
+ attr_reader :streams
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -18,17 +18,3 @@ module Workato
18
18
  end
19
19
  end
20
20
  end
21
-
22
- begin
23
- if ENV['TZ'].present? && ENV['TZ'] != 'UTC'
24
- warn "WARNING: TZ environment variable is set to '#{ENV['TZ']}'. Set TZ=UTC for consistency with Workato platform'"
25
- else
26
- ENV['TZ'] = 'UTC'
27
- end
28
- ::Time.zone = Workato::Connector::Sdk::DEFAULT_TIME_ZONE
29
- rescue TZInfo::DataSourceNotFound
30
- puts ''
31
- puts "tzinfo-data is not present. Please install gem 'tzinfo-data' by 'gem install tzinfo-data'"
32
- puts ''
33
- exit!
34
- end
@@ -0,0 +1,146 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require 'jwt'
5
+ require_relative './csv_package'
6
+ require_relative './stream_package'
7
+
8
+ using Workato::Extension::HashWithIndifferentAccess
9
+
10
+ module Workato
11
+ module Connector
12
+ module Sdk
13
+ module Dsl
14
+ class WorkatoPackage
15
+ JWT_ALGORITHMS = %w[RS256 RS384 RS512].freeze
16
+ JWT_RSA_KEY_MIN_LENGTH = 2048
17
+
18
+ VERIFY_RCA_ALGORITHMS = %w[SHA SHA1 SHA224 SHA256 SHA384 SHA512].freeze
19
+
20
+ def initialize(streams:, connection:)
21
+ @streams = streams
22
+ @connection = connection
23
+ end
24
+
25
+ def jwt_encode_rs256(payload, key, header_fields = {})
26
+ jwt_encode(payload, key, 'RS256', header_fields)
27
+ end
28
+
29
+ def jwt_encode(payload, key, algorithm, header_fields = {})
30
+ algorithm = algorithm.to_s.upcase
31
+ unless JWT_ALGORITHMS.include?(algorithm)
32
+ raise "Unsupported signing method. Supports only #{JWT_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
33
+ end
34
+
35
+ rsa_private = OpenSSL::PKey::RSA.new(key)
36
+ if rsa_private.n.num_bits < JWT_RSA_KEY_MIN_LENGTH
37
+ raise "A RSA key of size #{JWT_RSA_KEY_MIN_LENGTH} bits or larger MUST be used with JWT."
38
+ end
39
+
40
+ header_fields = HashWithIndifferentAccess.wrap(header_fields).except(:typ, :alg)
41
+ ::JWT.encode(payload, rsa_private, algorithm, header_fields)
42
+ end
43
+
44
+ def verify_rsa(payload, certificate, signature, algorithm = 'SHA256')
45
+ algorithm = algorithm.to_s.upcase
46
+ unless VERIFY_RCA_ALGORITHMS.include?(algorithm)
47
+ raise "Unsupported signing method. Supports only #{VERIFY_RCA_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
48
+ end
49
+
50
+ cert = OpenSSL::X509::Certificate.new(certificate)
51
+ digest = OpenSSL::Digest.new(algorithm)
52
+ cert.public_key.verify(digest, signature, payload)
53
+ rescue OpenSSL::PKey::PKeyError
54
+ raise 'An error occurred during signature verification. Check arguments'
55
+ rescue OpenSSL::X509::CertificateError
56
+ raise 'Invalid certificate format'
57
+ end
58
+
59
+ def parse_yaml(yaml)
60
+ ::Psych.safe_load(yaml)
61
+ rescue ::Psych::DisallowedClass => e
62
+ raise e.message
63
+ end
64
+
65
+ def render_yaml(obj)
66
+ ::Psych.dump(obj)
67
+ end
68
+
69
+ def parse_json(source)
70
+ JSON.parse(source)
71
+ rescue JSON::ParserError => e
72
+ raise JSONResponseFormatError, e
73
+ end
74
+
75
+ def uuid
76
+ SecureRandom.uuid
77
+ end
78
+
79
+ RANDOM_SIZE = 32
80
+
81
+ def random_bytes(len)
82
+ unless (len.is_a? ::Integer) && (len <= RANDOM_SIZE)
83
+ raise "The requested length or random bytes sequence should be <= #{RANDOM_SIZE}"
84
+ end
85
+
86
+ Types::Binary.new(::OpenSSL::Random.random_bytes(len))
87
+ end
88
+
89
+ ALLOWED_KEY_SIZES = [128, 192, 256].freeze
90
+
91
+ def aes_cbc_encrypt(string, key, init_vector = nil)
92
+ key_size = key.bytesize * 8
93
+ unless ALLOWED_KEY_SIZES.include?(key_size)
94
+ raise 'Incorrect key size for AES'
95
+ end
96
+
97
+ cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
98
+ cipher.encrypt
99
+ cipher.key = key
100
+ cipher.iv = init_vector if init_vector.present?
101
+ Types::Binary.new(cipher.update(string) + cipher.final)
102
+ end
103
+
104
+ def aes_cbc_decrypt(string, key, init_vector = nil)
105
+ key_size = key.bytesize * 8
106
+ unless ALLOWED_KEY_SIZES.include?(key_size)
107
+ raise 'Incorrect key size for AES'
108
+ end
109
+
110
+ cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
111
+ cipher.decrypt
112
+ cipher.key = key
113
+ cipher.iv = init_vector if init_vector.present?
114
+ Types::Binary.new(cipher.update(string) + cipher.final)
115
+ end
116
+
117
+ def pbkdf2_hmac_sha1(string, salt, iterations = 1000, key_len = 16)
118
+ Types::Binary.new(::OpenSSL::PKCS5.pbkdf2_hmac_sha1(string, salt, iterations, key_len))
119
+ end
120
+
121
+ def csv
122
+ @csv ||= CsvPackage.new
123
+ end
124
+
125
+ def stream
126
+ @stream ||= StreamPackage.new(streams: streams, connection: connection)
127
+ end
128
+
129
+ private
130
+
131
+ def method_missing(symbol, *_args)
132
+ raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato')
133
+ end
134
+
135
+ def respond_to_missing?(*)
136
+ false
137
+ end
138
+
139
+ attr_reader :streams
140
+
141
+ attr_reader :connection
142
+ end
143
+ end
144
+ end
145
+ end
146
+ end
@@ -5,25 +5,44 @@ require_relative './block_invocation_refinements'
5
5
 
6
6
  require_relative './dsl/http'
7
7
  require_relative './dsl/call'
8
+ require_relative './dsl/reinvoke_after'
8
9
  require_relative './dsl/error'
9
10
  require_relative './dsl/account_property'
10
11
  require_relative './dsl/lookup_table'
11
- require_relative './dsl/workato_code_lib'
12
+ require_relative './dsl/workato_package'
12
13
  require_relative './dsl/workato_schema'
13
14
  require_relative './dsl/time'
14
15
  require_relative './dsl/aws'
16
+ require_relative './dsl/execution_context'
15
17
 
16
18
  module Workato
17
19
  module Connector
18
20
  module Sdk
19
21
  module Dsl
20
22
  module Global
23
+ extend T::Sig
24
+ extend T::Helpers
25
+
26
+ abstract!
27
+
28
+ sig { abstract.returns(Streams) }
29
+ def streams; end
30
+
31
+ sig { abstract.returns(Connection) }
32
+ def connection; end
33
+
21
34
  include Time
22
35
  include AccountProperty
23
36
  include LookupTable
24
- include WorkatoCodeLib
25
37
  include WorkatoSchema
26
- include AWS
38
+
39
+ delegate :parse_json,
40
+ :uuid,
41
+ to: :workato
42
+
43
+ def workato
44
+ @workato ||= WorkatoPackage.new(streams: streams, connection: connection)
45
+ end
27
46
 
28
47
  def sleep(seconds)
29
48
  ::Kernel.sleep(seconds.presence || 0)
@@ -32,6 +51,39 @@ module Workato
32
51
  def puts(*args)
33
52
  T.unsafe(::Kernel).puts(*args)
34
53
  end
54
+
55
+ def encrypt(text, key)
56
+ ::Kernel.require('ruby_rncryptor')
57
+
58
+ enc_text = ::RubyRNCryptor.encrypt(text, key)
59
+ ::Base64.strict_encode64(enc_text)
60
+ end
61
+
62
+ def decrypt(text, key)
63
+ ::Kernel.require('ruby_rncryptor')
64
+
65
+ text = ::Base64.decode64(text)
66
+ dec_text = ::RubyRNCryptor.decrypt(text, key)
67
+ Workato::Types::Binary.new(dec_text)
68
+ rescue Exception => e # rubocop:disable Lint/RescueException
69
+ message = e.message.to_s
70
+ case message
71
+ when /Password may be incorrect/
72
+ ::Kernel.raise 'invalid/corrupt input or key'
73
+ when /RubyRNCryptor only decrypts version/
74
+ ::Kernel.raise 'invalid/corrupt input'
75
+ else
76
+ ::Kernel.raise
77
+ end
78
+ end
79
+
80
+ def blank; end
81
+
82
+ def clear; end
83
+
84
+ def null; end
85
+
86
+ def skip; end
35
87
  end
36
88
 
37
89
  class WithDsl
@@ -41,21 +93,23 @@ module Workato
41
93
 
42
94
  using BlockInvocationRefinements
43
95
 
44
- sig { params(connection: Connection, args: T.untyped, block: T.untyped).returns(T.untyped) }
45
- def execute(connection, *args, &block)
96
+ sig { params(connection: Connection, streams: Streams).void }
97
+ def initialize(connection = Connection.new, streams = ProhibitedStreams.new)
46
98
  @connection = connection
47
- T.unsafe(self).instance_exec(*args, &block)
99
+ @streams = streams
48
100
  end
49
101
 
50
- sig { params(connection: Connection, args: T.untyped, block: T.untyped).returns(T.untyped) }
51
- def self.execute(connection, *args, &block)
52
- T.unsafe(WithDsl.new).execute(connection, *args, &block)
102
+ def execute(...)
103
+ T.unsafe(self).instance_exec(...)
53
104
  end
54
105
 
55
106
  private
56
107
 
57
- sig { returns(Connection) }
108
+ sig { override.returns(Connection) }
58
109
  attr_reader :connection
110
+
111
+ sig { override.returns(Streams) }
112
+ attr_reader :streams
59
113
  end
60
114
  end
61
115
  end
@@ -4,7 +4,13 @@
4
4
  module Workato
5
5
  module Connector
6
6
  module Sdk
7
- InvalidDefinitionError = Class.new(StandardError)
7
+ Error = Class.new(StandardError)
8
+
9
+ DetectOnUnauthorizedRequestError = Class.new(Error)
10
+
11
+ RuntimeError = Class.new(Error)
12
+
13
+ InvalidDefinitionError = Class.new(Error)
8
14
 
9
15
  class UnexpectedMethodDefinitionError < InvalidDefinitionError
10
16
  attr_reader :name
@@ -28,11 +34,18 @@ module Workato
28
34
 
29
35
  InvalidSchemaError = Class.new(InvalidDefinitionError)
30
36
 
31
- CustomRequestError = Class.new(StandardError)
37
+ InvalidMultiAuthDefinition = Class.new(InvalidDefinitionError)
38
+
39
+ class UnresolvedMultiAuthOptionError < InvalidMultiAuthDefinition
40
+ attr_reader :name
32
41
 
33
- RuntimeError = Class.new(StandardError)
42
+ def initialize(name)
43
+ super("Cannot find multi-auth definition for '#{name}'")
44
+ @name = name
45
+ end
46
+ end
34
47
 
35
- class UnresolvedObjectDefinitionError < StandardError
48
+ class UnresolvedObjectDefinitionError < InvalidDefinitionError
36
49
  attr_reader :name
37
50
 
38
51
  def initialize(name)
@@ -41,7 +54,7 @@ module Workato
41
54
  end
42
55
  end
43
56
 
44
- class CircleReferenceObjectDefinitionError < StandardError
57
+ class CircleReferenceObjectDefinitionError < InvalidDefinitionError
45
58
  attr_reader :name
46
59
 
47
60
  def initialize(name, backtrace = [])
@@ -51,7 +64,11 @@ module Workato
51
64
  end
52
65
  end
53
66
 
54
- class RequestError < StandardError
67
+ RequestError = Class.new(RuntimeError)
68
+
69
+ RequestTimeoutError = Class.new(RequestError)
70
+
71
+ class RequestFailedError < RequestError
55
72
  attr_reader :method
56
73
  attr_reader :code
57
74
  attr_reader :response
@@ -70,7 +87,7 @@ module Workato
70
87
  end
71
88
  end
72
89
 
73
- class MissingRequiredInput < StandardError
90
+ class MissingRequiredInput < RuntimeError
74
91
  def initialize(label, toggle_label)
75
92
  message = if toggle_label && label != toggle_label
76
93
  "Either '#{label}' or '#{toggle_label}' must be present"
@@ -81,9 +98,9 @@ module Workato
81
98
  end
82
99
  end
83
100
 
84
- RequestTLSCertificateFormatError = Class.new(StandardError)
101
+ RequestTLSCertificateFormatError = Class.new(RequestError)
85
102
 
86
- RequestPayloadFormatError = Class.new(StandardError)
103
+ RequestPayloadFormatError = Class.new(RequestError)
87
104
 
88
105
  JSONRequestFormatError = Class.new(RequestPayloadFormatError)
89
106
 
@@ -98,6 +115,17 @@ module Workato
98
115
  MultipartFormRequestFormatError = Class.new(RequestPayloadFormatError)
99
116
 
100
117
  RAWResponseFormatError = Class.new(RequestPayloadFormatError)
118
+
119
+ class UndefinedStdLibMethodError < RuntimeError
120
+ attr_reader :name
121
+ attr_reader :package
122
+
123
+ def initialize(name, package)
124
+ @name = name
125
+ @package = package
126
+ super("Undefined method '#{name}' for \"#{package}\" namespace")
127
+ end
128
+ end
101
129
  end
102
130
  end
103
131
  end
@@ -4,6 +4,8 @@
4
4
  require 'csv'
5
5
  require 'singleton'
6
6
 
7
+ using Workato::Extension::HashWithIndifferentAccess
8
+
7
9
  module Workato
8
10
  module Connector
9
11
  module Sdk
@@ -40,7 +42,7 @@ module Workato
40
42
  @table_by_id ||= {}
41
43
  @table_by_name ||= {}
42
44
  data.each do |name, table|
43
- table = table.with_indifferent_access
45
+ table = HashWithIndifferentAccess.wrap(table)
44
46
  rows = table['rows'].freeze
45
47
  @table_by_id[table['id'].to_i] = rows
46
48
  @table_by_name[name] = rows
@@ -5,6 +5,8 @@ require_relative './dsl'
5
5
  require_relative './block_invocation_refinements'
6
6
  require_relative './schema'
7
7
 
8
+ using Workato::Extension::HashWithIndifferentAccess
9
+
8
10
  module Workato
9
11
  module Connector
10
12
  module Sdk
@@ -42,24 +44,32 @@ module Workato
42
44
  extend T::Sig
43
45
 
44
46
  include Dsl::Global
47
+ include Dsl::AWS
45
48
  include Dsl::HTTP
46
49
  include Dsl::Call
47
50
  include Dsl::Error
51
+ include Dsl::ExecutionContext
48
52
 
49
53
  using BlockInvocationRefinements
50
54
 
55
+ sig { override.returns(Streams) }
56
+ attr_reader :streams
57
+
51
58
  sig do
52
59
  params(
53
60
  operation: SorbetTypes::SourceHash,
54
61
  methods: SorbetTypes::SourceHash,
55
62
  connection: Connection,
63
+ streams: Streams,
56
64
  object_definitions: T.nilable(ObjectDefinitions)
57
65
  ).void
58
66
  end
59
- def initialize(operation: {}, methods: {}, connection: Connection.new, object_definitions: nil)
60
- @operation = T.let(operation.with_indifferent_access, HashWithIndifferentAccess)
61
- @_methods = T.let(methods.with_indifferent_access, HashWithIndifferentAccess)
67
+ def initialize(operation: {}, methods: {}, connection: Connection.new, streams: ProhibitedStreams.new,
68
+ object_definitions: nil)
69
+ @operation = T.let(HashWithIndifferentAccess.wrap(operation), HashWithIndifferentAccess)
70
+ @_methods = T.let(HashWithIndifferentAccess.wrap(methods), HashWithIndifferentAccess)
62
71
  @connection = T.let(connection, Connection)
72
+ @streams = T.let(streams, Streams)
63
73
  @object_definitions = T.let(object_definitions, T.nilable(ObjectDefinitions))
64
74
  end
65
75
 
@@ -80,13 +90,14 @@ module Workato
80
90
  connection.merge_settings!(settings) if settings
81
91
  request_or_result = T.unsafe(self).instance_exec(
82
92
  connection.settings,
83
- input.with_indifferent_access,
84
- Array.wrap(extended_input_schema).map(&:with_indifferent_access),
85
- Array.wrap(extended_output_schema).map(&:with_indifferent_access),
86
- continue.with_indifferent_access,
93
+ HashWithIndifferentAccess.wrap(input),
94
+ Array.wrap(extended_input_schema).map { |i| HashWithIndifferentAccess.wrap(i) },
95
+ Array.wrap(extended_output_schema).map { |i| HashWithIndifferentAccess.wrap(i) },
96
+ HashWithIndifferentAccess.wrap(continue),
87
97
  &block
88
98
  )
89
- resolve_request(request_or_result)
99
+ result = resolve_request(request_or_result)
100
+ try_convert_to_hash_with_indifferent_access(result)
90
101
  end
91
102
 
92
103
  sig do
@@ -225,7 +236,7 @@ module Workato
225
236
  end
226
237
  end
227
238
  when ::Hash
228
- request_or_result.inject(request_or_result.with_indifferent_access) do |acc, (key, value)|
239
+ request_or_result.inject(request_or_result) do |acc, (key, value)|
229
240
  response_value = resolve_request(value)
230
241
  if response_value.equal?(value)
231
242
  acc
@@ -238,6 +249,18 @@ module Workato
238
249
  end
239
250
  end
240
251
 
252
+ sig { params(value: T.untyped).returns(T.untyped) }
253
+ def try_convert_to_hash_with_indifferent_access(value)
254
+ case value
255
+ when ::Hash
256
+ HashWithIndifferentAccess.wrap(value)
257
+ when ::Array
258
+ value.map! { |i| try_convert_to_hash_with_indifferent_access(i) }
259
+ else
260
+ value
261
+ end
262
+ end
263
+
241
264
  sig { returns(ObjectDefinitions) }
242
265
  def object_definitions
243
266
  T.must(@object_definitions)
@@ -246,7 +269,7 @@ module Workato
246
269
  sig { returns(HashWithIndifferentAccess) }
247
270
  attr_reader :operation
248
271
 
249
- sig { returns(Connection) }
272
+ sig { override.returns(Connection) }
250
273
  attr_reader :connection
251
274
  end
252
275
  end