moneykit 0.0.2 → 0.0.5

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.
Files changed (222) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/moneykit/api/access_token_api.rb +53 -55
  4. data/lib/moneykit/api/account_numbers_api.rb +26 -26
  5. data/lib/moneykit/api/accounts_api.rb +88 -82
  6. data/lib/moneykit/api/identity_api.rb +31 -30
  7. data/lib/moneykit/api/institutions_api.rb +50 -48
  8. data/lib/moneykit/api/link_session_api.rb +47 -50
  9. data/lib/moneykit/api/links_api.rb +137 -81
  10. data/lib/moneykit/api/products_api.rb +33 -35
  11. data/lib/moneykit/api/transactions_api.rb +126 -101
  12. data/lib/moneykit/api/users_api.rb +100 -83
  13. data/lib/moneykit/api/webhooks_api.rb +97 -0
  14. data/lib/moneykit/api_client.rb +100 -103
  15. data/lib/moneykit/api_error.rb +14 -16
  16. data/lib/moneykit/configuration.rb +52 -65
  17. data/lib/moneykit/models/account.rb +69 -112
  18. data/lib/moneykit/models/account_balances.rb +64 -78
  19. data/lib/moneykit/models/account_group.rb +58 -61
  20. data/lib/moneykit/models/account_identity.rb +79 -124
  21. data/lib/moneykit/models/account_numbers.rb +96 -71
  22. data/lib/moneykit/models/account_numbers_link_product.rb +57 -69
  23. data/lib/moneykit/models/account_numbers_product_settings.rb +59 -63
  24. data/lib/moneykit/models/account_type.rb +23 -23
  25. data/lib/moneykit/models/account_with_account_numbers.rb +76 -124
  26. data/lib/moneykit/models/accounts_link_product.rb +53 -61
  27. data/lib/moneykit/models/ach_number.rb +57 -65
  28. data/lib/moneykit/models/address.rb +70 -90
  29. data/lib/moneykit/models/api_error_auth_expired_access_token_response.rb +72 -78
  30. data/lib/moneykit/models/api_error_auth_unauthorized_response.rb +69 -78
  31. data/lib/moneykit/models/api_error_rate_limit_exceeded_response.rb +72 -78
  32. data/lib/moneykit/models/app.rb +46 -50
  33. data/lib/moneykit/models/bacs_number.rb +53 -61
  34. data/lib/moneykit/models/balances.rb +58 -64
  35. data/lib/moneykit/models/basic_account_details.rb +62 -77
  36. data/lib/moneykit/models/country.rb +13 -14
  37. data/lib/moneykit/models/create_link_session_request.rb +109 -119
  38. data/lib/moneykit/models/create_link_session_response.rb +48 -52
  39. data/lib/moneykit/models/currency.rb +193 -193
  40. data/lib/moneykit/models/cursor.rb +40 -39
  41. data/lib/moneykit/models/cursor_pagination.rb +49 -54
  42. data/lib/moneykit/models/cursors.rb +40 -39
  43. data/lib/moneykit/models/customer_app.rb +54 -64
  44. data/lib/moneykit/models/customer_user.rb +59 -69
  45. data/lib/moneykit/models/eft_number.rb +56 -67
  46. data/lib/moneykit/models/email.rb +56 -63
  47. data/lib/moneykit/models/email1.rb +50 -53
  48. data/lib/moneykit/models/exchange_token_request.rb +48 -52
  49. data/lib/moneykit/models/exchange_token_response.rb +54 -64
  50. data/lib/moneykit/models/generate_access_token_response.rb +59 -73
  51. data/lib/moneykit/models/get_account_numbers_response.rb +58 -66
  52. data/lib/moneykit/models/get_account_response.rb +55 -67
  53. data/lib/moneykit/models/get_accounts_response.rb +58 -67
  54. data/lib/moneykit/models/get_institutions_response.rb +58 -67
  55. data/lib/moneykit/models/get_transactions_response.rb +81 -105
  56. data/lib/moneykit/models/get_user_accounts_response.rb +50 -58
  57. data/lib/moneykit/models/get_user_links_response.rb +50 -58
  58. data/lib/moneykit/models/get_user_transactions_response.rb +75 -95
  59. data/lib/moneykit/models/http_validation_error.rb +77 -84
  60. data/lib/moneykit/models/identity.rb +49 -49
  61. data/lib/moneykit/models/identity_link_product.rb +57 -69
  62. data/lib/moneykit/models/identity_product_settings.rb +59 -63
  63. data/lib/moneykit/models/identity_response.rb +58 -67
  64. data/lib/moneykit/models/institution.rb +85 -113
  65. data/lib/moneykit/models/institution_error_not_found_response.rb +72 -80
  66. data/lib/moneykit/models/institution_styling_response.rb +77 -93
  67. data/lib/moneykit/models/international_number.rb +54 -64
  68. data/lib/moneykit/models/introspect_client_response.rb +70 -89
  69. data/lib/moneykit/models/jwk_set.rb +51 -55
  70. data/lib/moneykit/models/link.rb +78 -100
  71. data/lib/moneykit/models/link1.rb +78 -100
  72. data/lib/moneykit/models/link2.rb +78 -100
  73. data/lib/moneykit/models/link3.rb +78 -100
  74. data/lib/moneykit/models/link4.rb +78 -100
  75. data/lib/moneykit/models/link_common.rb +82 -117
  76. data/lib/moneykit/models/link_error.rb +19 -19
  77. data/lib/moneykit/models/link_error_bad_config_response.rb +269 -0
  78. data/lib/moneykit/models/link_error_bad_state_response.rb +71 -88
  79. data/lib/moneykit/models/link_error_deleted_response.rb +72 -80
  80. data/lib/moneykit/models/link_error_forbidden_action_response.rb +69 -78
  81. data/lib/moneykit/models/link_error_not_found_response.rb +72 -80
  82. data/lib/moneykit/models/link_error_unauthorized_access_response.rb +72 -80
  83. data/lib/moneykit/models/link_permission_scope.rb +14 -15
  84. data/lib/moneykit/models/link_permissions.rb +52 -62
  85. data/lib/moneykit/models/link_products.rb +62 -78
  86. data/lib/moneykit/models/link_response.rb +95 -136
  87. data/lib/moneykit/models/link_session_customer_user.rb +65 -83
  88. data/lib/moneykit/models/link_session_customer_user_email.rb +59 -68
  89. data/lib/moneykit/models/link_session_customer_user_phone.rb +67 -82
  90. data/lib/moneykit/models/link_session_error_forbidden_config_response.rb +69 -78
  91. data/lib/moneykit/models/link_session_error_invalid_token_exchange.rb +69 -78
  92. data/lib/moneykit/models/link_session_setting_overrides.rb +64 -99
  93. data/lib/moneykit/models/link_state.rb +15 -16
  94. data/lib/moneykit/models/link_state_changed_webhook.rb +121 -148
  95. data/lib/moneykit/models/location_inner.rb +41 -46
  96. data/lib/moneykit/models/money_kit_env.rb +12 -13
  97. data/lib/moneykit/models/money_link_features.rb +62 -66
  98. data/lib/moneykit/models/moneylink_features.rb +50 -49
  99. data/lib/moneykit/models/numbers.rb +60 -73
  100. data/lib/moneykit/models/owner.rb +76 -89
  101. data/lib/moneykit/models/phone.rb +60 -68
  102. data/lib/moneykit/models/phone_number.rb +63 -74
  103. data/lib/moneykit/models/phone_number_type.rb +14 -15
  104. data/lib/moneykit/models/product.rb +14 -15
  105. data/lib/moneykit/models/products.rb +52 -64
  106. data/lib/moneykit/models/products1.rb +48 -56
  107. data/lib/moneykit/models/products_settings.rb +58 -70
  108. data/lib/moneykit/models/provider.rb +18 -17
  109. data/lib/moneykit/models/public_link_error.rb +43 -0
  110. data/lib/moneykit/models/refresh_products_request.rb +52 -65
  111. data/lib/moneykit/models/requested_link_permission.rb +60 -75
  112. data/lib/moneykit/models/response401_disconnect_links_id_delete.rb +83 -283
  113. data/lib/moneykit/models/response401_exchange_token_link_session_exchange_token_post.rb +82 -281
  114. data/lib/moneykit/models/response401_get_account_links_id_accounts_account_id_get.rb +83 -283
  115. data/lib/moneykit/models/response401_get_account_numbers_links_id_accounts_numbers_get.rb +83 -283
  116. data/lib/moneykit/models/response401_get_accounts_links_id_accounts_get.rb +83 -283
  117. data/lib/moneykit/models/response401_get_identities_links_id_identity_get.rb +83 -283
  118. data/lib/moneykit/models/response401_get_institution_institutions_institution_id_get.rb +82 -281
  119. data/lib/moneykit/models/response401_get_institution_styling_institutions_institution_id_styling_get.rb +66 -72
  120. data/lib/moneykit/models/response401_get_institutions_institutions_get.rb +82 -281
  121. data/lib/moneykit/models/response401_get_link_links_id_get.rb +83 -283
  122. data/lib/moneykit/models/response401_get_transactions_diff_links_id_transactions_sync_get.rb +83 -283
  123. data/lib/moneykit/models/response401_get_transactions_links_id_transactions_get.rb +83 -283
  124. data/lib/moneykit/models/response401_get_user_accounts_users_id_accounts_get.rb +82 -281
  125. data/lib/moneykit/models/response401_get_user_links_users_id_links_get.rb +82 -281
  126. data/lib/moneykit/models/response401_get_user_transactions_users_id_transactions_get.rb +82 -281
  127. data/lib/moneykit/models/response401_get_well_known_jwks_well_known_jwks_json_get.rb +82 -281
  128. data/lib/moneykit/models/response401_instrospect_client_auth_introspect_get.rb +82 -281
  129. data/lib/moneykit/models/response401_refresh_products_links_id_products_post.rb +83 -283
  130. data/lib/moneykit/models/response401_reset_login_links_id_reset_post.rb +102 -0
  131. data/lib/moneykit/models/response401_trigger_test_link_webhook_event_webhooks_test_link_id_post.rb +102 -0
  132. data/lib/moneykit/models/response401_update_link_links_id_patch.rb +83 -283
  133. data/lib/moneykit/models/settings.rb +61 -73
  134. data/lib/moneykit/models/supported_version.rb +11 -12
  135. data/lib/moneykit/models/transaction.rb +104 -131
  136. data/lib/moneykit/models/transaction_diff.rb +69 -78
  137. data/lib/moneykit/models/transaction_sync_response.rb +65 -87
  138. data/lib/moneykit/models/transaction_type.rb +12 -13
  139. data/lib/moneykit/models/transaction_type_filter.rb +12 -13
  140. data/lib/moneykit/models/transactions.rb +58 -57
  141. data/lib/moneykit/models/transactions1.rb +55 -63
  142. data/lib/moneykit/models/transactions_link_product.rb +57 -69
  143. data/lib/moneykit/models/transactions_product_settings.rb +67 -71
  144. data/lib/moneykit/models/update_link_request.rb +63 -69
  145. data/lib/moneykit/models/user_accounts_out.rb +40 -40
  146. data/lib/moneykit/models/user_links_out.rb +40 -40
  147. data/lib/moneykit/models/user_transactions_paged_response.rb +40 -40
  148. data/lib/moneykit/models/validation_error.rb +63 -77
  149. data/lib/moneykit/models/validation_error_location_inner.rb +101 -0
  150. data/lib/moneykit/models/webhook_link_test_event.rb +40 -0
  151. data/lib/moneykit/models/webhook_test_link_request.rb +252 -0
  152. data/lib/moneykit/models/webhook_test_link_response.rb +220 -0
  153. data/lib/moneykit/version.rb +10 -12
  154. data/lib/moneykit.rb +18 -39
  155. data/lib/plaid_compatible/money_kit_plaid_compatible/api/plaid_api.rb +738 -737
  156. data/lib/plaid_compatible/money_kit_plaid_compatible/api_client.rb +339 -340
  157. data/lib/plaid_compatible/money_kit_plaid_compatible/api_error.rb +47 -47
  158. data/lib/plaid_compatible/money_kit_plaid_compatible/configuration.rb +258 -260
  159. data/lib/plaid_compatible/money_kit_plaid_compatible/models/account_balance.rb +210 -212
  160. data/lib/plaid_compatible/money_kit_plaid_compatible/models/account_base.rb +221 -237
  161. data/lib/plaid_compatible/money_kit_plaid_compatible/models/account_identity.rb +231 -252
  162. data/lib/plaid_compatible/money_kit_plaid_compatible/models/account_subtype.rb +100 -101
  163. data/lib/plaid_compatible/money_kit_plaid_compatible/models/account_type.rb +35 -36
  164. data/lib/plaid_compatible/money_kit_plaid_compatible/models/accounts_get_request.rb +209 -211
  165. data/lib/plaid_compatible/money_kit_plaid_compatible/models/accounts_get_request_options.rb +188 -185
  166. data/lib/plaid_compatible/money_kit_plaid_compatible/models/accounts_get_response.rb +205 -210
  167. data/lib/plaid_compatible/money_kit_plaid_compatible/models/address.rb +195 -193
  168. data/lib/plaid_compatible/money_kit_plaid_compatible/models/address_data.rb +222 -226
  169. data/lib/plaid_compatible/money_kit_plaid_compatible/models/auth_get_numbers.rb +218 -226
  170. data/lib/plaid_compatible/money_kit_plaid_compatible/models/auth_get_request.rb +209 -211
  171. data/lib/plaid_compatible/money_kit_plaid_compatible/models/auth_get_request_options.rb +188 -185
  172. data/lib/plaid_compatible/money_kit_plaid_compatible/models/auth_get_response.rb +211 -222
  173. data/lib/plaid_compatible/money_kit_plaid_compatible/models/country_code.rb +32 -33
  174. data/lib/plaid_compatible/money_kit_plaid_compatible/models/email.rb +197 -198
  175. data/lib/plaid_compatible/money_kit_plaid_compatible/models/http_validation_error.rb +183 -181
  176. data/lib/plaid_compatible/money_kit_plaid_compatible/models/identity_get_request.rb +209 -211
  177. data/lib/plaid_compatible/money_kit_plaid_compatible/models/identity_get_request_options.rb +188 -185
  178. data/lib/plaid_compatible/money_kit_plaid_compatible/models/identity_get_response.rb +205 -210
  179. data/lib/plaid_compatible/money_kit_plaid_compatible/models/institution.rb +228 -232
  180. data/lib/plaid_compatible/money_kit_plaid_compatible/models/institutions_get_by_id_request.rb +216 -217
  181. data/lib/plaid_compatible/money_kit_plaid_compatible/models/institutions_get_by_id_response.rb +195 -196
  182. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item.rb +251 -261
  183. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_error_webhook.rb +217 -229
  184. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_get_request.rb +205 -205
  185. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_get_response.rb +201 -205
  186. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_public_token_exchange_request.rb +205 -205
  187. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_public_token_exchange_response.rb +206 -211
  188. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_remove_request.rb +205 -205
  189. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_remove_response.rb +188 -185
  190. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_status_investments.rb +195 -193
  191. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_status_last_webhook.rb +195 -193
  192. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_status_nullable.rb +194 -198
  193. data/lib/plaid_compatible/money_kit_plaid_compatible/models/item_status_transactions.rb +195 -193
  194. data/lib/plaid_compatible/money_kit_plaid_compatible/models/link_token_create_request.rb +272 -291
  195. data/lib/plaid_compatible/money_kit_plaid_compatible/models/link_token_create_request_user.rb +225 -225
  196. data/lib/plaid_compatible/money_kit_plaid_compatible/models/link_token_create_response.rb +206 -211
  197. data/lib/plaid_compatible/money_kit_plaid_compatible/models/numbers_ach.rb +215 -221
  198. data/lib/plaid_compatible/money_kit_plaid_compatible/models/numbers_bacs.rb +206 -211
  199. data/lib/plaid_compatible/money_kit_plaid_compatible/models/numbers_eft.rb +215 -224
  200. data/lib/plaid_compatible/money_kit_plaid_compatible/models/numbers_international.rb +206 -211
  201. data/lib/plaid_compatible/money_kit_plaid_compatible/models/owner.rb +218 -226
  202. data/lib/plaid_compatible/money_kit_plaid_compatible/models/personal_finance_category.rb +197 -198
  203. data/lib/plaid_compatible/money_kit_plaid_compatible/models/phone_number.rb +206 -211
  204. data/lib/plaid_compatible/money_kit_plaid_compatible/models/plaid_error.rb +253 -266
  205. data/lib/plaid_compatible/money_kit_plaid_compatible/models/plaid_error_type.rb +43 -44
  206. data/lib/plaid_compatible/money_kit_plaid_compatible/models/products.rb +33 -34
  207. data/lib/plaid_compatible/money_kit_plaid_compatible/models/removed_transaction.rb +187 -183
  208. data/lib/plaid_compatible/money_kit_plaid_compatible/models/transaction.rb +288 -315
  209. data/lib/plaid_compatible/money_kit_plaid_compatible/models/transactions_get_request.rb +225 -235
  210. data/lib/plaid_compatible/money_kit_plaid_compatible/models/transactions_get_request_options.rb +222 -224
  211. data/lib/plaid_compatible/money_kit_plaid_compatible/models/transactions_get_response.rb +225 -236
  212. data/lib/plaid_compatible/money_kit_plaid_compatible/models/transactions_refresh_request.rb +205 -205
  213. data/lib/plaid_compatible/money_kit_plaid_compatible/models/transactions_refresh_response.rb +188 -185
  214. data/lib/plaid_compatible/money_kit_plaid_compatible/models/transactions_sync_request.rb +223 -229
  215. data/lib/plaid_compatible/money_kit_plaid_compatible/models/transactions_sync_request_options.rb +197 -193
  216. data/lib/plaid_compatible/money_kit_plaid_compatible/models/transactions_sync_response.rb +235 -252
  217. data/lib/plaid_compatible/money_kit_plaid_compatible/models/validation_error.rb +198 -207
  218. data/lib/plaid_compatible/money_kit_plaid_compatible/models/webhook_environment_values.rb +32 -33
  219. data/lib/plaid_compatible/money_kit_plaid_compatible/version.rb +14 -14
  220. data/lib/plaid_compatible/money_kit_plaid_compatible.rb +24 -24
  221. data/moneykit.gemspec +22 -25
  222. metadata +14 -5
@@ -1,14 +1,12 @@
1
- =begin
2
- #Plaid Compatibility Layer
3
-
4
- #No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
5
-
6
- The version of the OpenAPI document: 0.1.0
7
-
8
- Generated by: https://openapi-generator.tech
9
- OpenAPI Generator version: 5.1.1
10
-
11
- =end
1
+ # #Plaid Compatibility Layer
2
+ #
3
+ # No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
4
+ #
5
+ # The version of the OpenAPI document: 0.1.0
6
+ #
7
+ # Generated by: https://openapi-generator.tech
8
+ # OpenAPI Generator version: 5.1.1
9
+ #
12
10
 
13
11
  require 'date'
14
12
  require 'json'
@@ -17,383 +15,384 @@ require 'tempfile'
17
15
  require 'faraday'
18
16
  require 'faraday/multipart'
19
17
 
20
- module MoneyKit::PlaidCompatible
21
- class ApiClient
22
- # The Configuration object holding settings to be used in the API client.
23
- attr_accessor :config
24
-
25
- # Defines the headers to be used in HTTP requests of all API calls by default.
26
- #
27
- # @return [Hash]
28
- attr_accessor :default_headers
29
-
30
- # The Faraday::Connection object for fine tuning configuration options.
31
- attr_reader :connection
32
-
33
- # Initializes the ApiClient
34
- # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
35
- def initialize(config = Configuration.default)
36
- @config = config
37
- @user_agent = "Plaid Ruby v1.0.0"
38
- @default_headers = {
39
- 'Content-Type' => 'application/json',
40
- 'User-Agent' => @user_agent,
41
- }
42
- @connection = create_connection
43
- end
44
-
45
- def create_connection
46
- @connection = Faraday.new(url: config.base_url) do |builder|
47
- block_given? ? yield(builder) : builder.adapter(Faraday.default_adapter)
18
+ module MoneyKit
19
+ module PlaidCompatible
20
+ class ApiClient
21
+ # The Configuration object holding settings to be used in the API client.
22
+ attr_accessor :config
23
+
24
+ # Defines the headers to be used in HTTP requests of all API calls by default.
25
+ #
26
+ # @return [Hash]
27
+ attr_accessor :default_headers
28
+
29
+ # The Faraday::Connection object for fine tuning configuration options.
30
+ attr_reader :connection
31
+
32
+ # Initializes the ApiClient
33
+ # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
34
+ def initialize(config = Configuration.default)
35
+ @config = config
36
+ @user_agent = 'Plaid Ruby v1.0.0'
37
+ @default_headers = {
38
+ 'Content-Type' => 'application/json',
39
+ 'User-Agent' => @user_agent
40
+ }
41
+ @connection = create_connection
48
42
  end
49
- end
50
43
 
51
- def self.default
52
- @@default ||= ApiClient.new
53
- end
44
+ def create_connection
45
+ @connection = Faraday.new(url: config.base_url) do |builder|
46
+ block_given? ? yield(builder) : builder.adapter(Faraday.default_adapter)
47
+ end
48
+ end
54
49
 
55
- # Call an API with given options.
56
- #
57
- # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
58
- # the data deserialized from response body (could be nil), response status code and response headers.
59
- def call_api(http_method, path, opts = {})
60
- if opts[:header_params]["Content-Type"] == "multipart/form-data"
61
- connection.request :multipart
62
- connection.request :url_encoded
50
+ def self.default
51
+ @@default ||= ApiClient.new
63
52
  end
64
53
 
65
- begin
66
- response = connection.public_send(http_method.to_sym.downcase) do |req|
67
- build_request(http_method, path, req, opts)
54
+ # Call an API with given options.
55
+ #
56
+ # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
57
+ # the data deserialized from response body (could be nil), response status code and response headers.
58
+ def call_api(http_method, path, opts = {})
59
+ if opts[:header_params]['Content-Type'] == 'multipart/form-data'
60
+ connection.request :multipart
61
+ connection.request :url_encoded
68
62
  end
69
63
 
70
- if @config.debugging
71
- @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
72
- end
64
+ begin
65
+ response = connection.public_send(http_method.to_sym.downcase) do |req|
66
+ build_request(http_method, path, req, opts)
67
+ end
73
68
 
74
- unless response.success?
75
- if response.status == 0
76
- # Errors from libcurl will be made visible here
77
- fail ApiError.new(:code => 0,
78
- :message => response.return_message)
79
- else
80
- raw_body = response.body
81
- # Gracefully handle malformed body which is possible during API outage/maintanance
82
- parsed_body = begin
83
- JSON.parse(raw_body)
84
- rescue JSON::ParserError
85
- nil
86
- end
87
- fail ApiError.new(:code => response.status,
88
- :response_headers => response.headers,
89
- :response_body => raw_body,
90
- :data => parsed_body),
91
- response.reason_phrase
69
+ @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" if @config.debugging
70
+
71
+ unless response.success?
72
+ if response.status == 0
73
+ # Errors from libcurl will be made visible here
74
+ raise ApiError.new(code: 0,
75
+ message: response.return_message)
76
+ else
77
+ raw_body = response.body
78
+ # Gracefully handle malformed body which is possible during API outage/maintanance
79
+ parsed_body = begin
80
+ JSON.parse(raw_body)
81
+ rescue JSON::ParserError
82
+ nil
83
+ end
84
+ raise ApiError.new(code: response.status,
85
+ response_headers: response.headers,
86
+ response_body: raw_body,
87
+ data: parsed_body),
88
+ response.reason_phrase
89
+ end
92
90
  end
91
+ rescue Faraday::TimeoutError
92
+ raise ApiError, 'Connection timed out'
93
93
  end
94
- rescue Faraday::TimeoutError
95
- fail ApiError.new('Connection timed out')
96
- end
97
94
 
98
- if opts[:return_type]
99
- prepare_file(response) if opts[:return_type] == 'File'
100
- data = deserialize(response, opts[:return_type])
101
- else
102
- data = nil
95
+ if opts[:return_type]
96
+ prepare_file(response) if opts[:return_type] == 'File'
97
+ data = deserialize(response, opts[:return_type])
98
+ else
99
+ data = nil
100
+ end
101
+ [data, response.status, response.headers]
103
102
  end
104
- return data, response.status, response.headers
105
- end
106
103
 
107
- # Builds the HTTP request
108
- #
109
- # @param [String] http_method HTTP method/verb (e.g. POST)
110
- # @param [String] path URL path (e.g. /account/new)
111
- # @option opts [Hash] :header_params Header parameters
112
- # @option opts [Hash] :query_params Query parameters
113
- # @option opts [Hash] :form_params Query parameters
114
- # @option opts [Object] :body HTTP body (JSON/XML)
115
- # @return [Typhoeus::Request] A Typhoeus Request
116
- def build_request(http_method, path, request, opts = {})
117
- url = build_request_url(path)
118
- http_method = http_method.to_sym.downcase
119
-
120
- header_params = @default_headers.merge(opts[:header_params] || {})
121
- query_params = opts[:query_params] || {}
122
- form_params = opts[:form_params] || {}
123
-
124
- update_params_for_auth! header_params, query_params, opts[:auth_names]
125
-
126
- req_opts = {
127
- :method => http_method,
128
- :headers => header_params,
129
- :params => query_params,
130
- :params_encoding => @config.params_encoding,
131
- :timeout => @config.timeout,
132
- :verbose => @config.debugging
133
- }
134
-
135
- if [:post, :patch, :put, :delete].include?(http_method)
136
- req_body = build_request_body(header_params, form_params, opts[:body])
137
- req_opts.update :body => req_body
138
- if @config.debugging
139
- @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
104
+ # Builds the HTTP request
105
+ #
106
+ # @param [String] http_method HTTP method/verb (e.g. POST)
107
+ # @param [String] path URL path (e.g. /account/new)
108
+ # @option opts [Hash] :header_params Header parameters
109
+ # @option opts [Hash] :query_params Query parameters
110
+ # @option opts [Hash] :form_params Query parameters
111
+ # @option opts [Object] :body HTTP body (JSON/XML)
112
+ # @return [Typhoeus::Request] A Typhoeus Request
113
+ def build_request(http_method, path, request, opts = {})
114
+ url = build_request_url(path)
115
+ http_method = http_method.to_sym.downcase
116
+
117
+ header_params = @default_headers.merge(opts[:header_params] || {})
118
+ query_params = opts[:query_params] || {}
119
+ form_params = opts[:form_params] || {}
120
+
121
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
122
+
123
+ req_opts = {
124
+ method: http_method,
125
+ headers: header_params,
126
+ params: query_params,
127
+ params_encoding: @config.params_encoding,
128
+ timeout: @config.timeout,
129
+ verbose: @config.debugging
130
+ }
131
+
132
+ if %i[post patch put delete].include?(http_method)
133
+ req_body = build_request_body(header_params, form_params, opts[:body])
134
+ req_opts.update body: req_body
135
+ @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n" if @config.debugging
140
136
  end
137
+ request.headers = header_params
138
+ request.body = req_body
139
+ request.url url
140
+ request.params = query_params
141
+ request
141
142
  end
142
- request.headers = header_params
143
- request.body = req_body
144
- request.url url
145
- request.params = query_params
146
- request
147
- end
148
143
 
149
- # Builds the HTTP request body
150
- #
151
- # @param [Hash] header_params Header parameters
152
- # @param [Hash] form_params Query parameters
153
- # @param [Object] body HTTP body (JSON/XML)
154
- # @return [String] HTTP body data in the form of string
155
- def build_request_body(header_params, form_params, body)
156
- # http form
157
- if header_params['Content-Type'] == 'application/x-www-form-urlencoded'
158
- data = URI.encode_www_form(form_params)
159
- elsif header_params['Content-Type'] == 'multipart/form-data'
160
- data = {}
161
- form_params.each do |key, value|
162
- case value
163
- when ::File, ::Tempfile
164
- # TODO hardcode to application/octet-stream, need better way to detect content type
165
- data[key] = Faraday::Multipart::Post::UploadIO.new(value.path, 'application/octet-stream', value.path)
166
- when ::Array, nil
167
- # let Faraday handle Array and nil parameters
168
- data[key] = value
169
- else
170
- data[key] = value.to_s
144
+ # Builds the HTTP request body
145
+ #
146
+ # @param [Hash] header_params Header parameters
147
+ # @param [Hash] form_params Query parameters
148
+ # @param [Object] body HTTP body (JSON/XML)
149
+ # @return [String] HTTP body data in the form of string
150
+ def build_request_body(header_params, form_params, body)
151
+ # http form
152
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded'
153
+ data = URI.encode_www_form(form_params)
154
+ elsif header_params['Content-Type'] == 'multipart/form-data'
155
+ data = {}
156
+ form_params.each do |key, value|
157
+ data[key] = case value
158
+ when ::File, ::Tempfile
159
+ # TODO: hardcode to application/octet-stream, need better way to detect content type
160
+ Faraday::Multipart::Post::UploadIO.new(value.path, 'application/octet-stream', value.path)
161
+ when ::Array, nil
162
+ # let Faraday handle Array and nil parameters
163
+ value
164
+ else
165
+ value.to_s
166
+ end
171
167
  end
168
+ elsif body
169
+ data = body.is_a?(String) ? body : body.to_json
170
+ else
171
+ data = nil
172
172
  end
173
- elsif body
174
- data = body.is_a?(String) ? body : body.to_json
175
- else
176
- data = nil
173
+ data
177
174
  end
178
- data
179
- end
180
175
 
181
- # Check if the given MIME is a JSON MIME.
182
- # JSON MIME examples:
183
- # application/json
184
- # application/json; charset=UTF8
185
- # APPLICATION/JSON
186
- # */*
187
- # @param [String] mime MIME
188
- # @return [Boolean] True if the MIME is application/json
189
- def json_mime?(mime)
190
- (mime == '*/*') || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil?
191
- end
176
+ # Check if the given MIME is a JSON MIME.
177
+ # JSON MIME examples:
178
+ # application/json
179
+ # application/json; charset=UTF8
180
+ # APPLICATION/JSON
181
+ # */*
182
+ # @param [String] mime MIME
183
+ # @return [Boolean] True if the MIME is application/json
184
+ def json_mime?(mime)
185
+ (mime == '*/*') || !(mime =~ %r{Application/.*json(?!p)(;.*)?}i).nil?
186
+ end
187
+
188
+ # Deserialize the response to the given return type.
189
+ #
190
+ # @param [Response] response HTTP response
191
+ # @param [String] return_type some examples: "User", "Array<User>", "Hash<String, Integer>"
192
+ def deserialize(response, return_type)
193
+ body = response.body
192
194
 
193
- # Deserialize the response to the given return type.
194
- #
195
- # @param [Response] response HTTP response
196
- # @param [String] return_type some examples: "User", "Array<User>", "Hash<String, Integer>"
197
- def deserialize(response, return_type)
198
- body = response.body
195
+ # handle file downloading - return the File instance processed in request callbacks
196
+ # note that response body is empty when the file is written in chunks in request on_body callback
197
+ return @tempfile if return_type == 'File'
199
198
 
200
- # handle file downloading - return the File instance processed in request callbacks
201
- # note that response body is empty when the file is written in chunks in request on_body callback
202
- return @tempfile if return_type == 'File'
199
+ return nil if body.nil? || body.empty?
203
200
 
204
- return nil if body.nil? || body.empty?
201
+ # return response body directly for String return type
202
+ return body if return_type == 'String'
205
203
 
206
- # return response body directly for String return type
207
- return body if return_type == 'String'
204
+ # ensuring a default content type
205
+ content_type = response.headers['Content-Type'] || 'application/json'
208
206
 
209
- # ensuring a default content type
210
- content_type = response.headers['Content-Type'] || 'application/json'
207
+ raise "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
211
208
 
212
- fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
209
+ begin
210
+ data = JSON.parse("[#{body}]", symbolize_names: true)[0]
211
+ rescue JSON::ParserError => e
212
+ raise e unless %w[String Date DateTime].include?(return_type)
213
213
 
214
- begin
215
- data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
216
- rescue JSON::ParserError => e
217
- if %w(String Date DateTime).include?(return_type)
218
214
  data = body
219
- else
220
- raise e
221
215
  end
222
- end
223
216
 
224
- convert_to_type data, return_type
225
- end
217
+ convert_to_type data, return_type
218
+ end
226
219
 
227
- # Convert data to the given return type.
228
- # @param [Object] data Data to be converted
229
- # @param [String] return_type Return type
230
- # @return [Mixed] Data in a particular type
231
- def convert_to_type(data, return_type)
232
- return nil if data.nil?
233
- case return_type
234
- when 'String'
235
- data.to_s
236
- when 'Integer'
237
- data.to_i
238
- when 'Float'
239
- data.to_f
240
- when 'Boolean'
241
- data == true
242
- when 'DateTime'
243
- # parse date time (expecting ISO 8601 format)
244
- DateTime.parse data
245
- when 'Date'
246
- # parse date time (expecting ISO 8601 format)
247
- Date.parse data
248
- when 'Object'
249
- # generic object (usually a Hash), return directly
250
- data
251
- when /\AArray<(.+)>\z/
252
- # e.g. Array<Pet>
253
- sub_type = $1
254
- data.map { |item| convert_to_type(item, sub_type) }
255
- when /\AHash\<String, (.+)\>\z/
256
- # e.g. Hash<String, Integer>
257
- sub_type = $1
258
- {}.tap do |hash|
259
- data.each { |k, v| hash[k] = convert_to_type(v, sub_type) }
220
+ # Convert data to the given return type.
221
+ # @param [Object] data Data to be converted
222
+ # @param [String] return_type Return type
223
+ # @return [Mixed] Data in a particular type
224
+ def convert_to_type(data, return_type)
225
+ return nil if data.nil?
226
+
227
+ case return_type
228
+ when 'String'
229
+ data.to_s
230
+ when 'Integer'
231
+ data.to_i
232
+ when 'Float'
233
+ data.to_f
234
+ when 'Boolean'
235
+ data == true
236
+ when 'DateTime'
237
+ # parse date time (expecting ISO 8601 format)
238
+ DateTime.parse data
239
+ when 'Date'
240
+ # parse date time (expecting ISO 8601 format)
241
+ Date.parse data
242
+ when 'Object'
243
+ # generic object (usually a Hash), return directly
244
+ data
245
+ when /\AArray<(.+)>\z/
246
+ # e.g. Array<Pet>
247
+ sub_type = ::Regexp.last_match(1)
248
+ data.map { |item| convert_to_type(item, sub_type) }
249
+ when /\AHash<String, (.+)>\z/
250
+ # e.g. Hash<String, Integer>
251
+ sub_type = ::Regexp.last_match(1)
252
+ {}.tap do |hash|
253
+ data.each { |k, v| hash[k] = convert_to_type(v, sub_type) }
254
+ end
255
+ else
256
+ # models, e.g. Pet
257
+ MoneyKit::PlaidCompatible.const_get(return_type).build_from_hash(data)
260
258
  end
261
- else
262
- # models, e.g. Pet
263
- MoneyKit::PlaidCompatible.const_get(return_type).build_from_hash(data)
264
259
  end
265
- end
266
260
 
267
- # Save response body into a file in (the defined) temporary folder, using the filename
268
- # from the "Content-Disposition" header if provided, otherwise a random filename.
269
- # The response body is written to the file in chunks in order to handle files which
270
- # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby
271
- # process can use.
272
- #
273
- # @see Configuration#temp_folder_path
274
- def prepare_file(response)
275
- content_disposition = response.headers["Content-Disposition"]
276
- if content_disposition && content_disposition =~ /filename=/i
277
- filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
278
- prefix = sanitize_filename(filename)
279
- else
280
- prefix = "download-"
261
+ # Save response body into a file in (the defined) temporary folder, using the filename
262
+ # from the "Content-Disposition" header if provided, otherwise a random filename.
263
+ # The response body is written to the file in chunks in order to handle files which
264
+ # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby
265
+ # process can use.
266
+ #
267
+ # @see Configuration#temp_folder_path
268
+ def prepare_file(response)
269
+ content_disposition = response.headers['Content-Disposition']
270
+ if content_disposition && content_disposition =~ /filename=/i
271
+ filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
272
+ prefix = sanitize_filename(filename)
273
+ else
274
+ prefix = 'download-'
275
+ end
276
+ prefix += '-' unless prefix.end_with?('-')
277
+ encoding = response.body.encoding
278
+ tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
279
+ @tempfile = tempfile
280
+ tempfile.write(response.body)
281
+ tempfile.close if tempfile
282
+ @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder " \
283
+ "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file " \
284
+ "will be deleted automatically with GC. It's also recommended to delete the temp file " \
285
+ 'explicitly with `tempfile.delete`'
281
286
  end
282
- prefix = prefix + "-" unless prefix.end_with?("-")
283
- encoding = response.body.encoding
284
- tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
285
- @tempfile = tempfile
286
- tempfile.write(response.body)
287
- tempfile.close if tempfile
288
- @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder " \
289
- "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file " \
290
- "will be deleted automatically with GC. It's also recommended to delete the temp file " \
291
- "explicitly with `tempfile.delete`"
292
- end
293
287
 
294
- # Sanitize filename by removing path.
295
- # e.g. ../../sun.gif becomes sun.gif
296
- #
297
- # @param [String] filename the filename to be sanitized
298
- # @return [String] the sanitized filename
299
- def sanitize_filename(filename)
300
- filename.gsub(/.*[\/\\]/, '')
301
- end
288
+ # Sanitize filename by removing path.
289
+ # e.g. ../../sun.gif becomes sun.gif
290
+ #
291
+ # @param [String] filename the filename to be sanitized
292
+ # @return [String] the sanitized filename
293
+ def sanitize_filename(filename)
294
+ filename.gsub(%r{.*[/\\]}, '')
295
+ end
302
296
 
303
- def build_request_url(path)
304
- # Add leading and trailing slashes to path
305
- path = "/#{path}".gsub(/\/+/, '/')
306
- @config.base_url + path
307
- end
297
+ def build_request_url(path)
298
+ # Add leading and trailing slashes to path
299
+ path = "/#{path}".gsub(%r{/+}, '/')
300
+ @config.base_url + path
301
+ end
308
302
 
309
- # Update hearder and query params based on authentication settings.
310
- #
311
- # @param [Hash] header_params Header parameters
312
- # @param [Hash] query_params Query parameters
313
- # @param [String] auth_names Authentication scheme name
314
- def update_params_for_auth!(header_params, query_params, auth_names)
315
- Array(auth_names).each do |auth_name|
316
- auth_setting = @config.auth_settings[auth_name]
317
- next unless auth_setting
318
- case auth_setting[:in]
319
- when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
320
- when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
321
- else fail ArgumentError, 'Authentication token must be in `query` of `header`'
303
+ # Update hearder and query params based on authentication settings.
304
+ #
305
+ # @param [Hash] header_params Header parameters
306
+ # @param [Hash] query_params Query parameters
307
+ # @param [String] auth_names Authentication scheme name
308
+ def update_params_for_auth!(header_params, query_params, auth_names)
309
+ Array(auth_names).each do |auth_name|
310
+ auth_setting = @config.auth_settings[auth_name]
311
+ next unless auth_setting
312
+
313
+ case auth_setting[:in]
314
+ when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
315
+ when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
316
+ else raise ArgumentError, 'Authentication token must be in `query` of `header`'
317
+ end
322
318
  end
323
319
  end
324
- end
325
320
 
326
- # Sets user agent in HTTP header
327
- #
328
- # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0)
329
- def user_agent=(user_agent)
330
- @user_agent = user_agent
331
- @default_headers['User-Agent'] = @user_agent
332
- end
321
+ # Sets user agent in HTTP header
322
+ #
323
+ # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0)
324
+ def user_agent=(user_agent)
325
+ @user_agent = user_agent
326
+ @default_headers['User-Agent'] = @user_agent
327
+ end
333
328
 
334
- # Return Accept header based on an array of accepts provided.
335
- # @param [Array] accepts array for Accept
336
- # @return [String] the Accept header (e.g. application/json)
337
- def select_header_accept(accepts)
338
- return nil if accepts.nil? || accepts.empty?
339
- # use JSON when present, otherwise use all of the provided
340
- json_accept = accepts.find { |s| json_mime?(s) }
341
- json_accept || accepts.join(',')
342
- end
329
+ # Return Accept header based on an array of accepts provided.
330
+ # @param [Array] accepts array for Accept
331
+ # @return [String] the Accept header (e.g. application/json)
332
+ def select_header_accept(accepts)
333
+ return nil if accepts.nil? || accepts.empty?
343
334
 
344
- # Return Content-Type header based on an array of content types provided.
345
- # @param [Array] content_types array for Content-Type
346
- # @return [String] the Content-Type header (e.g. application/json)
347
- def select_header_content_type(content_types)
348
- # use application/json by default
349
- return 'application/json' if content_types.nil? || content_types.empty?
350
- # use JSON when present, otherwise use the first one
351
- json_content_type = content_types.find { |s| json_mime?(s) }
352
- json_content_type || content_types.first
353
- end
335
+ # use JSON when present, otherwise use all of the provided
336
+ json_accept = accepts.find { |s| json_mime?(s) }
337
+ json_accept || accepts.join(',')
338
+ end
354
339
 
355
- # Convert object (array, hash, object, etc) to JSON string.
356
- # @param [Object] model object to be converted into JSON string
357
- # @return [String] JSON string representation of the object
358
- def object_to_http_body(model)
359
- return model if model.nil? || model.is_a?(String)
360
- local_body = nil
361
- if model.is_a?(Array)
362
- local_body = model.map { |m| object_to_hash(m) }
363
- else
364
- local_body = object_to_hash(model)
340
+ # Return Content-Type header based on an array of content types provided.
341
+ # @param [Array] content_types array for Content-Type
342
+ # @return [String] the Content-Type header (e.g. application/json)
343
+ def select_header_content_type(content_types)
344
+ # use application/json by default
345
+ return 'application/json' if content_types.nil? || content_types.empty?
346
+
347
+ # use JSON when present, otherwise use the first one
348
+ json_content_type = content_types.find { |s| json_mime?(s) }
349
+ json_content_type || content_types.first
365
350
  end
366
- local_body.to_json
367
- end
368
351
 
369
- # Convert object(non-array) to hash.
370
- # @param [Object] obj object to be converted into JSON string
371
- # @return [String] JSON string representation of the object
372
- def object_to_hash(obj)
373
- if obj.respond_to?(:to_hash)
374
- obj.to_hash
375
- else
376
- obj
352
+ # Convert object (array, hash, object, etc) to JSON string.
353
+ # @param [Object] model object to be converted into JSON string
354
+ # @return [String] JSON string representation of the object
355
+ def object_to_http_body(model)
356
+ return model if model.nil? || model.is_a?(String)
357
+
358
+ local_body = nil
359
+ local_body = if model.is_a?(Array)
360
+ model.map { |m| object_to_hash(m) }
361
+ else
362
+ object_to_hash(model)
363
+ end
364
+ local_body.to_json
377
365
  end
378
- end
379
366
 
380
- # Build parameter value according to the given collection format.
381
- # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
382
- def build_collection_param(param, collection_format)
383
- case collection_format
384
- when :csv
385
- param.join(',')
386
- when :ssv
387
- param.join(' ')
388
- when :tsv
389
- param.join("\t")
390
- when :pipes
391
- param.join('|')
392
- when :multi
393
- # return the array directly as typhoeus will handle it as expected
394
- param
395
- else
396
- fail "unknown collection format: #{collection_format.inspect}"
367
+ # Convert object(non-array) to hash.
368
+ # @param [Object] obj object to be converted into JSON string
369
+ # @return [String] JSON string representation of the object
370
+ def object_to_hash(obj)
371
+ if obj.respond_to?(:to_hash)
372
+ obj.to_hash
373
+ else
374
+ obj
375
+ end
376
+ end
377
+
378
+ # Build parameter value according to the given collection format.
379
+ # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
380
+ def build_collection_param(param, collection_format)
381
+ case collection_format
382
+ when :csv
383
+ param.join(',')
384
+ when :ssv
385
+ param.join(' ')
386
+ when :tsv
387
+ param.join("\t")
388
+ when :pipes
389
+ param.join('|')
390
+ when :multi
391
+ # return the array directly as typhoeus will handle it as expected
392
+ param
393
+ else
394
+ raise "unknown collection format: #{collection_format.inspect}"
395
+ end
397
396
  end
398
397
  end
399
398
  end