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.
- checksums.yaml +4 -4
- data/.yardopts +8 -0
- data/README.md +0 -4
- data/VERSION +1 -1
- data/lib/workato/cli/generate_command.rb +1 -0
- data/lib/workato/cli/main.rb +1 -0
- data/lib/workato/cli/multi_auth_selected_fallback.rb +1 -0
- data/lib/workato/cli/oauth2_command.rb +13 -14
- data/lib/workato/cli/push_command.rb +21 -5
- data/lib/workato/cli/schema_command.rb +18 -4
- data/lib/workato/connector/sdk/account_properties.rb +1 -1
- data/lib/workato/connector/sdk/action.rb +1 -1
- data/lib/workato/connector/sdk/block_invocation_refinements.rb +2 -1
- data/lib/workato/connector/sdk/connection.rb +8 -2
- data/lib/workato/connector/sdk/connector.rb +9 -0
- data/lib/workato/connector/sdk/dsl/aws.rb +10 -0
- data/lib/workato/connector/sdk/dsl/csv_package.rb +3 -3
- data/lib/workato/connector/sdk/dsl/error.rb +2 -0
- data/lib/workato/connector/sdk/dsl/execution_context.rb +2 -0
- data/lib/workato/connector/sdk/dsl/http.rb +6 -1
- data/lib/workato/connector/sdk/dsl/stream_package.rb +1 -7
- data/lib/workato/connector/sdk/dsl/workato_package.rb +54 -19
- data/lib/workato/connector/sdk/dsl.rb +2 -0
- data/lib/workato/connector/sdk/errors.rb +2 -0
- data/lib/workato/connector/sdk/object_definitions.rb +59 -18
- data/lib/workato/connector/sdk/operation.rb +1 -1
- data/lib/workato/connector/sdk/request.rb +6 -3
- data/lib/workato/connector/sdk/schema.rb +4 -3
- data/lib/workato/connector/sdk/settings.rb +3 -1
- data/lib/workato/connector/sdk/stream.rb +22 -3
- data/lib/workato/connector/sdk/streams.rb +1 -0
- data/lib/workato/connector/sdk/summarize.rb +2 -0
- data/lib/workato/connector/sdk.rb +1 -0
- data/lib/workato/extension/array.rb +1 -1
- data/lib/workato/extension/enumerable.rb +0 -2
- data/lib/workato/extension/extra_chain_cert.rb +2 -2
- data/lib/workato/extension/metadata_fix_wrap_kw_args.rb +1 -0
- data/lib/workato/extension/string.rb +10 -2
- data/lib/workato/testing/vcr_multipart_body_matcher.rb +1 -0
- data/lib/workato/types/binary.rb +45 -0
- data/lib/workato/types/unicode_string.rb +62 -0
- metadata +4 -31
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fe38da4979356285b7bd535a889ce87324c0c9e79af94ab64bbfbabff03f104
|
4
|
+
data.tar.gz: 12ae318a25eaf1fddc7c31f22f9870d4af28e736781ef32ff766c32ae14876d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2737cef0c57c48dc215dba1f3077669935fceb940be5484469e3901f6d848bee8af5bc408595a14a330bc96e3e553f088c25323867dc8d43d1b95930275c79af
|
7
|
+
data.tar.gz: 066b30f5e052e1dbd91c697b3e978ec548f0ffc76db9298168758e4b60f8ada8f1a13c1a603e0603d347e22fcca2e945fa3eeaedaa74139cef07b09b98b7c9ea
|
data/.yardopts
ADDED
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.
|
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"
|
data/lib/workato/cli/main.rb
CHANGED
@@ -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,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 '
|
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
|
-
|
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
|
-
|
190
|
-
|
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
|
-
|
73
|
-
|
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 =
|
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) }
|
@@ -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::
|
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::
|
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::
|
115
|
+
raise Sdk::ArgumentError, e.message
|
116
116
|
end
|
117
117
|
|
118
118
|
private
|
@@ -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.
|
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
|
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
|
-
|
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
|
56
|
+
raise Sdk::ArgumentError,
|
57
|
+
"Unsupported signing method. Supports only #{JWT_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
|
33
58
|
end
|
34
59
|
|
35
|
-
|
36
|
-
|
37
|
-
|
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,
|
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
|
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::
|
62
|
-
raise e
|
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
|
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")
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
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
|
-
|
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] =
|
26
|
-
|
27
|
-
|
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
|
-
|
61
|
+
|
62
|
+
sig { returns(SorbetTypes::SourceHash) }
|
45
63
|
attr_reader :object_definitions_source
|
46
64
|
|
47
|
-
|
48
|
-
|
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
|
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.
|
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
|
-
|
42
|
+
response!.send(...)
|
43
43
|
end
|
44
44
|
|
45
|
-
def
|
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
|
-
|
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,
|
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
|
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 }
|
@@ -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
|
@@ -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
|
-
|
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)
|
data/lib/workato/types/binary.rb
CHANGED
@@ -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.
|
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-
|
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
|