workato-connector-sdk 1.2.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +8 -0
  3. data/README.md +2 -6
  4. data/VERSION +1 -0
  5. data/lib/workato/cli/edit_command.rb +3 -1
  6. data/lib/workato/cli/exec_command.rb +76 -10
  7. data/lib/workato/cli/generate_command.rb +3 -2
  8. data/lib/workato/cli/main.rb +18 -10
  9. data/lib/workato/cli/oauth2_command.rb +4 -4
  10. data/lib/workato/cli/push_command.rb +23 -7
  11. data/lib/workato/cli/schema_command.rb +20 -6
  12. data/lib/workato/connector/sdk/account_properties.rb +3 -3
  13. data/lib/workato/connector/sdk/action.rb +20 -70
  14. data/lib/workato/connector/sdk/block_invocation_refinements.rb +4 -11
  15. data/lib/workato/connector/sdk/connection.rb +44 -21
  16. data/lib/workato/connector/sdk/connector.rb +73 -76
  17. data/lib/workato/connector/sdk/core.rb +62 -0
  18. data/lib/workato/connector/sdk/dsl/aws.rb +13 -3
  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/error.rb +2 -0
  22. data/lib/workato/connector/sdk/dsl/execution_context.rb +3 -0
  23. data/lib/workato/connector/sdk/dsl/http.rb +7 -2
  24. data/lib/workato/connector/sdk/dsl/reinvoke_after.rb +84 -0
  25. data/lib/workato/connector/sdk/dsl/stream_package.rb +59 -0
  26. data/lib/workato/connector/sdk/dsl/time.rb +0 -14
  27. data/lib/workato/connector/sdk/dsl/workato_package.rb +152 -0
  28. data/lib/workato/connector/sdk/dsl.rb +65 -10
  29. data/lib/workato/connector/sdk/errors.rb +28 -11
  30. data/lib/workato/connector/sdk/object_definitions.rb +59 -18
  31. data/lib/workato/connector/sdk/operation.rb +10 -3
  32. data/lib/workato/connector/sdk/request.rb +67 -26
  33. data/lib/workato/connector/sdk/schema/field/convertors.rb +2 -2
  34. data/lib/workato/connector/sdk/schema.rb +10 -7
  35. data/lib/workato/connector/sdk/settings.rb +13 -2
  36. data/lib/workato/connector/sdk/stream.rb +262 -0
  37. data/lib/workato/connector/sdk/streams.rb +72 -0
  38. data/lib/workato/connector/sdk/summarize.rb +4 -2
  39. data/lib/workato/connector/sdk/trigger.rb +14 -7
  40. data/lib/workato/connector/sdk/version.rb +1 -1
  41. data/lib/workato/connector/sdk.rb +20 -46
  42. data/lib/workato/extension/array.rb +2 -0
  43. data/lib/workato/extension/case_sensitive_headers.rb +0 -1
  44. data/lib/workato/extension/content_encoding_decoder.rb +2 -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/metadata_fix_wrap_kw_args.rb +11 -0
  52. data/lib/workato/extension/string.rb +23 -111
  53. data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +2 -0
  54. data/lib/workato/testing/vcr_multipart_body_matcher.rb +1 -0
  55. data/lib/workato/types/binary.rb +99 -0
  56. data/lib/workato/types/unicode_string.rb +62 -0
  57. metadata +34 -62
  58. data/lib/workato/connector/sdk/dsl/csv.rb +0 -125
  59. data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +0 -167
  60. data/lib/workato/connector/sdk/schema/type/unicode_string.rb +0 -23
@@ -0,0 +1,133 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require 'csv'
5
+
6
+ module Workato
7
+ module Connector
8
+ module Sdk
9
+ CsvError = Class.new(Sdk::RuntimeError)
10
+
11
+ CsvFormatError = Class.new(CsvError)
12
+
13
+ class CsvFileTooBigError < CsvError
14
+ extend T::Sig
15
+
16
+ sig { returns(Integer) }
17
+ attr_reader :size
18
+
19
+ sig { returns(Integer) }
20
+ attr_reader :max
21
+
22
+ sig { params(size: Integer, max: Integer).void }
23
+ def initialize(size, max)
24
+ super("CSV file is too big. Max allowed: #{max.to_s(:human_size)}, got: #{size.to_s(:human_size)}")
25
+ @size = T.let(size, Integer)
26
+ @max = T.let(max, Integer)
27
+ end
28
+ end
29
+
30
+ class CsvFileTooManyLinesError < CsvError
31
+ extend T::Sig
32
+
33
+ sig { returns(Integer) }
34
+ attr_reader :max
35
+
36
+ sig { params(max: Integer).void }
37
+ def initialize(max)
38
+ super("CSV file has too many lines. Max allowed: #{max}")
39
+ @max = T.let(max, Integer)
40
+ end
41
+ end
42
+
43
+ module Dsl
44
+ class CsvPackage
45
+ extend T::Sig
46
+
47
+ MAX_FILE_SIZE_FOR_PARSE = T.let(30.megabytes, Integer)
48
+ private_constant :MAX_FILE_SIZE_FOR_PARSE
49
+
50
+ MAX_LINES_FOR_PARSE = 65_000
51
+ private_constant :MAX_LINES_FOR_PARSE
52
+
53
+ sig do
54
+ params(
55
+ str: String,
56
+ headers: T.any(T::Boolean, T::Array[String], String),
57
+ col_sep: T.nilable(String),
58
+ row_sep: T.nilable(String),
59
+ quote_char: T.nilable(String),
60
+ skip_blanks: T.nilable(T::Boolean),
61
+ skip_first_line: T::Boolean
62
+ ).returns(
63
+ T::Array[T::Hash[String, T.untyped]]
64
+ )
65
+ end
66
+ def parse(str, headers:, col_sep: nil, row_sep: nil, quote_char: nil, skip_blanks: nil,
67
+ skip_first_line: false)
68
+ if str.bytesize > MAX_FILE_SIZE_FOR_PARSE
69
+ raise CsvFileTooBigError.new(str.bytesize, MAX_FILE_SIZE_FOR_PARSE)
70
+ end
71
+
72
+ index = 0
73
+ options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
74
+ skip_blanks: skip_blanks }.compact
75
+ Enumerator.new do |consumer|
76
+ CSV.parse(str, **options) do |row|
77
+ if index.zero? && skip_first_line
78
+ index += 1
79
+ next
80
+ end
81
+ if index == MAX_LINES_FOR_PARSE
82
+ raise CsvFileTooManyLinesError, MAX_LINES_FOR_PARSE
83
+ end
84
+
85
+ index += 1
86
+ consumer.yield(T.cast(row, CSV::Row).to_hash)
87
+ end
88
+ end.to_a
89
+ rescue CSV::MalformedCSVError => e
90
+ raise CsvFormatError, e
91
+ rescue ArgumentError => e
92
+ raise Sdk::RuntimeError, e.message
93
+ end
94
+
95
+ sig do
96
+ params(
97
+ str: T.nilable(String),
98
+ headers: T.nilable(T::Array[String]),
99
+ col_sep: T.nilable(String),
100
+ row_sep: T.nilable(String),
101
+ quote_char: T.nilable(String),
102
+ force_quotes: T.nilable(T::Boolean),
103
+ blk: T.proc.params(csv: CSV).void
104
+ ).returns(
105
+ String
106
+ )
107
+ end
108
+ def generate(str = nil, headers: nil, col_sep: nil, row_sep: nil, quote_char: nil, force_quotes: nil, &blk)
109
+ options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
110
+ force_quotes: force_quotes }.compact
111
+ options[:write_headers] = options[:headers].present?
112
+
113
+ ::CSV.generate(str || String.new, **options, &blk)
114
+ rescue ArgumentError => e
115
+ raise Sdk::RuntimeError, e.message
116
+ end
117
+
118
+ private
119
+
120
+ T::Sig::WithoutRuntime.sig { params(symbol: T.any(String, Symbol), _args: T.untyped).void }
121
+ def method_missing(symbol, *_args)
122
+ raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato.csv')
123
+ end
124
+
125
+ T::Sig::WithoutRuntime.sig { params(_args: T.untyped).returns(T::Boolean) }
126
+ def respond_to_missing?(*_args)
127
+ false
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -6,6 +6,8 @@ module Workato
6
6
  module Sdk
7
7
  module Dsl
8
8
  module Error
9
+ # @param message [String]
10
+ # @raise [Workato::Connector::Sdk::RuntimeError]
9
11
  def error(message)
10
12
  raise Sdk::RuntimeError, message
11
13
  end
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'securerandom'
5
+ require 'active_support/core_ext/class/attribute'
5
6
 
6
7
  module Workato
7
8
  module Connector
@@ -37,6 +38,8 @@ module Workato
37
38
  T.unsafe(self).recipe_id.reverse
38
39
  end
39
40
  end
41
+
42
+ private_constant :ClassMethods
40
43
  end
41
44
  end
42
45
  end
@@ -8,8 +8,13 @@ module Workato
8
8
  # https://docs.workato.com/developing-connectors/sdk/sdk-reference/http.html#http-methods
9
9
  module HTTP
10
10
  PARALLEL_SUCCESS_INDEX = 0
11
+ private_constant :PARALLEL_SUCCESS_INDEX
12
+
11
13
  PARALLEL_RESULTS_INDEX = 1
14
+ private_constant :PARALLEL_RESULTS_INDEX
15
+
12
16
  PARALLEL_ERRORS_INDEX = 2
17
+ private_constant :PARALLEL_ERRORS_INDEX
13
18
 
14
19
  def get(url, params = {})
15
20
  http_request(url, method: 'GET').params(params).response_format_json
@@ -52,8 +57,8 @@ module Workato
52
57
  response = nil
53
58
  exception = nil
54
59
  begin
55
- response = request.execute!
56
- rescue RequestError, RuntimeError => e
60
+ response = request.response!
61
+ rescue StandardError => e
57
62
  exception = e.to_s
58
63
  end
59
64
  result[PARALLEL_SUCCESS_INDEX] &&= exception.nil?
@@ -0,0 +1,84 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Workato
5
+ module Connector
6
+ module Sdk
7
+ module Dsl
8
+ module ReinvokeAfter
9
+ extend T::Sig
10
+
11
+ sig do
12
+ params(
13
+ continue: T::Hash[T.untyped, T.untyped],
14
+ temp_output: T.nilable(T::Hash[T.untyped, T.untyped])
15
+ ).void
16
+ end
17
+ def checkpoint!(continue:, temp_output: nil)
18
+ # no-op
19
+ end
20
+
21
+ sig do
22
+ params(
23
+ seconds: T.any(Integer, Float),
24
+ continue: T::Hash[T.untyped, T.untyped],
25
+ temp_output: T.nilable(T::Hash[T.untyped, T.untyped])
26
+ ).void
27
+ end
28
+ def reinvoke_after(seconds:, continue:, temp_output: nil) # rubocop:disable Lint/UnusedMethodArgument
29
+ Kernel.throw REINVOKE_AFTER_SIGNAL, ReinvokeParams.new(
30
+ seconds: seconds,
31
+ continue: continue
32
+ )
33
+ end
34
+
35
+ private
36
+
37
+ MAX_REINVOKES = 5
38
+ private_constant :MAX_REINVOKES
39
+
40
+ REINVOKE_AFTER_SIGNAL = :reinvoke_after
41
+ private_constant :REINVOKE_AFTER_SIGNAL
42
+
43
+ class ReinvokeParams < T::Struct
44
+ prop :seconds, T.any(Float, Integer)
45
+ prop :continue, T::Hash[T.untyped, T.untyped]
46
+ end
47
+ private_constant :ReinvokeParams
48
+
49
+ sig { params(continue: T::Hash[T.any(Symbol, String), T.untyped], _blk: Proc).returns(T.untyped) }
50
+ def loop_reinvoke_after(continue, &_blk)
51
+ reinvokes_remaining = T.let(reinvoke_limit, Integer)
52
+
53
+ Kernel.loop do
54
+ reinvoke_after = Kernel.catch(REINVOKE_AFTER_SIGNAL) do
55
+ return yield(continue)
56
+ end
57
+
58
+ if reinvokes_remaining.zero?
59
+ Kernel.raise "Max number of reinvokes on SDK Gem reached. Current limit is #{reinvoke_limit}"
60
+ end
61
+
62
+ reinvokes_remaining -= 1
63
+
64
+ reinvoke_after = T.cast(reinvoke_after, ReinvokeParams)
65
+ reinvoke_sleep(reinvoke_after.seconds)
66
+ continue = reinvoke_after.continue
67
+ end
68
+ end
69
+
70
+ sig { params(seconds: T.any(Float, Integer)).void }
71
+ def reinvoke_sleep(seconds)
72
+ Kernel.sleep((ENV['WAIT_REINVOKE_AFTER'].presence || seconds).to_f)
73
+ end
74
+
75
+ sig { returns(Integer) }
76
+ def reinvoke_limit
77
+ @reinvoke_limit = T.let(@reinvoke_limit, T.nilable(Integer))
78
+ @reinvoke_limit ||= (ENV['MAX_REINVOKES'].presence || MAX_REINVOKES).to_i
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,59 @@
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.each_chunk(stream: stream, from: from, frame_size: frame_size, &blk)
31
+ end
32
+
33
+ sig { params(stream_name: String, input: SorbetTypes::StreamInputHash).returns(Stream::Proxy) }
34
+ def out(stream_name, input = {})
35
+ Stream::Proxy.new(input: input, name: stream_name, stream: streams[stream_name])
36
+ end
37
+
38
+ private
39
+
40
+ T::Sig::WithoutRuntime.sig { params(symbol: T.any(String, Symbol), _args: T.untyped).void }
41
+ def method_missing(symbol, *_args)
42
+ raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato.stream')
43
+ end
44
+
45
+ T::Sig::WithoutRuntime.sig { params(_args: T.untyped).returns(T::Boolean) }
46
+ def respond_to_missing?(*_args)
47
+ false
48
+ end
49
+
50
+ sig { returns(Connection) }
51
+ attr_reader :connection
52
+
53
+ sig { returns(Streams) }
54
+ attr_reader :streams
55
+ end
56
+ end
57
+ end
58
+ end
59
+ 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,152 @@
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
+ private_constant :JWT_ALGORITHMS
17
+
18
+ JWT_RSA_KEY_MIN_LENGTH = 2048
19
+ private_constant :JWT_RSA_KEY_MIN_LENGTH
20
+
21
+ VERIFY_RCA_ALGORITHMS = %w[SHA SHA1 SHA224 SHA256 SHA384 SHA512].freeze
22
+ private_constant :VERIFY_RCA_ALGORITHMS
23
+
24
+ RANDOM_SIZE = 32
25
+ private_constant :RANDOM_SIZE
26
+
27
+ ALLOWED_KEY_SIZES = [128, 192, 256].freeze
28
+ private_constant :ALLOWED_KEY_SIZES
29
+
30
+ def initialize(streams:, connection:)
31
+ @streams = streams
32
+ @connection = connection
33
+ end
34
+
35
+ def jwt_encode_rs256(payload, key, header_fields = {})
36
+ jwt_encode(payload, key, 'RS256', header_fields)
37
+ end
38
+
39
+ def jwt_encode(payload, key, algorithm, header_fields = {})
40
+ algorithm = algorithm.to_s.upcase
41
+ unless JWT_ALGORITHMS.include?(algorithm)
42
+ raise "Unsupported signing method. Supports only #{JWT_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
43
+ end
44
+
45
+ rsa_private = OpenSSL::PKey::RSA.new(key)
46
+ if rsa_private.n.num_bits < JWT_RSA_KEY_MIN_LENGTH
47
+ raise "A RSA key of size #{JWT_RSA_KEY_MIN_LENGTH} bits or larger MUST be used with JWT."
48
+ end
49
+
50
+ header_fields = HashWithIndifferentAccess.wrap(header_fields).except(:typ, :alg)
51
+ ::JWT.encode(payload, rsa_private, algorithm, header_fields)
52
+ end
53
+
54
+ def verify_rsa(payload, certificate, signature, algorithm = 'SHA256')
55
+ algorithm = algorithm.to_s.upcase
56
+ unless VERIFY_RCA_ALGORITHMS.include?(algorithm)
57
+ raise "Unsupported signing method. Supports only #{VERIFY_RCA_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
58
+ end
59
+
60
+ cert = OpenSSL::X509::Certificate.new(certificate)
61
+ digest = OpenSSL::Digest.new(algorithm)
62
+ cert.public_key.verify(digest, signature, payload)
63
+ rescue OpenSSL::PKey::PKeyError
64
+ raise 'An error occurred during signature verification. Check arguments'
65
+ rescue OpenSSL::X509::CertificateError
66
+ raise 'Invalid certificate format'
67
+ end
68
+
69
+ def parse_yaml(yaml)
70
+ ::Psych.safe_load(yaml)
71
+ rescue ::Psych::DisallowedClass => e
72
+ raise e.message
73
+ end
74
+
75
+ def render_yaml(obj)
76
+ ::Psych.dump(obj)
77
+ end
78
+
79
+ def parse_json(source)
80
+ JSON.parse(source)
81
+ rescue JSON::ParserError => e
82
+ raise JSONResponseFormatError, e
83
+ end
84
+
85
+ def uuid
86
+ SecureRandom.uuid
87
+ end
88
+
89
+ def random_bytes(len)
90
+ unless (len.is_a? ::Integer) && (len <= RANDOM_SIZE)
91
+ raise "The requested length or random bytes sequence should be <= #{RANDOM_SIZE}"
92
+ end
93
+
94
+ Types::Binary.new(::OpenSSL::Random.random_bytes(len))
95
+ end
96
+
97
+ def aes_cbc_encrypt(string, key, init_vector = nil)
98
+ key_size = key.bytesize * 8
99
+ unless ALLOWED_KEY_SIZES.include?(key_size)
100
+ raise 'Incorrect key size for AES'
101
+ end
102
+
103
+ cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
104
+ cipher.encrypt
105
+ cipher.key = key
106
+ cipher.iv = init_vector if init_vector.present?
107
+ Types::Binary.new(cipher.update(string) + cipher.final)
108
+ end
109
+
110
+ def aes_cbc_decrypt(string, key, init_vector = nil)
111
+ key_size = key.bytesize * 8
112
+ unless ALLOWED_KEY_SIZES.include?(key_size)
113
+ raise 'Incorrect key size for AES'
114
+ end
115
+
116
+ cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
117
+ cipher.decrypt
118
+ cipher.key = key
119
+ cipher.iv = init_vector if init_vector.present?
120
+ Types::Binary.new(cipher.update(string) + cipher.final)
121
+ end
122
+
123
+ def pbkdf2_hmac_sha1(string, salt, iterations = 1000, key_len = 16)
124
+ Types::Binary.new(::OpenSSL::PKCS5.pbkdf2_hmac_sha1(string, salt, iterations, key_len))
125
+ end
126
+
127
+ def csv
128
+ @csv ||= CsvPackage.new
129
+ end
130
+
131
+ def stream
132
+ @stream ||= StreamPackage.new(streams: streams, connection: connection)
133
+ end
134
+
135
+ private
136
+
137
+ def method_missing(symbol, *_args)
138
+ raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato')
139
+ end
140
+
141
+ def respond_to_missing?(*)
142
+ false
143
+ end
144
+
145
+ attr_reader :streams
146
+
147
+ attr_reader :connection
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -5,10 +5,11 @@ 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'
@@ -19,12 +20,31 @@ module Workato
19
20
  module Sdk
20
21
  module Dsl
21
22
  module Global
23
+ extend T::Sig
24
+ extend T::Helpers
25
+
26
+ abstract!
27
+
28
+ # @api private
29
+ sig { abstract.returns(Streams) }
30
+ def streams; end
31
+
32
+ # @api private
33
+ sig { abstract.returns(Connection) }
34
+ def connection; end
35
+
22
36
  include Time
23
37
  include AccountProperty
24
38
  include LookupTable
25
- include WorkatoCodeLib
26
39
  include WorkatoSchema
27
- include AWS
40
+
41
+ delegate :parse_json,
42
+ :uuid,
43
+ to: :workato
44
+
45
+ def workato
46
+ @workato ||= WorkatoPackage.new(streams: streams, connection: connection)
47
+ end
28
48
 
29
49
  def sleep(seconds)
30
50
  ::Kernel.sleep(seconds.presence || 0)
@@ -33,6 +53,39 @@ module Workato
33
53
  def puts(*args)
34
54
  T.unsafe(::Kernel).puts(*args)
35
55
  end
56
+
57
+ def encrypt(text, key)
58
+ ::Kernel.require('ruby_rncryptor')
59
+
60
+ enc_text = ::RubyRNCryptor.encrypt(text, key)
61
+ ::Base64.strict_encode64(enc_text)
62
+ end
63
+
64
+ def decrypt(text, key)
65
+ ::Kernel.require('ruby_rncryptor')
66
+
67
+ text = ::Base64.decode64(text)
68
+ dec_text = ::RubyRNCryptor.decrypt(text, key)
69
+ Workato::Types::Binary.new(dec_text)
70
+ rescue Exception => e # rubocop:disable Lint/RescueException
71
+ message = e.message.to_s
72
+ case message
73
+ when /Password may be incorrect/
74
+ ::Kernel.raise 'invalid/corrupt input or key'
75
+ when /RubyRNCryptor only decrypts version/
76
+ ::Kernel.raise 'invalid/corrupt input'
77
+ else
78
+ ::Kernel.raise
79
+ end
80
+ end
81
+
82
+ def blank; end
83
+
84
+ def clear; end
85
+
86
+ def null; end
87
+
88
+ def skip; end
36
89
  end
37
90
 
38
91
  class WithDsl
@@ -42,21 +95,23 @@ module Workato
42
95
 
43
96
  using BlockInvocationRefinements
44
97
 
45
- sig { params(connection: Connection, args: T.untyped, block: T.untyped).returns(T.untyped) }
46
- def execute(connection, *args, &block)
98
+ sig { params(connection: Connection, streams: Streams).void }
99
+ def initialize(connection = Connection.new, streams = ProhibitedStreams.new)
47
100
  @connection = connection
48
- T.unsafe(self).instance_exec(*args, &block)
101
+ @streams = streams
49
102
  end
50
103
 
51
- sig { params(connection: Connection, args: T.untyped, block: T.untyped).returns(T.untyped) }
52
- def self.execute(connection, *args, &block)
53
- T.unsafe(WithDsl.new).execute(connection, *args, &block)
104
+ def execute(...)
105
+ T.unsafe(self).instance_exec(...)
54
106
  end
55
107
 
56
108
  private
57
109
 
58
- sig { returns(Connection) }
110
+ sig { override.returns(Connection) }
59
111
  attr_reader :connection
112
+
113
+ sig { override.returns(Streams) }
114
+ attr_reader :streams
60
115
  end
61
116
  end
62
117
  end