workato-connector-sdk 1.3.0 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +8 -0
  3. data/README.md +0 -4
  4. data/VERSION +1 -1
  5. data/lib/workato/cli/generate_command.rb +1 -0
  6. data/lib/workato/cli/main.rb +1 -0
  7. data/lib/workato/cli/multi_auth_selected_fallback.rb +1 -0
  8. data/lib/workato/cli/oauth2_command.rb +13 -14
  9. data/lib/workato/cli/push_command.rb +21 -5
  10. data/lib/workato/cli/schema_command.rb +18 -4
  11. data/lib/workato/connector/sdk/account_properties.rb +1 -1
  12. data/lib/workato/connector/sdk/action.rb +1 -1
  13. data/lib/workato/connector/sdk/block_invocation_refinements.rb +2 -1
  14. data/lib/workato/connector/sdk/connection.rb +8 -2
  15. data/lib/workato/connector/sdk/connector.rb +9 -0
  16. data/lib/workato/connector/sdk/dsl/aws.rb +10 -0
  17. data/lib/workato/connector/sdk/dsl/csv_package.rb +3 -3
  18. data/lib/workato/connector/sdk/dsl/error.rb +2 -0
  19. data/lib/workato/connector/sdk/dsl/execution_context.rb +2 -0
  20. data/lib/workato/connector/sdk/dsl/http.rb +6 -1
  21. data/lib/workato/connector/sdk/dsl/stream_package.rb +1 -7
  22. data/lib/workato/connector/sdk/dsl/workato_package.rb +54 -19
  23. data/lib/workato/connector/sdk/dsl.rb +2 -0
  24. data/lib/workato/connector/sdk/errors.rb +2 -0
  25. data/lib/workato/connector/sdk/object_definitions.rb +59 -18
  26. data/lib/workato/connector/sdk/operation.rb +1 -1
  27. data/lib/workato/connector/sdk/request.rb +6 -3
  28. data/lib/workato/connector/sdk/schema.rb +4 -3
  29. data/lib/workato/connector/sdk/settings.rb +3 -1
  30. data/lib/workato/connector/sdk/stream.rb +22 -3
  31. data/lib/workato/connector/sdk/streams.rb +1 -0
  32. data/lib/workato/connector/sdk/summarize.rb +2 -0
  33. data/lib/workato/connector/sdk.rb +1 -0
  34. data/lib/workato/extension/array.rb +1 -1
  35. data/lib/workato/extension/enumerable.rb +0 -2
  36. data/lib/workato/extension/extra_chain_cert.rb +2 -2
  37. data/lib/workato/extension/metadata_fix_wrap_kw_args.rb +1 -0
  38. data/lib/workato/extension/string.rb +10 -2
  39. data/lib/workato/testing/vcr_multipart_body_matcher.rb +1 -0
  40. data/lib/workato/types/binary.rb +45 -0
  41. data/lib/workato/types/unicode_string.rb +62 -0
  42. metadata +4 -31
  43. data/lib/workato/connector/sdk/schema/type/unicode_string.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e0a739fc6bc5fe15228d209dc24ac4858c3815b4252b5f6d9abd9ae0644b15d
4
- data.tar.gz: d4089c8dc7f6c8f9bd171730797a7b82eeb3192883d4b5883a5998985a20001a
3
+ metadata.gz: 3fe38da4979356285b7bd535a889ce87324c0c9e79af94ab64bbfbabff03f104
4
+ data.tar.gz: 12ae318a25eaf1fddc7c31f22f9870d4af28e736781ef32ff766c32ae14876d2
5
5
  SHA512:
6
- metadata.gz: f6a00086288382c03c024f351e69ca79749d6ef41a833141140274926bec885a7382ce505e9b4981c05a465efa2f1c97cb30697906b8ba6c63d02709dedc9de7
7
- data.tar.gz: b5b289bf86ac5970420e20762609256a6280f00a76ae604fcff206f65f40abb517f22c2207f93f1d439b250e4d725e4a5a91865904bf32c93459c52c932e70b3
6
+ metadata.gz: 2737cef0c57c48dc215dba1f3077669935fceb940be5484469e3901f6d848bee8af5bc408595a14a330bc96e3e553f088c25323867dc8d43d1b95930275c79af
7
+ data.tar.gz: 066b30f5e052e1dbd91c697b3e978ec548f0ffc76db9298168758e4b60f8ada8f1a13c1a603e0603d347e22fcca2e945fa3eeaedaa74139cef07b09b98b7c9ea
data/.yardopts ADDED
@@ -0,0 +1,8 @@
1
+ --title "Workato Connector SDK Ruby"
2
+ --main README.md
3
+ --no-private
4
+ --plugin sorbet
5
+ --exclude lib/workato/cli/
6
+ --exclude lib/workato/utilities/
7
+ --exclude lib/workato/web/
8
+ --exclude lib/workato/extension/
data/README.md CHANGED
@@ -339,7 +339,6 @@ Options:
339
339
  [--col-sep=COL_SEP] # Use separator for CSV converter
340
340
  # Default: comma
341
341
  # Possible values: comma, space, tab, colon, semicolon, pipe
342
- [--api-email=API_EMAIL] # Email for accessing Workato API or set WORKATO_API_EMAIL environment variable
343
342
  [--api-token=API_TOKEN] # Token for accessing Workato API or set WORKATO_API_TOKEN environment variable
344
343
  ```
345
344
 
@@ -425,8 +424,6 @@ Options:
425
424
  -l, [--logo=LOGO] # Path to connector logo: png or jpeg file
426
425
  -n, [--notes=NOTES] # Release notes
427
426
  -c, [--connector=CONNECTOR] # Path to connector source code
428
- [--api-email=API_EMAIL] # Email for accessing Workato API.
429
- # If present overrides value from WORKATO_API_EMAIL environment variable.
430
427
  [--api-token=API_TOKEN] # Token for accessing Workato API.
431
428
  # If present overrides value from WORKATO_API_TOKEN environment variable.
432
429
  [--environment=ENVIRONMENT] # Data center specific URL to push connector code.
@@ -1139,7 +1136,6 @@ jobs:
1139
1136
  run: bundle exec rspec
1140
1137
  # - name: Push to DEV workspace # Use this to push to DEV. This can be enabled when a PR is merged.
1141
1138
  # env:
1142
- # WORKATO_API_EMAIL: ${{ secrets.WORKATO_DEV_ENVIRONMENT_API_EMAIL}}
1143
1139
  # WORKATO_API_TOKEN: ${{ secrets.WORKATO_DEV_ENVIRONMENT_API_TOKEN}}
1144
1140
  # run: workato push
1145
1141
  ```
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.0
1
+ 1.3.2
@@ -50,6 +50,7 @@ module Workato
50
50
  enum: SchemaCommand::CSV_SEPARATORS,
51
51
  default: 'comma'
52
52
  method_option :api_email,
53
+ hide: true,
53
54
  type: :string,
54
55
  desc: 'Email for accessing Workato API or ' \
55
56
  "set #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} environment variable"
@@ -128,6 +128,7 @@ module Workato
128
128
  desc: 'Path to connector source code',
129
129
  lazy_default: Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH
130
130
  method_option :api_email,
131
+ hide: true,
131
132
  type: :string,
132
133
  desc: "Email for accessing Workato API.\n" \
133
134
  "If present overrides value from #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} " \
@@ -1,3 +1,4 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Workato
@@ -1,6 +1,7 @@
1
1
  # typed: false
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'thor'
4
5
  require 'securerandom'
5
6
  require 'workato/web/app'
6
7
  require_relative './multi_auth_selected_fallback'
@@ -70,7 +71,7 @@ module Workato
70
71
  end
71
72
 
72
73
  def require_gems
73
- require 'oauth2'
74
+ require 'rest-client'
74
75
  require 'launchy'
75
76
  require 'rack'
76
77
  end
@@ -79,7 +80,7 @@ module Workato
79
80
  @thread = Thread.start do
80
81
  Rack::Handler::WEBrick.run(
81
82
  Workato::Web::App.new,
82
- {
83
+ **{
83
84
  Port: port,
84
85
  BindAddress: options[:ip] || DEFAULT_ADDRESS,
85
86
  SSLEnable: https,
@@ -107,7 +108,7 @@ module Workato
107
108
  unless connector.connection.authorization.oauth2?
108
109
  raise 'Authorization type is not OAuth2. ' \
109
110
  'For multi-auth connector ensure correct auth type was used. ' \
110
- "Expected: 'oauth2', got: '#{connector.connection.authorization.type}''"
111
+ "Expected: 'oauth2', got: '#{connector.connection.authorization.type}'"
111
112
  end
112
113
  rescue Workato::Connector::Sdk::InvalidMultiAuthDefinition => e
113
114
  raise "#{e.message}. Please ensure:\n" \
@@ -116,16 +117,6 @@ module Workato
116
117
  'See more: https://docs.workato.com/developing-connectors/sdk/guides/authentication/multi_auth.html'
117
118
  end
118
119
 
119
- def client
120
- @client ||= OAuth2::Client.new(
121
- connector.connection.authorization.client_id,
122
- connector.connection.authorization.client_secret,
123
- site: connector.connection.base_uri,
124
- token_url: connector.connection.authorization.token_url,
125
- redirect_uri: redirect_url
126
- )
127
- end
128
-
129
120
  def authorize_url
130
121
  return @authorize_url if defined?(@authorize_url)
131
122
 
@@ -193,7 +184,15 @@ module Workato
193
184
  extra_settings ||= {}
194
185
  extra_settings.merge(tokens)
195
186
  else
196
- client.auth_code.get_token(code).to_hash
187
+ response = RestClient.post(
188
+ connector.connection.authorization.token_url,
189
+ code: code,
190
+ grant_type: :authorization_code,
191
+ client_id: connector.connection.authorization.client_id,
192
+ client_secret: connector.connection.authorization.client_secret,
193
+ redirect_uri: redirect_url
194
+ )
195
+ JSON.parse(response.body).to_hash
197
196
  end
198
197
  end
199
198
 
@@ -5,6 +5,7 @@ require 'uri'
5
5
  require 'ruby-progressbar'
6
6
  require 'zip'
7
7
  require 'fileutils'
8
+ require 'thor'
8
9
 
9
10
  module Workato
10
11
  module CLI
@@ -108,7 +109,7 @@ module Workato
108
109
  url = "#{api_base_url}#{API_IMPORT_PATH}/#{folder_id}"
109
110
  response = RestClient.post(
110
111
  url,
111
- File.open(zip_file_path),
112
+ File.open(zip_file_path, 'rb'),
112
113
  auth_headers.merge(
113
114
  'Content-Type' => 'application/zip'
114
115
  )
@@ -185,10 +186,25 @@ module Workato
185
186
  end
186
187
 
187
188
  def auth_headers
188
- {
189
- 'x-user-email' => api_email,
190
- 'x-user-token' => api_token
191
- }
189
+ @auth_headers ||=
190
+ if api_email.present?
191
+ warn <<~WARNING
192
+ You are using old authorization schema with --api-email and --api-token which is less secure and deprecated.
193
+ We strongly recommend migrating over to API Clients for authentication to Workato APIs.
194
+
195
+ Learn more: https://docs.workato.com/developing-connectors/sdk/cli/reference/cli-commands.html#workato-push
196
+
197
+ If you use API Client token but still see this message, ensure you do not pass --api-email param nor have #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} environment variable set.
198
+ WARNING
199
+ {
200
+ 'x-user-email' => api_email,
201
+ 'x-user-token' => api_token
202
+ }
203
+ else
204
+ {
205
+ 'Authorization' => "Bearer #{api_token}"
206
+ }
207
+ end
192
208
  end
193
209
 
194
210
  def folder_id
@@ -68,10 +68,24 @@ module Workato
68
68
  end
69
69
 
70
70
  def auth_headers
71
- {
72
- 'x-user-email' => api_email,
73
- 'x-user-token' => api_token
74
- }
71
+ if api_email.present?
72
+ warn <<~WARNING
73
+ You are using old authorization schema with --api-email and --api-token which is less secure and deprecated.
74
+ We strongly recommend migrating over to API Clients for authentication to Workato APIs.
75
+
76
+ Learn more: https://docs.workato.com/developing-connectors/sdk/cli/reference/cli-commands.html#workato-generate-schema
77
+
78
+ If you use API Client token but still see this message, ensure you do not pass --api-email param nor have #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} environment variable set.
79
+ WARNING
80
+ {
81
+ 'x-user-email' => api_email,
82
+ 'x-user-token' => api_token
83
+ }
84
+ else
85
+ {
86
+ 'Authorization' => "Bearer #{api_token}"
87
+ }
88
+ end
75
89
  end
76
90
 
77
91
  private_constant :API_GENERATE_SCHEMA_PATH
@@ -13,7 +13,7 @@ module Workato
13
13
 
14
14
  def self.from_yaml(path = DEFAULT_ACCOUNT_PROPERTIES_PATH)
15
15
  File.open(path) do |f|
16
- instance.load_data(YAML.safe_load(ERB.new(f.read).result, [::Symbol]).to_hash)
16
+ instance.load_data(YAML.safe_load(ERB.new(f.read).result, permitted_classes: [::Symbol]).to_hash)
17
17
  end
18
18
  end
19
19
 
@@ -117,7 +117,7 @@ module Workato
117
117
  retry_on_response.each { |m| m.is_a?(::Integer) ? @retry_codes << m : @retry_matchers << m }
118
118
  @retry_codes = RETRY_DEFAULT_CODES if @retry_codes.empty?
119
119
  @retry_methods = (retry_on_request.presence || RETRY_DEFAULT_METHODS).map(&:to_s).map(&:downcase)
120
- @retries_left = [[(max_retries.is_a?(::Integer) && max_retries) || MAX_RETRIES, MAX_RETRIES].min, 0].max
120
+ @retries_left = ((max_retries.is_a?(::Integer) && max_retries) || MAX_RETRIES).clamp(0, MAX_RETRIES)
121
121
  end
122
122
 
123
123
  sig { params(exception: RequestFailedError).returns(T::Boolean) }
@@ -4,7 +4,8 @@
4
4
  module Workato
5
5
  module Connector
6
6
  module Sdk
7
- # match proc's arguments, even if it's a lambda.
7
+ # Match proc's arguments, even if it's a lambda.
8
+ # @api private
8
9
  module BlockInvocationRefinements
9
10
  refine Proc do
10
11
  def call(*args, &block)
@@ -36,6 +36,7 @@ module Workato
36
36
 
37
37
  using BlockInvocationRefinements
38
38
 
39
+ # @api private
39
40
  sig { returns(HashWithIndifferentAccess) }
40
41
  attr_reader :source
41
42
 
@@ -56,11 +57,13 @@ module Workato
56
57
  @settings = T.let(settings, SorbetTypes::SettingsHash)
57
58
  end
58
59
 
60
+ # @api private
59
61
  sig { returns(SorbetTypes::SettingsHash) }
60
62
  def settings!
61
63
  @settings
62
64
  end
63
65
 
66
+ # @api private
64
67
  sig { returns(HashWithIndifferentAccess) }
65
68
  def settings
66
69
  # we can't freeze or memoise because some developers modify it for storing something temporary in it.
@@ -70,11 +73,13 @@ module Workato
70
73
  end
71
74
  end
72
75
 
76
+ # @api private
73
77
  sig { params(settings: SorbetTypes::SettingsHash).returns(SorbetTypes::SettingsHash) }
74
78
  def merge_settings!(settings)
75
79
  @settings.merge!(settings)
76
80
  end
77
81
 
82
+ # @api private
78
83
  sig { returns(T::Boolean) }
79
84
  def authorization?
80
85
  source[:authorization].present?
@@ -100,6 +105,7 @@ module Workato
100
105
  global_dsl_context.execute(self.settings, &source['base_uri'])
101
106
  end
102
107
 
108
+ # @api private
103
109
  sig do
104
110
  params(
105
111
  message: String,
@@ -267,6 +273,7 @@ module Workato
267
273
  end
268
274
  end
269
275
 
276
+ # @api private
270
277
  sig { params(settings: HashWithIndifferentAccess).returns(T.nilable(HashWithIndifferentAccess)) }
271
278
  def refresh!(settings)
272
279
  if oauth2?
@@ -300,6 +307,7 @@ module Workato
300
307
  end
301
308
  end
302
309
 
310
+ # @api private
303
311
  sig { returns(HashWithIndifferentAccess) }
304
312
  def source
305
313
  return @source unless multi?
@@ -381,8 +389,6 @@ module Workato
381
389
  Dsl::WithDsl.new(@connection)
382
390
  end
383
391
  end
384
-
385
- private_constant :Authorization
386
392
  end
387
393
  end
388
394
  end
@@ -13,6 +13,7 @@ module Workato
13
13
  class Connector
14
14
  extend T::Sig
15
15
 
16
+ # @api private
16
17
  sig { returns(HashWithIndifferentAccess) }
17
18
  attr_reader :source
18
19
 
@@ -208,6 +209,8 @@ module Workato
208
209
  end
209
210
  end
210
211
 
212
+ private_constant :ActionsProxy
213
+
211
214
  class MethodsProxy
212
215
  extend T::Sig
213
216
 
@@ -255,6 +258,8 @@ module Workato
255
258
  end
256
259
  end
257
260
 
261
+ private_constant :MethodsProxy
262
+
258
263
  class PickListsProxy
259
264
  extend T::Sig
260
265
 
@@ -306,6 +311,8 @@ module Workato
306
311
  end
307
312
  end
308
313
 
314
+ private_constant :PickListsProxy
315
+
309
316
  class TriggersProxy
310
317
  extend T::Sig
311
318
 
@@ -365,6 +372,8 @@ module Workato
365
372
  end
366
373
  end
367
374
  end
375
+
376
+ private_constant :TriggersProxy
368
377
  end
369
378
  end
370
379
  end
@@ -12,15 +12,25 @@ module Workato
12
12
  module Dsl
13
13
  module AWS
14
14
  TEMP_CREDENTIALS_REFRESH_TIMEOUT = 60 # seconds
15
+ private_constant :TEMP_CREDENTIALS_REFRESH_TIMEOUT
15
16
 
16
17
  DUMMY_AWS_IAM_EXTERNAL_ID = 'dummy-aws-iam-external-id'
18
+ private_constant :DUMMY_AWS_IAM_EXTERNAL_ID
19
+
17
20
  DUMMY_AWS_WORKATO_ACCOUNT_ID = 'dummy-aws-workato-account-id'
21
+ private_constant :DUMMY_AWS_WORKATO_ACCOUNT_ID
18
22
 
19
23
  AMAZON_ROLE_CLIENT_ID = ENV.fetch('AMAZON_ROLE_CLIENT_ID', nil)
24
+ private_constant :AMAZON_ROLE_CLIENT_ID
25
+
20
26
  AMAZON_ROLE_CLIENT_KEY = ENV.fetch('AMAZON_ROLE_CLIENT_KEY', nil)
27
+ private_constant :AMAZON_ROLE_CLIENT_KEY
28
+
21
29
  AMAZON_ROLE_CLIENT_SECRET = ENV.fetch('AMAZON_ROLE_CLIENT_SECRET', nil)
30
+ private_constant :AMAZON_ROLE_CLIENT_SECRET
22
31
 
23
32
  WWW_FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded; charset=utf-8'
33
+ private_constant :WWW_FORM_CONTENT_TYPE
24
34
 
25
35
  def aws
26
36
  @aws ||= Private.new(connection: connection)
@@ -6,7 +6,7 @@ require 'csv'
6
6
  module Workato
7
7
  module Connector
8
8
  module Sdk
9
- CsvError = Class.new(Sdk::RuntimeError)
9
+ CsvError = Class.new(Sdk::Error)
10
10
 
11
11
  CsvFormatError = Class.new(CsvError)
12
12
 
@@ -89,7 +89,7 @@ module Workato
89
89
  rescue CSV::MalformedCSVError => e
90
90
  raise CsvFormatError, e
91
91
  rescue ArgumentError => e
92
- raise Sdk::RuntimeError, e.message
92
+ raise Sdk::ArgumentError, e.message
93
93
  end
94
94
 
95
95
  sig do
@@ -112,7 +112,7 @@ module Workato
112
112
 
113
113
  ::CSV.generate(str || String.new, **options, &blk)
114
114
  rescue ArgumentError => e
115
- raise Sdk::RuntimeError, e.message
115
+ raise Sdk::ArgumentError, e.message
116
116
  end
117
117
 
118
118
  private
@@ -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
@@ -38,6 +38,8 @@ module Workato
38
38
  T.unsafe(self).recipe_id.reverse
39
39
  end
40
40
  end
41
+
42
+ private_constant :ClassMethods
41
43
  end
42
44
  end
43
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,7 +57,7 @@ module Workato
52
57
  response = nil
53
58
  exception = nil
54
59
  begin
55
- response = request.execute!
60
+ response = request.response!
56
61
  rescue StandardError => e
57
62
  exception = e.to_s
58
63
  end
@@ -27,13 +27,7 @@ module Workato
27
27
  stream = out(stream[:name], stream[:input] || {})
28
28
  end
29
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
30
+ Stream.each_chunk(stream: stream, from: from, frame_size: frame_size, &blk)
37
31
  end
38
32
 
39
33
  sig { params(stream_name: String, input: SorbetTypes::StreamInputHash).returns(Stream::Proxy) }
@@ -10,12 +10,36 @@ using Workato::Extension::HashWithIndifferentAccess
10
10
  module Workato
11
11
  module Connector
12
12
  module Sdk
13
+ JSONParsingError = Class.new(Error)
14
+
13
15
  module Dsl
14
16
  class WorkatoPackage
15
- JWT_ALGORITHMS = %w[RS256 RS384 RS512].freeze
17
+ JWT_RSA_ALGORITHMS = %w[RS256 RS384 RS512].freeze
18
+ private_constant :JWT_RSA_ALGORITHMS
19
+
16
20
  JWT_RSA_KEY_MIN_LENGTH = 2048
21
+ private_constant :JWT_RSA_KEY_MIN_LENGTH
22
+
23
+ JWT_HMAC_ALGORITHMS = %w[HS256].freeze
24
+ private_constant :JWT_HMAC_ALGORITHMS
25
+
26
+ JWT_ECDSA_ALGORITHMS = %w[ES256 ES384 ES512].freeze
27
+ private_constant :JWT_ECDSA_ALGORITHMS
28
+
29
+ JWT_ECDSA_KEY_LENGTH_MAPPING = { 'ES256' => 256, 'ES384' => 384, 'ES512' => 521 }.freeze
30
+ private_constant :JWT_ECDSA_KEY_LENGTH_MAPPING
31
+
32
+ JWT_ALGORITHMS = (JWT_RSA_ALGORITHMS + JWT_HMAC_ALGORITHMS + JWT_ECDSA_ALGORITHMS).freeze
33
+ private_constant :JWT_ALGORITHMS
17
34
 
18
35
  VERIFY_RCA_ALGORITHMS = %w[SHA SHA1 SHA224 SHA256 SHA384 SHA512].freeze
36
+ private_constant :VERIFY_RCA_ALGORITHMS
37
+
38
+ RANDOM_SIZE = 32
39
+ private_constant :RANDOM_SIZE
40
+
41
+ ALLOWED_KEY_SIZES = [128, 192, 256].freeze
42
+ private_constant :ALLOWED_KEY_SIZES
19
43
 
20
44
  def initialize(streams:, connection:)
21
45
  @streams = streams
@@ -29,37 +53,52 @@ module Workato
29
53
  def jwt_encode(payload, key, algorithm, header_fields = {})
30
54
  algorithm = algorithm.to_s.upcase
31
55
  unless JWT_ALGORITHMS.include?(algorithm)
32
- raise "Unsupported signing method. Supports only #{JWT_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
56
+ raise Sdk::ArgumentError,
57
+ "Unsupported signing method. Supports only #{JWT_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
33
58
  end
34
59
 
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."
60
+ if JWT_RSA_ALGORITHMS.include?(algorithm)
61
+ key = OpenSSL::PKey::RSA.new(key)
62
+ if key.n.num_bits < JWT_RSA_KEY_MIN_LENGTH
63
+ raise Sdk::ArgumentError,
64
+ "A RSA key of size #{JWT_RSA_KEY_MIN_LENGTH} bits or larger MUST be used with JWT"
65
+ end
66
+ elsif JWT_ECDSA_ALGORITHMS.include?(algorithm)
67
+ key = OpenSSL::PKey::EC.new(key)
68
+ if key.group.order.num_bits != JWT_ECDSA_KEY_LENGTH_MAPPING[algorithm]
69
+ raise Sdk::ArgumentError,
70
+ "An ECDSA key of size #{JWT_ECDSA_KEY_LENGTH_MAPPING[algorithm]} bits MUST be used with JWT"
71
+ end
38
72
  end
39
73
 
40
74
  header_fields = HashWithIndifferentAccess.wrap(header_fields).except(:typ, :alg)
41
- ::JWT.encode(payload, rsa_private, algorithm, header_fields)
75
+ ::JWT.encode(payload, key, algorithm, header_fields)
76
+ rescue JWT::IncorrectAlgorithm
77
+ raise Sdk::ArgumentError, 'Mismatched algorithm and key'
78
+ rescue OpenSSL::PKey::PKeyError
79
+ raise Sdk::ArgumentError, 'Invalid key'
42
80
  end
43
81
 
44
82
  def verify_rsa(payload, certificate, signature, algorithm = 'SHA256')
45
83
  algorithm = algorithm.to_s.upcase
46
84
  unless VERIFY_RCA_ALGORITHMS.include?(algorithm)
47
- raise "Unsupported signing method. Supports only #{VERIFY_RCA_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
85
+ raise Sdk::ArgumentError,
86
+ "Unsupported signing method. Supports only #{VERIFY_RCA_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
48
87
  end
49
88
 
50
89
  cert = OpenSSL::X509::Certificate.new(certificate)
51
90
  digest = OpenSSL::Digest.new(algorithm)
52
91
  cert.public_key.verify(digest, signature, payload)
53
92
  rescue OpenSSL::PKey::PKeyError
54
- raise 'An error occurred during signature verification. Check arguments'
93
+ raise Sdk::ArgumentError, 'An error occurred during signature verification. Check arguments'
55
94
  rescue OpenSSL::X509::CertificateError
56
- raise 'Invalid certificate format'
95
+ raise Sdk::ArgumentError, 'Invalid certificate format'
57
96
  end
58
97
 
59
98
  def parse_yaml(yaml)
60
99
  ::Psych.safe_load(yaml)
61
- rescue ::Psych::DisallowedClass => e
62
- raise e.message
100
+ rescue ::Psych::Exception => e
101
+ raise Sdk::ArgumentError, "YAML Parsing error. #{e}"
63
102
  end
64
103
 
65
104
  def render_yaml(obj)
@@ -69,29 +108,25 @@ module Workato
69
108
  def parse_json(source)
70
109
  JSON.parse(source)
71
110
  rescue JSON::ParserError => e
72
- raise JSONResponseFormatError, e
111
+ raise JSONParsingError, e
73
112
  end
74
113
 
75
114
  def uuid
76
115
  SecureRandom.uuid
77
116
  end
78
117
 
79
- RANDOM_SIZE = 32
80
-
81
118
  def random_bytes(len)
82
119
  unless (len.is_a? ::Integer) && (len <= RANDOM_SIZE)
83
- raise "The requested length or random bytes sequence should be <= #{RANDOM_SIZE}"
120
+ raise Sdk::ArgumentError, "The requested length or random bytes sequence should be <= #{RANDOM_SIZE}"
84
121
  end
85
122
 
86
123
  Types::Binary.new(::OpenSSL::Random.random_bytes(len))
87
124
  end
88
125
 
89
- ALLOWED_KEY_SIZES = [128, 192, 256].freeze
90
-
91
126
  def aes_cbc_encrypt(string, key, init_vector = nil)
92
127
  key_size = key.bytesize * 8
93
128
  unless ALLOWED_KEY_SIZES.include?(key_size)
94
- raise 'Incorrect key size for AES'
129
+ raise Sdk::ArgumentError, 'Incorrect key size for AES'
95
130
  end
96
131
 
97
132
  cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
@@ -104,7 +139,7 @@ module Workato
104
139
  def aes_cbc_decrypt(string, key, init_vector = nil)
105
140
  key_size = key.bytesize * 8
106
141
  unless ALLOWED_KEY_SIZES.include?(key_size)
107
- raise 'Incorrect key size for AES'
142
+ raise Sdk::ArgumentError, 'Incorrect key size for AES'
108
143
  end
109
144
 
110
145
  cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
@@ -25,9 +25,11 @@ module Workato
25
25
 
26
26
  abstract!
27
27
 
28
+ # @api private
28
29
  sig { abstract.returns(Streams) }
29
30
  def streams; end
30
31
 
32
+ # @api private
31
33
  sig { abstract.returns(Connection) }
32
34
  def connection; end
33
35
 
@@ -10,6 +10,8 @@ module Workato
10
10
 
11
11
  RuntimeError = Class.new(Error)
12
12
 
13
+ ArgumentError = Class.new(Error)
14
+
13
15
  InvalidDefinitionError = Class.new(Error)
14
16
 
15
17
  class UnexpectedMethodDefinitionError < InvalidDefinitionError
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require_relative './block_invocation_refinements'
@@ -6,31 +6,45 @@ require_relative './block_invocation_refinements'
6
6
  module Workato
7
7
  module Connector
8
8
  module Sdk
9
+ module SorbetTypes
10
+ ObjectDefinitionOutput = T.type_alias { T::Array[HashWithIndifferentAccess] }
11
+ end
12
+
9
13
  class ObjectDefinitions
14
+ extend T::Sig
15
+
10
16
  using BlockInvocationRefinements
11
17
 
18
+ sig do
19
+ params(
20
+ object_definitions: SorbetTypes::SourceHash,
21
+ connection: Connection,
22
+ methods: SorbetTypes::SourceHash
23
+ ).void
24
+ end
12
25
  def initialize(object_definitions:, connection:, methods:)
13
26
  @object_definitions_source = object_definitions
14
27
  @methods_source = methods
15
28
  @connection = connection
16
- define_object_definition_methods(object_definitions)
29
+ @object_definitions = T.let({}, T::Hash[T.any(String, Symbol), ObjectDefinition])
30
+ define_object_definition_methods
17
31
  end
18
32
 
33
+ sig do
34
+ params(
35
+ settings: T.nilable(SorbetTypes::SettingsHash),
36
+ config_fields: SorbetTypes::OperationInputHash
37
+ ).returns(HashWithIndifferentAccess)
38
+ end
19
39
  def lazy(settings = nil, config_fields = {})
20
40
  DupHashWithIndifferentAccess.new do |object_definitions, name|
21
41
  fields_proc = object_definitions_source.dig(name, :fields)
22
42
  raise Workato::Connector::Sdk::UnresolvedObjectDefinitionError, name unless fields_proc
23
43
 
24
44
  begin
25
- object_definitions[name] = Action.new(
26
- action: {
27
- execute: lambda do |connection, input|
28
- instance_exec(connection, input, object_definitions, &fields_proc)
29
- end
30
- },
31
- methods: methods_source,
32
- connection: connection
33
- ).execute(settings, config_fields)
45
+ object_definitions[name] = create_operation.execute(settings, config_fields) do |connection, input|
46
+ instance_exec(connection, input, object_definitions, &fields_proc)
47
+ end
34
48
  rescue SystemStackError => e
35
49
  raise Workato::Connector::Sdk::CircleReferenceObjectDefinitionError.new(name, e.backtrace)
36
50
  end
@@ -39,40 +53,67 @@ module Workato
39
53
 
40
54
  private
41
55
 
56
+ sig { returns(SorbetTypes::SourceHash) }
42
57
  attr_reader :methods_source
58
+
59
+ sig { returns(Connection) }
43
60
  attr_reader :connection
44
- attr_reader :settings
61
+
62
+ sig { returns(SorbetTypes::SourceHash) }
45
63
  attr_reader :object_definitions_source
46
64
 
47
- def define_object_definition_methods(object_definitions)
48
- object_definitions.each do |(object, _definition)|
65
+ sig { void }
66
+ def define_object_definition_methods
67
+ object_definitions_source.each do |(object, _definition)|
49
68
  define_singleton_method(object) do
50
- @object_definitions ||= {}
51
69
  @object_definitions[object] ||= ObjectDefinition.new(name: object, object_definitions: self)
52
70
  end
53
71
  end
54
72
  end
55
73
 
74
+ sig { returns(Operation) }
75
+ def create_operation
76
+ Operation.new(methods: methods_source, connection: connection)
77
+ end
78
+
56
79
  class ObjectDefinition
80
+ extend T::Sig
81
+
82
+ sig { params(name: T.any(String, Symbol), object_definitions: ObjectDefinitions).void }
57
83
  def initialize(name:, object_definitions:)
58
- @object_definitions = object_definitions
59
84
  @name = name
85
+ @object_definitions = object_definitions
60
86
  end
61
87
 
88
+ sig do
89
+ params(
90
+ settings: T.nilable(SorbetTypes::SettingsHash),
91
+ config_fields: SorbetTypes::OperationInputHash
92
+ ).returns(SorbetTypes::ObjectDefinitionOutput)
93
+ end
62
94
  def fields(settings = nil, config_fields = {})
63
95
  object_definitions_lazy_hash = @object_definitions.lazy(settings, config_fields)
64
96
  object_definitions_lazy_hash[@name]
65
97
  end
66
98
  end
67
99
 
100
+ private_constant :ObjectDefinition
101
+
68
102
  class DupHashWithIndifferentAccess < HashWithIndifferentAccess
103
+ extend T::Sig
104
+ extend T::Generic
105
+
106
+ K = type_member { { fixed: T.any(String, Symbol) } }
107
+ V = type_member { { fixed: T.untyped } }
108
+ Elem = type_member { { fixed: T.untyped } }
109
+
110
+ sig { params(name: K).returns(V) }
69
111
  def [](name)
70
112
  super.deep_dup
71
113
  end
72
114
  end
73
115
 
74
- private_constant 'ObjectDefinition'
75
- private_constant 'DupHashWithIndifferentAccess'
116
+ private_constant :DupHashWithIndifferentAccess
76
117
  end
77
118
  end
78
119
  end
@@ -225,7 +225,7 @@ module Workato
225
225
  def resolve_request(request_or_result)
226
226
  case request_or_result
227
227
  when Request
228
- resolve_request(request_or_result.execute!)
228
+ resolve_request(request_or_result.response!)
229
229
  when ::Array
230
230
  request_or_result.each_with_index.inject(request_or_result) do |acc, (item, index)|
231
231
  response_item = resolve_request(item)
@@ -39,10 +39,10 @@ module Workato
39
39
  end
40
40
 
41
41
  def method_missing(...)
42
- execute!.send(...)
42
+ response!.send(...)
43
43
  end
44
44
 
45
- def execute!
45
+ def response!
46
46
  __getobj__ || __setobj__(response)
47
47
  rescue RestClient::Exceptions::Timeout => e
48
48
  Kernel.raise RequestTimeoutError, e
@@ -254,7 +254,7 @@ module Workato
254
254
  end
255
255
 
256
256
  def try(...)
257
- execute!.try(...)
257
+ response!.try(...)
258
258
  end
259
259
 
260
260
  private
@@ -513,6 +513,8 @@ module Workato
513
513
  attr_reader :original_filename
514
514
  end
515
515
 
516
+ private_constant :Part
517
+
516
518
  class RestClientRequest < ::RestClient::Request
517
519
  def initialize(args)
518
520
  super
@@ -540,6 +542,7 @@ module Workato
540
542
  net
541
543
  end
542
544
  end
545
+
543
546
  private_constant :RestClientRequest
544
547
  end
545
548
  end
@@ -101,7 +101,7 @@ 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::Types::Binary, Type::UnicodeString,
104
+ when ::Numeric, ::TrueClass, ::FalseClass, Workato::Types::Binary, Workato::Types::UnicodeString,
105
105
  ::Array, ::Hash, Stream::Proxy
106
106
  return value
107
107
  when Extension::Array::ArrayWhere
@@ -111,7 +111,7 @@ module Workato
111
111
  return Workato::Types::Binary.new(value)
112
112
  end
113
113
 
114
- return Type::UnicodeString.new(value)
114
+ return Workato::Types::UnicodeString.new(value)
115
115
  else
116
116
  if value.respond_to?(:to_time)
117
117
  return Type::Time.from_time(value.to_time)
@@ -127,6 +127,8 @@ module Workato
127
127
  end
128
128
  end
129
129
 
130
+ private_constant :Schema
131
+
130
132
  class Fields < ::Array
131
133
  def initialize(fields)
132
134
  ::Array.wrap(fields).each do |field|
@@ -232,4 +234,3 @@ require_relative './schema/field/object'
232
234
  require_relative './schema/field/string'
233
235
 
234
236
  require_relative './schema/type/time'
235
- require_relative './schema/type/unicode_string'
@@ -82,7 +82,7 @@ module Workato
82
82
 
83
83
  def read_plain_file
84
84
  all_settings = File.open(path) do |f|
85
- YAML.safe_load(f.read, [::Symbol]).to_hash.with_indifferent_access
85
+ YAML.safe_load(f.read, permitted_classes: [::Symbol]).to_hash.with_indifferent_access
86
86
  end
87
87
 
88
88
  (name ? all_settings.fetch(name) : all_settings) || {}
@@ -144,6 +144,8 @@ module Workato
144
144
  raise MissingKeyError.new(key_path: key_path, env_key: env_key) if raise_if_missing_key
145
145
  end
146
146
  end
147
+
148
+ private_constant :FixedEncryptedConfiguration
147
149
  end
148
150
  end
149
151
  end
@@ -79,6 +79,22 @@ module Workato
79
79
  data
80
80
  end
81
81
 
82
+ class << self
83
+ extend T::Sig
84
+
85
+ sig do
86
+ params(
87
+ stream: T.any(Proxy, T::Hash[T.untyped, T.untyped], String),
88
+ from: T.nilable(Integer),
89
+ frame_size: T.nilable(Integer),
90
+ blk: SorbetTypes::StreamInProc
91
+ ).void
92
+ end
93
+ def each_chunk(stream:, from:, frame_size: nil, &blk)
94
+ Reader.new(stream: stream, from: from, frame_size: frame_size).each_chunk(&blk)
95
+ end
96
+ end
97
+
82
98
  class Reader
83
99
  extend T::Sig
84
100
 
@@ -153,6 +169,9 @@ module Workato
153
169
  end
154
170
  end
155
171
 
172
+ private_constant :Reader
173
+
174
+ # @api private
156
175
  class Proxy
157
176
  extend T::Sig
158
177
 
@@ -193,7 +212,7 @@ module Workato
193
212
  attr_reader :input
194
213
 
195
214
  class Chunk < T::Struct
196
- const :data, T.untyped
215
+ const :data, T.untyped # rubocop:disable Sorbet/ForbidUntypedStructProps
197
216
  const :from, Integer
198
217
  const :eof, T::Boolean
199
218
  const :next_from, T.nilable(Integer)
@@ -212,9 +231,9 @@ module Workato
212
231
  class Mock
213
232
  extend T::Sig
214
233
 
215
- sig { params(chunks: T.untyped).void }
234
+ sig { params(chunks: T::Hash[T.any(Integer, String), T.untyped]).void }
216
235
  def initialize(chunks:)
217
- @chunks = chunks
236
+ @chunks = T.let(chunks.transform_keys(&:to_i), T::Hash[Integer, T.untyped])
218
237
  end
219
238
 
220
239
  sig { params(from: Integer, frame_size: Integer, _blk: Reader::ProxyReadProc).void }
@@ -56,6 +56,7 @@ module Workato
56
56
  attr_reader :connection
57
57
  end
58
58
 
59
+ # @api private
59
60
  class ProhibitedStreams < Streams
60
61
  extend T::Sig
61
62
 
@@ -57,6 +57,8 @@ module Workato
57
57
  end
58
58
  end
59
59
  end
60
+
61
+ private_constant :Summarize
60
62
  end
61
63
  end
62
64
  end
@@ -8,6 +8,7 @@ require 'active_support/all'
8
8
  require 'active_support/json'
9
9
 
10
10
  require_relative '../types/binary'
11
+ require_relative '../types/unicode_string'
11
12
 
12
13
  require_relative '../extension/array'
13
14
  require_relative '../extension/case_sensitive_headers'
@@ -17,7 +17,7 @@ module Workato
17
17
  map { |r| r.to_csv(options) }.join
18
18
  else
19
19
  options.delete(:multi_line)
20
- super(options)
20
+ super(**options)
21
21
  end
22
22
  end
23
23
 
@@ -45,8 +45,6 @@ module Enumerable
45
45
  nil
46
46
  end
47
47
 
48
- private
49
-
50
48
  def transform_select(&block)
51
49
  map do |*items|
52
50
  result = block.call(*items)
@@ -12,10 +12,10 @@ module Workato
12
12
  attr_accessor :extra_chain_cert
13
13
 
14
14
  def self.included(base)
15
- ssl_ivnames = base.const_get('SSL_IVNAMES', false)
15
+ ssl_ivnames = base.const_get('SSL_IVNAMES', false) # rubocop:disable Sorbet/ConstantsFromStrings
16
16
  ssl_ivnames << :@extra_chain_cert unless ssl_ivnames.include?(:@extra_chain_cert)
17
17
 
18
- ssl_attributes = base.const_get('SSL_ATTRIBUTES', false)
18
+ ssl_attributes = base.const_get('SSL_ATTRIBUTES', false) # rubocop:disable Sorbet/ConstantsFromStrings
19
19
  ssl_attributes << :extra_chain_cert unless ssl_attributes.include?(:extra_chain_cert)
20
20
  end
21
21
  end
@@ -1,3 +1,4 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'active_support/messages/metadata'
@@ -16,6 +16,15 @@ module Workato
16
16
  end
17
17
  end
18
18
 
19
+ def binary?
20
+ warn <<~WARNING
21
+ WARNING: Ambiguous use of `String#binary?' method.
22
+ For correct behavior of `binary?` method use explicit Workato::Types::UnicodeString for input strings and Workato::Types::Binary for input binaries
23
+ See: https://www.rubydoc.info/gems/workato-connector-sdk/Workato/Types
24
+ WARNING
25
+ encoding == Encoding::ASCII_8BIT
26
+ end
27
+
19
28
  def is_int? # rubocop:disable Naming/PredicateName
20
29
  present? && (self !~ /\D/)
21
30
  end
@@ -36,8 +45,7 @@ module Workato
36
45
  end
37
46
 
38
47
  def strip_tags
39
- @html_full_sanitizer ||= Rails::Html::Sanitizer.full_sanitizer.new
40
- @html_full_sanitizer.sanitize(self)
48
+ Rails::Html::Sanitizer.full_sanitizer.new.sanitize(self)
41
49
  end
42
50
 
43
51
  def to_time(form = :local, format: nil)
@@ -5,6 +5,7 @@ module Workato
5
5
  module Testing
6
6
  class VCRMultipartBodyMatcher
7
7
  MULTIPART_HEADER_MATCHER = %r{^multipart/form-data; boundary=(.+)$}.freeze
8
+ private_constant :MULTIPART_HEADER_MATCHER
8
9
 
9
10
  class << self
10
11
  def call(request1, request2)
@@ -1,7 +1,49 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Workato
4
5
  module Types
6
+ # Explicit wrapper for binary data
7
+ #
8
+ # Workato runtime always converts a String to {Workato::Types::UnicodeString} and
9
+ # binary data to {Workato::Types::Binary} before execute an action.
10
+ #
11
+ # == Call action or trigger by name
12
+ #
13
+ # SDK emulator applies trigger's or action's input/output schema and normalize string when invoke them by name.
14
+ # If you call an operation like this, then emulator passes input with
15
+ # {Workato::Types::UnicodeString} or {Workato::Types::Binary} to the operation
16
+ #
17
+ # CLI
18
+ # workato exec 'actions.test_action'
19
+ # workato exec 'triggers.test_poll_trigger'
20
+ #
21
+ # RSpec
22
+ # connector.actions.test_action.invoke(input)
23
+ # connector.triggers.test_poll_trigger.invoke(input)
24
+ #
25
+ # == Direct call to execute or poll block
26
+ #
27
+ # Schema is not applied when call an action's execute block directly. For example
28
+ #
29
+ # CLI
30
+ # workato exec 'actions.test_action.execute'
31
+ #
32
+ # RSpec
33
+ # connector.actions.test_action.execute(settings, input, input_schema, output_schema)
34
+ #
35
+ # In that case if action's code relies on methods of {Workato::Types::UnicodeString} or {Workato::Types::Binary}
36
+ # then this explicit wrapper should be used for correct behavior.
37
+ #
38
+ # @example
39
+ # input = {
40
+ # file_content: Workato::Types::Binary.new(File.read('/path/to/file.bin', 'wb')),
41
+ # file_name: Workato::Types::UnicodeString.new("Hello World!")
42
+ # }
43
+ #
44
+ # connector.actions.upload(settings, input)
45
+ #
46
+ # @see Workato::Types::UnicodeString
5
47
  class Binary < ::String
6
48
  TITLE_LENGTH = 16
7
49
  SUMMARY_LENGTH = 128
@@ -19,6 +61,9 @@ module Workato
19
61
  summary
20
62
  end
21
63
 
64
+ # Returns true for binary data
65
+ #
66
+ # @return [Boolean]
22
67
  def binary?
23
68
  true
24
69
  end
@@ -0,0 +1,62 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module Workato
5
+ module Types
6
+ # Explicit wrapper for unicode strings.
7
+ #
8
+ # Workato runtime always converts a String to {Workato::Types::UnicodeString} and
9
+ # binary data to {Workato::Types::Binary} before execute an action.
10
+ #
11
+ # == Call action or trigger by name
12
+ #
13
+ # SDK emulator applies trigger's or action's input/output schema and normalize string when invoke them by name.
14
+ # If you call an operation like this, then emulator passes input with
15
+ # {Workato::Types::UnicodeString} or {Workato::Types::Binary} to the operation
16
+ #
17
+ # CLI
18
+ # workato exec 'actions.test_action'
19
+ # workato exec 'triggers.test_poll_trigger'
20
+ #
21
+ # RSpec
22
+ # connector.actions.test_action.invoke(input)
23
+ # connector.triggers.test_poll_trigger.invoke(input)
24
+ #
25
+ # == Direct call to execute or poll block
26
+ #
27
+ # Schema is not applied when call an action's execute block directly. For example
28
+ #
29
+ # CLI
30
+ # workato exec 'actions.test_action.execute'
31
+ #
32
+ # RSpec
33
+ # connector.actions.test_action.execute(settings, input, input_schema, output_schema)
34
+ #
35
+ # In that case if action's code relies on methods of {Workato::Types::UnicodeString} or {Workato::Types::Binary}
36
+ # then this explicit wrapper should be used for correct behavior.
37
+ #
38
+ # @example
39
+ # input = {
40
+ # file_content: Workato::Types::Binary.new(File.read('/path/to/file.bin', 'wb')),
41
+ # file_name: Workato::Types::UnicodeString.new("Hello World!")
42
+ # }
43
+ #
44
+ # connector.actions.upload(settings, input)
45
+ #
46
+ # @see Workato::Types::Binary
47
+ class UnicodeString < ::String
48
+ # @param str Ruby string
49
+ def initialize(str)
50
+ super(str, **{})
51
+ encode!('UTF-8')
52
+ end
53
+
54
+ # Returns false for unicode strings
55
+ #
56
+ # @return [Boolean]
57
+ def binary?
58
+ false
59
+ end
60
+ end
61
+ end
62
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workato-connector-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Abolmasov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-26 00:00:00.000000000 Z
11
+ date: 2023-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -164,34 +164,6 @@ dependencies:
164
164
  - - '='
165
165
  - !ruby/object:Gem::Version
166
166
  version: 1.13.10
167
- - !ruby/object:Gem::Dependency
168
- name: oauth2
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: '1.0'
174
- type: :runtime
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - "~>"
179
- - !ruby/object:Gem::Version
180
- version: '1.0'
181
- - !ruby/object:Gem::Dependency
182
- name: psych
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
186
- - !ruby/object:Gem::Version
187
- version: '3.0'
188
- type: :runtime
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
193
- - !ruby/object:Gem::Version
194
- version: '3.0'
195
167
  - !ruby/object:Gem::Dependency
196
168
  name: rack
197
169
  requirement: !ruby/object:Gem::Requirement
@@ -410,6 +382,7 @@ executables:
410
382
  extensions: []
411
383
  extra_rdoc_files: []
412
384
  files:
385
+ - ".yardopts"
413
386
  - LICENSE.md
414
387
  - README.md
415
388
  - VERSION
@@ -461,7 +434,6 @@ files:
461
434
  - lib/workato/connector/sdk/schema/field/object.rb
462
435
  - lib/workato/connector/sdk/schema/field/string.rb
463
436
  - lib/workato/connector/sdk/schema/type/time.rb
464
- - lib/workato/connector/sdk/schema/type/unicode_string.rb
465
437
  - lib/workato/connector/sdk/settings.rb
466
438
  - lib/workato/connector/sdk/stream.rb
467
439
  - lib/workato/connector/sdk/streams.rb
@@ -493,6 +465,7 @@ files:
493
465
  - lib/workato/testing/vcr_encrypted_cassette_serializer.rb
494
466
  - lib/workato/testing/vcr_multipart_body_matcher.rb
495
467
  - lib/workato/types/binary.rb
468
+ - lib/workato/types/unicode_string.rb
496
469
  - lib/workato/utilities/encoding.rb
497
470
  - lib/workato/utilities/xml.rb
498
471
  - lib/workato/web/app.rb
@@ -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