workato-connector-sdk 0.5.0 → 1.0.2

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 (68) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +44 -24
  3. data/lib/workato/cli/edit_command.rb +4 -3
  4. data/lib/workato/cli/exec_command.rb +24 -35
  5. data/lib/workato/cli/generate_command.rb +4 -3
  6. data/lib/workato/cli/generators/connector_generator.rb +1 -0
  7. data/lib/workato/cli/generators/master_key_generator.rb +1 -0
  8. data/lib/workato/cli/main.rb +4 -2
  9. data/lib/workato/cli/oauth2_command.rb +6 -5
  10. data/lib/workato/cli/push_command.rb +5 -4
  11. data/lib/workato/cli/schema_command.rb +4 -3
  12. data/lib/workato/connector/sdk/account_properties.rb +1 -0
  13. data/lib/workato/connector/sdk/action.rb +78 -20
  14. data/lib/workato/connector/sdk/block_invocation_refinements.rb +1 -0
  15. data/lib/workato/connector/sdk/connection.rb +202 -44
  16. data/lib/workato/connector/sdk/connector.rb +200 -65
  17. data/lib/workato/connector/sdk/dsl/account_property.rb +1 -0
  18. data/lib/workato/connector/sdk/dsl/aws.rb +23 -27
  19. data/lib/workato/connector/sdk/dsl/call.rb +1 -0
  20. data/lib/workato/connector/sdk/dsl/error.rb +1 -0
  21. data/lib/workato/connector/sdk/dsl/http.rb +2 -7
  22. data/lib/workato/connector/sdk/dsl/lookup_table.rb +1 -0
  23. data/lib/workato/connector/sdk/dsl/time.rb +6 -0
  24. data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +38 -0
  25. data/lib/workato/connector/sdk/dsl/workato_schema.rb +1 -0
  26. data/lib/workato/connector/sdk/dsl.rb +19 -4
  27. data/lib/workato/connector/sdk/errors.rb +4 -3
  28. data/lib/workato/connector/sdk/lookup_tables.rb +1 -0
  29. data/lib/workato/connector/sdk/object_definitions.rb +7 -8
  30. data/lib/workato/connector/sdk/operation.rb +127 -88
  31. data/lib/workato/connector/sdk/request.rb +45 -17
  32. data/lib/workato/connector/sdk/schema/field/array.rb +1 -0
  33. data/lib/workato/connector/sdk/schema/field/convertors.rb +1 -0
  34. data/lib/workato/connector/sdk/schema/field/date.rb +1 -0
  35. data/lib/workato/connector/sdk/schema/field/date_time.rb +1 -0
  36. data/lib/workato/connector/sdk/schema/field/integer.rb +1 -0
  37. data/lib/workato/connector/sdk/schema/field/number.rb +1 -0
  38. data/lib/workato/connector/sdk/schema/field/object.rb +1 -0
  39. data/lib/workato/connector/sdk/schema/field/string.rb +1 -0
  40. data/lib/workato/connector/sdk/schema/type/time.rb +1 -0
  41. data/lib/workato/connector/sdk/schema/type/unicode_string.rb +1 -0
  42. data/lib/workato/connector/sdk/schema.rb +1 -0
  43. data/lib/workato/connector/sdk/settings.rb +9 -4
  44. data/lib/workato/connector/sdk/summarize.rb +3 -2
  45. data/lib/workato/connector/sdk/trigger.rb +112 -18
  46. data/lib/workato/connector/sdk/version.rb +2 -1
  47. data/lib/workato/connector/sdk/workato_schemas.rb +1 -0
  48. data/lib/workato/connector/sdk/xml.rb +1 -0
  49. data/lib/workato/connector/sdk.rb +4 -0
  50. data/lib/workato/extension/array.rb +1 -0
  51. data/lib/workato/extension/case_sensitive_headers.rb +1 -0
  52. data/lib/workato/extension/currency.rb +1 -0
  53. data/lib/workato/extension/date.rb +1 -0
  54. data/lib/workato/extension/enumerable.rb +1 -0
  55. data/lib/workato/extension/extra_chain_cert.rb +1 -0
  56. data/lib/workato/extension/hash.rb +1 -0
  57. data/lib/workato/extension/integer.rb +1 -0
  58. data/lib/workato/extension/nil_class.rb +1 -0
  59. data/lib/workato/extension/object.rb +1 -0
  60. data/lib/workato/extension/phone.rb +1 -0
  61. data/lib/workato/extension/string.rb +9 -15
  62. data/lib/workato/extension/symbol.rb +1 -0
  63. data/lib/workato/extension/time.rb +1 -0
  64. data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +5 -0
  65. data/lib/workato/testing/vcr_multipart_body_matcher.rb +1 -0
  66. data/lib/workato/web/app.rb +1 -0
  67. data/lib/workato-connector-sdk.rb +1 -0
  68. metadata +64 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: d8d30836873d60dede61747b573f51864653aeabc2831f173663db68f42479c5
4
- data.tar.gz: 19c2031601b7f63b317c42f081cf08044e3b75f3feefabc4f557f86b95f5e3c5
2
+ SHA1:
3
+ metadata.gz: f52b011085690e264b4e2082fb2f13c1375e74fe
4
+ data.tar.gz: 190c0bc7e6264ab9524acdda484e07154dd0b2b8
5
5
  SHA512:
6
- metadata.gz: e378b75932e66e5e9399870981d62473cdfe14f98facaebefc7de3faaf27e1382b17b6f019c45530f7130d9c81498ae3410bf2278ba67e29efd73fb6790e8c1e
7
- data.tar.gz: 8d6a10d7e30515c7e6c86a9eb1cc2f88794d05bf42b0ccc2d3a24ac094134a8fd8a4cb3a7a8c321c2b786cc22a8825b26945a30b0d6eaa4de8d9451beefe3b42
6
+ metadata.gz: 29480d50f931dec0b0f18bf8f7c97f0a6029dd2656ba367ce0a3015a2a32e961bca9981083e01455d9c65cba2244dea5491b34d02e18a9cb8c4ac1a02f9a1d85
7
+ data.tar.gz: 1681f2fc8fc0eec6949361ae49ae26fdea3372eab98fb745e9d4a55d192b0e74a34d446655d2b5b08ede89d09cf748d4610ef86b08bab3210165de961004bbb6
data/README.md CHANGED
@@ -265,27 +265,28 @@ Usage:
265
265
  workato exec <PATH>
266
266
 
267
267
  Options:
268
- -c, [--connector=CONNECTOR] # Path to connector source code
269
- -s, [--settings=SETTINGS] # Path to plain or encrypted file with connection configs, passwords, tokens, secrets etc
270
- -n, [--connection=CONNECTION] # Connection name if settings file contains multiple settings
271
- -k, [--key=KEY] # Path to file with encrypt/decrypt key. NOTE: key from WORKATO_CONNECTOR_MASTER_KEY has higher priority
272
- -i, [--input=INPUT] # Path to file with input JSON
273
- [--closure=CLOSURE] # Path to file with next poll closure JSON
274
- [--continue=CONTINUE] # Path to file with next multistep action continue closure JSON
275
- -a, [--args=ARGS] # Path to file with method arguments JSON
276
- [--extended-input-schema=EXTENDED_INPUT_SCHEMA] # Path to file with extended input schema definition JSON
277
- [--extended-output-schema=EXTENDED_OUTPUT_SCHEMA] # Path to file with extended output schema definition JSON
278
- [--config-fields=CONFIG_FIELDS] # Path to file with config fields JSON
279
- -w, [--webhook-payload=WEBHOOK_PAYLOAD] # Path to file with webhook payload JSON
280
- [--webhook-params=WEBHOOK_PARAMS] # Path to file with webhook params JSON
281
- [--webhook-headers=WEBHOOK_HEADERS] # Path to file with webhook headers JSON
282
- [--webhook-url=WEBHOOK_URL] # Webhook URL for automatic webhook subscription
283
- -o, [--output=OUTPUT] # Write output to JSON file
284
- [--oauth2-code=OAUTH2_CODE] # OAuth2 code exchange to tokens pair
285
- [--redirect-url=REDIRECT_URL] # OAuth2 callback url
286
- [--refresh-token=REFRESH_TOKEN] # OAuth2 refresh token
287
- [--debug], [--no-debug]
288
- [--verbose], [--no-verbose]
268
+ -c, [--connector=CONNECTOR] # Path to connector source code
269
+ -s, [--settings=SETTINGS] # Path to plain or encrypted file with connection configs, passwords, tokens, secrets etc
270
+ -n, [--connection=CONNECTION] # Connection name if settings file contains multiple settings
271
+ -k, [--key=KEY] # Path to file with encrypt/decrypt key. NOTE: key from WORKATO_CONNECTOR_MASTER_KEY has higher priority
272
+ -i, [--input=INPUT] # Path to file with input JSON
273
+ [--closure=CLOSURE] # Path to file with next poll closure JSON
274
+ [--continue=CONTINUE] # Path to file with next multistep action continue closure JSON
275
+ -a, [--args=ARGS] # Path to file with method arguments JSON
276
+ [--extended-input-schema=EXTENDED_INPUT_SCHEMA] # Path to file with extended input schema definition JSON
277
+ [--extended-output-schema=EXTENDED_OUTPUT_SCHEMA] # Path to file with extended output schema definition JSON
278
+ [--config-fields=CONFIG_FIELDS] # Path to file with config fields JSON
279
+ -w, [--webhook-payload=WEBHOOK_PAYLOAD] # Path to file with webhook payload JSON
280
+ [--webhook-params=WEBHOOK_PARAMS] # Path to file with webhook params JSON
281
+ [--webhook-headers=WEBHOOK_HEADERS] # Path to file with webhook headers JSON
282
+ [--webhook-subscribe-output=WEBHOOK_SUBSCRIBE_OUTPUT] # Path to file with webhook subscribe output JSON
283
+ [--webhook-url=WEBHOOK_URL] # Webhook URL for automatic webhook subscription
284
+ -o, [--output=OUTPUT] # Write output to JSON file
285
+ [--oauth2-code=OAUTH2_CODE] # OAuth2 code exchange to tokens pair
286
+ [--redirect-url=REDIRECT_URL] # OAuth2 callback url
287
+ [--refresh-token=REFRESH_TOKEN] # OAuth2 refresh token
288
+ [--debug], [--no-debug]
289
+ [--verbose], [--no-verbose]
289
290
 
290
291
  Description:
291
292
  The 'workato exec' executes connector's lambda block at <PATH>. Lambda's parameters can be provided if needed, see options part.
@@ -319,7 +320,26 @@ Commands:
319
320
  workato generate test # Generate empty test for connector
320
321
  ```
321
322
 
322
- **NOTE: `workato generate schema` is currently not implemented.**
323
+ ### 3.4.1 workato generate schema
324
+ Use command to generate Workato Schema from a sample file. Supported inputs csv, json
325
+
326
+ ```
327
+ workato generate help schema
328
+
329
+ Usage:
330
+ workato generate schema
331
+
332
+ Options:
333
+ [--json=JSON] # Path to JSON sample file
334
+ [--csv=CSV] # Path to CSV sample file
335
+ [--col-sep=COL_SEP] # Use separator for CSV converter
336
+ # Default: comma
337
+ # Possible values: comma, space, tab, colon, semicolon, pipe
338
+ [--api-email=API_EMAIL] # Email for accessing Workato API or set WORKATO_API_EMAIL environment variable
339
+ [--api-token=API_TOKEN] # Token for accessing Workato API or set WORKATO_API_TOKEN environment variable
340
+ ```
341
+
342
+ ### 3.4.2 workato generate test
323
343
 
324
344
  - Use `workato generate test` to generate tests based on your connector.rb file.
325
345
 
@@ -400,8 +420,8 @@ Options:
400
420
  -l, [--logo=LOGO] # Path to connector logo: png or jpeg file
401
421
  -n, [--notes=NOTES] # Release notes
402
422
  -c, [--connector=CONNECTOR] # Path to connector source code
403
- [--api-email=API_EMAIL] # Email for accessing Workato API or set WORKATO_API_EMAIL env
404
- [--api-token=API_TOKEN] # Token for accessing Workato API or set WORKATO_API_TOKEN env
423
+ [--api-email=API_EMAIL] # Email for accessing Workato API or set WORKATO_API_EMAIL environment variable
424
+ [--api-token=API_TOKEN] # Token for accessing Workato API or set WORKATO_API_TOKEN environment variable
405
425
  [--environment=ENVIRONMENT] # Server to push connector code to
406
426
  # Default: live
407
427
  # Possible values: preview, preview-eu, live, live-eu
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'active_support/encrypted_configuration'
@@ -33,9 +34,9 @@ module Workato
33
34
 
34
35
  private
35
36
 
36
- attr_reader :key_path,
37
- :encrypted_file_path,
38
- :encrypted_config
37
+ attr_reader :key_path
38
+ attr_reader :encrypted_file_path
39
+ attr_reader :encrypted_config
39
40
 
40
41
  def ensure_encryption_key_present
41
42
  return if encrypted_config.key.present?
@@ -1,3 +1,4 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'thor'
@@ -24,8 +25,8 @@ module Workato
24
25
 
25
26
  private
26
27
 
27
- attr_reader :path,
28
- :options
28
+ attr_reader :path
29
+ attr_reader :options
29
30
 
30
31
  # rubocop:disable Style/GuardClause
31
32
  def load_from_default_files
@@ -46,11 +47,9 @@ module Workato
46
47
 
47
48
  def params
48
49
  @params ||= {
49
- connector: connector,
50
50
  settings: settings,
51
51
  input: from_json(options[:input]),
52
- output: from_json(options[:input]),
53
- webhook_subscribe_output: from_json(options[:input]),
52
+ webhook_subscribe_output: from_json(options[:webhook_subscribe_output]),
54
53
  args: from_json(options[:args]).presence || [],
55
54
  extended_input_schema: from_json(options[:extended_input_schema]).presence || [],
56
55
  extended_output_schema: from_json(options[:extended_output_schema]).presence || [],
@@ -69,7 +68,7 @@ module Workato
69
68
  end
70
69
 
71
70
  def connector
72
- Workato::Connector::Sdk::Connector.from_file(
71
+ @connector ||= Workato::Connector::Sdk::Connector.from_file(
73
72
  options[:connector] || Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH,
74
73
  settings
75
74
  )
@@ -85,16 +84,23 @@ module Workato
85
84
  )
86
85
  @settings = settings_store.read
87
86
 
88
- Workato::Connector::Sdk::Operation.on_settings_updated = lambda do |message, new_settings|
89
- $stdout.pause if verbose?
90
- say('')
91
- say(message)
92
- loop do
93
- answer = ask('Updated settings file with new connection attributes? (Yes or No)').to_s.downcase
94
- break if %w[n no].include?(answer)
95
- break settings_store.update(new_settings) if %w[y yes].include?(answer)
87
+ Workato::Connector::Sdk::Connection.on_settings_update = lambda do |message, &refresher|
88
+ begin
89
+ $stdout.pause if verbose?
90
+ say('')
91
+ say(message)
92
+ new_settings = refresher.call
93
+ loop do
94
+ answer = ask('Updated settings file with new connection attributes? (Yes or No)').to_s.downcase
95
+ break new_settings if %w[n no].include?(answer)
96
+ next unless %w[y yes].include?(answer)
97
+
98
+ settings_store.update(new_settings)
99
+ break new_settings
100
+ end
101
+ ensure
102
+ $stdout.resume if verbose?
96
103
  end
97
- $stdout.resume if verbose?
98
104
  end
99
105
 
100
106
  @settings
@@ -103,9 +109,9 @@ module Workato
103
109
  def from_json(path, parse_json_times: false)
104
110
  old_parse_json_times = ActiveSupport.parse_json_times
105
111
  ::ActiveSupport.parse_json_times = parse_json_times
106
- result = path ? ::ActiveSupport::JSON.decode(File.read(path)) : {}
112
+ path ? ::ActiveSupport::JSON.decode(File.read(path)) : {}
113
+ ensure
107
114
  ::ActiveSupport.parse_json_times = old_parse_json_times
108
- result
109
115
  end
110
116
 
111
117
  def inspect_params(params)
@@ -121,30 +127,13 @@ module Workato
121
127
  end
122
128
 
123
129
  def execute_path
124
- methods = path.split('.')
125
- method = methods.pop
126
- object = methods.inject(params[:connector]) { |obj, m| obj.public_send(m) }
127
- output = invoke_method(object, method)
128
- if output.respond_to?(:invoke)
129
- invoke_method(output, :invoke)
130
- else
131
- output
132
- end
130
+ connector.invoke(path, params)
133
131
  rescue Exception => e # rubocop:disable Lint/RescueException
134
132
  raise DebugExceptionError, e if options[:debug]
135
133
 
136
134
  raise
137
135
  end
138
136
 
139
- def invoke_method(object, method)
140
- parameters = object.method(method).parameters.reject { |p| p[0] == :block }.map(&:second)
141
- args = params.values_at(*parameters)
142
- if parameters.last == :args
143
- args = args.take(args.length - 1) + Array.wrap(args.last).flatten(1)
144
- end
145
- object.public_send(method, *args)
146
- end
147
-
148
137
  def show_output(output)
149
138
  if options[:output].present?
150
139
  File.open(options[:output], 'w') do |f|
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Workato
@@ -45,17 +46,17 @@ module Workato
45
46
  method_option :csv, type: :string, desc: 'Path to CSV sample file'
46
47
  method_option :col_sep,
47
48
  type: :string,
48
- desc: 'Use separator for CSV convertor',
49
+ desc: 'Use separator for CSV converter',
49
50
  enum: SchemaCommand::CSV_SEPARATORS,
50
51
  default: 'comma'
51
52
  method_option :api_email,
52
53
  type: :string,
53
54
  desc: 'Email for accessing Workato API or '\
54
- "set #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} env"
55
+ "set #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} environment variable"
55
56
  method_option :api_token,
56
57
  type: :string,
57
58
  desc: 'Token for accessing Workato API or ' \
58
- "set #{Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV} env"
59
+ "set #{Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV} environment variable"
59
60
 
60
61
  long_desc <<~HELP
61
62
  The 'workato generate schema' command generates Workato Schema from a sample file.
@@ -1,3 +1,4 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Workato
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Workato
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'thor'
@@ -54,6 +55,7 @@ module Workato
54
55
  method_option :webhook_payload, type: :string, aliases: '-w', desc: 'Path to file with webhook payload JSON'
55
56
  method_option :webhook_params, type: :string, desc: 'Path to file with webhook params JSON'
56
57
  method_option :webhook_headers, type: :string, desc: 'Path to file with webhook headers JSON'
58
+ method_option :webhook_subscribe_output, type: :string, desc: 'Path to file with webhook subscribe output JSON'
57
59
  method_option :webhook_url, type: :string, desc: 'Webhook URL for automatic webhook subscription'
58
60
  method_option :output, type: :string, aliases: '-o', desc: 'Write output to JSON file'
59
61
  method_option :oauth2_code, type: :string, desc: 'OAuth2 code exchange to tokens pair'
@@ -126,11 +128,11 @@ module Workato
126
128
  method_option :api_email,
127
129
  type: :string,
128
130
  desc: 'Email for accessing Workato API or '\
129
- "set #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} env"
131
+ "set #{Workato::Connector::Sdk::WORKATO_API_EMAIL_ENV} environment variable"
130
132
  method_option :api_token,
131
133
  type: :string,
132
134
  desc: 'Token for accessing Workato API or ' \
133
- "set #{Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV} env"
135
+ "set #{Workato::Connector::Sdk::WORKATO_API_TOKEN_ENV} environment variable"
134
136
  method_option :environment,
135
137
  type: :string,
136
138
  enum: Workato::CLI::PushCommand::ENVIRONMENTS.keys,
@@ -1,3 +1,4 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'securerandom'
@@ -55,11 +56,11 @@ module Workato
55
56
 
56
57
  private
57
58
 
58
- attr_reader :https,
59
- :base_url,
60
- :redirect_url,
61
- :port,
62
- :options
59
+ attr_reader :https
60
+ attr_reader :base_url
61
+ attr_reader :redirect_url
62
+ attr_reader :port
63
+ attr_reader :options
63
64
 
64
65
  def verbose?
65
66
  !!options[:verbose]
@@ -1,3 +1,4 @@
1
+ # typed: true
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'uri'
@@ -55,10 +56,10 @@ module Workato
55
56
 
56
57
  private
57
58
 
58
- attr_reader :options,
59
- :api_token,
60
- :api_email,
61
- :api_base_url
59
+ attr_reader :options
60
+ attr_reader :api_token
61
+ attr_reader :api_email
62
+ attr_reader :api_base_url
62
63
 
63
64
  def verbose?
64
65
  @options[:verbose]
@@ -1,3 +1,4 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Workato
@@ -31,9 +32,9 @@ module Workato
31
32
 
32
33
  private
33
34
 
34
- attr_reader :options,
35
- :api_token,
36
- :api_email
35
+ attr_reader :options
36
+ attr_reader :api_token
37
+ attr_reader :api_email
37
38
 
38
39
  def verbose?
39
40
  @options[:verbose]
@@ -1,3 +1,4 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require 'csv'
@@ -1,3 +1,4 @@
1
+ # typed: strict
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative './operation'
@@ -7,27 +8,52 @@ module Workato
7
8
  module Connector
8
9
  module Sdk
9
10
  class Action < Operation
11
+ extend T::Sig
10
12
  using BlockInvocationRefinements
11
13
 
12
- RETRY_DEFAULT_CODES = [429, 500, 502, 503, 504, 507].freeze
13
- RETRY_DEFAULT_METHODS = %i[get head].freeze
14
- RETRY_DELAY = 5.seconds
14
+ RETRY_DEFAULT_CODES = T.let([429, 500, 502, 503, 504, 507].freeze, T::Array[Integer])
15
+ RETRY_DEFAULT_METHODS = T.let(%i[get head].freeze, T::Array[Symbol])
16
+ RETRY_DELAY = T.let(5, Integer) # seconds
15
17
  MAX_RETRIES = 3
16
18
 
17
19
  MAX_REINVOKES = 5
18
20
 
19
- def initialize(action:, connection: {}, methods: {}, settings: {}, object_definitions: nil)
21
+ sig do
22
+ params(
23
+ action: SorbetTypes::SourceHash,
24
+ methods: SorbetTypes::SourceHash,
25
+ connection: Connection,
26
+ object_definitions: T.nilable(ObjectDefinitions)
27
+ ).void
28
+ end
29
+ def initialize(action:, methods: {}, connection: Connection.new, object_definitions: nil)
20
30
  super(
21
31
  operation: action,
22
32
  connection: connection,
23
33
  methods: methods,
24
- settings: settings,
25
34
  object_definitions: object_definitions
26
35
  )
27
36
 
37
+ @retries_left = T.let(0, Integer)
38
+ @retry_codes = T.let([], T::Array[Integer])
39
+ @retry_methods = T.let([], T::Array[String])
40
+ @retry_matchers = T.let([], T::Array[T.any(Symbol, String, Regexp)])
41
+
28
42
  initialize_retry
29
43
  end
30
44
 
45
+ sig do
46
+ params(
47
+ settings: T.nilable(SorbetTypes::SettingsHash),
48
+ input: SorbetTypes::OperationInputHash,
49
+ extended_input_schema: SorbetTypes::OperationSchema,
50
+ extended_output_schema: SorbetTypes::OperationSchema,
51
+ continue: T::Hash[T.any(Symbol, String), T.untyped],
52
+ block: T.nilable(SorbetTypes::OperationExecuteProc)
53
+ ).returns(
54
+ T.untyped
55
+ )
56
+ end
31
57
  def execute(settings = nil, input = {}, extended_input_schema = [], extended_output_schema = [], continue = {},
32
58
  &block)
33
59
  raise InvalidDefinitionError, "'execute' block is required for action" unless block || action[:execute]
@@ -39,7 +65,7 @@ module Workato
39
65
 
40
66
  reinvoke_sleep if @reinvoke_after
41
67
 
42
- @reinvoke_after = nil
68
+ reinvoke_reset
43
69
 
44
70
  result = super(
45
71
  settings,
@@ -52,15 +78,17 @@ module Workato
52
78
 
53
79
  break result unless @reinvoke_after
54
80
 
55
- continue = @reinvoke_after[:continue]
81
+ continue = @reinvoke_after.continue
56
82
  end
57
83
  rescue RequestError => e
58
84
  raise e unless retry?(e)
59
85
 
60
86
  @retries_left -= 1
61
- sleep(RETRY_DELAY) && retry
87
+ sleep(RETRY_DELAY)
88
+ retry
62
89
  end
63
90
 
91
+ sig { params(input: SorbetTypes::OperationInputHash).returns(T::Hash[T.any(String, Symbol), T.untyped]) }
64
92
  def invoke(input = {})
65
93
  extended_schema = extended_schema(nil, input)
66
94
  config_schema = Schema.new(schema: config_fields_schema)
@@ -72,63 +100,93 @@ module Workato
72
100
  apply_output_schema(output, output_schema)
73
101
  end
74
102
 
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
75
109
  def checkpoint!(continue:, temp_output: nil)
76
110
  # no-op
77
111
  end
78
112
 
79
- def reinvoke_after(seconds:, continue:, temp_output: nil)
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))
80
122
  @reinvokes_remaining = (@reinvokes_remaining ? @reinvokes_remaining - 1 : reinvoke_limit)
81
- @reinvoke_after = {
123
+ @reinvoke_after = ReinvokeAfter.new(
82
124
  seconds: seconds,
83
- continue: continue,
84
- temp_output: temp_output
85
- }
125
+ continue: continue
126
+ )
86
127
  end
87
128
 
88
129
  private
89
130
 
131
+ sig { returns(T::Array[T.any(Symbol, String, Regexp, Integer)]) }
90
132
  def retry_on_response
91
133
  Array(action[:retry_on_response])
92
134
  end
93
135
 
136
+ sig { returns(T::Array[T.any(Symbol, String, Regexp, Integer)]) }
94
137
  def retry_on_request
95
138
  Array(action[:retry_on_request])
96
139
  end
97
140
 
141
+ sig { returns(T.nilable(Integer)) }
98
142
  def max_retries
99
143
  action[:max_retries]
100
144
  end
101
145
 
146
+ sig { void }
102
147
  def initialize_retry
103
- @retries_left = 0
104
148
  return if retry_on_response.blank?
105
149
 
106
- @retry_codes = []
107
- @retry_matchers = []
108
150
  retry_on_response.each { |m| m.is_a?(::Integer) ? @retry_codes << m : @retry_matchers << m }
109
151
  @retry_codes = RETRY_DEFAULT_CODES if @retry_codes.empty?
110
152
  @retry_methods = (retry_on_request.presence || RETRY_DEFAULT_METHODS).map(&:to_s).map(&:downcase)
111
153
  @retries_left = [[max_retries.is_a?(::Integer) && max_retries || MAX_RETRIES, MAX_RETRIES].min, 0].max
112
154
  end
113
155
 
156
+ sig { params(exception: RequestError).returns(T::Boolean) }
114
157
  def retry?(exception)
115
- return unless @retries_left.positive?
116
- return unless @retry_codes.include?(exception.code.to_i)
117
- return unless @retry_matchers.empty? || @retry_matchers.any? do |m|
158
+ return false unless @retries_left.positive?
159
+ return false unless @retry_codes.include?(exception.code.to_i)
160
+ return false unless @retry_matchers.empty? || @retry_matchers.any? do |m|
118
161
  m === exception.message || m === exception.response
119
162
  end
120
163
 
121
164
  @retry_methods.include?(exception.method.to_s.downcase)
122
165
  end
123
166
 
167
+ sig { void }
124
168
  def reinvoke_sleep
125
- sleep((ENV['WAIT_REINVOKE_AFTER'].presence || @reinvoke_after[:seconds]).to_f)
169
+ sleep((ENV['WAIT_REINVOKE_AFTER'].presence || T.must(@reinvoke_after).seconds).to_f)
126
170
  end
127
171
 
172
+ sig { returns(Integer) }
128
173
  def reinvoke_limit
174
+ @reinvoke_limit = T.let(@reinvoke_limit, T.nilable(Integer))
129
175
  @reinvoke_limit ||= (ENV['MAX_REINVOKES'].presence || MAX_REINVOKES).to_i
130
176
  end
131
177
 
178
+ sig { void }
179
+ def reinvoke_reset
180
+ @reinvoke_after = T.let(nil, T.nilable(ReinvokeAfter))
181
+ end
182
+
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
+
132
190
  alias action operation
133
191
  end
134
192
  end
@@ -1,3 +1,4 @@
1
+ # typed: false
1
2
  # frozen_string_literal: true
2
3
 
3
4
  module Workato