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
@@ -1,125 +0,0 @@
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
- module Csv
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
- class << self
54
- extend T::Sig
55
-
56
- sig do
57
- params(
58
- str: String,
59
- headers: T.any(T::Boolean, T::Array[String], String),
60
- col_sep: T.nilable(String),
61
- row_sep: T.nilable(String),
62
- quote_char: T.nilable(String),
63
- skip_blanks: T.nilable(T::Boolean),
64
- skip_first_line: T::Boolean
65
- ).returns(
66
- T::Array[T::Hash[String, T.untyped]]
67
- )
68
- end
69
- def parse(str, headers:, col_sep: nil, row_sep: nil, quote_char: nil, skip_blanks: nil,
70
- skip_first_line: false)
71
- if str.bytesize > MAX_FILE_SIZE_FOR_PARSE
72
- raise CsvFileTooBigError.new(str.bytesize, MAX_FILE_SIZE_FOR_PARSE)
73
- end
74
-
75
- index = 0
76
- options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
77
- skip_blanks: skip_blanks }.compact
78
- Enumerator.new do |consumer|
79
- CSV.parse(str, options) do |row|
80
- if index.zero? && skip_first_line
81
- index += 1
82
- next
83
- end
84
- if index == MAX_LINES_FOR_PARSE
85
- raise CsvFileTooManyLinesError, MAX_LINES_FOR_PARSE
86
- end
87
-
88
- index += 1
89
- consumer.yield(T.cast(row, CSV::Row).to_hash)
90
- end
91
- end.to_a
92
- rescue CSV::MalformedCSVError => e
93
- raise CsvFormatError, e
94
- rescue ArgumentError => e
95
- raise Sdk::RuntimeError, e.message
96
- end
97
-
98
- sig do
99
- params(
100
- str: T.nilable(String),
101
- headers: T.nilable(T::Array[String]),
102
- col_sep: T.nilable(String),
103
- row_sep: T.nilable(String),
104
- quote_char: T.nilable(String),
105
- force_quotes: T.nilable(T::Boolean),
106
- blk: T.proc.params(csv: CSV).void
107
- ).returns(
108
- String
109
- )
110
- end
111
- def generate(str = nil, headers: nil, col_sep: nil, row_sep: nil, quote_char: nil, force_quotes: nil, &blk)
112
- options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
113
- force_quotes: force_quotes }.compact
114
- options[:write_headers] = options[:headers].present?
115
-
116
- ::CSV.generate(str || String.new, options, &blk)
117
- rescue ArgumentError => e
118
- raise Sdk::RuntimeError, e.message
119
- end
120
- end
121
- end
122
- end
123
- end
124
- end
125
- end
@@ -1,167 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require 'jwt'
5
- require_relative './csv'
6
-
7
- using Workato::Extension::HashWithIndifferentAccess
8
-
9
- module Workato
10
- module Connector
11
- module Sdk
12
- module Dsl
13
- module WorkatoCodeLib
14
- JWT_ALGORITHMS = %w[RS256 RS384 RS512].freeze
15
- JWT_RSA_KEY_MIN_LENGTH = 2048
16
-
17
- VERIFY_RCA_ALGORITHMS = %w[SHA SHA1 SHA224 SHA256 SHA384 SHA512].freeze
18
-
19
- def workato
20
- WorkatoCodeLib
21
- end
22
-
23
- def parse_json(source)
24
- WorkatoCodeLib.parse_json(source)
25
- end
26
-
27
- def uuid
28
- WorkatoCodeLib.uuid
29
- end
30
-
31
- def encrypt(text, key)
32
- ::Kernel.require('ruby_rncryptor')
33
-
34
- enc_text = ::RubyRNCryptor.encrypt(text, key)
35
- ::Base64.strict_encode64(enc_text)
36
- end
37
-
38
- def decrypt(text, key)
39
- ::Kernel.require('ruby_rncryptor')
40
-
41
- text = ::Base64.decode64(text)
42
- dec_text = ::RubyRNCryptor.decrypt(text, key)
43
- Workato::Extension::Binary.new(dec_text)
44
- rescue Exception => e # rubocop:disable Lint/RescueException
45
- message = e.message.to_s
46
- case message
47
- when /Password may be incorrect/
48
- ::Kernel.raise 'invalid/corrupt input or key'
49
- when /RubyRNCryptor only decrypts version/
50
- ::Kernel.raise 'invalid/corrupt input'
51
- else
52
- ::Kernel.raise
53
- end
54
- end
55
-
56
- def blank; end
57
-
58
- def clear; end
59
-
60
- def null; end
61
-
62
- def skip; end
63
-
64
- class << self
65
- def jwt_encode_rs256(payload, key, header_fields = {})
66
- jwt_encode(payload, key, 'RS256', header_fields)
67
- end
68
-
69
- def jwt_encode(payload, key, algorithm, header_fields = {})
70
- algorithm = algorithm.to_s.upcase
71
- unless JWT_ALGORITHMS.include?(algorithm)
72
- raise "Unsupported signing method. Supports only #{JWT_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
73
- end
74
-
75
- rsa_private = OpenSSL::PKey::RSA.new(key)
76
- if rsa_private.n.num_bits < JWT_RSA_KEY_MIN_LENGTH
77
- raise "A RSA key of size #{JWT_RSA_KEY_MIN_LENGTH} bits or larger MUST be used with JWT."
78
- end
79
-
80
- header_fields = HashWithIndifferentAccess.wrap(header_fields).except(:typ, :alg)
81
- ::JWT.encode(payload, rsa_private, algorithm, header_fields)
82
- end
83
-
84
- def verify_rsa(payload, certificate, signature, algorithm = 'SHA256')
85
- algorithm = algorithm.to_s.upcase
86
- unless VERIFY_RCA_ALGORITHMS.include?(algorithm)
87
- raise "Unsupported signing method. Supports only #{VERIFY_RCA_ALGORITHMS.join(', ')}. Got: '#{algorithm}'" # rubocop:disable Layout/LineLength
88
- end
89
-
90
- cert = OpenSSL::X509::Certificate.new(certificate)
91
- digest = OpenSSL::Digest.new(algorithm)
92
- cert.public_key.verify(digest, signature, payload)
93
- rescue OpenSSL::PKey::PKeyError
94
- raise 'An error occurred during signature verification. Check arguments'
95
- rescue OpenSSL::X509::CertificateError
96
- raise 'Invalid certificate format'
97
- end
98
-
99
- def parse_yaml(yaml)
100
- ::Psych.safe_load(yaml)
101
- rescue ::Psych::DisallowedClass => e
102
- raise e.message
103
- end
104
-
105
- def render_yaml(obj)
106
- ::Psych.dump(obj)
107
- end
108
-
109
- def parse_json(source)
110
- JSON.parse(source)
111
- end
112
-
113
- def uuid
114
- SecureRandom.uuid
115
- end
116
-
117
- RANDOM_SIZE = 32
118
-
119
- def random_bytes(len)
120
- unless (len.is_a? ::Integer) && (len <= RANDOM_SIZE)
121
- raise "The requested length or random bytes sequence should be <= #{RANDOM_SIZE}"
122
- end
123
-
124
- Extension::Binary.new(::OpenSSL::Random.random_bytes(len))
125
- end
126
-
127
- ALLOWED_KEY_SIZES = [128, 192, 256].freeze
128
-
129
- def aes_cbc_encrypt(string, key, init_vector = nil)
130
- key_size = key.bytesize * 8
131
- unless ALLOWED_KEY_SIZES.include?(key_size)
132
- raise 'Incorrect key size for AES'
133
- end
134
-
135
- cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
136
- cipher.encrypt
137
- cipher.key = key
138
- cipher.iv = init_vector if init_vector.present?
139
- Extension::Binary.new(cipher.update(string) + cipher.final)
140
- end
141
-
142
- def aes_cbc_decrypt(string, key, init_vector = nil)
143
- key_size = key.bytesize * 8
144
- unless ALLOWED_KEY_SIZES.include?(key_size)
145
- raise 'Incorrect key size for AES'
146
- end
147
-
148
- cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
149
- cipher.decrypt
150
- cipher.key = key
151
- cipher.iv = init_vector if init_vector.present?
152
- Extension::Binary.new(cipher.update(string) + cipher.final)
153
- end
154
-
155
- def pbkdf2_hmac_sha1(string, salt, iterations = 1000, key_len = 16)
156
- Extension::Binary.new(::OpenSSL::PKCS5.pbkdf2_hmac_sha1(string, salt, iterations, key_len))
157
- end
158
-
159
- def csv
160
- Csv
161
- end
162
- end
163
- end
164
- end
165
- end
166
- end
167
- end
@@ -1,23 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- module Workato
5
- module Connector
6
- module Sdk
7
- class Schema
8
- module Type
9
- class UnicodeString < ::String
10
- def initialize(str)
11
- super(str, {})
12
- encode!('UTF-8')
13
- end
14
-
15
- def binary?
16
- false
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end