increase 0.1.2 → 0.2.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/OPENAPI_VERSION +1 -0
  3. data/README.md +174 -45
  4. data/bin/generate +152 -0
  5. data/bin/setup +8 -0
  6. data/generate/resource.rb.erb +18 -0
  7. data/lib/increase/client.rb +2 -0
  8. data/lib/increase/configuration.rb +1 -1
  9. data/lib/increase/resource.rb +85 -119
  10. data/lib/increase/resources/account_numbers.rb +7 -0
  11. data/lib/increase/resources/account_statements.rb +15 -0
  12. data/lib/increase/resources/account_transfers.rb +10 -2
  13. data/lib/increase/resources/accounts.rb +9 -1
  14. data/lib/increase/resources/ach_prenotifications.rb +17 -0
  15. data/lib/increase/resources/ach_transfers.rb +10 -2
  16. data/lib/increase/resources/card_disputes.rb +17 -0
  17. data/lib/increase/resources/card_profiles.rb +17 -0
  18. data/lib/increase/resources/cards.rb +9 -1
  19. data/lib/increase/resources/check_deposits.rb +17 -0
  20. data/lib/increase/resources/check_transfers.rb +23 -0
  21. data/lib/increase/resources/declined_transactions.rb +15 -0
  22. data/lib/increase/resources/digital_wallet_tokens.rb +15 -0
  23. data/lib/increase/resources/documents.rb +15 -0
  24. data/lib/increase/resources/entities.rb +19 -0
  25. data/lib/increase/resources/event_subscriptions.rb +19 -0
  26. data/lib/increase/resources/events.rb +5 -0
  27. data/lib/increase/resources/external_accounts.rb +19 -0
  28. data/lib/increase/resources/files.rb +17 -0
  29. data/lib/increase/resources/groups.rb +13 -0
  30. data/lib/increase/resources/inbound_ach_transfer_returns.rb +17 -0
  31. data/lib/increase/resources/inbound_wire_drawdown_requests.rb +15 -0
  32. data/lib/increase/resources/limits.rb +19 -0
  33. data/lib/increase/resources/oauth_connections.rb +15 -0
  34. data/lib/increase/resources/pending_transactions.rb +5 -0
  35. data/lib/increase/resources/real_time_decisions.rb +15 -0
  36. data/lib/increase/resources/routing_numbers.rb +13 -0
  37. data/lib/increase/resources/transactions.rb +5 -0
  38. data/lib/increase/resources/wire_drawdown_requests.rb +17 -0
  39. data/lib/increase/resources/wire_transfers.rb +21 -0
  40. data/lib/increase/response_array.rb +19 -0
  41. data/lib/increase/version.rb +1 -1
  42. data/lib/increase/webhook/signature.rb +9 -1
  43. data/openapi.json +32098 -0
  44. metadata +62 -6
@@ -1,7 +1,10 @@
1
1
  require "increase/response_hash"
2
+ require "increase/response_array"
2
3
 
3
4
  module Increase
4
5
  class Resource
6
+ PAGINATION_MAX_LIMIT = 100
7
+
5
8
  def initialize(client: nil)
6
9
  if instance_of?(Resource)
7
10
  raise NotImplementedError, "Resource is an abstract class. You should perform actions on its subclasses (Accounts, Transactions, Card, etc.)"
@@ -18,51 +21,41 @@ module Increase
18
21
  end
19
22
 
20
23
  def self.resource_url
21
- "/#{resource_name.downcase.tr(" ", "_")}"
24
+ "/#{self::API_NAME}"
22
25
  end
23
26
 
24
- def self.resource_name
25
- if self == Resource
26
- raise NotImplementedError, "Resource is an abstract class. You should perform actions on its subclasses (Accounts, Transactions, Card, etc.)"
27
- end
28
-
29
- name.split("::").last.gsub(/[A-Z]/, ' \0').strip
30
- end
31
-
32
- def self.endpoint(name, http_method, to: :same_as_name, with: nil)
33
- to = nil if to == :root
34
- to = name.to_s if to == :same_as_name
35
- to = [to].flatten.compact
27
+ def self.endpoint(name, http_method, path: nil, with: nil)
28
+ path = [path].flatten.compact
36
29
  with = [with].flatten.compact
37
30
 
38
- raise Error, "Invalid `to`. Max of 2 elements allowed" if to.size > 2
39
- raise Error, "Only one `to` allowed when not `with` an `id`" if to.size > 1 && !with.include?(:id)
31
+ # TODO: This doesn't support multiple path params
32
+ is_id = ->(path_segment) { path_segment.is_a?(Symbol) && path_segment.to_s.end_with?('id') }
33
+ has_id = path.any? is_id
40
34
 
41
35
  request_method = :request
42
36
  request_method = :paginated_request if with.include?(:pagination)
43
37
 
44
38
  method =
45
- if with.include?(:id)
39
+ if has_id
46
40
  # Method signature with a required `id` param
47
41
  ->(id, params = nil, headers = nil, &block) do
48
- url = self.class.resource_url
49
- url +=
50
- if to.size == 2
51
- "/#{to[0]}/#{id}/#{to[1]}"
52
- elsif to.size == 1
53
- # Default to id first
54
- "/#{id}/#{to[0]}"
55
- else
56
- "/#{id}"
57
- end
42
+ segments = path.map { |segment| is_id.call(segment) ? id : segment }
43
+ url = ([self.class.resource_url] + segments).join("/")
44
+
45
+ if with.include?(:file_upload)
46
+ headers = {"Content-Type" => "multipart/form-data"}.merge(headers || {})
47
+ end
58
48
 
59
49
  send(request_method, http_method, url, params, headers, &block)
60
50
  end
61
51
  else
62
52
  # Method signature without a required `id` param
63
53
  ->(params = nil, headers = nil, &block) do
64
- url = self.class.resource_url
65
- url += "/#{to[0]}" if to.size == 1
54
+ url = ([self.class.resource_url] + path).join("/")
55
+
56
+ if with.include?(:file_upload)
57
+ headers = {"Content-Type" => "multipart/form-data"}.merge(headers || {})
58
+ end
66
59
 
67
60
  send(request_method, http_method, url, params, headers, &block)
68
61
  end
@@ -87,98 +80,27 @@ module Increase
87
80
  # endpoint which is a `GET` request to the resource's root URL.
88
81
 
89
82
  def create
90
- endpoint :create, :post, to: :root
83
+ endpoint :create, :post
91
84
  end
92
85
 
93
86
  def list
94
- endpoint :list, :get, to: :root, with: :pagination
87
+ endpoint :list, :get, with: :pagination
95
88
  end
96
89
 
97
90
  def update
98
- endpoint :update, :patch, to: :root, with: :id
91
+ endpoint :update, :patch, path: [:id]
99
92
  end
100
93
 
101
94
  def retrieve
102
- endpoint :retrieve, :get, to: :root, with: :id
95
+ endpoint :retrieve, :get, path: [:id]
103
96
  end
104
97
  end
105
98
 
106
- # def self.endpoint_action(method, http_method)
107
- # define_singleton_method(method) do |*args, &block|
108
- # new.send(:action, method, http_method, *args, &block)
109
- # end
110
- #
111
- # define_method(method) do |*args, &block|
112
- # new.send(:action, method, http_method, *args, &block)
113
- # end
114
- # end
115
- #
116
- # private_class_method :endpoint_action
117
- #
118
- # private
119
- #
120
- # def create(params = nil, headers = nil)
121
- # request(:post, self.class.resource_url, params, headers)
122
- # end
123
- #
124
- # def list(params = nil, headers = nil, &block)
125
- # results = []
126
- # count = 0
127
- # limit = params&.[](:limit) || params&.[]("limit")
128
- # if limit == :all || limit&.>(100)
129
- # params&.delete(:limit)
130
- # params&.delete("limit")
131
- # end
132
- #
133
- # loop do
134
- # res = request(:get, self.class.resource_url, params, headers)
135
- # data = res["data"]
136
- # count += data.size
137
- # if ![nil, :all].include?(limit) && count >= limit
138
- # data = data[0..(limit - (count - data.size) - 1)]
139
- # end
140
- #
141
- # if block
142
- # block.call(data)
143
- # else
144
- # results += data
145
- # end
146
- #
147
- # if limit.nil? || (limit != :all && count >= limit) || res["next_cursor"].nil?
148
- # if block
149
- # break
150
- # else
151
- # return results
152
- # end
153
- # end
154
- #
155
- # params = (params || {}).merge({ cursor: res["next_cursor"] })
156
- # end
157
- # end
158
- #
159
- # def update(id, params = nil, headers = nil)
160
- # raise Error, "id must be a string" unless id.is_a?(String)
161
- # path = "#{self.class.resource_url}/#{id}"
162
- # request(:patch, path, params, headers)
163
- # end
164
- #
165
- # def retrieve(id, params = nil, headers = nil)
166
- # raise Error, "id must be a string" unless id.is_a?(String)
167
- # path = "#{self.class.resource_url}/#{id}"
168
- # request(:get, path, params, headers)
169
- # end
170
- #
171
- # # Such as for "/accounts/{account_id}/close"
172
- # # "close" is the action.
173
- # def action(action, http_method, id, params = nil, headers = nil)
174
- # raise Error, "id must be a string" unless id.is_a?(String)
175
- # path = "#{self.class.resource_url}/#{id}/#{action}"
176
- # request(http_method, path, params, headers)
177
- # end
178
-
179
99
  private
180
100
 
181
101
  def request(method, path, params = nil, headers = nil, &block)
102
+ headers ||= {}
103
+
182
104
  if block
183
105
  # Assume the caller wants to automatically paginate
184
106
  return paginated_request(method, path, params, headers, &block)
@@ -188,51 +110,95 @@ module Increase
188
110
  headers = {"Content-Type" => "application/json"}.merge!(headers || {})
189
111
  end
190
112
 
113
+ # Hack to check for correct file upload params
114
+ if headers["Content-Type"] == "multipart/form-data"
115
+ attr = :file # TODO: Make this configurable
116
+ if params.nil? || params[attr].nil?
117
+ # No file to upload
118
+ elsif params[attr].is_a?(Faraday::Multipart::FilePart) || params[attr].is_a?(Faraday::Multipart::ParamPart)
119
+ # All is good!
120
+ else
121
+ # Soft fail
122
+ warn "File upload requires a `#{attr}` param with a Faraday::Multipart::FilePart or Faraday::MultiPart::ParamPart object. See docs."
123
+ end
124
+ end
125
+
191
126
  response = @client.connection.send(method, path, params, headers)
192
127
  ResponseHash.new(response.body, response: response)
193
128
  end
194
129
 
195
130
  def paginated_request(method, path, params = nil, headers = nil, &block)
131
+ params ||= {}
132
+ limit = params[:limit] || params["limit"]
133
+ if limit == :all || limit&.>(PAGINATION_MAX_LIMIT)
134
+ # Request `limit` can not be greater than `PAGINATION_MAX_LIMIT`
135
+ params.delete("limit")
136
+ params[:limit] = PAGINATION_MAX_LIMIT
137
+ end
138
+
196
139
  results = []
197
140
  count = 0
198
- limit = params&.[](:limit) || params&.[]("limit")
199
- if limit == :all || limit&.>(100)
200
- params&.delete(:limit)
201
- params&.delete("limit")
202
- end
203
141
 
204
142
  loop do
205
143
  res = request(method, path, params, headers)
206
144
  data = res["data"]
207
145
 
208
- # Handle case where endpoint doesn't actually support pagination.
209
- # For example, someone passes a block to `Account.create`
146
+ # Handle case where endpoint doesn't support pagination.
147
+ # For example, someone passes a block to `Accounts.create`
210
148
  if data.nil?
211
- # In this case, we'll both yield and return the response
212
- yield res if block
149
+ # In this case, we'll both yield and return the response.
150
+ # `res` here is already a `ResponseHash` since it comes from `request`
151
+ if block
152
+ yield res and return
153
+ end
213
154
  return res
214
155
  end
215
156
 
157
+ # From here on, the endpoint definitely supports pagination
158
+
216
159
  count += data.size
160
+ # Restrict number of results to the limit
217
161
  if ![nil, :all].include?(limit) && count >= limit
218
162
  data = data[0..(limit - (count - data.size) - 1)]
219
163
  end
220
164
 
165
+ # Either yield or collect the results
221
166
  if block
222
- block.call(data)
167
+ block.call(ResponseArray.new(data, full_response: res, response: res.response))
223
168
  else
224
169
  results += data
225
170
  end
226
171
 
227
- if limit.nil? || (limit != :all && count >= limit) || res["next_cursor"].nil?
172
+ # Handle case where user doesn't want to paginate
173
+ if limit.nil?
228
174
  if block
229
- break
175
+ # Block has already been called above
176
+ return
230
177
  else
231
- return results
178
+ return ResponseArray.new(results, full_response: res, response: res.response)
232
179
  end
233
180
  end
234
181
 
235
- params = (params || {}).merge({cursor: res["next_cursor"]})
182
+ # From here on, this is for sure a paginated request
183
+
184
+ # Handle case where we've hit the last page
185
+ if (limit != :all && count >= limit) || res["next_cursor"].nil?
186
+ if block
187
+ # We've already yielded all the data above
188
+ return
189
+ else
190
+ # Wrap with a `ResponseArray`. However, there are multiple
191
+ # requests/responses associated with this array. The `full_response`
192
+ # and `response` only store the last response.
193
+ return ResponseArray.new(results, full_response: res, response: res.response)
194
+ end
195
+ end
196
+
197
+ # Update the cursor and loop again!
198
+ params[:cursor] = res["next_cursor"]
199
+ if limit != :all
200
+ params[:limit] = [limit - count, PAGINATION_MAX_LIMIT].min
201
+ end
236
202
  end
237
203
  end
238
204
  end
@@ -4,9 +4,16 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class AccountNumbers < Resource
7
+ NAME = "Account Numbers"
8
+ API_NAME = "account_numbers"
9
+
10
+ # Create an Account Number
7
11
  create
12
+ # List Account Numbers
8
13
  list
14
+ # Update an Account Number
9
15
  update
16
+ # Retrieve an Account Number
10
17
  retrieve
11
18
  end
12
19
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class AccountStatements < Resource
7
+ NAME = "Account Statements"
8
+ API_NAME = "account_statements"
9
+
10
+ # List Account Statements
11
+ list
12
+ # Retrieve an Account Statement
13
+ retrieve
14
+ end
15
+ end
@@ -4,10 +4,18 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class AccountTransfers < Resource
7
+ NAME = "Account Transfers"
8
+ API_NAME = "account_transfers"
9
+
10
+ # Create an Account Transfer
7
11
  create
12
+ # List Account Transfers
8
13
  list
14
+ # Retrieve an Account Transfer
9
15
  retrieve
10
- endpoint :approve, :post, with: :id
11
- endpoint :cancel, :post, with: :id
16
+ # Approve an Account Transfer
17
+ endpoint :approve, :post, path: [:account_transfer_id, "approve"]
18
+ # Cancel an Account Transfer
19
+ endpoint :cancel, :post, path: [:account_transfer_id, "cancel"]
12
20
  end
13
21
  end
@@ -4,10 +4,18 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class Accounts < Resource
7
+ NAME = "Accounts"
8
+ API_NAME = "accounts"
9
+
10
+ # Create an Account
7
11
  create
12
+ # List Accounts
8
13
  list
14
+ # Update an Account
9
15
  update
16
+ # Retrieve an Account
10
17
  retrieve
11
- endpoint :close, :post, with: :id
18
+ # Close an Account
19
+ endpoint :close, :post, path: [:account_id, "close"]
12
20
  end
13
21
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class AchPrenotifications < Resource
7
+ NAME = "ACH Prenotifications"
8
+ API_NAME = "ach_prenotifications"
9
+
10
+ # Create an ACH Prenotification
11
+ create
12
+ # List ACH Prenotifications
13
+ list
14
+ # Retrieve an ACH Prenotification
15
+ retrieve
16
+ end
17
+ end
@@ -4,10 +4,18 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class AchTransfers < Resource
7
+ NAME = "ACH Transfers"
8
+ API_NAME = "ach_transfers"
9
+
10
+ # Create an ACH Transfer
7
11
  create
12
+ # List ACH Transfers
8
13
  list
14
+ # Retrieve an ACH Transfer
9
15
  retrieve
10
- endpoint :approve, :post, with: :id
11
- endpoint :cancel, :post, with: :id
16
+ # Approve an ACH Transfer
17
+ endpoint :approve, :post, path: [:ach_transfer_id, "approve"]
18
+ # Cancel a pending ACH Transfer
19
+ endpoint :cancel, :post, path: [:ach_transfer_id, "cancel"]
12
20
  end
13
21
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class CardDisputes < Resource
7
+ NAME = "Card Disputes"
8
+ API_NAME = "card_disputes"
9
+
10
+ # Create a Card Dispute
11
+ create
12
+ # List Card Disputes
13
+ list
14
+ # Retrieve a Card Dispute
15
+ retrieve
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class CardProfiles < Resource
7
+ NAME = "Card Profiles"
8
+ API_NAME = "card_profiles"
9
+
10
+ # Create a Card Profile
11
+ create
12
+ # List Card Profiles
13
+ list
14
+ # Retrieve a Card Profile
15
+ retrieve
16
+ end
17
+ end
@@ -4,10 +4,18 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class Cards < Resource
7
+ NAME = "Cards"
8
+ API_NAME = "cards"
9
+
10
+ # Create a Card
7
11
  create
12
+ # List Cards
8
13
  list
9
- endpoint :details, :get, with: :id
14
+ # Retrieve sensitive details for a Card
15
+ endpoint :details, :get, path: [:card_id, "details"]
16
+ # Update a Card
10
17
  update
18
+ # Retrieve a Card
11
19
  retrieve
12
20
  end
13
21
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class CheckDeposits < Resource
7
+ NAME = "Check Deposits"
8
+ API_NAME = "check_deposits"
9
+
10
+ # Create a Check Deposit
11
+ create
12
+ # List Check Deposits
13
+ list
14
+ # Retrieve a Check Deposit
15
+ retrieve
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class CheckTransfers < Resource
7
+ NAME = "Check Transfers"
8
+ API_NAME = "check_transfers"
9
+
10
+ # Create a Check Transfer
11
+ create
12
+ # List Check Transfers
13
+ list
14
+ # Retrieve a Check Transfer
15
+ retrieve
16
+ # Approve a Check Transfer
17
+ endpoint :approve, :post, path: [:check_transfer_id, "approve"]
18
+ # Cancel a pending Check Transfer
19
+ endpoint :cancel, :post, path: [:check_transfer_id, "cancel"]
20
+ # Request a stop payment on a Check Transfer
21
+ endpoint :stop_payment, :post, path: [:check_transfer_id, "stop_payment"]
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class DeclinedTransactions < Resource
7
+ NAME = "Declined Transactions"
8
+ API_NAME = "declined_transactions"
9
+
10
+ # List Declined Transactions
11
+ list
12
+ # Retrieve a Declined Transaction
13
+ retrieve
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class DigitalWalletTokens < Resource
7
+ NAME = "Digital Wallet Tokens"
8
+ API_NAME = "digital_wallet_tokens"
9
+
10
+ # List Digital Wallet Tokens
11
+ list
12
+ # Retrieve a Digital Wallet Token
13
+ retrieve
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class Documents < Resource
7
+ NAME = "Documents"
8
+ API_NAME = "documents"
9
+
10
+ # List Documents
11
+ list
12
+ # Retrieve a Document
13
+ retrieve
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class Entities < Resource
7
+ NAME = "Entities"
8
+ API_NAME = "entities"
9
+
10
+ # Create an Entity
11
+ create
12
+ # List Entities
13
+ list
14
+ # Retrieve an Entity
15
+ retrieve
16
+ # Create a supplemental document for an Entity
17
+ endpoint :supplemental_documents, :post, path: [:entity_id, "supplemental_documents"]
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class EventSubscriptions < Resource
7
+ NAME = "Event Subscriptions"
8
+ API_NAME = "event_subscriptions"
9
+
10
+ # Create an Event Subscription
11
+ create
12
+ # List Event Subscriptions
13
+ list
14
+ # Update an Event Subscription
15
+ update
16
+ # Retrieve an Event Subscription
17
+ retrieve
18
+ end
19
+ end
@@ -4,7 +4,12 @@ require "increase/resource"
4
4
 
5
5
  module Increase
6
6
  class Events < Resource
7
+ NAME = "Events"
8
+ API_NAME = "events"
9
+
10
+ # List Events
7
11
  list
12
+ # Retrieve an Event
8
13
  retrieve
9
14
  end
10
15
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class ExternalAccounts < Resource
7
+ NAME = "External Accounts"
8
+ API_NAME = "external_accounts"
9
+
10
+ # Create an External Account
11
+ create
12
+ # List External Accounts
13
+ list
14
+ # Update an External Account
15
+ update
16
+ # Retrieve an External Account
17
+ retrieve
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class Files < Resource
7
+ NAME = "Files"
8
+ API_NAME = "files"
9
+
10
+ # Create a File
11
+ endpoint :create, :post, with: :file_upload
12
+ # List Files
13
+ list
14
+ # Retrieve a File
15
+ retrieve
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class Groups < Resource
7
+ NAME = "Groups"
8
+ API_NAME = "groups"
9
+
10
+ # Retrieve Group details
11
+ endpoint :current, :get, path: "current"
12
+ end
13
+ end