flowcommerce-reference 0.4.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 13b5712eece4ef28651a789a2c5124981f1eb5c1
4
+ data.tar.gz: d97dd87622d76f9f45a6f6636c8ede911ce2765a
5
+ SHA512:
6
+ metadata.gz: 9a3f99e0b1817a913ffc05797ec7858ad2dd97bb5dd749be94bf216c6ca3b78d70c6a732c7a073dd67e53992f5617062cf2721d7aafc08e3cff9bd03178f780c
7
+ data.tar.gz: fce76d6ad82251a30140dea63ac96328a1942c953f01fb25a3281959e9d98fed4ad51e9ba3cd5722101785f2120d169cddbe467e746694db8ba141a0148bbc95
@@ -0,0 +1,125 @@
1
+ require_relative 'io_flow_reference_v0'
2
+ require_relative 'version'
3
+ require_relative 'generated/currencies'
4
+ require_relative 'generated/countries'
5
+ require_relative 'generated/continents'
6
+ require_relative 'generated/languages'
7
+ require_relative 'generated/payment_methods'
8
+
9
+ module Flow
10
+ module Reference
11
+ class Currencies
12
+ class << self
13
+ def find(currency_code)
14
+ code = currency_code.to_s.downcase.gsub(/[^\w]/, '').capitalize
15
+ return nil unless code.length == 3
16
+ return nil unless Data.respond_to?(code)
17
+ Data.send(code)
18
+ end
19
+
20
+ def find!(currency_code)
21
+ find(currency_code) || raise(ArgumentError, 'Currency "%s" is not found' % currency_code)
22
+ end
23
+ end
24
+ end
25
+
26
+ class Countries
27
+ class << self
28
+ def find(country_code)
29
+ code = country_code.to_s.downcase.gsub(/[^\w]/,"").capitalize
30
+ return nil unless [2,3].include?(code.length)
31
+ return nil unless Data.respond_to?(code)
32
+ Data.send(code)
33
+ end
34
+
35
+ def find!(country_code)
36
+ find(country_code) || raise(ArgumentError, 'Country "%s" is not found' % country_code)
37
+ end
38
+ end
39
+ end
40
+
41
+ class Locales
42
+ class << self
43
+ def find(locale_code)
44
+ code = locale_code.to_s.downcase.gsub(/[^\w]/,"").capitalize
45
+ return nil unless code.length == 3
46
+ return nil unless Data.respond_to?(code)
47
+ Data.send(code)
48
+ end
49
+
50
+ def find!(locale_code)
51
+ find(locale_code) || raise(ArgumentError, 'Country "%s" is not found' % locale_code)
52
+ end
53
+ end
54
+ end
55
+
56
+ class Continents
57
+ class << self
58
+ def find(continent_code)
59
+ code = continent_code.to_s.downcase.gsub(/[^\w]/,"").capitalize
60
+ return nil unless code.length == 3
61
+ return nil unless Data.respond_to?(code)
62
+ Data.send(code)
63
+ end
64
+
65
+ def find!(continent_code)
66
+ find(continent_code) || raise(ArgumentError, 'Continent "%s" is not found' % continent_code)
67
+ end
68
+ end
69
+ end
70
+
71
+ class Languages
72
+ class << self
73
+ def find(language_code)
74
+ code = language_code.to_s.downcase.gsub(/[^\w]/,"").capitalize
75
+ return nil unless code.length == 2
76
+ return nil unless Data.respond_to?(code)
77
+ Data.send(code)
78
+ end
79
+
80
+ def find!(language_code)
81
+ find(language_code) || raise(ArgumentError, 'Language "%s" is not found' % language_code)
82
+ end
83
+ end
84
+ end
85
+
86
+ class PaymentMethods
87
+ class << self
88
+ def find(payment_code)
89
+ code = payment_code.gsub(/[^\w]/,'').capitalize.gsub(/_(\w)/){ $1.upcase }
90
+ return nil unless Data.respond_to?(code)
91
+ Data.send(code)
92
+ end
93
+
94
+ def find!(payment_code)
95
+ find(payment_code) || raise(ArgumentError, 'Payment method "%s" is not found' % payment_code)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ module Io::Flow::Reference::V0::Models
103
+ class Currency
104
+ def to_cents(amount_in)
105
+ amount = amount_in.to_f
106
+
107
+ if number_decimals > 0
108
+ (amount * (10**number_decimals)).round(0)
109
+ else
110
+ amount.to_i
111
+ end
112
+ end
113
+ end
114
+
115
+ class Continent
116
+ end
117
+
118
+ class Country
119
+ def locales
120
+ list = 'country_%s' % @iso_3166_3.downcase
121
+ ref = ::Flow::Reference::Locales::Data
122
+ ref.respond_to?(list) ? ref.send(list) : nil
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,1370 @@
1
+ # Generated by API Builder - https://www.apibuilder.io
2
+ # Service version: 0.5.9
3
+ # apibuilder 0.14.3 app.apibuilder.io/flow/reference/0.5.9/ruby_client
4
+
5
+ require 'cgi'
6
+ require 'net/http'
7
+ require 'net/https'
8
+ require 'uri'
9
+ require 'base64'
10
+
11
+ require 'date'
12
+ require 'rubygems'
13
+ require 'json'
14
+ require 'bigdecimal'
15
+
16
+ # Reference data that changes infrequently including countries, currencies,
17
+ # languages, etc.
18
+ module Io
19
+ module Flow
20
+ module Reference
21
+ module V0
22
+
23
+ class Client
24
+
25
+ module Constants
26
+
27
+ BASE_URL = 'https://api.flow.io/reference' unless defined?(Constants::BASE_URL)
28
+ NAMESPACE = 'io.flow.reference.v0' unless defined?(Constants::NAMESPACE)
29
+ USER_AGENT = 'apibuilder 0.14.3 app.apibuilder.io/flow/reference/0.5.9/ruby_client' unless defined?(Constants::USER_AGENT)
30
+ VERSION = '0.5.9' unless defined?(Constants::VERSION)
31
+ VERSION_MAJOR = 0 unless defined?(VERSION_MAJOR)
32
+
33
+ end
34
+
35
+ attr_reader :url
36
+
37
+ def initialize(url, opts={})
38
+ @url = HttpClient::Preconditions.assert_class('url', url, String)
39
+ @base_url = URI(url)
40
+ @authorization = HttpClient::Preconditions.assert_class_or_nil('authorization', opts.delete(:authorization), HttpClient::Authorization)
41
+ @default_headers = HttpClient::Preconditions.assert_class('default_headers', opts.delete(:default_headers) || {}, Hash)
42
+ @http_handler = opts.delete(:http_handler) || HttpClient::DefaultHttpHandler.new
43
+
44
+ HttpClient::Preconditions.assert_empty_opts(opts)
45
+ HttpClient::Preconditions.check_state(url.match(/http.+/i), "URL[%s] must start with http" % url)
46
+ end
47
+
48
+ # Creates an instance of the client using the base url specified in the API spec.
49
+ def Client.at_base_url(opts={})
50
+ Client.new(Constants::BASE_URL, opts)
51
+ end
52
+
53
+ def request(path=nil)
54
+ HttpClient::Preconditions.assert_class_or_nil('path', path, String)
55
+ request = HttpClient::Request.new(@http_handler, @base_url, path.to_s).with_header('User-Agent', Constants::USER_AGENT).with_header('X-Apidoc-Version', Constants::VERSION).with_header('X-Apidoc-Version-Major', Constants::VERSION_MAJOR)
56
+
57
+ @default_headers.each do |key, value|
58
+ request = request.with_header(key, value)
59
+ end
60
+
61
+ if @authorization
62
+ request = request.with_auth(@authorization)
63
+ end
64
+
65
+ request
66
+ end
67
+
68
+ def countries
69
+ @countries ||= ::Io::Flow::Reference::V0::Clients::Countries.new(self)
70
+ end
71
+
72
+ def currencies
73
+ @currencies ||= ::Io::Flow::Reference::V0::Clients::Currencies.new(self)
74
+ end
75
+
76
+ def languages
77
+ @languages ||= ::Io::Flow::Reference::V0::Clients::Languages.new(self)
78
+ end
79
+
80
+ def locales
81
+ @locales ||= ::Io::Flow::Reference::V0::Clients::Locales.new(self)
82
+ end
83
+
84
+ def payment_methods
85
+ @payment_methods ||= ::Io::Flow::Reference::V0::Clients::PaymentMethods.new(self)
86
+ end
87
+
88
+ def provinces
89
+ @provinces ||= ::Io::Flow::Reference::V0::Clients::Provinces.new(self)
90
+ end
91
+
92
+ def regions
93
+ @regions ||= ::Io::Flow::Reference::V0::Clients::Regions.new(self)
94
+ end
95
+
96
+ def timezones
97
+ @timezones ||= ::Io::Flow::Reference::V0::Clients::Timezones.new(self)
98
+ end
99
+ end
100
+
101
+ module Clients
102
+
103
+ class Countries
104
+
105
+ def initialize(client)
106
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
107
+ end
108
+
109
+ # Returns a list of countries.
110
+ def get(incoming={})
111
+ opts = HttpClient::Helper.symbolize_keys(incoming)
112
+ query = {
113
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
114
+ }.delete_if { |k, v| v.nil? }
115
+ r = @client.request("/reference/countries").with_query(query).get
116
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Country.new(x) }
117
+ end
118
+
119
+ end
120
+
121
+ class Currencies
122
+
123
+ def initialize(client)
124
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
125
+ end
126
+
127
+ # Returns a list of currencies.
128
+ def get(incoming={})
129
+ opts = HttpClient::Helper.symbolize_keys(incoming)
130
+ query = {
131
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
132
+ }.delete_if { |k, v| v.nil? }
133
+ r = @client.request("/reference/currencies").with_query(query).get
134
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Currency.new(x) }
135
+ end
136
+
137
+ end
138
+
139
+ class Languages
140
+
141
+ def initialize(client)
142
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
143
+ end
144
+
145
+ # Returns a list of languages.
146
+ def get(incoming={})
147
+ opts = HttpClient::Helper.symbolize_keys(incoming)
148
+ query = {
149
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
150
+ }.delete_if { |k, v| v.nil? }
151
+ r = @client.request("/reference/languages").with_query(query).get
152
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Language.new(x) }
153
+ end
154
+
155
+ end
156
+
157
+ class Locales
158
+
159
+ def initialize(client)
160
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
161
+ end
162
+
163
+ # Returns a list of locales.
164
+ def get(incoming={})
165
+ opts = HttpClient::Helper.symbolize_keys(incoming)
166
+ query = {
167
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
168
+ }.delete_if { |k, v| v.nil? }
169
+ r = @client.request("/reference/locales").with_query(query).get
170
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Locale.new(x) }
171
+ end
172
+
173
+ # Returns the locale with the specifed id.
174
+ def get_by_id(id)
175
+ HttpClient::Preconditions.assert_class('id', id, String)
176
+ r = @client.request("/reference/locales/#{CGI.escape(id)}").get
177
+ ::Io::Flow::Reference::V0::Models::Locale.new(r)
178
+ end
179
+
180
+ end
181
+
182
+ class PaymentMethods
183
+
184
+ def initialize(client)
185
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
186
+ end
187
+
188
+ # Returns a list of payment methods supported by Flow.
189
+ def get(incoming={})
190
+ opts = HttpClient::Helper.symbolize_keys(incoming)
191
+ query = {
192
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
193
+ }.delete_if { |k, v| v.nil? }
194
+ r = @client.request("/reference/payment-methods").with_query(query).get
195
+ r.map { |x| ::Io::Flow::Reference::V0::Models::PaymentMethod.new(x) }
196
+ end
197
+
198
+ end
199
+
200
+ class Provinces
201
+
202
+ def initialize(client)
203
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
204
+ end
205
+
206
+ # Returns a list of provinces.
207
+ def get(incoming={})
208
+ opts = HttpClient::Helper.symbolize_keys(incoming)
209
+ query = {
210
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String)),
211
+ :countries => (x = opts.delete(:countries); x.nil? ? nil : HttpClient::Preconditions.assert_class('countries', x, Array).map { |v| HttpClient::Preconditions.assert_class('countries', v, String) })
212
+ }.delete_if { |k, v| v.nil? }
213
+ r = @client.request("/reference/provinces").with_query(query).get
214
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Province.new(x) }
215
+ end
216
+
217
+ # Returns the province with the specifed id.
218
+ def get_by_id(id)
219
+ HttpClient::Preconditions.assert_class('id', id, String)
220
+ r = @client.request("/reference/provinces/#{CGI.escape(id)}").get
221
+ ::Io::Flow::Reference::V0::Models::Province.new(r)
222
+ end
223
+
224
+ end
225
+
226
+ class Regions
227
+
228
+ def initialize(client)
229
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
230
+ end
231
+
232
+ # Returns a list of regions.
233
+ def get(incoming={})
234
+ opts = HttpClient::Helper.symbolize_keys(incoming)
235
+ query = {
236
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
237
+ }.delete_if { |k, v| v.nil? }
238
+ r = @client.request("/reference/regions").with_query(query).get
239
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Region.new(x) }
240
+ end
241
+
242
+ # Returns the region with the specifed id.
243
+ def get_by_id(id)
244
+ HttpClient::Preconditions.assert_class('id', id, String)
245
+ r = @client.request("/reference/regions/#{CGI.escape(id)}").get
246
+ ::Io::Flow::Reference::V0::Models::Region.new(r)
247
+ end
248
+
249
+ end
250
+
251
+ class Timezones
252
+
253
+ def initialize(client)
254
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
255
+ end
256
+
257
+ # Returns a list of timezones.
258
+ def get(incoming={})
259
+ opts = HttpClient::Helper.symbolize_keys(incoming)
260
+ query = {
261
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
262
+ }.delete_if { |k, v| v.nil? }
263
+ r = @client.request("/reference/timezones").with_query(query).get
264
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Timezone.new(x) }
265
+ end
266
+
267
+ end
268
+
269
+ end
270
+
271
+ module Models
272
+
273
+ class PaymentMethodType
274
+
275
+ attr_reader :value
276
+
277
+ def initialize(value)
278
+ @value = HttpClient::Preconditions.assert_class('value', value, String)
279
+ end
280
+
281
+ # Returns the instance of PaymentMethodType for this value, creating a new instance for an unknown value
282
+ def PaymentMethodType.apply(value)
283
+ if value.instance_of?(PaymentMethodType)
284
+ value
285
+ else
286
+ HttpClient::Preconditions.assert_class_or_nil('value', value, String)
287
+ value.nil? ? nil : (from_string(value) || PaymentMethodType.new(value))
288
+ end
289
+ end
290
+
291
+ # Returns the instance of PaymentMethodType for this value, or nil if not found
292
+ def PaymentMethodType.from_string(value)
293
+ HttpClient::Preconditions.assert_class('value', value, String)
294
+ PaymentMethodType.ALL.find { |v| v.value == value }
295
+ end
296
+
297
+ def PaymentMethodType.ALL
298
+ @@all ||= [PaymentMethodType.card, PaymentMethodType.online, PaymentMethodType.offline]
299
+ end
300
+
301
+ # Represents all form of card payment (e.g. credit, debit, etc.)
302
+ def PaymentMethodType.card
303
+ @@_card ||= PaymentMethodType.new('card')
304
+ end
305
+
306
+ # Represents the most common form of alternative payment methods which require
307
+ # some degree of integration online (e.g. a redirect) to complete payment.
308
+ def PaymentMethodType.online
309
+ @@_online ||= PaymentMethodType.new('online')
310
+ end
311
+
312
+ # Offline payment method types represent payments like Cash On Delivery which
313
+ # require offline collection
314
+ def PaymentMethodType.offline
315
+ @@_offline ||= PaymentMethodType.new('offline')
316
+ end
317
+
318
+ def to_hash
319
+ value
320
+ end
321
+
322
+ end
323
+
324
+ class ProvinceType
325
+
326
+ attr_reader :value
327
+
328
+ def initialize(value)
329
+ @value = HttpClient::Preconditions.assert_class('value', value, String)
330
+ end
331
+
332
+ # Returns the instance of ProvinceType for this value, creating a new instance for an unknown value
333
+ def ProvinceType.apply(value)
334
+ if value.instance_of?(ProvinceType)
335
+ value
336
+ else
337
+ HttpClient::Preconditions.assert_class_or_nil('value', value, String)
338
+ value.nil? ? nil : (from_string(value) || ProvinceType.new(value))
339
+ end
340
+ end
341
+
342
+ # Returns the instance of ProvinceType for this value, or nil if not found
343
+ def ProvinceType.from_string(value)
344
+ HttpClient::Preconditions.assert_class('value', value, String)
345
+ ProvinceType.ALL.find { |v| v.value == value }
346
+ end
347
+
348
+ def ProvinceType.ALL
349
+ @@all ||= [ProvinceType.city, ProvinceType.dependency, ProvinceType.district, ProvinceType.emirate, ProvinceType.entity, ProvinceType.municipality, ProvinceType.outlying_area, ProvinceType.parish, ProvinceType.province, ProvinceType.state, ProvinceType.territory, ProvinceType.other]
350
+ end
351
+
352
+ def ProvinceType.city
353
+ @@_city ||= ProvinceType.new('city')
354
+ end
355
+
356
+ def ProvinceType.dependency
357
+ @@_dependency ||= ProvinceType.new('dependency')
358
+ end
359
+
360
+ def ProvinceType.district
361
+ @@_district ||= ProvinceType.new('district')
362
+ end
363
+
364
+ def ProvinceType.emirate
365
+ @@_emirate ||= ProvinceType.new('emirate')
366
+ end
367
+
368
+ def ProvinceType.entity
369
+ @@_entity ||= ProvinceType.new('entity')
370
+ end
371
+
372
+ def ProvinceType.municipality
373
+ @@_municipality ||= ProvinceType.new('municipality')
374
+ end
375
+
376
+ def ProvinceType.outlying_area
377
+ @@_outlying_area ||= ProvinceType.new('outlying_area')
378
+ end
379
+
380
+ def ProvinceType.parish
381
+ @@_parish ||= ProvinceType.new('parish')
382
+ end
383
+
384
+ def ProvinceType.province
385
+ @@_province ||= ProvinceType.new('province')
386
+ end
387
+
388
+ def ProvinceType.state
389
+ @@_state ||= ProvinceType.new('state')
390
+ end
391
+
392
+ def ProvinceType.territory
393
+ @@_territory ||= ProvinceType.new('territory')
394
+ end
395
+
396
+ def ProvinceType.other
397
+ @@_other ||= ProvinceType.new('other')
398
+ end
399
+
400
+ def to_hash
401
+ value
402
+ end
403
+
404
+ end
405
+
406
+ # Partner that actually takes a shipment between places (ex: FedEx, DHL, SF
407
+ # Express)
408
+ class Carrier
409
+
410
+ attr_reader :id, :name, :tracking_url
411
+
412
+ def initialize(incoming={})
413
+ opts = HttpClient::Helper.symbolize_keys(incoming)
414
+ HttpClient::Preconditions.require_keys(opts, [:id, :name, :tracking_url], 'Carrier')
415
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
416
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
417
+ @tracking_url = HttpClient::Preconditions.assert_class('tracking_url', opts.delete(:tracking_url), String)
418
+ end
419
+
420
+ def to_json
421
+ JSON.dump(to_hash)
422
+ end
423
+
424
+ def copy(incoming={})
425
+ Carrier.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
426
+ end
427
+
428
+ def to_hash
429
+ {
430
+ :id => id,
431
+ :name => name,
432
+ :tracking_url => tracking_url
433
+ }
434
+ end
435
+
436
+ end
437
+
438
+ # Specific service rendered by the carrier (fedex ground saturday, ups overnight
439
+ # weekend, etc)
440
+ class CarrierService
441
+
442
+ attr_reader :id, :carrier, :name
443
+
444
+ def initialize(incoming={})
445
+ opts = HttpClient::Helper.symbolize_keys(incoming)
446
+ HttpClient::Preconditions.require_keys(opts, [:id, :carrier, :name], 'CarrierService')
447
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
448
+ @carrier = (x = opts.delete(:carrier); x.is_a?(::Io::Flow::Reference::V0::Models::Carrier) ? x : ::Io::Flow::Reference::V0::Models::Carrier.new(x))
449
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
450
+ end
451
+
452
+ def to_json
453
+ JSON.dump(to_hash)
454
+ end
455
+
456
+ def copy(incoming={})
457
+ CarrierService.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
458
+ end
459
+
460
+ def to_hash
461
+ {
462
+ :id => id,
463
+ :carrier => carrier.to_hash,
464
+ :name => name
465
+ }
466
+ end
467
+
468
+ end
469
+
470
+ # ISO 3166 country codes. Note Flow APIs will accept either the 2 or 3 character
471
+ # country code, but internally we normalize data and store as the 3 character,
472
+ # upper case ISO code. See https://api.flow.io/reference/countries
473
+ class Country
474
+
475
+ attr_reader :name, :iso_3166_2, :iso_3166_3, :languages, :measurement_system, :default_currency, :timezones, :default_delivered_duty
476
+
477
+ def initialize(incoming={})
478
+ opts = HttpClient::Helper.symbolize_keys(incoming)
479
+ HttpClient::Preconditions.require_keys(opts, [:name, :iso_3166_2, :iso_3166_3, :languages, :measurement_system, :timezones], 'Country')
480
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
481
+ @iso_3166_2 = HttpClient::Preconditions.assert_class('iso_3166_2', opts.delete(:iso_3166_2), String)
482
+ @iso_3166_3 = HttpClient::Preconditions.assert_class('iso_3166_3', opts.delete(:iso_3166_3), String)
483
+ @languages = HttpClient::Preconditions.assert_class('languages', opts.delete(:languages), Array).map { |v| HttpClient::Preconditions.assert_class('languages', v, String) }
484
+ @measurement_system = HttpClient::Preconditions.assert_class('measurement_system', opts.delete(:measurement_system), String)
485
+ @default_currency = (x = opts.delete(:default_currency); x.nil? ? nil : HttpClient::Preconditions.assert_class('default_currency', x, String))
486
+ @timezones = HttpClient::Preconditions.assert_class('timezones', opts.delete(:timezones), Array).map { |v| HttpClient::Preconditions.assert_class('timezones', v, String) }
487
+ @default_delivered_duty = (x = opts.delete(:default_delivered_duty); x.nil? ? nil : HttpClient::Preconditions.assert_class('default_delivered_duty', x, String))
488
+ end
489
+
490
+ def to_json
491
+ JSON.dump(to_hash)
492
+ end
493
+
494
+ def copy(incoming={})
495
+ Country.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
496
+ end
497
+
498
+ def to_hash
499
+ {
500
+ :name => name,
501
+ :iso_3166_2 => iso_3166_2,
502
+ :iso_3166_3 => iso_3166_3,
503
+ :languages => languages,
504
+ :measurement_system => measurement_system,
505
+ :default_currency => default_currency,
506
+ :timezones => timezones,
507
+ :default_delivered_duty => default_delivered_duty
508
+ }
509
+ end
510
+
511
+ end
512
+
513
+ # ISO 4217 3-character currency code. See
514
+ # https://api.flow.io/reference/currencies
515
+ class Currency
516
+
517
+ attr_reader :name, :iso_4217_3, :number_decimals, :symbols, :default_locale
518
+
519
+ def initialize(incoming={})
520
+ opts = HttpClient::Helper.symbolize_keys(incoming)
521
+ HttpClient::Preconditions.require_keys(opts, [:name, :iso_4217_3, :number_decimals], 'Currency')
522
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
523
+ @iso_4217_3 = HttpClient::Preconditions.assert_class('iso_4217_3', opts.delete(:iso_4217_3), String)
524
+ @number_decimals = HttpClient::Preconditions.assert_class('number_decimals', opts.delete(:number_decimals), Integer)
525
+ @symbols = (x = opts.delete(:symbols); x.nil? ? nil : (x = x; x.is_a?(::Io::Flow::Reference::V0::Models::CurrencySymbols) ? x : ::Io::Flow::Reference::V0::Models::CurrencySymbols.new(x)))
526
+ @default_locale = (x = opts.delete(:default_locale); x.nil? ? nil : HttpClient::Preconditions.assert_class('default_locale', x, String))
527
+ end
528
+
529
+ def to_json
530
+ JSON.dump(to_hash)
531
+ end
532
+
533
+ def copy(incoming={})
534
+ Currency.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
535
+ end
536
+
537
+ def to_hash
538
+ {
539
+ :name => name,
540
+ :iso_4217_3 => iso_4217_3,
541
+ :number_decimals => number_decimals,
542
+ :symbols => symbols.nil? ? nil : symbols.to_hash,
543
+ :default_locale => default_locale
544
+ }
545
+ end
546
+
547
+ end
548
+
549
+ # Defines one or more symbols representing this currency
550
+ class CurrencySymbols
551
+
552
+ attr_reader :primary, :narrow
553
+
554
+ def initialize(incoming={})
555
+ opts = HttpClient::Helper.symbolize_keys(incoming)
556
+ HttpClient::Preconditions.require_keys(opts, [:primary], 'CurrencySymbols')
557
+ @primary = HttpClient::Preconditions.assert_class('primary', opts.delete(:primary), String)
558
+ @narrow = (x = opts.delete(:narrow); x.nil? ? nil : HttpClient::Preconditions.assert_class('narrow', x, String))
559
+ end
560
+
561
+ def to_json
562
+ JSON.dump(to_hash)
563
+ end
564
+
565
+ def copy(incoming={})
566
+ CurrencySymbols.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
567
+ end
568
+
569
+ def to_hash
570
+ {
571
+ :primary => primary,
572
+ :narrow => narrow
573
+ }
574
+ end
575
+
576
+ end
577
+
578
+ # ISO 639 2-character language code. See https://api.flow.io/reference/languages
579
+ class Language
580
+
581
+ attr_reader :name, :iso_639_2
582
+
583
+ def initialize(incoming={})
584
+ opts = HttpClient::Helper.symbolize_keys(incoming)
585
+ HttpClient::Preconditions.require_keys(opts, [:name, :iso_639_2], 'Language')
586
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
587
+ @iso_639_2 = HttpClient::Preconditions.assert_class('iso_639_2', opts.delete(:iso_639_2), String)
588
+ end
589
+
590
+ def to_json
591
+ JSON.dump(to_hash)
592
+ end
593
+
594
+ def copy(incoming={})
595
+ Language.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
596
+ end
597
+
598
+ def to_hash
599
+ {
600
+ :name => name,
601
+ :iso_639_2 => iso_639_2
602
+ }
603
+ end
604
+
605
+ end
606
+
607
+ # Locales defines standard conventions for presentation of content. See
608
+ # https://api.flow.io/reference/locales
609
+ class Locale
610
+
611
+ attr_reader :id, :name, :country, :language, :numbers
612
+
613
+ def initialize(incoming={})
614
+ opts = HttpClient::Helper.symbolize_keys(incoming)
615
+ HttpClient::Preconditions.require_keys(opts, [:id, :name, :country, :language, :numbers], 'Locale')
616
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
617
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
618
+ @country = HttpClient::Preconditions.assert_class('country', opts.delete(:country), String)
619
+ @language = HttpClient::Preconditions.assert_class('language', opts.delete(:language), String)
620
+ @numbers = (x = opts.delete(:numbers); x.is_a?(::Io::Flow::Reference::V0::Models::LocaleNumbers) ? x : ::Io::Flow::Reference::V0::Models::LocaleNumbers.new(x))
621
+ end
622
+
623
+ def to_json
624
+ JSON.dump(to_hash)
625
+ end
626
+
627
+ def copy(incoming={})
628
+ Locale.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
629
+ end
630
+
631
+ def to_hash
632
+ {
633
+ :id => id,
634
+ :name => name,
635
+ :country => country,
636
+ :language => language,
637
+ :numbers => numbers.to_hash
638
+ }
639
+ end
640
+
641
+ end
642
+
643
+ # Number formats defined for a given locale
644
+ class LocaleNumbers
645
+
646
+ attr_reader :decimal, :group
647
+
648
+ def initialize(incoming={})
649
+ opts = HttpClient::Helper.symbolize_keys(incoming)
650
+ HttpClient::Preconditions.require_keys(opts, [:decimal, :group], 'LocaleNumbers')
651
+ @decimal = HttpClient::Preconditions.assert_class('decimal', opts.delete(:decimal), String)
652
+ @group = HttpClient::Preconditions.assert_class('group', opts.delete(:group), String)
653
+ end
654
+
655
+ def to_json
656
+ JSON.dump(to_hash)
657
+ end
658
+
659
+ def copy(incoming={})
660
+ LocaleNumbers.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
661
+ end
662
+
663
+ def to_hash
664
+ {
665
+ :decimal => decimal,
666
+ :group => group
667
+ }
668
+ end
669
+
670
+ end
671
+
672
+ # Localized translation of a given province/region/country
673
+ class LocalizedTranslation
674
+
675
+ attr_reader :locale, :name
676
+
677
+ def initialize(incoming={})
678
+ opts = HttpClient::Helper.symbolize_keys(incoming)
679
+ HttpClient::Preconditions.require_keys(opts, [:locale, :name], 'LocalizedTranslation')
680
+ @locale = (x = opts.delete(:locale); x.is_a?(::Io::Flow::Reference::V0::Models::Locale) ? x : ::Io::Flow::Reference::V0::Models::Locale.new(x))
681
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
682
+ end
683
+
684
+ def to_json
685
+ JSON.dump(to_hash)
686
+ end
687
+
688
+ def copy(incoming={})
689
+ LocalizedTranslation.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
690
+ end
691
+
692
+ def to_hash
693
+ {
694
+ :locale => locale.to_hash,
695
+ :name => name
696
+ }
697
+ end
698
+
699
+ end
700
+
701
+ # Represents a single payment method - e.g VISA or Paypal - and any associated
702
+ # metadata required for processing
703
+ class PaymentMethod
704
+
705
+ attr_reader :id, :type, :name, :images, :regions
706
+
707
+ def initialize(incoming={})
708
+ opts = HttpClient::Helper.symbolize_keys(incoming)
709
+ HttpClient::Preconditions.require_keys(opts, [:id, :type, :name, :images, :regions], 'PaymentMethod')
710
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
711
+ @type = (x = opts.delete(:type); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodType) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodType.apply(x))
712
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
713
+ @images = (x = opts.delete(:images); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImages) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImages.new(x))
714
+ @regions = HttpClient::Preconditions.assert_class('regions', opts.delete(:regions), Array).map { |v| HttpClient::Preconditions.assert_class('regions', v, String) }
715
+ end
716
+
717
+ def to_json
718
+ JSON.dump(to_hash)
719
+ end
720
+
721
+ def copy(incoming={})
722
+ PaymentMethod.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
723
+ end
724
+
725
+ def to_hash
726
+ {
727
+ :id => id,
728
+ :type => type.value,
729
+ :name => name,
730
+ :images => images.to_hash,
731
+ :regions => regions
732
+ }
733
+ end
734
+
735
+ end
736
+
737
+ class PaymentMethodImage
738
+
739
+ attr_reader :url, :width, :height
740
+
741
+ def initialize(incoming={})
742
+ opts = HttpClient::Helper.symbolize_keys(incoming)
743
+ HttpClient::Preconditions.require_keys(opts, [:url, :width, :height], 'PaymentMethodImage')
744
+ @url = HttpClient::Preconditions.assert_class('url', opts.delete(:url), String)
745
+ @width = HttpClient::Preconditions.assert_class('width', opts.delete(:width), Integer)
746
+ @height = HttpClient::Preconditions.assert_class('height', opts.delete(:height), Integer)
747
+ end
748
+
749
+ def to_json
750
+ JSON.dump(to_hash)
751
+ end
752
+
753
+ def copy(incoming={})
754
+ PaymentMethodImage.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
755
+ end
756
+
757
+ def to_hash
758
+ {
759
+ :url => url,
760
+ :width => width,
761
+ :height => height
762
+ }
763
+ end
764
+
765
+ end
766
+
767
+ class PaymentMethodImages
768
+
769
+ attr_reader :small, :medium, :large
770
+
771
+ def initialize(incoming={})
772
+ opts = HttpClient::Helper.symbolize_keys(incoming)
773
+ HttpClient::Preconditions.require_keys(opts, [:small, :medium, :large], 'PaymentMethodImages')
774
+ @small = (x = opts.delete(:small); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImage) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImage.new(x))
775
+ @medium = (x = opts.delete(:medium); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImage) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImage.new(x))
776
+ @large = (x = opts.delete(:large); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImage) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImage.new(x))
777
+ end
778
+
779
+ def to_json
780
+ JSON.dump(to_hash)
781
+ end
782
+
783
+ def copy(incoming={})
784
+ PaymentMethodImages.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
785
+ end
786
+
787
+ def to_hash
788
+ {
789
+ :small => small.to_hash,
790
+ :medium => medium.to_hash,
791
+ :large => large.to_hash
792
+ }
793
+ end
794
+
795
+ end
796
+
797
+ # A subdivision/province/state within a country. These conform to the ISO 3166-2
798
+ # standard for country subdivisions. See https://api.flow.io/reference/provinces
799
+ class Province
800
+
801
+ attr_reader :id, :iso_3166_2, :name, :country, :province_type, :translations
802
+
803
+ def initialize(incoming={})
804
+ opts = HttpClient::Helper.symbolize_keys(incoming)
805
+ HttpClient::Preconditions.require_keys(opts, [:id, :iso_3166_2, :name, :country, :province_type], 'Province')
806
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
807
+ @iso_3166_2 = HttpClient::Preconditions.assert_class('iso_3166_2', opts.delete(:iso_3166_2), String)
808
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
809
+ @country = HttpClient::Preconditions.assert_class('country', opts.delete(:country), String)
810
+ @province_type = (x = opts.delete(:province_type); x.is_a?(::Io::Flow::Reference::V0::Models::ProvinceType) ? x : ::Io::Flow::Reference::V0::Models::ProvinceType.apply(x))
811
+ @translations = (x = opts.delete(:translations); x.nil? ? nil : HttpClient::Preconditions.assert_class('translations', x, Array).map { |v| (x = v; x.is_a?(::Io::Flow::Reference::V0::Models::LocalizedTranslation) ? x : ::Io::Flow::Reference::V0::Models::LocalizedTranslation.new(x)) })
812
+ end
813
+
814
+ def to_json
815
+ JSON.dump(to_hash)
816
+ end
817
+
818
+ def copy(incoming={})
819
+ Province.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
820
+ end
821
+
822
+ def to_hash
823
+ {
824
+ :id => id,
825
+ :iso_3166_2 => iso_3166_2,
826
+ :name => name,
827
+ :country => country,
828
+ :province_type => province_type.value,
829
+ :translations => translations.nil? ? nil : translations.map { |o| o.to_hash }
830
+ }
831
+ end
832
+
833
+ end
834
+
835
+ # A region represents a geographic area of the world. Regions can be countries,
836
+ # continents or other political areas (like the Eurozone). See
837
+ # https://api.flow.io/reference/regions
838
+ class Region
839
+
840
+ attr_reader :id, :name, :countries, :currencies, :languages, :measurement_systems, :timezones
841
+
842
+ def initialize(incoming={})
843
+ opts = HttpClient::Helper.symbolize_keys(incoming)
844
+ HttpClient::Preconditions.require_keys(opts, [:id, :name, :countries, :currencies, :languages, :measurement_systems, :timezones], 'Region')
845
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
846
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
847
+ @countries = HttpClient::Preconditions.assert_class('countries', opts.delete(:countries), Array).map { |v| HttpClient::Preconditions.assert_class('countries', v, String) }
848
+ @currencies = HttpClient::Preconditions.assert_class('currencies', opts.delete(:currencies), Array).map { |v| HttpClient::Preconditions.assert_class('currencies', v, String) }
849
+ @languages = HttpClient::Preconditions.assert_class('languages', opts.delete(:languages), Array).map { |v| HttpClient::Preconditions.assert_class('languages', v, String) }
850
+ @measurement_systems = HttpClient::Preconditions.assert_class('measurement_systems', opts.delete(:measurement_systems), Array).map { |v| HttpClient::Preconditions.assert_class('measurement_systems', v, String) }
851
+ @timezones = HttpClient::Preconditions.assert_class('timezones', opts.delete(:timezones), Array).map { |v| HttpClient::Preconditions.assert_class('timezones', v, String) }
852
+ end
853
+
854
+ def to_json
855
+ JSON.dump(to_hash)
856
+ end
857
+
858
+ def copy(incoming={})
859
+ Region.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
860
+ end
861
+
862
+ def to_hash
863
+ {
864
+ :id => id,
865
+ :name => name,
866
+ :countries => countries,
867
+ :currencies => currencies,
868
+ :languages => languages,
869
+ :measurement_systems => measurement_systems,
870
+ :timezones => timezones
871
+ }
872
+ end
873
+
874
+ end
875
+
876
+ # Time zone data is provided by the public IANA time zone database. See
877
+ # http://www.iana.org/time-zones
878
+ class Timezone
879
+
880
+ attr_reader :name, :description, :offset
881
+
882
+ def initialize(incoming={})
883
+ opts = HttpClient::Helper.symbolize_keys(incoming)
884
+ HttpClient::Preconditions.require_keys(opts, [:name, :description, :offset], 'Timezone')
885
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
886
+ @description = HttpClient::Preconditions.assert_class('description', opts.delete(:description), String)
887
+ @offset = HttpClient::Preconditions.assert_class('offset', opts.delete(:offset), Integer)
888
+ end
889
+
890
+ def to_json
891
+ JSON.dump(to_hash)
892
+ end
893
+
894
+ def copy(incoming={})
895
+ Timezone.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
896
+ end
897
+
898
+ def to_hash
899
+ {
900
+ :name => name,
901
+ :description => description,
902
+ :offset => offset
903
+ }
904
+ end
905
+
906
+ end
907
+
908
+ end
909
+
910
+ # ===== END OF SERVICE DEFINITION =====
911
+ module HttpClient
912
+
913
+ class HttpHandler
914
+
915
+ # Returns a client instance to use
916
+ #
917
+ # @param base_uri The base URI for this API
918
+ # @param path the Requested full http path (including any query strings)
919
+ def instance(base_uri, path)
920
+ raise "Override in subclass"
921
+ end
922
+
923
+ end
924
+
925
+ class HttpHandlerInstance
926
+
927
+ # Executes a request. The provided request object will be an
928
+ # instance of Net::HTTP (e.g. Net::HTTP::Get)
929
+ def execute(request)
930
+ raise "Override in subclass"
931
+ end
932
+
933
+ end
934
+
935
+ class DefaultHttpHandler < HttpHandler
936
+
937
+ def instance(base_uri, path)
938
+ DefaultHttpHandlerInstance.new(base_uri)
939
+ end
940
+
941
+ end
942
+
943
+ class DefaultHttpHandlerInstance < HttpHandlerInstance
944
+
945
+ attr_reader :client
946
+
947
+ def initialize(base_uri)
948
+ @base_uri = Preconditions.assert_class('base_uri', base_uri, URI)
949
+ @client = Net::HTTP.new(@base_uri.host, @base_uri.port)
950
+ if @base_uri.scheme == "https"
951
+ configure_ssl
952
+ end
953
+ end
954
+
955
+ def execute(request)
956
+ response = begin
957
+ @client.request(request)
958
+ rescue SocketError => e
959
+ raise StandardError.new("Error accessing uri[#{full_uri(request.path)}]: #{e}")
960
+ end
961
+
962
+ case response
963
+ when Net::HTTPSuccess
964
+ response.body
965
+ else
966
+ body = response.body rescue nil
967
+ raise HttpClient::ServerError.new(response.code.to_i, response.message, :body => body, :uri => full_uri(request.path).to_s)
968
+ end
969
+ end
970
+
971
+ def full_uri(path)
972
+ path.start_with?(@base_uri.to_s) ? path : File.join(@base_uri.to_s, path)
973
+ end
974
+
975
+ # Called to configure SSL if the base uri requires it
976
+ def configure_ssl
977
+ @client.use_ssl = true
978
+ @client.verify_mode = OpenSSL::SSL::VERIFY_PEER
979
+ @client.cert_store = OpenSSL::X509::Store.new
980
+ @client.cert_store.set_default_paths
981
+ end
982
+
983
+ end
984
+
985
+ class Request
986
+
987
+ attr_reader :base_uri, :path, :full_uri
988
+
989
+ def initialize(http_handler, base_uri, path)
990
+ @http_handler = http_handler
991
+ @base_uri = Preconditions.assert_class('base_uri', base_uri, URI)
992
+ @path = Preconditions.assert_class('path', path, String)
993
+ @full_uri = @base_uri.to_s + @path
994
+ @params = nil
995
+ @body = nil
996
+ @auth = nil
997
+ @headers = {}
998
+ @header_keys_lower_case = []
999
+ end
1000
+
1001
+ def with_header(name, value)
1002
+ Preconditions.check_not_blank('name', name, "Header name is required")
1003
+ Preconditions.check_not_blank('value', value, "Header value is required")
1004
+ Preconditions.check_state(!@headers.has_key?(name),
1005
+ "Duplicate header named[%s]" % name)
1006
+ @headers[name] = value
1007
+ @header_keys_lower_case << name.downcase
1008
+ self
1009
+ end
1010
+
1011
+ def with_auth(auth)
1012
+ Preconditions.assert_class('auth', auth, HttpClient::Authorization)
1013
+ Preconditions.check_state(@auth.nil?, "auth previously set")
1014
+
1015
+ if auth.scheme.name == AuthScheme::BASIC.name
1016
+ @auth = auth
1017
+ else
1018
+ raise "Auth Scheme[#{auth.scheme.name}] not supported"
1019
+ end
1020
+ self
1021
+ end
1022
+
1023
+ def with_query(params)
1024
+ Preconditions.assert_class('params', params, Hash)
1025
+ Preconditions.check_state(@params.nil?, "Already have query parameters")
1026
+ @params = params
1027
+ self
1028
+ end
1029
+
1030
+ # Wrapper to set Content-Type header to application/json and set
1031
+ # the provided json document as the body
1032
+ def with_json(json)
1033
+ @headers['Content-Type'] ||= 'application/json; charset=UTF-8'
1034
+ with_body(json)
1035
+ end
1036
+
1037
+ def with_body(body)
1038
+ Preconditions.check_not_blank('body', body)
1039
+ @body = body
1040
+ self
1041
+ end
1042
+
1043
+ def get(&block)
1044
+ do_request(Net::HTTP::Get, &block)
1045
+ end
1046
+
1047
+ def delete(&block)
1048
+ do_request(Net::HTTP::Delete, &block)
1049
+ end
1050
+
1051
+ def options(&block)
1052
+ do_request(Net::HTTP::Options, &block)
1053
+ end
1054
+
1055
+ def post(&block)
1056
+ do_request(Net::HTTP::Post, &block)
1057
+ end
1058
+
1059
+ def put(&block)
1060
+ do_request(Net::HTTP::Put, &block)
1061
+ end
1062
+
1063
+ class PATCH < Net::HTTP::Put
1064
+ METHOD = "PATCH"
1065
+ end
1066
+
1067
+ def patch(&block)
1068
+ do_request(PATCH, &block)
1069
+ end
1070
+
1071
+ def do_request(klass)
1072
+ Preconditions.assert_class('klass', klass, Class)
1073
+
1074
+ uri = @full_uri.dup
1075
+ if q = to_query(@params)
1076
+ uri += "?%s" % q
1077
+ end
1078
+
1079
+ request = klass.send(:new, uri)
1080
+
1081
+ curl = ['curl']
1082
+ if klass != Net::HTTP::Get
1083
+ curl << "-X%s" % klass.name.split("::").last.upcase
1084
+ end
1085
+
1086
+ if @body
1087
+ # DEBUG path = "/tmp/rest_client.tmp"
1088
+ # DEBUG File.open(path, "w") { |os| os << @body.to_s }
1089
+ # DEBUG curl << "-d@%s" % path
1090
+ request.body = @body
1091
+ end
1092
+
1093
+ if @auth
1094
+ curl << "-u \"%s:%s\"" % [@auth.username, @auth.password]
1095
+ Preconditions.check_state(!@header_keys_lower_case.include?("authorization"),
1096
+ "Cannot specify both an Authorization header and an auth instance")
1097
+ user_pass = "%s:%s" % [@auth.username, @auth.password]
1098
+ encoded = Base64.encode64(user_pass).to_s.split("\n").map(&:strip).join
1099
+ request.add_field("Authorization", "Basic %s" % encoded)
1100
+ end
1101
+
1102
+ @headers.each { |key, value|
1103
+ curl << "-H \"%s: %s\"" % [key, value]
1104
+ request.add_field(key, value)
1105
+ }
1106
+
1107
+ curl << "'%s%s'" % [@base_uri, path]
1108
+ # DEBUG puts curl.join(" ")
1109
+
1110
+ raw_response = @http_handler.instance(@base_uri, request.path).execute(request)
1111
+ response = raw_response.to_s == "" ? nil : JSON.parse(raw_response)
1112
+
1113
+ if block_given?
1114
+ yield response
1115
+ else
1116
+ response
1117
+ end
1118
+ end
1119
+
1120
+ private
1121
+ def to_query(params={})
1122
+ parts = (params || {}).map { |k,v|
1123
+ if v.is_a?(Enumerable)
1124
+ v.map { |el| "%s=%s" % [k, CGI.escape(el.to_s)] }
1125
+ else
1126
+ "%s=%s" % [k, CGI.escape(v.to_s)]
1127
+ end
1128
+ }
1129
+ parts.empty? ? nil : parts.join("&")
1130
+ end
1131
+
1132
+ end
1133
+
1134
+ class ServerError < StandardError
1135
+
1136
+ attr_reader :code, :details, :body, :uri
1137
+
1138
+ def initialize(code, details, incoming={})
1139
+ opts = HttpClient::Helper.symbolize_keys(incoming)
1140
+ @code = HttpClient::Preconditions.assert_class('code', code, Integer)
1141
+ @details = HttpClient::Preconditions.assert_class('details', details, String)
1142
+ @body = HttpClient::Preconditions.assert_class_or_nil('body', opts.delete(:body), String)
1143
+ @uri = HttpClient::Preconditions.assert_class_or_nil('uri', opts.delete(:uri), String)
1144
+ HttpClient::Preconditions.assert_empty_opts(opts)
1145
+ super(self.message)
1146
+ end
1147
+
1148
+ def message
1149
+ m = "%s %s" % [@code, @details]
1150
+ if @body
1151
+ m << ": %s" % @body
1152
+ end
1153
+ m
1154
+ end
1155
+
1156
+ def body_json
1157
+ @body ? JSON.parse(@body) : nil
1158
+ end
1159
+
1160
+ end
1161
+
1162
+ class PreconditionException < StandardError
1163
+
1164
+ attr_reader :message
1165
+
1166
+ def initialize(message)
1167
+ super(message)
1168
+ @message = message
1169
+ end
1170
+
1171
+ end
1172
+
1173
+ module Preconditions
1174
+
1175
+ def Preconditions.check_argument(expression, error_message=nil)
1176
+ if !expression
1177
+ raise PreconditionException.new(error_message || "check_argument failed")
1178
+ end
1179
+ nil
1180
+ end
1181
+
1182
+ def Preconditions.check_state(expression, error_message=nil)
1183
+ if !expression
1184
+ raise PreconditionException.new(error_message || "check_state failed")
1185
+ end
1186
+ nil
1187
+ end
1188
+
1189
+ def Preconditions.check_not_nil(field_name, reference, error_message=nil)
1190
+ if reference.nil?
1191
+ raise PreconditionException.new(error_message || "argument for %s cannot be nil" % field_name)
1192
+ end
1193
+ reference
1194
+ end
1195
+
1196
+ def Preconditions.check_not_blank(field_name, reference, error_message=nil)
1197
+ if reference.to_s.strip == ""
1198
+ raise PreconditionException.new(error_message || "argument for %s cannot be blank" % field_name)
1199
+ end
1200
+ reference
1201
+ end
1202
+
1203
+ # Throws an error if opts is not empty. Useful when parsing
1204
+ # arguments to a function
1205
+ def Preconditions.assert_empty_opts(opts)
1206
+ if !opts.empty?
1207
+ raise PreconditionException.new("Invalid opts: #{opts.keys.inspect}\n#{opts.inspect}")
1208
+ end
1209
+ end
1210
+
1211
+ # Requires that the provided hash has the specified keys.
1212
+ # @param fields A list of symbols
1213
+ def Preconditions.require_keys(hash, fields, error_prefix=nil)
1214
+ missing = fields.select { |f| !hash.has_key?(f) }
1215
+ if !missing.empty?
1216
+ msg = "Missing required fields: " + missing.join(", ")
1217
+ raise PreconditionException.new(error_prefix.empty? ? msg : "#{error_prefix}: #{msg}")
1218
+ end
1219
+ end
1220
+
1221
+ # Asserts that value is not nill and is_?(klass). Returns
1222
+ # value. Common use is
1223
+ #
1224
+ # amount = Preconditions.assert_class('amount', amount, BigDecimal)
1225
+ def Preconditions.assert_class(field_name, value, klass)
1226
+ Preconditions.check_not_nil('field_name', field_name)
1227
+ Preconditions.check_not_nil('klass', klass)
1228
+ Preconditions.check_not_nil('value', value, "Value for %s cannot be nil. Expected an instance of class %s" % [field_name, klass.name])
1229
+ Preconditions.check_state(value.is_a?(klass),
1230
+ "Value for #{field_name} is of type[#{value.class}] - class[#{klass}] is required. value[#{value.inspect.to_s}]")
1231
+ value
1232
+ end
1233
+
1234
+ def Preconditions.assert_class_or_nil(field_name, value, klass)
1235
+ if !value.nil?
1236
+ Preconditions.assert_class(field_name, value, klass)
1237
+ end
1238
+ end
1239
+
1240
+ def Preconditions.assert_boolean(field_name, value)
1241
+ Preconditions.check_not_nil('field_name', field_name)
1242
+ Preconditions.check_not_nil('value', value, "Value for %s cannot be nil. Expected an instance of TrueClass or FalseClass" % field_name)
1243
+ Preconditions.check_state(value.is_a?(TrueClass) || value.is_a?(FalseClass),
1244
+ "Value for #{field_name} is of type[#{value.class}] - class[TrueClass or FalseClass] is required. value[#{value.inspect.to_s}]")
1245
+ value
1246
+ end
1247
+
1248
+ def Preconditions.assert_boolean_or_nil(field_name, value)
1249
+ if !value.nil?
1250
+ Preconditions.assert_boolean(field_name, value)
1251
+ end
1252
+ end
1253
+
1254
+ def Preconditions.assert_collection_of_class(field_name, values, klass)
1255
+ Preconditions.assert_class(field_name, values, Array)
1256
+ values.each { |v| Preconditions.assert_class(field_name, v, klass) }
1257
+ end
1258
+
1259
+ def Preconditions.assert_hash_of_class(field_name, hash, klass)
1260
+ Preconditions.assert_class(field_name, hash, Hash)
1261
+ values.each { |k, v| Preconditions.assert_class(field_name, v, klass) }
1262
+ end
1263
+
1264
+ end
1265
+
1266
+ class AuthScheme
1267
+
1268
+ attr_reader :name
1269
+
1270
+ def initialize(name)
1271
+ @name = HttpClient::Preconditions.check_not_blank('name', name)
1272
+ end
1273
+
1274
+ BASIC = AuthScheme.new("basic") unless defined?(BASIC)
1275
+
1276
+ end
1277
+
1278
+ class Authorization
1279
+
1280
+ attr_reader :scheme, :username, :password
1281
+
1282
+ def initialize(scheme, username, opts={})
1283
+ @scheme = HttpClient::Preconditions.assert_class('schema', scheme, AuthScheme)
1284
+ @username = HttpClient::Preconditions.check_not_blank('username', username, "username is required")
1285
+ @password = HttpClient::Preconditions.assert_class_or_nil('password', opts.delete(:password), String)
1286
+ HttpClient::Preconditions.assert_empty_opts(opts)
1287
+ end
1288
+
1289
+ def Authorization.basic(username, password=nil)
1290
+ Authorization.new(AuthScheme::BASIC, username, :password => password)
1291
+ end
1292
+
1293
+ end
1294
+
1295
+ module Helper
1296
+
1297
+ def Helper.symbolize_keys(hash)
1298
+ Preconditions.assert_class('hash', hash, Hash)
1299
+ new_hash = {}
1300
+ hash.each { |k, v|
1301
+ new_hash[k.to_sym] = v
1302
+ }
1303
+ new_hash
1304
+ end
1305
+
1306
+ def Helper.to_big_decimal(value)
1307
+ value ? BigDecimal.new(value.to_s) : nil
1308
+ end
1309
+
1310
+ def Helper.to_object(value)
1311
+ value ? (value.is_a?(Hash) ? value : JSON.parse(value)) : nil
1312
+ end
1313
+
1314
+ def Helper.to_uuid(value)
1315
+ Preconditions.check_state(value.nil? || value.match(/^\w\w\w\w\w\w\w\w\-\w\w\w\w\-\w\w\w\w\-\w\w\w\w\-\w\w\w\w\w\w\w\w\w\w\w\w$/),
1316
+ "Invalid guid[%s]" % value)
1317
+ value
1318
+ end
1319
+
1320
+ def Helper.to_date_iso8601(value)
1321
+ if value.is_a?(Date)
1322
+ value
1323
+ elsif value
1324
+ Date.parse(value.to_s)
1325
+ else
1326
+ nil
1327
+ end
1328
+ end
1329
+
1330
+ def Helper.to_date_time_iso8601(value)
1331
+ if value.is_a?(DateTime)
1332
+ value
1333
+ elsif value
1334
+ DateTime.parse(value.to_s)
1335
+ else
1336
+ nil
1337
+ end
1338
+ end
1339
+
1340
+ def Helper.date_iso8601_to_string(value)
1341
+ value.nil? ? nil : value.strftime('%Y-%m-%d')
1342
+ end
1343
+
1344
+ def Helper.date_time_iso8601_to_string(value)
1345
+ value.nil? ? nil : value.strftime('%Y-%m-%dT%H:%M:%S%z')
1346
+ end
1347
+
1348
+ TRUE_STRINGS = ['t', 'true', 'y', 'yes', 'on', '1', 'trueclass'] unless defined?(TRUE_STRINGS)
1349
+ FALSE_STRINGS = ['f', 'false', 'n', 'no', 'off', '0', 'falseclass'] unless defined?(FALSE_STRINGS)
1350
+
1351
+ def Helper.to_boolean(field_name, value)
1352
+ string = value.to_s.strip.downcase
1353
+ if TRUE_STRINGS.include?(string)
1354
+ true
1355
+ elsif FALSE_STRINGS.include?(string)
1356
+ false
1357
+ elsif string != ""
1358
+ raise PreconditionException.new("Unsupported boolean value[#{string}]. For true, must be one of: #{TRUE_STRINGS.inspect}. For false, must be one of: #{FALSE_STRINGS.inspect}")
1359
+ else
1360
+ nil
1361
+ end
1362
+ end
1363
+
1364
+ end
1365
+
1366
+ end
1367
+ end
1368
+ end
1369
+ end
1370
+ end