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.
@@ -0,0 +1,166 @@
1
+ # Generated by Flow.io (2017) code builder
2
+
3
+ module Flow
4
+ module Reference
5
+ class PaymentMethods
6
+ SUPPORTED_CREDIT_CARDS = [:ach, :alipay, :american_express, :bankTransfer_IBAN, :bitcoin, :bitpay, :cartes_bancaires, :china_union_pay, :dankort, :diners_club, :directEbanking, :discover, :dotpay, :dragonpay_ebanking, :dragonpay_gcash, :dragonpay_otc_banking, :ebanking_FI, :giropay, :ideal, :interac, :jcb, :kcp_banktransfer, :kcp_creditcard, :kcp_payco, :klarna, :maestro, :mastercard, :molpay_points, :multibanco, :paypal, :qiwiwallet, :sepadirectdebit, :trustly, :trustpay, :unionpay, :visa, :wechatpay]
7
+
8
+ class Data
9
+ class << self
10
+ def new_pm(hash)
11
+ ::Io::Flow::Reference::V0::Models::PaymentMethod.new(hash)
12
+ end
13
+
14
+ def Ach
15
+ new_pm({"id":"ach","type":"online","name":"ACH","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/ach/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/ach/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/ach/120/original.png","width":256,"height":256}},"regions":["world"]})
16
+ end
17
+
18
+ def Alipay
19
+ new_pm({"id":"alipay","type":"online","name":"Alipay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/alipay/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/alipay/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/alipay/120/original.png","width":256,"height":256}},"regions":["world"]})
20
+ end
21
+
22
+ def AmericanExpress
23
+ new_pm({"id":"american_express","type":"card","name":"American Express","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/american_express/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/american_express/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/american_express/120/original.png","width":256,"height":256}},"regions":["world"]})
24
+ end
25
+
26
+ def BanktransferIban
27
+ new_pm({"id":"bankTransfer_IBAN","type":"online","name":"International Bank Transfer (IBAN)","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/bankTransfer_IBAN/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/bankTransfer_IBAN/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/bankTransfer_IBAN/120/original.png","width":256,"height":256}},"regions":["world"]})
28
+ end
29
+
30
+ def Bitcoin
31
+ new_pm({"id":"bitcoin","type":"online","name":"Bitcoin","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/bitcoin/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/bitcoin/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/bitcoin/120/original.png","width":256,"height":256}},"regions":["world"]})
32
+ end
33
+
34
+ def Bitpay
35
+ new_pm({"id":"bitpay","type":"online","name":"BitPay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/bitpay/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/bitpay/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/bitpay/120/original.png","width":256,"height":256}},"regions":["world"]})
36
+ end
37
+
38
+ def CartesBancaires
39
+ new_pm({"id":"cartes_bancaires","type":"card","name":"Cartes Bancaires","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/cartes_bancaires/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/cartes_bancaires/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/cartes_bancaires/120/original.png","width":256,"height":256}},"regions":["fra"]})
40
+ end
41
+
42
+ def ChinaUnionPay
43
+ new_pm({"id":"china_union_pay","type":"card","name":"China Union Pay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/china_union_pay/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/china_union_pay/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/china_union_pay/120/original.png","width":256,"height":256}},"regions":["chn"]})
44
+ end
45
+
46
+ def Dankort
47
+ new_pm({"id":"dankort","type":"card","name":"Dankort","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/dankort/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/dankort/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/dankort/120/original.png","width":256,"height":256}},"regions":["europe"]})
48
+ end
49
+
50
+ def DinersClub
51
+ new_pm({"id":"diners_club","type":"card","name":"Diners Club","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/diners_club/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/diners_club/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/diners_club/120/original.png","width":256,"height":256}},"regions":["europe","north-america"]})
52
+ end
53
+
54
+ def Directebanking
55
+ new_pm({"id":"directEbanking","type":"online","name":"Sofortüberweisung","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/directEbanking/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/directEbanking/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/directEbanking/120/original.png","width":256,"height":256}},"regions":["world"]})
56
+ end
57
+
58
+ def Discover
59
+ new_pm({"id":"discover","type":"card","name":"Discover","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/discover/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/discover/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/discover/120/original.png","width":256,"height":256}},"regions":["europe","north-america"]})
60
+ end
61
+
62
+ def Dotpay
63
+ new_pm({"id":"dotpay","type":"online","name":"Dotpay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/dotpay/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/dotpay/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/dotpay/120/original.png","width":256,"height":256}},"regions":["world"]})
64
+ end
65
+
66
+ def DragonpayEbanking
67
+ new_pm({"id":"dragonpay_ebanking","type":"online","name":"Dragonpay eBanking","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/dragonpay_ebanking/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/dragonpay_ebanking/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/dragonpay_ebanking/120/original.png","width":256,"height":256}},"regions":["world"]})
68
+ end
69
+
70
+ def DragonpayGcash
71
+ new_pm({"id":"dragonpay_gcash","type":"online","name":"GCash via Dragonpay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/dragonpay_gcash/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/dragonpay_gcash/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/dragonpay_gcash/120/original.png","width":256,"height":256}},"regions":["world"]})
72
+ end
73
+
74
+ def DragonpayOtcBanking
75
+ new_pm({"id":"dragonpay_otc_banking","type":"online","name":"Dragonpay OTC","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/dragonpay_otc_banking/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/dragonpay_otc_banking/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/dragonpay_otc_banking/120/original.png","width":256,"height":256}},"regions":["world"]})
76
+ end
77
+
78
+ def EbankingFi
79
+ new_pm({"id":"ebanking_FI","type":"online","name":"Finnish E-Banking","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/ebanking_FI/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/ebanking_FI/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/ebanking_FI/120/original.png","width":256,"height":256}},"regions":["world"]})
80
+ end
81
+
82
+ def Giropay
83
+ new_pm({"id":"giropay","type":"online","name":"GiroPay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/giropay/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/giropay/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/giropay/120/original.png","width":256,"height":256}},"regions":["world"]})
84
+ end
85
+
86
+ def Ideal
87
+ new_pm({"id":"ideal","type":"online","name":"iDEAL","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/ideal/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/ideal/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/ideal/120/original.png","width":256,"height":256}},"regions":["world"]})
88
+ end
89
+
90
+ def Interac
91
+ new_pm({"id":"interac","type":"online","name":"Interac Online","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/interac/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/interac/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/interac/120/original.png","width":256,"height":256}},"regions":["world"]})
92
+ end
93
+
94
+ def Jcb
95
+ new_pm({"id":"jcb","type":"card","name":"Jcb","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/jcb/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/jcb/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/jcb/120/original.png","width":256,"height":256}},"regions":["jpn"]})
96
+ end
97
+
98
+ def KcpBanktransfer
99
+ new_pm({"id":"kcp_banktransfer","type":"online","name":"Bank Transfer via KCP","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/kcp_banktransfer/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/kcp_banktransfer/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/kcp_banktransfer/120/original.png","width":256,"height":256}},"regions":["world"]})
100
+ end
101
+
102
+ def KcpCreditcard
103
+ new_pm({"id":"kcp_creditcard","type":"online","name":"Credit Card via KCP","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/kcp_creditcard/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/kcp_creditcard/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/kcp_creditcard/120/original.png","width":256,"height":256}},"regions":["world"]})
104
+ end
105
+
106
+ def KcpPayco
107
+ new_pm({"id":"kcp_payco","type":"online","name":"PayCo","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/kcp_payco/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/kcp_payco/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/kcp_payco/120/original.png","width":256,"height":256}},"regions":["world"]})
108
+ end
109
+
110
+ def Klarna
111
+ new_pm({"id":"klarna","type":"online","name":"Klarna","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/klarna/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/klarna/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/klarna/120/original.png","width":256,"height":256}},"regions":["world"]})
112
+ end
113
+
114
+ def Maestro
115
+ new_pm({"id":"maestro","type":"card","name":"Maestro","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/maestro/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/maestro/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/maestro/120/original.png","width":256,"height":256}},"regions":["europe","north-america"]})
116
+ end
117
+
118
+ def Mastercard
119
+ new_pm({"id":"mastercard","type":"card","name":"Mastercard","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/mastercard/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/mastercard/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/mastercard/120/original.png","width":256,"height":256}},"regions":["world"]})
120
+ end
121
+
122
+ def MolpayPoints
123
+ new_pm({"id":"molpay_points","type":"online","name":"MOLPoints via MOLPay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/molpay_points/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/molpay_points/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/molpay_points/120/original.png","width":256,"height":256}},"regions":["world"]})
124
+ end
125
+
126
+ def Multibanco
127
+ new_pm({"id":"multibanco","type":"online","name":"Multibanco","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/multibanco/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/multibanco/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/multibanco/120/original.png","width":256,"height":256}},"regions":["world"]})
128
+ end
129
+
130
+ def Paypal
131
+ new_pm({"id":"paypal","type":"online","name":"PayPal","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/paypal/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/paypal/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/paypal/120/original.png","width":180,"height":60}},"regions":["world"]})
132
+ end
133
+
134
+ def Qiwiwallet
135
+ new_pm({"id":"qiwiwallet","type":"online","name":"Qiwi Wallet","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/qiwiwallet/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/qiwiwallet/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/qiwiwallet/120/original.png","width":256,"height":256}},"regions":["world"]})
136
+ end
137
+
138
+ def Sepadirectdebit
139
+ new_pm({"id":"sepadirectdebit","type":"online","name":"SEPA Direct Debit","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/sepadirectdebit/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/sepadirectdebit/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/sepadirectdebit/120/original.png","width":256,"height":256}},"regions":["world"]})
140
+ end
141
+
142
+ def Trustly
143
+ new_pm({"id":"trustly","type":"online","name":"Trustly","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/trustly/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/trustly/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/trustly/120/original.png","width":256,"height":256}},"regions":["world"]})
144
+ end
145
+
146
+ def Trustpay
147
+ new_pm({"id":"trustpay","type":"online","name":"TrustPay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/trustpay/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/trustpay/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/trustpay/120/original.png","width":256,"height":256}},"regions":["world"]})
148
+ end
149
+
150
+ def Unionpay
151
+ new_pm({"id":"unionpay","type":"online","name":"UnionPay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/unionpay/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/unionpay/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/unionpay/120/original.png","width":256,"height":256}},"regions":["world"]})
152
+ end
153
+
154
+ def Visa
155
+ new_pm({"id":"visa","type":"card","name":"VISA","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/visa/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/visa/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/visa/120/original.png","width":256,"height":256}},"regions":["world"]})
156
+ end
157
+
158
+ def Wechatpay
159
+ new_pm({"id":"wechatpay","type":"online","name":"WeChat Pay","images":{"small":{"url":"https://flowcdn.io/util/logos/payment-methods/wechatpay/30/original.png","width":65,"height":41},"medium":{"url":"https://flowcdn.io/util/logos/payment-methods/wechatpay/60/original.png","width":100,"height":60},"large":{"url":"https://flowcdn.io/util/logos/payment-methods/wechatpay/120/original.png","width":256,"height":256}},"regions":["world"]})
160
+ end
161
+
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,1104 @@
1
+ # Generated by apidoc - http://www.apidoc.me
2
+ # Service version: 0.2.83
3
+ # apidoc:0.11.76 http://www.apidoc.me/flow/reference/0.2.83/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 = 'apidoc:0.11.76 http://www.apidoc.me/flow/reference/0.2.83/ruby_client' unless defined?(Constants::USER_AGENT)
30
+ VERSION = '0.2.87' 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 regions
85
+ @regions ||= ::Io::Flow::Reference::V0::Clients::Regions.new(self)
86
+ end
87
+
88
+ def timezones
89
+ @timezones ||= ::Io::Flow::Reference::V0::Clients::Timezones.new(self)
90
+ end
91
+ end
92
+
93
+ module Clients
94
+
95
+ class Countries
96
+
97
+ def initialize(client)
98
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
99
+ end
100
+
101
+ # Returns a list of countries.
102
+ def get(incoming={})
103
+ opts = HttpClient::Helper.symbolize_keys(incoming)
104
+ query = {
105
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
106
+ }.delete_if { |k, v| v.nil? }
107
+ r = @client.request("/reference/countries").with_query(query).get
108
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Country.new(x) }
109
+ end
110
+
111
+ end
112
+
113
+ class Currencies
114
+
115
+ def initialize(client)
116
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
117
+ end
118
+
119
+ # Returns a list of currencies.
120
+ def get(incoming={})
121
+ opts = HttpClient::Helper.symbolize_keys(incoming)
122
+ query = {
123
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
124
+ }.delete_if { |k, v| v.nil? }
125
+ r = @client.request("/reference/currencies").with_query(query).get
126
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Currency.new(x) }
127
+ end
128
+
129
+ end
130
+
131
+ class Languages
132
+
133
+ def initialize(client)
134
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
135
+ end
136
+
137
+ # Returns a list of languages.
138
+ def get(incoming={})
139
+ opts = HttpClient::Helper.symbolize_keys(incoming)
140
+ query = {
141
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
142
+ }.delete_if { |k, v| v.nil? }
143
+ r = @client.request("/reference/languages").with_query(query).get
144
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Language.new(x) }
145
+ end
146
+
147
+ end
148
+
149
+ class Locales
150
+
151
+ def initialize(client)
152
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
153
+ end
154
+
155
+ # Returns a list of locales.
156
+ def get(incoming={})
157
+ opts = HttpClient::Helper.symbolize_keys(incoming)
158
+ query = {
159
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
160
+ }.delete_if { |k, v| v.nil? }
161
+ r = @client.request("/reference/locales").with_query(query).get
162
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Locale.new(x) }
163
+ end
164
+
165
+ # Returns the locale with the specifed id.
166
+ def get_by_id(id)
167
+ HttpClient::Preconditions.assert_class('id', id, String)
168
+ r = @client.request("/reference/locales/#{CGI.escape(id)}").get
169
+ ::Io::Flow::Reference::V0::Models::Locale.new(r)
170
+ end
171
+
172
+ end
173
+
174
+ class Regions
175
+
176
+ def initialize(client)
177
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
178
+ end
179
+
180
+ # Returns a list of regions.
181
+ def get(incoming={})
182
+ opts = HttpClient::Helper.symbolize_keys(incoming)
183
+ query = {
184
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
185
+ }.delete_if { |k, v| v.nil? }
186
+ r = @client.request("/reference/regions").with_query(query).get
187
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Region.new(x) }
188
+ end
189
+
190
+ # Returns the region with the specifed id.
191
+ def get_by_id(id)
192
+ HttpClient::Preconditions.assert_class('id', id, String)
193
+ r = @client.request("/reference/regions/#{CGI.escape(id)}").get
194
+ ::Io::Flow::Reference::V0::Models::Region.new(r)
195
+ end
196
+
197
+ end
198
+
199
+ class Timezones
200
+
201
+ def initialize(client)
202
+ @client = HttpClient::Preconditions.assert_class('client', client, ::Io::Flow::Reference::V0::Client)
203
+ end
204
+
205
+ # Returns a list of timezones.
206
+ def get(incoming={})
207
+ opts = HttpClient::Helper.symbolize_keys(incoming)
208
+ query = {
209
+ :q => (x = opts.delete(:q); x.nil? ? nil : HttpClient::Preconditions.assert_class('q', x, String))
210
+ }.delete_if { |k, v| v.nil? }
211
+ r = @client.request("/reference/timezones").with_query(query).get
212
+ r.map { |x| ::Io::Flow::Reference::V0::Models::Timezone.new(x) }
213
+ end
214
+
215
+ end
216
+
217
+ end
218
+
219
+ module Models
220
+
221
+ class PaymentMethodType
222
+
223
+ attr_reader :value
224
+
225
+ def initialize(value)
226
+ @value = HttpClient::Preconditions.assert_class('value', value, String)
227
+ end
228
+
229
+ # Returns the instance of PaymentMethodType for this value, creating a new instance for an unknown value
230
+ def PaymentMethodType.apply(value)
231
+ if value.instance_of?(PaymentMethodType)
232
+ value
233
+ else
234
+ HttpClient::Preconditions.assert_class_or_nil('value', value, String)
235
+ value.nil? ? nil : (from_string(value) || PaymentMethodType.new(value))
236
+ end
237
+ end
238
+
239
+ # Returns the instance of PaymentMethodType for this value, or nil if not found
240
+ def PaymentMethodType.from_string(value)
241
+ HttpClient::Preconditions.assert_class('value', value, String)
242
+ PaymentMethodType.ALL.find { |v| v.value == value }
243
+ end
244
+
245
+ def PaymentMethodType.ALL
246
+ @@all ||= [PaymentMethodType.card, PaymentMethodType.online, PaymentMethodType.offline]
247
+ end
248
+
249
+ # Represents all form of card payment (e.g. credit, debit, etc.)
250
+ def PaymentMethodType.card
251
+ @@_card ||= PaymentMethodType.new('card')
252
+ end
253
+
254
+ # Represents the most common form of alternative payment methods which require
255
+ # some degree of integration online (e.g. a redirect) to complete payment.
256
+ def PaymentMethodType.online
257
+ @@_online ||= PaymentMethodType.new('online')
258
+ end
259
+
260
+ # Offline payment method types represent payments like Cash On Delivery which
261
+ # require offline collection
262
+ def PaymentMethodType.offline
263
+ @@_offline ||= PaymentMethodType.new('offline')
264
+ end
265
+
266
+ def to_hash
267
+ value
268
+ end
269
+
270
+ end
271
+
272
+ # ISO 3166 country codes. Note Flow APIs will accept either the 2 or 3 character
273
+ # country code, but internally we normalize data and store as the 3 character,
274
+ # upper case ISO code. See https://api.flow.io/reference/countries
275
+ class Country
276
+
277
+ attr_reader :name, :iso_3166_2, :iso_3166_3, :languages, :measurement_system, :default_currency, :timezones, :default_delivered_duty
278
+
279
+ def initialize(incoming={})
280
+ opts = HttpClient::Helper.symbolize_keys(incoming)
281
+ HttpClient::Preconditions.require_keys(opts, [:name, :iso_3166_2, :iso_3166_3, :languages, :measurement_system, :timezones], 'Country')
282
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
283
+ @iso_3166_2 = HttpClient::Preconditions.assert_class('iso_3166_2', opts.delete(:iso_3166_2), String)
284
+ @iso_3166_3 = HttpClient::Preconditions.assert_class('iso_3166_3', opts.delete(:iso_3166_3), String)
285
+ @languages = HttpClient::Preconditions.assert_class('languages', opts.delete(:languages), Array).map { |v| HttpClient::Preconditions.assert_class('languages', v, String) }
286
+ @measurement_system = HttpClient::Preconditions.assert_class('measurement_system', opts.delete(:measurement_system), String)
287
+ @default_currency = (x = opts.delete(:default_currency); x.nil? ? nil : HttpClient::Preconditions.assert_class('default_currency', x, String))
288
+ @timezones = HttpClient::Preconditions.assert_class('timezones', opts.delete(:timezones), Array).map { |v| HttpClient::Preconditions.assert_class('timezones', v, String) }
289
+ @default_delivered_duty = (x = opts.delete(:default_delivered_duty); x.nil? ? nil : HttpClient::Preconditions.assert_class('default_delivered_duty', x, String))
290
+ end
291
+
292
+ def to_json
293
+ JSON.dump(to_hash)
294
+ end
295
+
296
+ def copy(incoming={})
297
+ Country.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
298
+ end
299
+
300
+ def to_hash
301
+ {
302
+ :name => name,
303
+ :iso_3166_2 => iso_3166_2,
304
+ :iso_3166_3 => iso_3166_3,
305
+ :languages => languages,
306
+ :measurement_system => measurement_system,
307
+ :default_currency => default_currency,
308
+ :timezones => timezones,
309
+ :default_delivered_duty => default_delivered_duty
310
+ }
311
+ end
312
+
313
+ end
314
+
315
+ # ISO 4217 3-character currency code. See
316
+ # https://api.flow.io/reference/currencies
317
+ class Currency
318
+
319
+ attr_reader :name, :iso_4217_3, :number_decimals, :symbols, :default_locale
320
+
321
+ def initialize(incoming={})
322
+ opts = HttpClient::Helper.symbolize_keys(incoming)
323
+ HttpClient::Preconditions.require_keys(opts, [:name, :iso_4217_3, :number_decimals], 'Currency')
324
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
325
+ @iso_4217_3 = HttpClient::Preconditions.assert_class('iso_4217_3', opts.delete(:iso_4217_3), String)
326
+ @number_decimals = HttpClient::Preconditions.assert_class('number_decimals', opts.delete(:number_decimals), Integer)
327
+ @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)))
328
+ @default_locale = (x = opts.delete(:default_locale); x.nil? ? nil : HttpClient::Preconditions.assert_class('default_locale', x, String))
329
+ end
330
+
331
+ def to_json
332
+ JSON.dump(to_hash)
333
+ end
334
+
335
+ def copy(incoming={})
336
+ Currency.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
337
+ end
338
+
339
+ def to_hash
340
+ {
341
+ :name => name,
342
+ :iso_4217_3 => iso_4217_3,
343
+ :number_decimals => number_decimals,
344
+ :symbols => symbols.nil? ? nil : symbols.to_hash,
345
+ :default_locale => default_locale
346
+ }
347
+ end
348
+
349
+ end
350
+
351
+ # Defines one or more symbols representing this currency
352
+ class CurrencySymbols
353
+
354
+ attr_reader :primary, :narrow
355
+
356
+ def initialize(incoming={})
357
+ opts = HttpClient::Helper.symbolize_keys(incoming)
358
+ HttpClient::Preconditions.require_keys(opts, [:primary], 'CurrencySymbols')
359
+ @primary = HttpClient::Preconditions.assert_class('primary', opts.delete(:primary), String)
360
+ @narrow = (x = opts.delete(:narrow); x.nil? ? nil : HttpClient::Preconditions.assert_class('narrow', x, String))
361
+ end
362
+
363
+ def to_json
364
+ JSON.dump(to_hash)
365
+ end
366
+
367
+ def copy(incoming={})
368
+ CurrencySymbols.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
369
+ end
370
+
371
+ def to_hash
372
+ {
373
+ :primary => primary,
374
+ :narrow => narrow
375
+ }
376
+ end
377
+
378
+ end
379
+
380
+ # ISO 639 2-character language code. See https://api.flow.io/reference/languages
381
+ class Language
382
+
383
+ attr_reader :name, :iso_639_2
384
+
385
+ def initialize(incoming={})
386
+ opts = HttpClient::Helper.symbolize_keys(incoming)
387
+ HttpClient::Preconditions.require_keys(opts, [:name, :iso_639_2], 'Language')
388
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
389
+ @iso_639_2 = HttpClient::Preconditions.assert_class('iso_639_2', opts.delete(:iso_639_2), String)
390
+ end
391
+
392
+ def to_json
393
+ JSON.dump(to_hash)
394
+ end
395
+
396
+ def copy(incoming={})
397
+ Language.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
398
+ end
399
+
400
+ def to_hash
401
+ {
402
+ :name => name,
403
+ :iso_639_2 => iso_639_2
404
+ }
405
+ end
406
+
407
+ end
408
+
409
+ # Locales defines standard conventions for presentation of content. See
410
+ # https://api.flow.io/reference/locales
411
+ class Locale
412
+
413
+ attr_reader :id, :name, :country, :language, :numbers
414
+
415
+ def initialize(incoming={})
416
+ opts = HttpClient::Helper.symbolize_keys(incoming)
417
+ HttpClient::Preconditions.require_keys(opts, [:id, :name, :country, :language, :numbers], 'Locale')
418
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
419
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
420
+ @country = HttpClient::Preconditions.assert_class('country', opts.delete(:country), String)
421
+ @language = HttpClient::Preconditions.assert_class('language', opts.delete(:language), String)
422
+ @numbers = (x = opts.delete(:numbers); x.is_a?(::Io::Flow::Reference::V0::Models::LocaleNumbers) ? x : ::Io::Flow::Reference::V0::Models::LocaleNumbers.new(x))
423
+ end
424
+
425
+ def to_json
426
+ JSON.dump(to_hash)
427
+ end
428
+
429
+ def copy(incoming={})
430
+ Locale.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
431
+ end
432
+
433
+ def to_hash
434
+ {
435
+ :id => id,
436
+ :name => name,
437
+ :country => country,
438
+ :language => language,
439
+ :numbers => numbers.to_hash
440
+ }
441
+ end
442
+
443
+ end
444
+
445
+ # Number formats defined for a given locale
446
+ class LocaleNumbers
447
+
448
+ attr_reader :decimal, :group
449
+
450
+ def initialize(incoming={})
451
+ opts = HttpClient::Helper.symbolize_keys(incoming)
452
+ HttpClient::Preconditions.require_keys(opts, [:decimal, :group], 'LocaleNumbers')
453
+ @decimal = HttpClient::Preconditions.assert_class('decimal', opts.delete(:decimal), String)
454
+ @group = HttpClient::Preconditions.assert_class('group', opts.delete(:group), String)
455
+ end
456
+
457
+ def to_json
458
+ JSON.dump(to_hash)
459
+ end
460
+
461
+ def copy(incoming={})
462
+ LocaleNumbers.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
463
+ end
464
+
465
+ def to_hash
466
+ {
467
+ :decimal => decimal,
468
+ :group => group
469
+ }
470
+ end
471
+
472
+ end
473
+
474
+ # Represents a single payment method - e.g VISA or Paypal - and any associated
475
+ # metadata required for processing
476
+ class PaymentMethod
477
+
478
+ attr_reader :id, :type, :name, :images, :regions
479
+
480
+ def initialize(incoming={})
481
+ opts = HttpClient::Helper.symbolize_keys(incoming)
482
+ HttpClient::Preconditions.require_keys(opts, [:id, :type, :name, :images, :regions], 'PaymentMethod')
483
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
484
+ @type = (x = opts.delete(:type); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodType) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodType.apply(x))
485
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
486
+ @images = (x = opts.delete(:images); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImages) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImages.new(x))
487
+ @regions = HttpClient::Preconditions.assert_class('regions', opts.delete(:regions), Array).map { |v| HttpClient::Preconditions.assert_class('regions', v, String) }
488
+ end
489
+
490
+ def to_json
491
+ JSON.dump(to_hash)
492
+ end
493
+
494
+ def copy(incoming={})
495
+ PaymentMethod.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
496
+ end
497
+
498
+ def to_hash
499
+ {
500
+ :id => id,
501
+ :type => type.value,
502
+ :name => name,
503
+ :images => images.to_hash,
504
+ :regions => regions
505
+ }
506
+ end
507
+
508
+ end
509
+
510
+ class PaymentMethodImage
511
+
512
+ attr_reader :url, :width, :height
513
+
514
+ def initialize(incoming={})
515
+ opts = HttpClient::Helper.symbolize_keys(incoming)
516
+ HttpClient::Preconditions.require_keys(opts, [:url, :width, :height], 'PaymentMethodImage')
517
+ @url = HttpClient::Preconditions.assert_class('url', opts.delete(:url), String)
518
+ @width = HttpClient::Preconditions.assert_class('width', opts.delete(:width), Integer)
519
+ @height = HttpClient::Preconditions.assert_class('height', opts.delete(:height), Integer)
520
+ end
521
+
522
+ def to_json
523
+ JSON.dump(to_hash)
524
+ end
525
+
526
+ def copy(incoming={})
527
+ PaymentMethodImage.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
528
+ end
529
+
530
+ def to_hash
531
+ {
532
+ :url => url,
533
+ :width => width,
534
+ :height => height
535
+ }
536
+ end
537
+
538
+ end
539
+
540
+ class PaymentMethodImages
541
+
542
+ attr_reader :small, :medium, :large
543
+
544
+ def initialize(incoming={})
545
+ opts = HttpClient::Helper.symbolize_keys(incoming)
546
+ HttpClient::Preconditions.require_keys(opts, [:small, :medium, :large], 'PaymentMethodImages')
547
+ @small = (x = opts.delete(:small); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImage) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImage.new(x))
548
+ @medium = (x = opts.delete(:medium); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImage) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImage.new(x))
549
+ @large = (x = opts.delete(:large); x.is_a?(::Io::Flow::Reference::V0::Models::PaymentMethodImage) ? x : ::Io::Flow::Reference::V0::Models::PaymentMethodImage.new(x))
550
+ end
551
+
552
+ def to_json
553
+ JSON.dump(to_hash)
554
+ end
555
+
556
+ def copy(incoming={})
557
+ PaymentMethodImages.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
558
+ end
559
+
560
+ def to_hash
561
+ {
562
+ :small => small.to_hash,
563
+ :medium => medium.to_hash,
564
+ :large => large.to_hash
565
+ }
566
+ end
567
+
568
+ end
569
+
570
+ # A region represents a geographic area of the world. Regions can be countries,
571
+ # continents or other political areas (like the Eurozone). See
572
+ # https://api.flow.io/reference/regions
573
+ class Region
574
+
575
+ attr_reader :id, :name, :countries, :currencies, :languages, :measurement_systems, :timezones
576
+
577
+ def initialize(incoming={})
578
+ opts = HttpClient::Helper.symbolize_keys(incoming)
579
+ HttpClient::Preconditions.require_keys(opts, [:id, :name, :countries, :currencies, :languages, :measurement_systems, :timezones], 'Region')
580
+ @id = HttpClient::Preconditions.assert_class('id', opts.delete(:id), String)
581
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
582
+ @countries = HttpClient::Preconditions.assert_class('countries', opts.delete(:countries), Array).map { |v| HttpClient::Preconditions.assert_class('countries', v, String) }
583
+ @currencies = HttpClient::Preconditions.assert_class('currencies', opts.delete(:currencies), Array).map { |v| HttpClient::Preconditions.assert_class('currencies', v, String) }
584
+ @languages = HttpClient::Preconditions.assert_class('languages', opts.delete(:languages), Array).map { |v| HttpClient::Preconditions.assert_class('languages', v, String) }
585
+ @measurement_systems = HttpClient::Preconditions.assert_class('measurement_systems', opts.delete(:measurement_systems), Array).map { |v| HttpClient::Preconditions.assert_class('measurement_systems', v, String) }
586
+ @timezones = HttpClient::Preconditions.assert_class('timezones', opts.delete(:timezones), Array).map { |v| HttpClient::Preconditions.assert_class('timezones', v, String) }
587
+ end
588
+
589
+ def to_json
590
+ JSON.dump(to_hash)
591
+ end
592
+
593
+ def copy(incoming={})
594
+ Region.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
595
+ end
596
+
597
+ def to_hash
598
+ {
599
+ :id => id,
600
+ :name => name,
601
+ :countries => countries,
602
+ :currencies => currencies,
603
+ :languages => languages,
604
+ :measurement_systems => measurement_systems,
605
+ :timezones => timezones
606
+ }
607
+ end
608
+
609
+ end
610
+
611
+ # Time zone data is provided by the public IANA time zone database. See
612
+ # http://www.iana.org/time-zones
613
+ class Timezone
614
+
615
+ attr_reader :name, :description, :offset
616
+
617
+ def initialize(incoming={})
618
+ opts = HttpClient::Helper.symbolize_keys(incoming)
619
+ HttpClient::Preconditions.require_keys(opts, [:name, :description, :offset], 'Timezone')
620
+ @name = HttpClient::Preconditions.assert_class('name', opts.delete(:name), String)
621
+ @description = HttpClient::Preconditions.assert_class('description', opts.delete(:description), String)
622
+ @offset = HttpClient::Preconditions.assert_class('offset', opts.delete(:offset), Integer)
623
+ end
624
+
625
+ def to_json
626
+ JSON.dump(to_hash)
627
+ end
628
+
629
+ def copy(incoming={})
630
+ Timezone.new(to_hash.merge(HttpClient::Helper.symbolize_keys(incoming)))
631
+ end
632
+
633
+ def to_hash
634
+ {
635
+ :name => name,
636
+ :description => description,
637
+ :offset => offset
638
+ }
639
+ end
640
+
641
+ end
642
+
643
+ end
644
+
645
+ # ===== END OF SERVICE DEFINITION =====
646
+ module HttpClient
647
+
648
+ class HttpHandler
649
+
650
+ # Returns a client instance to use
651
+ #
652
+ # @param base_uri The base URI for this API
653
+ # @param path the Requested full http path (including any query strings)
654
+ def instance(base_uri, path)
655
+ raise "Override in subclass"
656
+ end
657
+
658
+ end
659
+
660
+ class HttpHandlerInstance
661
+
662
+ # Executes a request. The provided request object will be an
663
+ # instance of Net::HTTP (e.g. Net::HTTP::Get)
664
+ def execute(request)
665
+ raise "Override in subclass"
666
+ end
667
+
668
+ end
669
+
670
+ class DefaultHttpHandler < HttpHandler
671
+
672
+ def instance(base_uri, path)
673
+ DefaultHttpHandlerInstance.new(base_uri)
674
+ end
675
+
676
+ end
677
+
678
+ class DefaultHttpHandlerInstance < HttpHandlerInstance
679
+
680
+ attr_reader :client
681
+
682
+ def initialize(base_uri)
683
+ @base_uri = Preconditions.assert_class('base_uri', base_uri, URI)
684
+ @client = Net::HTTP.new(@base_uri.host, @base_uri.port)
685
+ if @base_uri.scheme == "https"
686
+ configure_ssl
687
+ end
688
+ end
689
+
690
+ def execute(request)
691
+ response = begin
692
+ @client.request(request)
693
+ rescue SocketError => e
694
+ raise Exception.new("Error accessing uri[#{full_uri(request.path)}]: #{e}")
695
+ end
696
+
697
+ case response
698
+ when Net::HTTPSuccess
699
+ response.body
700
+ else
701
+ body = response.body rescue nil
702
+ raise HttpClient::ServerError.new(response.code.to_i, response.message, :body => body, :uri => full_uri(request.path).to_s)
703
+ end
704
+ end
705
+
706
+ def full_uri(path)
707
+ File.join(@base_uri.to_s, path)
708
+ end
709
+
710
+ # Called to configure SSL if the base uri requires it
711
+ def configure_ssl
712
+ @client.use_ssl = true
713
+ @client.verify_mode = OpenSSL::SSL::VERIFY_PEER
714
+ @client.cert_store = OpenSSL::X509::Store.new
715
+ @client.cert_store.set_default_paths
716
+ end
717
+
718
+ end
719
+
720
+ class Request
721
+
722
+ attr_reader :path
723
+
724
+ def initialize(http_handler, base_uri, path)
725
+ @http_handler = http_handler
726
+ @base_uri = Preconditions.assert_class('base_uri', base_uri, URI)
727
+ @path = Preconditions.assert_class('path', path, String)
728
+ @params = nil
729
+ @body = nil
730
+ @auth = nil
731
+ @headers = {}
732
+ @header_keys_lower_case = []
733
+ end
734
+
735
+ def with_header(name, value)
736
+ Preconditions.check_not_blank('name', name, "Header name is required")
737
+ Preconditions.check_not_blank('value', value, "Header value is required")
738
+ Preconditions.check_state(!@headers.has_key?(name),
739
+ "Duplicate header named[%s]" % name)
740
+ @headers[name] = value
741
+ @header_keys_lower_case << name.downcase
742
+ self
743
+ end
744
+
745
+ def with_auth(auth)
746
+ Preconditions.assert_class('auth', auth, HttpClient::Authorization)
747
+ Preconditions.check_state(@auth.nil?, "auth previously set")
748
+
749
+ if auth.scheme.name == AuthScheme::BASIC.name
750
+ @auth = auth
751
+ else
752
+ raise "Auth Scheme[#{auth.scheme.name}] not supported"
753
+ end
754
+ self
755
+ end
756
+
757
+ def with_query(params)
758
+ Preconditions.assert_class('params', params, Hash)
759
+ Preconditions.check_state(@params.nil?, "Already have query parameters")
760
+ @params = params
761
+ self
762
+ end
763
+
764
+ # Wrapper to set Content-Type header to application/json and set
765
+ # the provided json document as the body
766
+ def with_json(json)
767
+ @headers['Content-Type'] ||= 'application/json; charset=UTF-8'
768
+ with_body(json)
769
+ end
770
+
771
+ def with_body(body)
772
+ Preconditions.check_not_blank('body', body)
773
+ @body = body
774
+ self
775
+ end
776
+
777
+ def get(&block)
778
+ do_request(Net::HTTP::Get, &block)
779
+ end
780
+
781
+ def delete(&block)
782
+ do_request(Net::HTTP::Delete, &block)
783
+ end
784
+
785
+ def options(&block)
786
+ do_request(Net::HTTP::Options, &block)
787
+ end
788
+
789
+ def post(&block)
790
+ do_request(Net::HTTP::Post, &block)
791
+ end
792
+
793
+ def put(&block)
794
+ do_request(Net::HTTP::Put, &block)
795
+ end
796
+
797
+ class PATCH < Net::HTTP::Put
798
+ METHOD = "PATCH"
799
+ end
800
+
801
+ def patch(&block)
802
+ do_request(PATCH, &block)
803
+ end
804
+
805
+ def do_request(klass)
806
+ Preconditions.assert_class('klass', klass, Class)
807
+
808
+ uri = path.dup
809
+ if q = to_query(@params)
810
+ uri += "?%s" % q
811
+ end
812
+
813
+ request = klass.send(:new, uri)
814
+
815
+ curl = ['curl']
816
+ if klass != Net::HTTP::Get
817
+ curl << "-X%s" % klass.name.split("::").last.upcase
818
+ end
819
+
820
+ if @body
821
+ # DEBUG path = "/tmp/rest_client.tmp"
822
+ # DEBUG File.open(path, "w") { |os| os << @body.to_s }
823
+ # DEBUG curl << "-d@%s" % path
824
+ request.body = @body
825
+ end
826
+
827
+ if @auth
828
+ curl << "-u \"%s:%s\"" % [@auth.username, @auth.password]
829
+ Preconditions.check_state(!@header_keys_lower_case.include?("authorization"),
830
+ "Cannot specify both an Authorization header and an auth instance")
831
+ user_pass = "%s:%s" % [@auth.username, @auth.password]
832
+ encoded = Base64.encode64(user_pass).to_s.split("\n").map(&:strip).join
833
+ request.add_field("Authorization", "Basic %s" % encoded)
834
+ end
835
+
836
+ @headers.each { |key, value|
837
+ curl << "-H \"%s: %s\"" % [key, value]
838
+ request.add_field(key, value)
839
+ }
840
+
841
+ curl << "'%s%s'" % [@base_uri, path]
842
+ # DEBUG puts curl.join(" ")
843
+
844
+ raw_response = @http_handler.instance(@base_uri, request.path).execute(request)
845
+ response = raw_response.to_s == "" ? nil : JSON.parse(raw_response)
846
+
847
+ if block_given?
848
+ yield response
849
+ else
850
+ response
851
+ end
852
+ end
853
+
854
+ private
855
+ def to_query(params={})
856
+ parts = (params || {}).map { |k,v|
857
+ if v.is_a?(Enumerable)
858
+ v.map { |el| "%s=%s" % [k, CGI.escape(el.to_s)] }
859
+ else
860
+ "%s=%s" % [k, CGI.escape(v.to_s)]
861
+ end
862
+ }
863
+ parts.empty? ? nil : parts.join("&")
864
+ end
865
+
866
+ end
867
+
868
+ class ServerError < StandardError
869
+
870
+ attr_reader :code, :details, :body, :uri
871
+
872
+ def initialize(code, details, incoming={})
873
+ opts = HttpClient::Helper.symbolize_keys(incoming)
874
+ @code = HttpClient::Preconditions.assert_class('code', code, Integer)
875
+ @details = HttpClient::Preconditions.assert_class('details', details, String)
876
+ @body = HttpClient::Preconditions.assert_class_or_nil('body', opts.delete(:body), String)
877
+ @uri = HttpClient::Preconditions.assert_class_or_nil('uri', opts.delete(:uri), String)
878
+ HttpClient::Preconditions.assert_empty_opts(opts)
879
+ super(self.message)
880
+ end
881
+
882
+ def message
883
+ m = "%s %s" % [@code, @details]
884
+ if @body
885
+ m << ": %s" % @body
886
+ end
887
+ m
888
+ end
889
+
890
+ def body_json
891
+ @body ? JSON.parse(@body) : nil
892
+ end
893
+
894
+ end
895
+
896
+ class PreconditionException < Exception
897
+
898
+ attr_reader :message
899
+
900
+ def initialize(message)
901
+ super(message)
902
+ @message = message
903
+ end
904
+
905
+ end
906
+
907
+ module Preconditions
908
+
909
+ def Preconditions.check_argument(expression, error_message=nil)
910
+ if !expression
911
+ raise PreconditionException.new(error_message || "check_argument failed")
912
+ end
913
+ nil
914
+ end
915
+
916
+ def Preconditions.check_state(expression, error_message=nil)
917
+ if !expression
918
+ raise PreconditionException.new(error_message || "check_state failed")
919
+ end
920
+ nil
921
+ end
922
+
923
+ def Preconditions.check_not_nil(field_name, reference, error_message=nil)
924
+ if reference.nil?
925
+ raise PreconditionException.new(error_message || "argument for %s cannot be nil" % field_name)
926
+ end
927
+ reference
928
+ end
929
+
930
+ def Preconditions.check_not_blank(field_name, reference, error_message=nil)
931
+ if reference.to_s.strip == ""
932
+ raise PreconditionException.new(error_message || "argument for %s cannot be blank" % field_name)
933
+ end
934
+ reference
935
+ end
936
+
937
+ # Throws an error if opts is not empty. Useful when parsing
938
+ # arguments to a function
939
+ def Preconditions.assert_empty_opts(opts)
940
+ if !opts.empty?
941
+ raise PreconditionException.new("Invalid opts: #{opts.keys.inspect}\n#{opts.inspect}")
942
+ end
943
+ end
944
+
945
+ # Requires that the provided hash has the specified keys.
946
+ # @param fields A list of symbols
947
+ def Preconditions.require_keys(hash, fields, error_prefix=nil)
948
+ missing = fields.select { |f| !hash.has_key?(f) }
949
+ if !missing.empty?
950
+ msg = "Missing required fields: " + missing.join(", ")
951
+ raise PreconditionException.new(error_prefix.empty? ? msg : "#{error_prefix}: #{msg}")
952
+ end
953
+ end
954
+
955
+ # Asserts that value is not nill and is_?(klass). Returns
956
+ # value. Common use is
957
+ #
958
+ # amount = Preconditions.assert_class('amount', amount, BigDecimal)
959
+ def Preconditions.assert_class(field_name, value, klass)
960
+ Preconditions.check_not_nil('field_name', field_name)
961
+ Preconditions.check_not_nil('klass', klass)
962
+ Preconditions.check_not_nil('value', value, "Value for %s cannot be nil. Expected an instance of class %s" % [field_name, klass.name])
963
+ Preconditions.check_state(value.is_a?(klass),
964
+ "Value for #{field_name} is of type[#{value.class}] - class[#{klass}] is required. value[#{value.inspect.to_s}]")
965
+ value
966
+ end
967
+
968
+ def Preconditions.assert_class_or_nil(field_name, value, klass)
969
+ if !value.nil?
970
+ Preconditions.assert_class(field_name, value, klass)
971
+ end
972
+ end
973
+
974
+ def Preconditions.assert_boolean(field_name, value)
975
+ Preconditions.check_not_nil('field_name', field_name)
976
+ Preconditions.check_not_nil('value', value, "Value for %s cannot be nil. Expected an instance of TrueClass or FalseClass" % field_name)
977
+ Preconditions.check_state(value.is_a?(TrueClass) || value.is_a?(FalseClass),
978
+ "Value for #{field_name} is of type[#{value.class}] - class[TrueClass or FalseClass] is required. value[#{value.inspect.to_s}]")
979
+ value
980
+ end
981
+
982
+ def Preconditions.assert_boolean_or_nil(field_name, value)
983
+ if !value.nil?
984
+ Preconditions.assert_boolean(field_name, value)
985
+ end
986
+ end
987
+
988
+ def Preconditions.assert_collection_of_class(field_name, values, klass)
989
+ Preconditions.assert_class(field_name, values, Array)
990
+ values.each { |v| Preconditions.assert_class(field_name, v, klass) }
991
+ end
992
+
993
+ def Preconditions.assert_hash_of_class(field_name, hash, klass)
994
+ Preconditions.assert_class(field_name, hash, Hash)
995
+ values.each { |k, v| Preconditions.assert_class(field_name, v, klass) }
996
+ end
997
+
998
+ end
999
+
1000
+ class AuthScheme
1001
+
1002
+ attr_reader :name
1003
+
1004
+ def initialize(name)
1005
+ @name = HttpClient::Preconditions.check_not_blank('name', name)
1006
+ end
1007
+
1008
+ BASIC = AuthScheme.new("basic") unless defined?(BASIC)
1009
+
1010
+ end
1011
+
1012
+ class Authorization
1013
+
1014
+ attr_reader :scheme, :username, :password
1015
+
1016
+ def initialize(scheme, username, opts={})
1017
+ @scheme = HttpClient::Preconditions.assert_class('schema', scheme, AuthScheme)
1018
+ @username = HttpClient::Preconditions.check_not_blank('username', username, "username is required")
1019
+ @password = HttpClient::Preconditions.assert_class_or_nil('password', opts.delete(:password), String)
1020
+ HttpClient::Preconditions.assert_empty_opts(opts)
1021
+ end
1022
+
1023
+ def Authorization.basic(username, password=nil)
1024
+ Authorization.new(AuthScheme::BASIC, username, :password => password)
1025
+ end
1026
+
1027
+ end
1028
+
1029
+ module Helper
1030
+
1031
+ def Helper.symbolize_keys(hash)
1032
+ Preconditions.assert_class('hash', hash, Hash)
1033
+ new_hash = {}
1034
+ hash.each { |k, v|
1035
+ new_hash[k.to_sym] = v
1036
+ }
1037
+ new_hash
1038
+ end
1039
+
1040
+ def Helper.to_big_decimal(value)
1041
+ value ? BigDecimal.new(value.to_s) : nil
1042
+ end
1043
+
1044
+ def Helper.to_object(value)
1045
+ value ? (value.is_a?(Hash) ? value : JSON.parse(value)) : nil
1046
+ end
1047
+
1048
+ def Helper.to_uuid(value)
1049
+ 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$/),
1050
+ "Invalid guid[%s]" % value)
1051
+ value
1052
+ end
1053
+
1054
+ def Helper.to_date_iso8601(value)
1055
+ if value.is_a?(Date)
1056
+ value
1057
+ elsif value
1058
+ Date.parse(value.to_s)
1059
+ else
1060
+ nil
1061
+ end
1062
+ end
1063
+
1064
+ def Helper.to_date_time_iso8601(value)
1065
+ if value.is_a?(DateTime)
1066
+ value
1067
+ elsif value
1068
+ DateTime.parse(value.to_s)
1069
+ else
1070
+ nil
1071
+ end
1072
+ end
1073
+
1074
+ def Helper.date_iso8601_to_string(value)
1075
+ value.nil? ? nil : value.strftime('%Y-%m-%d')
1076
+ end
1077
+
1078
+ def Helper.date_time_iso8601_to_string(value)
1079
+ value.nil? ? nil : value.strftime('%Y-%m-%dT%H:%M:%S%z')
1080
+ end
1081
+
1082
+ TRUE_STRINGS = ['t', 'true', 'y', 'yes', 'on', '1', 'trueclass'] unless defined?(TRUE_STRINGS)
1083
+ FALSE_STRINGS = ['f', 'false', 'n', 'no', 'off', '0', 'falseclass'] unless defined?(FALSE_STRINGS)
1084
+
1085
+ def Helper.to_boolean(field_name, value)
1086
+ string = value.to_s.strip.downcase
1087
+ if TRUE_STRINGS.include?(string)
1088
+ true
1089
+ elsif FALSE_STRINGS.include?(string)
1090
+ false
1091
+ elsif string != ""
1092
+ 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}")
1093
+ else
1094
+ nil
1095
+ end
1096
+ end
1097
+
1098
+ end
1099
+
1100
+ end
1101
+ end
1102
+ end
1103
+ end
1104
+ end