workato-connector-sdk 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b49034b5762b2b44d0987d72eb74327e379284347b793714149d85d354a5bb57
4
- data.tar.gz: 1be17d19381fe42689ef4a157a56eca0fb8c61a9c0e90e981e5a373305ed771f
3
+ metadata.gz: 2a456929ee155b6a048f547defcb4f3ccfcdd2172c1e0539ca601d8268bc0060
4
+ data.tar.gz: 588a1bae54828aa7fb750aaa53ca57336c14693478ac096b810b441008186fde
5
5
  SHA512:
6
- metadata.gz: 5bcc365d25ec713df12b75d9d6d5fb8a6a73266b94cf012829e4a2c98af955f1fcfa7b0d0f7e69861a4ee6cb54af24ed8952bbb590553e93a37fcf2933c69459
7
- data.tar.gz: 1da6193b9a1b04e3d3e2c6fb34fcd0eeec7666908c61df5c7ec386381ba8f33207b50b8ffc1e9d581fecb599fc423f84f9f79867120322356aa4d645b9b7da5e
6
+ metadata.gz: 5ab021777798644396d5d910c6d3c6f6ebf7ef23956ca7c3b5e79ec2d01d9f59776ea7afa4cbf8c9d501d18c4fc8142e1d4794e15bb3ade22692a3a95c94e4f4
7
+ data.tar.gz: e101977c93f1d878cd27c7170e143fbaf7f1221b52d80c489c5ca37915783662bd8571041bae0d4ad75094851ad74f00e6434c331da902d580e9e13098eb21a5
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
@@ -13,7 +13,7 @@ This guide below showcases how you can do the following things:
13
13
 
14
14
  ## Prerequisites
15
15
  1. Install [RVM ("Ruby Version Manager")](http://rvm.io/) or a Ruby manager of your choice. You can find more at [here](https://www.ruby-lang.org/en/documentation/installation/)
16
- 2. Choose between Ruby versions `2.4.10` `2.5.X` or `2.7.X`. Our preferred version is `2.7.X`.
16
+ 2. Choose between Ruby versions `2.7.X`, `3.0.X`, `3.1.X`. Our preferred version is `2.7.6`.
17
17
  3. Verify you're running a valid ruby version. Do this by running either `ruby -v` or the commands within your version manager. i.e., `rvm current` if you have installed RVM.
18
18
  4. For Windows you need tzinfo-data gem installed as well. `gem install tzinfo-data`
19
19
  5. SDK depends on `charlock_holmes` gem. Check [gem's documentation](https://github.com/brianmario/charlock_holmes#installing) if you have troubles when install this dependency. Additional [details for Windows](https://github.com/brianmario/charlock_holmes/issues/84#issuecomment-652877605)
@@ -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.
@@ -1124,7 +1121,7 @@ jobs:
1124
1121
  runs-on: ubuntu-latest
1125
1122
  strategy:
1126
1123
  matrix:
1127
- ruby-version: ['2.4.10', '2.5', '2.7']
1124
+ ruby-version: ['2.7', '3.0', '3.1']
1128
1125
 
1129
1126
  steps:
1130
1127
  - uses: actions/checkout@v2
@@ -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 ADDED
@@ -0,0 +1 @@
1
+ 1.3.1
@@ -3,6 +3,8 @@
3
3
 
4
4
  require 'active_support/encrypted_configuration'
5
5
 
6
+ require_relative '../extension/metadata_fix_wrap_kw_args'
7
+
6
8
  module Workato
7
9
  module CLI
8
10
  class EditCommand
@@ -23,7 +25,7 @@ module Workato
23
25
 
24
26
  catch_editing_exceptions do
25
27
  encrypted_config.change do |tmp_path|
26
- system("#{ENV['EDITOR']} #{tmp_path}")
28
+ system("#{ENV.fetch('EDITOR', nil)} #{tmp_path}")
27
29
  end
28
30
  end
29
31
 
@@ -1,9 +1,12 @@
1
- # typed: false
1
+ # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'thor'
5
+ require 'active_support/json'
5
6
  require_relative './multi_auth_selected_fallback'
6
7
 
8
+ Method.prepend(T::CompatibilityPatches::MethodExtensions)
9
+
7
10
  module Workato
8
11
  module CLI
9
12
  class ExecCommand
@@ -21,7 +24,7 @@ module Workato
21
24
  load_from_default_files
22
25
  inspect_params(params)
23
26
  output = with_progress { execute_path }
24
- show_output(output)
27
+ show_output(output.as_json)
25
28
  output
26
29
  end
27
30
 
@@ -65,8 +68,12 @@ module Workato
65
68
  oauth2_code: options[:oauth2_code],
66
69
  redirect_url: options[:redirect_url],
67
70
  refresh_token: options[:refresh_token],
71
+ from: options[:from].to_i,
72
+ frame_size: options[:frame_size]&.to_i || Workato::Connector::Sdk::Stream::DEFAULT_FRAME_SIZE,
68
73
  recipe_id: Workato::Connector::Sdk::Operation.recipe_id!
69
- }
74
+ }.tap do |h|
75
+ h[:to] = h[:from] + h[:frame_size] - 1
76
+ end
70
77
  end
71
78
 
72
79
  def connector
@@ -94,9 +101,10 @@ module Workato
94
101
  end
95
102
  end
96
103
 
97
- Workato::Connector::Sdk::Connection.on_settings_update = lambda do |message, &refresher|
104
+ Workato::Connector::Sdk::Connection.on_settings_update = lambda do |message, _settings_before, refresher|
98
105
  new_settings = refresher.call
99
106
  break unless new_settings
107
+ break new_settings if @settings == new_settings
100
108
 
101
109
  with_user_interaction do
102
110
  loop do
@@ -105,6 +113,7 @@ module Workato
105
113
  break new_settings if %w[n no].include?(answer)
106
114
  next unless %w[y yes].include?(answer)
107
115
 
116
+ @settings.merge!(new_settings)
108
117
  settings_store.update(new_settings)
109
118
  break new_settings
110
119
  end
@@ -135,11 +144,11 @@ module Workato
135
144
  end
136
145
 
137
146
  def execute_path
138
- connector.invoke(path, params)
147
+ InvokePath.new(path: path, connector: connector, params: params).call
139
148
  rescue Workato::Connector::Sdk::InvalidMultiAuthDefinition => e
140
- raise "#{e.message}. Please ensure:\n"\
149
+ raise "#{e.message}. Please ensure:\n" \
141
150
  "- 'selected' block is defined and returns value from 'options' list\n" \
142
- "- settings file contains value expected by 'selected' block\n\n"\
151
+ "- settings file contains value expected by 'selected' block\n\n" \
143
152
  'See more: https://docs.workato.com/developing-connectors/sdk/guides/authentication/multi_auth.html'
144
153
  rescue Exception => e # rubocop:disable Lint/RescueException
145
154
  raise DebugExceptionError, e if options[:debug]
@@ -149,9 +158,7 @@ module Workato
149
158
 
150
159
  def show_output(output)
151
160
  if options[:output].present?
152
- File.open(options[:output], 'w') do |f|
153
- f.write(JSON.dump(output))
154
- end
161
+ File.write(options[:output], JSON.dump(output))
155
162
  elsif options[:output].nil?
156
163
  say('OUTPUT') if verbose?
157
164
  jj output
@@ -214,6 +221,65 @@ module Workato
214
221
  alias puts log
215
222
  alias print log
216
223
  end
224
+
225
+ class InvokePath
226
+ extend T::Sig
227
+
228
+ sig do
229
+ params(
230
+ path: String,
231
+ connector: Workato::Connector::Sdk::Connector,
232
+ params: T::Hash[Symbol, T.untyped]
233
+ ).void
234
+ end
235
+ def initialize(path:, connector:, params:)
236
+ @path = T.let(path, String)
237
+ @connector = T.let(connector, Workato::Connector::Sdk::Connector)
238
+ @params = T.let(params, T::Hash[Symbol, T.untyped])
239
+ end
240
+
241
+ sig { returns(T.untyped) }
242
+ def call
243
+ invoke_path
244
+ end
245
+
246
+ private
247
+
248
+ sig { returns(String) }
249
+ attr_reader :path
250
+
251
+ sig { returns(Workato::Connector::Sdk::Connector) }
252
+ attr_reader :connector
253
+
254
+ sig { returns(T::Hash[Symbol, T.untyped]) }
255
+ attr_reader :params
256
+
257
+ sig { returns(T.untyped) }
258
+ def invoke_path
259
+ methods = path.split('.')
260
+ method = methods.pop
261
+ raise ArgumentError, 'path is not found' unless method
262
+
263
+ object = methods.inject(connector) { |obj, m| obj.public_send(m) }
264
+ output = invoke_method(object, method)
265
+ if output.respond_to?(:invoke)
266
+ invoke_method(output, :invoke)
267
+ else
268
+ output
269
+ end
270
+ end
271
+
272
+ sig { params(object: T.untyped, method: T.any(Symbol, String)).returns(T.untyped) }
273
+ def invoke_method(object, method)
274
+ parameters = object.method(method).parameters.reject { |p| p[0] == :block }.map(&:second)
275
+ args = params.values_at(*parameters)
276
+ if parameters.last == :args
277
+ args = args.take(args.length - 1) + Array.wrap(args.last).flatten(1)
278
+ end
279
+ object.public_send(method, *args)
280
+ end
281
+ end
282
+ private_constant :InvokePath
217
283
  end
218
284
  end
219
285
  end
@@ -50,8 +50,9 @@ 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
- desc: 'Email for accessing Workato API or '\
55
+ desc: 'Email for accessing Workato API or ' \
55
56
  "set #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} environment variable"
56
57
  method_option :api_token,
57
58
  type: :string,
@@ -125,7 +126,7 @@ module Workato
125
126
  end
126
127
 
127
128
  def sanitized_filename(name)
128
- name.downcase.gsub(/[^0-9A-z.\-]/, '_')
129
+ name.downcase.gsub(/[^0-9A-z.-]/, '_')
129
130
  end
130
131
  end
131
132
  end
@@ -34,14 +34,14 @@ module Workato
34
34
  method_option :connector, type: :string, aliases: '-c', desc: 'Path to connector source code',
35
35
  lazy_default: Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH
36
36
  method_option :settings, type: :string, aliases: '-s',
37
- desc: 'Path to plain or encrypted file with connection configs, '\
37
+ desc: 'Path to plain or encrypted file with connection configs, ' \
38
38
  'passwords, tokens, secrets etc',
39
39
  lazy_default: Workato::Connector::Sdk::DEFAULT_ENCRYPTED_SETTINGS_PATH
40
40
  method_option :connection, type: :string, aliases: '-n',
41
41
  desc: 'Connection name if settings file contains multiple settings'
42
42
  method_option :key, type: :string, aliases: '-k',
43
43
  lazy_default: Workato::Connector::Sdk::DEFAULT_MASTER_KEY_PATH,
44
- desc: "Path to file with encrypt/decrypt key.\n"\
44
+ desc: "Path to file with encrypt/decrypt key.\n" \
45
45
  "NOTE: key from #{Workato::Connector::Sdk::DEFAULT_MASTER_KEY_ENV} has higher priority"
46
46
  method_option :input, type: :string, aliases: '-i', desc: 'Path to file with input JSON'
47
47
  method_option :closure, type: :string, desc: 'Path to file with next poll closure JSON'
@@ -61,6 +61,8 @@ module Workato
61
61
  method_option :oauth2_code, type: :string, desc: 'OAuth2 code exchange to tokens pair'
62
62
  method_option :redirect_url, type: :string, desc: 'OAuth2 callback url'
63
63
  method_option :refresh_token, type: :string, desc: 'OAuth2 refresh token'
64
+ method_option :from, type: :numeric, desc: 'Stream byte offset to read from'
65
+ method_option :frame_size, type: :numeric, desc: 'Stream chunk read size in bytes. Should be positive'
64
66
 
65
67
  method_option :debug, type: :boolean
66
68
 
@@ -75,7 +77,7 @@ module Workato
75
77
 
76
78
  method_option :key, type: :string, aliases: '-k',
77
79
  lazy_default: Workato::Connector::Sdk::DEFAULT_MASTER_KEY_PATH,
78
- desc: "Path to file with encrypt/decrypt key.\n"\
80
+ desc: "Path to file with encrypt/decrypt key.\n" \
79
81
  "NOTE: key from #{Workato::Connector::Sdk::DEFAULT_MASTER_KEY_ENV} has higher priority"
80
82
 
81
83
  def edit(path)
@@ -126,20 +128,21 @@ module Workato
126
128
  desc: 'Path to connector source code',
127
129
  lazy_default: Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH
128
130
  method_option :api_email,
131
+ hide: true,
129
132
  type: :string,
130
- desc: "Email for accessing Workato API.\n"\
131
- "If present overrides value from #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} "\
133
+ desc: "Email for accessing Workato API.\n" \
134
+ "If present overrides value from #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} " \
132
135
  'environment variable.'
133
136
  method_option :api_token,
134
137
  type: :string,
135
138
  desc: "Token for accessing Workato API.\n" \
136
- "If present overrides value from #{Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV} "\
139
+ "If present overrides value from #{Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV} " \
137
140
  'environment variable.'
138
141
  method_option :environment,
139
142
  type: :string,
140
- desc: "Data center specific URL to push connector code.\n"\
141
- "If present overrides value from #{Workato::Connector::Sdk::WORKATO_BASE_URL_ENV} "\
142
- "environment variable.\n"\
143
+ desc: "Data center specific URL to push connector code.\n" \
144
+ "If present overrides value from #{Workato::Connector::Sdk::WORKATO_BASE_URL_ENV} " \
145
+ "environment variable.\n" \
143
146
  "Examples: 'https://app.workato.com', 'https://app.eu.workato.com'"
144
147
  method_option :folder,
145
148
  type: :string,
@@ -171,7 +174,7 @@ module Workato
171
174
  type: :string,
172
175
  aliases: '-k',
173
176
  lazy_default: Workato::Connector::Sdk::DEFAULT_MASTER_KEY_PATH,
174
- desc: "Path to file with encrypt/decrypt key.\n"\
177
+ desc: "Path to file with encrypt/decrypt key.\n" \
175
178
  "NOTE: key from #{Workato::Connector::Sdk::DEFAULT_MASTER_KEY_ENV} has higher priority"
176
179
  method_option :port,
177
180
  type: :string,
@@ -191,6 +194,11 @@ module Workato
191
194
  ).call
192
195
  end
193
196
 
197
+ desc 'version', 'Shows gem version'
198
+ def version
199
+ puts Workato::Connector::Sdk::VERSION
200
+ end
201
+
194
202
  class << self
195
203
  def print_options(shell, options, group_name = nil)
196
204
  return if options.empty?
@@ -105,14 +105,14 @@ module Workato
105
105
 
106
106
  def ensure_oauth2_type
107
107
  unless connector.connection.authorization.oauth2?
108
- raise 'Authorization type is not OAuth2. '\
109
- 'For multi-auth connector ensure correct auth type was used. '\
108
+ raise 'Authorization type is not OAuth2. ' \
109
+ 'For multi-auth connector ensure correct auth type was used. ' \
110
110
  "Expected: 'oauth2', got: '#{connector.connection.authorization.type}''"
111
111
  end
112
112
  rescue Workato::Connector::Sdk::InvalidMultiAuthDefinition => e
113
- raise "#{e.message}. Please ensure:\n"\
113
+ raise "#{e.message}. Please ensure:\n" \
114
114
  "- 'selected' block is defined and returns value from 'options' list\n" \
115
- "- settings file contains value expected by 'selected' block\n\n"\
115
+ "- settings file contains value expected by 'selected' block\n\n" \
116
116
  'See more: https://docs.workato.com/developing-connectors/sdk/guides/authentication/multi_auth.html'
117
117
  end
118
118
 
@@ -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
@@ -35,8 +36,8 @@ module Workato
35
36
  @api_base_url = ENVIRONMENTS.fetch(options[:environment]) do
36
37
  options[:environment].presence || Workato::Connector::Sdk::WORKATO_BASE_URL
37
38
  end
38
- @api_email = options[:api_email] || ENV[Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV]
39
- @api_token = options[:api_token] || ENV[Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV]
39
+ @api_email = options[:api_email] || ENV.fetch(Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV, nil)
40
+ @api_token = options[:api_token] || ENV.fetch(Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV, nil)
40
41
  @folder_id = options[:folder]
41
42
  end
42
43
 
@@ -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
@@ -12,8 +12,8 @@ module Workato
12
12
  API_GENERATE_SCHEMA_PATH = '/api/sdk/generate_schema'
13
13
 
14
14
  def initialize(options:)
15
- @api_email = options[:api_email] || ENV[Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV]
16
- @api_token = options[:api_token] || ENV[Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV]
15
+ @api_email = options[:api_email] || ENV.fetch(Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV, nil)
16
+ @api_token = options[:api_token] || ENV.fetch(Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV, nil)
17
17
  @options = options
18
18
  end
19
19
 
@@ -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
 
@@ -29,9 +29,9 @@ module Workato
29
29
  end
30
30
 
31
31
  def self.from_csv(path = './account_properties.csv')
32
- props = CSV.foreach(path, headers: true, return_headers: false).map do |row|
32
+ props = CSV.foreach(path, headers: true, return_headers: false).to_h do |row|
33
33
  [row[0], row[1]]
34
- end.to_h
34
+ end
35
35
  instance.load_data(props)
36
36
  end
37
37
 
@@ -11,29 +11,34 @@ module Workato
11
11
  extend T::Sig
12
12
  using BlockInvocationRefinements
13
13
 
14
+ include Dsl::ReinvokeAfter
15
+
14
16
  RETRY_DEFAULT_CODES = T.let([429, 500, 502, 503, 504, 507].freeze, T::Array[Integer])
15
17
  RETRY_DEFAULT_METHODS = T.let(%i[get head].freeze, T::Array[Symbol])
16
18
  RETRY_DELAY = T.let(5, Integer) # seconds
19
+ RETRY_DELAY_EXP_BASE = T.let(2, Integer)
17
20
  MAX_RETRIES = 3
18
21
 
19
- MAX_REINVOKES = 5
20
-
21
22
  sig do
22
23
  params(
23
24
  action: SorbetTypes::SourceHash,
24
25
  methods: SorbetTypes::SourceHash,
25
26
  connection: Connection,
26
- object_definitions: T.nilable(ObjectDefinitions)
27
+ object_definitions: T.nilable(ObjectDefinitions),
28
+ streams: Streams
27
29
  ).void
28
30
  end
29
- def initialize(action:, methods: {}, connection: Connection.new, object_definitions: nil)
31
+ def initialize(action:, methods: {}, connection: Connection.new, object_definitions: nil,
32
+ streams: ProhibitedStreams.new)
30
33
  super(
31
34
  operation: action,
32
35
  connection: connection,
33
36
  methods: methods,
34
- object_definitions: object_definitions
37
+ object_definitions: object_definitions,
38
+ streams: streams
35
39
  )
36
40
 
41
+ @retry_delay_factor = T.let(1, Integer)
37
42
  @retries_left = T.let(0, Integer)
38
43
  @retry_codes = T.let([], T::Array[Integer])
39
44
  @retry_methods = T.let([], T::Array[String])
@@ -58,33 +63,21 @@ module Workato
58
63
  &block)
59
64
  raise InvalidDefinitionError, "'execute' block is required for action" unless block || action[:execute]
60
65
 
61
- loop do
62
- if @reinvokes_remaining&.zero?
63
- raise "Max number of reinvokes on SDK Gem reached. Current limit is #{reinvoke_limit}"
64
- end
65
-
66
- reinvoke_sleep if @reinvoke_after
67
-
68
- reinvoke_reset
69
-
70
- result = super(
66
+ loop_reinvoke_after(continue) do |next_continue|
67
+ return super(
71
68
  settings,
72
69
  input,
73
70
  extended_input_schema,
74
71
  extended_output_schema,
75
- continue,
72
+ next_continue,
76
73
  &(block || action[:execute])
77
74
  )
78
-
79
- break result unless @reinvoke_after
80
-
81
- continue = @reinvoke_after.continue
82
75
  end
83
- rescue RequestError => e
76
+ rescue RequestFailedError => e
84
77
  raise e unless retry?(e)
85
78
 
86
79
  @retries_left -= 1
87
- sleep(RETRY_DELAY)
80
+ retry_sleep
88
81
  retry
89
82
  end
90
83
 
@@ -100,32 +93,6 @@ module Workato
100
93
  apply_output_schema(output, output_schema)
101
94
  end
102
95
 
103
- sig do
104
- params(
105
- continue: T::Hash[T.untyped, T.untyped],
106
- temp_output: T.nilable(T::Hash[T.untyped, T.untyped])
107
- ).void
108
- end
109
- def checkpoint!(continue:, temp_output: nil)
110
- # no-op
111
- end
112
-
113
- sig do
114
- params(
115
- seconds: Integer,
116
- continue: T::Hash[T.untyped, T.untyped],
117
- temp_output: T.nilable(T::Hash[T.untyped, T.untyped])
118
- ).void
119
- end
120
- def reinvoke_after(seconds:, continue:, temp_output: nil) # rubocop:disable Lint/UnusedMethodArgument
121
- @reinvokes_remaining = T.let(@reinvokes_remaining, T.nilable(Integer))
122
- @reinvokes_remaining = (@reinvokes_remaining ? @reinvokes_remaining - 1 : reinvoke_limit)
123
- @reinvoke_after = ReinvokeAfter.new(
124
- seconds: seconds,
125
- continue: continue
126
- )
127
- end
128
-
129
96
  private
130
97
 
131
98
  sig { returns(T::Array[T.any(Symbol, String, Regexp, Integer)]) }
@@ -150,10 +117,10 @@ module Workato
150
117
  retry_on_response.each { |m| m.is_a?(::Integer) ? @retry_codes << m : @retry_matchers << m }
151
118
  @retry_codes = RETRY_DEFAULT_CODES if @retry_codes.empty?
152
119
  @retry_methods = (retry_on_request.presence || RETRY_DEFAULT_METHODS).map(&:to_s).map(&:downcase)
153
- @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, MAX_RETRIES].min, 0].max
154
121
  end
155
122
 
156
- sig { params(exception: RequestError).returns(T::Boolean) }
123
+ sig { params(exception: RequestFailedError).returns(T::Boolean) }
157
124
  def retry?(exception)
158
125
  return false unless @retries_left.positive?
159
126
  return false unless @retry_codes.include?(exception.code.to_i)
@@ -165,28 +132,11 @@ module Workato
165
132
  end
166
133
 
167
134
  sig { void }
168
- def reinvoke_sleep
169
- sleep((ENV['WAIT_REINVOKE_AFTER'].presence || T.must(@reinvoke_after).seconds).to_f)
170
- end
171
-
172
- sig { returns(Integer) }
173
- def reinvoke_limit
174
- @reinvoke_limit = T.let(@reinvoke_limit, T.nilable(Integer))
175
- @reinvoke_limit ||= (ENV['MAX_REINVOKES'].presence || MAX_REINVOKES).to_i
176
- end
177
-
178
- sig { void }
179
- def reinvoke_reset
180
- @reinvoke_after = T.let(nil, T.nilable(ReinvokeAfter))
135
+ def retry_sleep
136
+ sleep(@retry_delay_factor * RETRY_DELAY)
137
+ @retry_delay_factor *= RETRY_DELAY_EXP_BASE
181
138
  end
182
139
 
183
- class ReinvokeAfter < T::Struct
184
- prop :seconds, T.any(Float, Integer)
185
- prop :continue, T::Hash[T.untyped, T.untyped]
186
- end
187
-
188
- private_constant :ReinvokeAfter
189
-
190
140
  alias action operation
191
141
  end
192
142
  end
@@ -4,27 +4,20 @@
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
- module CallRefinement
10
+ refine Proc do
10
11
  def call(*args, &block)
11
12
  super(*args.take(parameters.length), &block)
12
13
  end
13
14
  end
14
15
 
15
- refine Proc do
16
- prepend CallRefinement
17
- end
18
-
19
- module InstanceExecRefinement
16
+ refine BasicObject do
20
17
  def instance_exec(*args, &block)
21
18
  super(*args.take(block.parameters.length), &block)
22
19
  end
23
20
  end
24
-
25
- refine BasicObject do
26
- prepend InstanceExecRefinement
27
- end
28
21
  end
29
22
  end
30
23
  end