workato-connector-sdk 0.5.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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