workato-connector-sdk 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +20 -0
  3. data/README.md +1093 -0
  4. data/exe/workato +5 -0
  5. data/lib/workato/cli/edit_command.rb +71 -0
  6. data/lib/workato/cli/exec_command.rb +191 -0
  7. data/lib/workato/cli/generate_command.rb +105 -0
  8. data/lib/workato/cli/generators/connector_generator.rb +94 -0
  9. data/lib/workato/cli/generators/master_key_generator.rb +56 -0
  10. data/lib/workato/cli/main.rb +142 -0
  11. data/lib/workato/cli/push_command.rb +208 -0
  12. data/lib/workato/connector/sdk/account_properties.rb +60 -0
  13. data/lib/workato/connector/sdk/action.rb +88 -0
  14. data/lib/workato/connector/sdk/block_invocation_refinements.rb +30 -0
  15. data/lib/workato/connector/sdk/connector.rb +230 -0
  16. data/lib/workato/connector/sdk/dsl/account_property.rb +15 -0
  17. data/lib/workato/connector/sdk/dsl/call.rb +17 -0
  18. data/lib/workato/connector/sdk/dsl/error.rb +15 -0
  19. data/lib/workato/connector/sdk/dsl/http.rb +60 -0
  20. data/lib/workato/connector/sdk/dsl/lookup_table.rb +15 -0
  21. data/lib/workato/connector/sdk/dsl/time.rb +21 -0
  22. data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +105 -0
  23. data/lib/workato/connector/sdk/dsl/workato_schema.rb +15 -0
  24. data/lib/workato/connector/sdk/dsl.rb +46 -0
  25. data/lib/workato/connector/sdk/errors.rb +30 -0
  26. data/lib/workato/connector/sdk/lookup_tables.rb +62 -0
  27. data/lib/workato/connector/sdk/object_definitions.rb +74 -0
  28. data/lib/workato/connector/sdk/operation.rb +217 -0
  29. data/lib/workato/connector/sdk/request.rb +399 -0
  30. data/lib/workato/connector/sdk/settings.rb +130 -0
  31. data/lib/workato/connector/sdk/summarize.rb +61 -0
  32. data/lib/workato/connector/sdk/trigger.rb +96 -0
  33. data/lib/workato/connector/sdk/version.rb +9 -0
  34. data/lib/workato/connector/sdk/workato_schemas.rb +37 -0
  35. data/lib/workato/connector/sdk/xml.rb +35 -0
  36. data/lib/workato/connector/sdk.rb +58 -0
  37. data/lib/workato/extension/array.rb +124 -0
  38. data/lib/workato/extension/case_sensitive_headers.rb +51 -0
  39. data/lib/workato/extension/currency.rb +15 -0
  40. data/lib/workato/extension/date.rb +14 -0
  41. data/lib/workato/extension/enumerable.rb +55 -0
  42. data/lib/workato/extension/extra_chain_cert.rb +40 -0
  43. data/lib/workato/extension/hash.rb +13 -0
  44. data/lib/workato/extension/integer.rb +17 -0
  45. data/lib/workato/extension/nil_class.rb +17 -0
  46. data/lib/workato/extension/object.rb +38 -0
  47. data/lib/workato/extension/phone.rb +14 -0
  48. data/lib/workato/extension/string.rb +268 -0
  49. data/lib/workato/extension/symbol.rb +13 -0
  50. data/lib/workato/extension/time.rb +13 -0
  51. data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +38 -0
  52. data/lib/workato/testing/vcr_multipart_body_matcher.rb +32 -0
  53. data/lib/workato-connector-sdk.rb +3 -0
  54. data/templates/.rspec.erb +3 -0
  55. data/templates/Gemfile.erb +10 -0
  56. data/templates/connector.rb.erb +37 -0
  57. data/templates/spec/action_spec.rb.erb +36 -0
  58. data/templates/spec/connector_spec.rb.erb +18 -0
  59. data/templates/spec/method_spec.rb.erb +13 -0
  60. data/templates/spec/object_definition_spec.rb.erb +18 -0
  61. data/templates/spec/pick_list_spec.rb.erb +13 -0
  62. data/templates/spec/spec_helper.rb.erb +38 -0
  63. data/templates/spec/trigger_spec.rb.erb +61 -0
  64. metadata +372 -0
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Workato
4
+ module Extension
5
+ module Currency
6
+ def to_currency(options = {})
7
+ ActiveSupport::NumberHelper::NumberToCurrencyConverter(self, options)
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ String.include(Workato::Extension::Currency)
14
+ Integer.include(Workato::Extension::Currency)
15
+ Float.include(Workato::Extension::Currency)
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Workato
4
+ module Extension
5
+ module Date
6
+ def yweek
7
+ cweek
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ Date.include(Workato::Extension::Date)
14
+ DateTime.include(Workato::Extension::Date)
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Enumerable
4
+ def where(options = {})
5
+ obj = first
6
+ list = if obj.is_a?(::Hash)
7
+ self
8
+ else
9
+ []
10
+ end
11
+ Workato::Extension::Array::ArrayWhere.new(list, options || {})
12
+ end
13
+
14
+ def format_map(format)
15
+ if format.blank?
16
+ return self
17
+ end
18
+
19
+ map do |val|
20
+ format % (Array(val).map { |v| v.is_a?(HashWithIndifferentAccess) ? v.symbolize_keys : v })
21
+ end
22
+ end
23
+
24
+ def smart_join(separator)
25
+ transform_select do |val|
26
+ val = val.strip if val.is_a?(::String)
27
+ val.presence
28
+ end.join(separator)
29
+ end
30
+
31
+ def pluck(*keys)
32
+ if keys.many?
33
+ map { |element| keys.map { |key| element.respond_to?(:dig) ? element.dig(*key) : element[key] } }
34
+ else
35
+ map { |element| element.respond_to?(:dig) ? element.dig(*keys.first) : element[keys.first] }
36
+ end
37
+ end
38
+
39
+ def transform_find(&block)
40
+ each do |*items|
41
+ result = block.call(*items)
42
+ return result if result
43
+ end
44
+ nil
45
+ end
46
+
47
+ private
48
+
49
+ def transform_select(&block)
50
+ map do |*items|
51
+ result = block.call(*items)
52
+ result || nil
53
+ end.reject(&:nil?)
54
+ end
55
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rest-client'
4
+ require 'net/http'
5
+
6
+ module Workato
7
+ module Extension
8
+ module ExtraChainCert
9
+ module Net
10
+ module HTTP
11
+ attr_accessor :extra_chain_cert
12
+
13
+ def self.included(base)
14
+ ssl_ivnames = base.const_get('SSL_IVNAMES', false)
15
+ ssl_ivnames << :@extra_chain_cert unless ssl_ivnames.include?(:@extra_chain_cert)
16
+
17
+ ssl_attributes = base.const_get('SSL_ATTRIBUTES', false)
18
+ ssl_attributes << :extra_chain_cert unless ssl_attributes.include?(:extra_chain_cert)
19
+ end
20
+ end
21
+ end
22
+
23
+ ::Net::HTTP.include Net::HTTP
24
+
25
+ module RestClient
26
+ module Request
27
+ attr_accessor :extra_chain_cert
28
+
29
+ def net_http_object(hostname, port)
30
+ net = super(hostname, port)
31
+ net.extra_chain_cert = extra_chain_cert if extra_chain_cert
32
+ net
33
+ end
34
+ end
35
+ end
36
+
37
+ ::RestClient::Request.prepend RestClient::Request
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Workato
4
+ module Extension
5
+ module Hash
6
+ def encode_www_form
7
+ ::URI.encode_www_form(self)
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ Hash.include(Workato::Extension::Hash)
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Workato
4
+ module Extension
5
+ module Integer
6
+ def is_int? # rubocop:disable Naming/PredicateName
7
+ true
8
+ end
9
+
10
+ def to_time
11
+ ::Time.zone.at(self)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ Integer.include(Workato::Extension::Integer)
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Workato
4
+ module Extension
5
+ module NilClass
6
+ def is_int? # rubocop:disable Naming/PredicateName
7
+ false
8
+ end
9
+
10
+ def is_number? # rubocop:disable Naming/PredicateName
11
+ false
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ NilClass.include(Workato::Extension::NilClass)
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Workato
4
+ module Extension
5
+ module Object
6
+ # rubocop:disable Naming/PredicateName
7
+ def is_true?(null_true: false)
8
+ if is_a?(::String)
9
+ return true if (self =~ (/\A(true|t|yes|y|1)\Z/i)).present?
10
+ return false if (self =~ (/\A(false|f|no|n|0)\Z/i)).present?
11
+ raise "Can't convert empty string to boolean" if blank?
12
+
13
+ raise "Can't convert string value #{self} to boolean"
14
+ elsif is_a?(::Integer)
15
+ return true if self == 1
16
+ return false if zero?
17
+
18
+ raise "Can't convert number value #{self} to boolean"
19
+ elsif is_a?(::TrueClass)
20
+ true
21
+ elsif is_a?(::FalseClass)
22
+ false
23
+ elsif is_a?(::NilClass)
24
+ null_true == true
25
+ else
26
+ raise "Can't convert type #{self.class.name} to boolean"
27
+ end
28
+ end
29
+
30
+ def is_not_true?(null_not_true: true)
31
+ !is_true?(null_true: !null_not_true)
32
+ end
33
+ # rubocop:enable Naming/PredicateName
34
+ end
35
+ end
36
+ end
37
+
38
+ Object.include(Workato::Extension::Object)
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Workato
4
+ module Extension
5
+ module Phone
6
+ def to_phone(options = {})
7
+ ActiveSupport::NumberHelper::NumberToPhoneConverter(self, options).to_s
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ String.include(Workato::Extension::Phone)
14
+ Integer.include(Workato::Extension::Phone)
@@ -0,0 +1,268 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Workato
4
+ module Extension
5
+ module String
6
+ HUMAN_DATE_FP = { '%d' => 'DD', '%m' => 'MM', '%Y' => 'YYYY' }.freeze
7
+ HUMAN_DATE_FORMAT = %w[%d %m %Y].permutation(3).each_with_object({}) do |fmt, r|
8
+ %w[/ -].each do |s|
9
+ v = fmt.join(s)
10
+ k = fmt.map { |fp| HUMAN_DATE_FP[fp] }.join(s)
11
+ r[k] = v
12
+ end
13
+ end
14
+ TO_COUNTRY_METHODS = %w[alpha2 alpha3 name number].freeze
15
+ TO_CURRENCY_METHODS = %w[code name symbol].freeze
16
+ TO_STATE_METHODS = %w[code name].freeze
17
+
18
+ def is_int? # rubocop:disable Naming/PredicateName
19
+ present? && (self !~ /\D/)
20
+ end
21
+
22
+ def is_number? # rubocop:disable Naming/PredicateName
23
+ return false if blank?
24
+
25
+ match?(/^\d+$/) ||
26
+ begin
27
+ Float(self)
28
+ rescue StandardError
29
+ false
30
+ end.present?
31
+ end
32
+
33
+ def split_strip_compact(pattern, parts = 0)
34
+ split(pattern, parts).map(&:strip).select(&:present?)
35
+ end
36
+
37
+ def strip_tags
38
+ Loofah::Helpers.strip_tags(self)
39
+ end
40
+
41
+ def to_time(form = :local, format: nil)
42
+ if format.present?
43
+ format = HUMAN_DATE_FORMAT[format] if HUMAN_DATE_FORMAT.key?(format)
44
+ time = ::Time.strptime(self, format)
45
+ form == :utc ? time.utc : time.getlocal
46
+ else
47
+ super form
48
+ end
49
+ end
50
+
51
+ def quote
52
+ gsub("'", "''")
53
+ end
54
+
55
+ def to_date(format: nil)
56
+ if format.present?
57
+ format = HUMAN_DATE_FORMAT[format] if HUMAN_DATE_FORMAT.key?(format)
58
+ ::Date.strptime(self, format)
59
+ else
60
+ super()
61
+ end
62
+ end
63
+
64
+ def transliterate(replacement = '?')
65
+ I18n.transliterate(self, replacement)
66
+ end
67
+
68
+ def labelize(*acronyms)
69
+ acronyms.unshift(/^id$/i, /^ur[il]$/i)
70
+ split(/_+ # snake_case => Snake case
71
+ |
72
+ (?<!\d)(?=\d)|(?<=\d)(?!\d) # concatenated42numbers => Concatenated 42 numbers
73
+ |
74
+ (?<![A-Z])(?=[A-Z]) # camelCase => Camel case
75
+ |
76
+ (?<=[A-Z0-9])(?=[A-Z][^A-Z0-9_] # MIXEDCase => Mixed case
77
+ )/x).select(&:present?).map.with_index do |word, i|
78
+ if /^[A-Z]+$/ =~ word
79
+ word
80
+ elsif acronyms.any? { |pattern| pattern =~ word }
81
+ word.upcase
82
+ elsif i.zero?
83
+ word.humanize
84
+ else
85
+ word.downcase
86
+ end
87
+ end.join(' ')
88
+ end
89
+
90
+ def to_hex
91
+ unpack('H*')[0]
92
+ end
93
+
94
+ def base64
95
+ encode_base64
96
+ end
97
+
98
+ alias encode_hex to_hex
99
+
100
+ def decode_hex
101
+ Binary.new([self].pack('H*'))
102
+ end
103
+
104
+ def encode_base64
105
+ Base64.strict_encode64(self)
106
+ end
107
+
108
+ def decode_base64
109
+ Binary.new(Base64.decode64(self))
110
+ end
111
+
112
+ def encode_urlsafe_base64
113
+ Base64.urlsafe_encode64(self)
114
+ end
115
+
116
+ def encode_url
117
+ ::ERB::Util.url_encode(self)
118
+ end
119
+
120
+ def decode_urlsafe_base64
121
+ Binary.new(Base64.urlsafe_decode64(self))
122
+ end
123
+
124
+ def encode_sha256
125
+ Binary.new(::Digest::SHA256.digest(self))
126
+ end
127
+
128
+ def hmac_sha256(key)
129
+ digest = ::OpenSSL::Digest.new('sha256')
130
+ Binary.new(::OpenSSL::HMAC.digest(digest, key, self))
131
+ end
132
+
133
+ def hmac_sha512(key)
134
+ digest = ::OpenSSL::Digest.new('sha512')
135
+ Binary.new(::OpenSSL::HMAC.digest(digest, key, self))
136
+ end
137
+
138
+ def md5_hexdigest
139
+ ::Digest::MD5.hexdigest(self)
140
+ end
141
+
142
+ def sha1
143
+ Binary.new(::Digest::SHA1.digest(self))
144
+ end
145
+
146
+ def hmac_sha1(key)
147
+ digest = ::OpenSSL::Digest.new('sha1')
148
+ Binary.new(::OpenSSL::HMAC.digest(digest, key, self))
149
+ end
150
+
151
+ def hmac_md5(key)
152
+ digest = ::OpenSSL::Digest.new('md5')
153
+ Binary.new(::OpenSSL::HMAC.digest(digest, key, self))
154
+ end
155
+
156
+ def from_xml
157
+ XML.parse_xml_to_hash self
158
+ end
159
+
160
+ TO_COUNTRY_METHODS.each do |suffix|
161
+ define_method("to_country_#{suffix}") do
162
+ to_country.try(suffix)
163
+ end
164
+ end
165
+
166
+ TO_CURRENCY_METHODS.each do |suffix|
167
+ define_method("to_currency_#{suffix}") do
168
+ to_currency_obj.try(suffix)
169
+ end
170
+ end
171
+
172
+ TO_STATE_METHODS.each do |suffix|
173
+ define_method("to_state_#{suffix}") do |country_name = 'US'|
174
+ to_state(country_name).try(:[], suffix)
175
+ end
176
+ end
177
+
178
+ protected
179
+
180
+ def to_country
181
+ TO_COUNTRY_METHODS.transform_find do |attr|
182
+ ISO3166::Country.send("find_country_by_#{attr}", self)
183
+ end
184
+ end
185
+
186
+ def to_currency_obj
187
+ ISO4217::Currency.from_code(self) || to_country.try(:currency)
188
+ end
189
+
190
+ def to_state(country_name = 'US')
191
+ country_name = country_name.presence || 'US'
192
+ country = country_name.to_country
193
+ return nil if country.blank?
194
+
195
+ state = upcase
196
+ country.states.transform_find do |code, data|
197
+ name = data['name'].upcase
198
+ other_names = Array(data['names']).map(&:upcase)
199
+ if code == state || name == state || other_names.include?(state)
200
+ {
201
+ code: code,
202
+ name: name
203
+ }.with_indifferent_access
204
+ end
205
+ end
206
+ end
207
+ end
208
+
209
+ class Binary < ::String
210
+ TITLE_LENGTH = 16
211
+ SUMMARY_LENGTH = 128
212
+
213
+ def initialize(str)
214
+ super(str)
215
+ force_encoding(Encoding::ASCII_8BIT)
216
+ end
217
+
218
+ def to_s
219
+ self
220
+ end
221
+
222
+ def binary?
223
+ true
224
+ end
225
+
226
+ def base64
227
+ Base64.strict_encode64(self)
228
+ end
229
+
230
+ def as_string(encoding)
231
+ String.new(self, encoding: encoding).encode(encoding, invalid: :replace, undef: :replace)
232
+ end
233
+
234
+ def as_utf8
235
+ as_string('utf-8')
236
+ end
237
+
238
+ # representation in event title
239
+ def title
240
+ if length.positive?
241
+ "0x#{byteslice(0, TITLE_LENGTH).unpack1('H*')}#{bytesize > TITLE_LENGTH ? '…' : ''}"
242
+ else
243
+ ''
244
+ end
245
+ end
246
+
247
+ def sha1
248
+ Binary.new(::Digest::SHA1.digest(self))
249
+ end
250
+
251
+ def summary
252
+ if length.positive?
253
+ left = "0x#{byteslice(0, SUMMARY_LENGTH).unpack1('H*')}"
254
+ right = bytesize > SUMMARY_LENGTH ? "…(#{bytesize - SUMMARY_LENGTH} bytes more)" : ''
255
+ "#{left}#{right}"
256
+ else
257
+ ''
258
+ end
259
+ end
260
+
261
+ def self.from_base64(base64str)
262
+ new(Base64.strict_decode64(base64str))
263
+ end
264
+ end
265
+ end
266
+ end
267
+
268
+ String.include(Workato::Extension::String)