increase 0.1.3 → 0.3.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/OPENAPI_VERSION +1 -0
  3. data/README.md +156 -48
  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/file_upload.rb +50 -0
  10. data/lib/increase/resource.rb +85 -119
  11. data/lib/increase/resources/account_numbers.rb +7 -0
  12. data/lib/increase/resources/account_statements.rb +15 -0
  13. data/lib/increase/resources/account_transfers.rb +10 -2
  14. data/lib/increase/resources/accounts.rb +9 -1
  15. data/lib/increase/resources/ach_prenotifications.rb +17 -0
  16. data/lib/increase/resources/ach_transfers.rb +10 -2
  17. data/lib/increase/resources/card_disputes.rb +17 -0
  18. data/lib/increase/resources/card_profiles.rb +17 -0
  19. data/lib/increase/resources/cards.rb +9 -1
  20. data/lib/increase/resources/check_deposits.rb +17 -0
  21. data/lib/increase/resources/check_transfers.rb +12 -3
  22. data/lib/increase/resources/declined_transactions.rb +15 -0
  23. data/lib/increase/resources/digital_wallet_tokens.rb +15 -0
  24. data/lib/increase/resources/documents.rb +15 -0
  25. data/lib/increase/resources/entities.rb +19 -0
  26. data/lib/increase/resources/event_subscriptions.rb +19 -0
  27. data/lib/increase/resources/events.rb +5 -0
  28. data/lib/increase/resources/external_accounts.rb +19 -0
  29. data/lib/increase/resources/files.rb +17 -0
  30. data/lib/increase/resources/groups.rb +13 -0
  31. data/lib/increase/resources/inbound_ach_transfer_returns.rb +17 -0
  32. data/lib/increase/resources/inbound_wire_drawdown_requests.rb +15 -0
  33. data/lib/increase/resources/limits.rb +7 -0
  34. data/lib/increase/resources/oauth_connections.rb +15 -0
  35. data/lib/increase/resources/pending_transactions.rb +5 -0
  36. data/lib/increase/resources/real_time_decisions.rb +15 -0
  37. data/lib/increase/resources/routing_numbers.rb +4 -0
  38. data/lib/increase/resources/transactions.rb +5 -0
  39. data/lib/increase/resources/wire_drawdown_requests.rb +17 -0
  40. data/lib/increase/resources/wire_transfers.rb +21 -0
  41. data/lib/increase/response_array.rb +19 -0
  42. data/lib/increase/version.rb +1 -1
  43. data/lib/increase/webhook/signature.rb +9 -1
  44. data/lib/increase.rb +2 -1
  45. data/openapi.json +32098 -0
  46. metadata +74 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5dab8c774d39cce112627bc75d36a10947419d640db56e45dfc4f2cd75330656
4
- data.tar.gz: a93d12bf1e5a64938dcf41b339a1de33c36c82ad8b5430169156cb868e0cf87a
3
+ metadata.gz: a945cde9440a62a76cd7a95c5bc91b7dfea452fada50349e3d749c6fc95fa72e
4
+ data.tar.gz: b6ce6f53d72e35e027287feff54fc47c7e855fa364fc11040646efd92c8ce028
5
5
  SHA512:
6
- metadata.gz: f74f1fd78799702a1dfed5180e93155ca7595a4f8d758545e483f3aee5db6cac853ff044fe043bcc33918eb85dd17c4544ea359654adfa1b52448240e1a38d42
7
- data.tar.gz: ce8aacf00abb9d1660cff928a80ecc5f74900f6ea998cb47a512dedb080cfd252740e4c7f15d982580dae0f026c172948d3948fcbd9438a0348e6b8dd2ee28f6
6
+ metadata.gz: 30fb2ded08ba6aa27adfa4f85932e941d4e727ae069ab8df915c2dd001cdd35779b8b58090e29695100270ec66da45cd6d495efdd0b7acc4bf747473b3a5970a
7
+ data.tar.gz: 5a591e007db71c14a1a4e827650bea8a6eda56d68e248eb2988e02380c6de4ccdc5054963c09bda8f2797c36a7dc148fb5a14de58105ff535cbc56bd137f7698
data/OPENAPI_VERSION ADDED
@@ -0,0 +1 @@
1
+ v0.0.1
data/README.md CHANGED
@@ -1,19 +1,32 @@
1
1
  # Increase
2
2
 
3
- A Ruby API client for [Increase](https://increase.com/), a platform for Bare-Metal Banking APIs!
3
+ A Ruby API client for [Increase](https://increase.com/), a platform for
4
+ Bare-Metal Banking APIs!
5
+
6
+ - [Installation](#installation)
7
+ - [Usage](#usage)
8
+ - [Per-request Configuration](#per-request-configuration)
9
+ - [Pagination](#pagination)
10
+ - [Error Handling](#error-handling)
11
+ - [Configuration](#configuration)
12
+ - [File Uploads](#file-uploads)
13
+ - [Webhooks](#webhooks)
14
+ - [Idempotency](#idempotency)
15
+ - [Development](#development)
4
16
 
5
17
  ## Installation
6
18
 
7
19
  Install the gem and add to the application's Gemfile by executing:
8
20
 
9
21
  ```sh
10
- $ bundle add increase
22
+ $ bundle add increase -v 0.3.0
11
23
  ```
12
24
 
13
- If bundler is not being used to manage dependencies, install the gem by executing:
25
+ If bundler is not being used to manage dependencies, install the gem by
26
+ executing:
14
27
 
15
28
  ```sh
16
- $ gem install increase
29
+ $ gem install increase -v 0.3.0
17
30
  ```
18
31
 
19
32
  ## Usage
@@ -43,32 +56,42 @@ Increase::AchTransfers.create(
43
56
 
44
57
  ### Per-request Configuration
45
58
 
46
- By default, the client will use the global API key and configurations. However, you can define a custom client to be
47
- used for per-request configuration.
59
+ By default, the client will use the global API key and configurations. However,
60
+ you can define a custom client to be used for per-request configuration.
48
61
 
49
- For example, you may want to have access to production and sandbox data at the same.
62
+ For example, you may want access to production and sandbox data at the same
63
+ time.
50
64
 
51
65
  ```ruby
52
66
  sandbox = Increase::Client.new(
53
- api_key: 'time_is_money',
67
+ api_key: 'playing_it_safe',
54
68
  base_url: 'https://sandbox.increase.com'
55
69
  )
56
70
 
57
71
  # This request will use the `sandbox` client and its configurations
58
72
  Increase::Transactions.with_config(sandbox).list
59
- # => [{some sandbox transactions here}, {transaction}, {transaction}]
73
+ # => [{some sandbox transactions here}, {transaction}, {transaction}, ...]
60
74
 
61
- # This request will still use the global configurations (where the API key is a production key)
75
+ # This request will still use the global configurations (using production key)
62
76
  Increase::Transactions.list
63
- # => [{some production transactions here}, {transaction}, {transaction}]
77
+ # => [{some production transactions here}, {transaction}, {transaction}, ...]
64
78
  ```
65
79
 
66
- See the [Configuration](#configuration) section for more information on the available configurations.
80
+ Alternatively, directly passing as hash to `with_config` works too!
81
+
82
+ ```ruby
83
+ Increase::Transactions.with_config(api_key: 'time_is_money', base_url: :sandbox).list
84
+ # => [{some sandbox transactions here}, {transaction}, {transaction}, ...]
85
+ ```
86
+
87
+ See the [Configuration](#configuration) section for more information on the
88
+ available configurations.
67
89
 
68
90
  ### Pagination
69
91
 
70
- When listing resources (e.g. transactions), **Increase** limits the number of results per page to 100. Luckily, the
71
- client will automatically paginate through all the results for you!
92
+ When listing resources (e.g. transactions), **Increase** limits the number of
93
+ results per page to 100. Luckily, the client will automatically paginate through
94
+ all the results for you!
72
95
 
73
96
  ```ruby
74
97
  Increase::Transactions.list(limit: :all) do |transactions|
@@ -78,38 +101,48 @@ end
78
101
 
79
102
  # Or, if you'd like a gargantuan array of all the transactions
80
103
  Increase::Transactions.list(limit: :all)
81
- Increase::Transactions.list(limit: 2_000)
104
+
105
+ # You can also use the `next_cursor` to manually paginate through the results
106
+ txns = Increase::Transactions.list(
107
+ limit: 2_000,
108
+ 'created_at.after': '2022-01-15T06:34:23Z'
109
+ )
110
+ # => [{transaction}, {transaction}, {transaction}, ...]
111
+ txns.next_cursor
112
+ # => "eyJwb2NpdGlvbiI6eyJvZmlzZXQiOjEwMH0sIm3pbHRlclI6e319"
82
113
  ```
83
114
 
84
115
  Watch out for the rate limit!
85
116
 
86
117
  ### Error Handling
87
118
 
88
- Whenever you make an oopsies, the client will raise an error! Errors originating from the API will be a subclass
89
- of `Increase::ApiError`.
119
+ Whenever you make an oopsie, the client will raise an error! Errors originating
120
+ from the API will be a subclass of `Increase::ApiError`.
90
121
 
91
122
  ```ruby
92
123
 
93
124
  begin
94
- Increase::Transactions.retrieve('transaction_1234abcd')
125
+ Increase::Transactions.retrieve('i_dont_exist')
95
126
  rescue Increase::ApiError => e
96
- puts e.message # "[404: object_not_found_error] Could not find the specified object. No resource of type ..."
127
+ puts e.message # "[404: object_not_found_error] Could not find the ..."
97
128
  puts e.title # "Could not find the specified object."
98
- puts e.detail # "No resource of type transaction was found with ID transaction_1234abcd."
129
+ puts e.detail # "No resource of type transaction was found with ID ..."
99
130
  puts e.status # 404
100
131
 
101
- puts e.response # This contains the full response from the API, including headers! (its a Faraday::Response object)
132
+ puts e.response # This contains the full response, including headers!
133
+ # => #<Faraday::Response:0x000000010b1fe2b0 ...>
102
134
 
103
- puts e.class # Increase::ObjectNotFoundError (it's a subclass of Increase::ApiError!)
135
+ puts e.class # Increase::ObjectNotFoundError (subclass of Increase::ApiError)
104
136
  end
105
137
  ```
106
138
 
107
- To disable this behavior, set `Increase.raise_api_errors = false`. Errors will then be returned as a normal response.
139
+ To disable this behavior, set `Increase.raise_api_errors = false`. Errors will
140
+ then be returned as a normal response.
108
141
 
109
142
  ```ruby
110
143
  Increase.raise_api_errors = false # Default: true
111
144
 
112
- Increase::Transactions.retrieve('transaction_1234abcd')
145
+ Increase::Transactions.retrieve('i_dont_exist')
113
146
  # => {"status"=>404, "type"=>"object_not_found_error", ... }
114
147
  ```
115
148
 
@@ -140,21 +173,80 @@ Increase.configure do |config|
140
173
  end
141
174
  ```
142
175
 
143
- If you are using Rails, the recommended way is to set your configurations as a block in an initializer.
176
+ If you are using Rails, the recommended way is to set your configurations as a
177
+ block in an initializer.
144
178
 
145
179
  ```ruby
146
180
  # config/initializers/increase.rb
147
181
 
148
182
  Increase.configure do |config|
149
- config.api_key = 'money_cant_buy_happiness'
150
- config.base_url = :production
183
+ # Your Increase API Key!
184
+ # Grab it from https://dashboard.increase.com/developers/api_keys
185
+ config.api_key = Rails.application.credentials.dig(:increase, :api_key)
186
+
187
+ # The base URL for Increase's API.
188
+ # You can use
189
+ # - :production (https://api.increase.com)
190
+ # - :sandbox (https://sandbox.increase.com)
191
+ # - or set an actual URL
192
+ config.base_url = Rails.env.production? ? :production : :sandbox
193
+
194
+ # Whether to raise an error when the API returns a non-2XX status.
195
+ # If disabled (false), the client will return the error response as a normal,
196
+ # instead of raising an error.
197
+ #
198
+ # Learn more about...
199
+ # - Increase's errors: https://increase.com/documentation/api#errors
200
+ # - Error classes: https://github.com/garyhtou/increase-ruby/blob/main/lib/increase/errors.rb
201
+ config.raise_api_errors = true # Default: true
151
202
  end
152
203
  ```
153
204
 
205
+ ### File Uploads
206
+
207
+ It's as simple as passing in a file path!
208
+
209
+ ```ruby
210
+ Increase::Files.create(
211
+ purpose: 'identity_document',
212
+ file: '/path/to/file.jpg'
213
+ )
214
+ ```
215
+
216
+ Alternatively, you can pass in a `File` object.
217
+
218
+ ```ruby
219
+ file = File.open('/path/to/file.jpg')
220
+
221
+ Increase::Files.create(
222
+ purpose: 'identity_document',
223
+ file: file
224
+ )
225
+ ```
226
+
227
+ Or, get even fancier and use `Increase::FileUpload` to specify the content type
228
+ and filename.
229
+
230
+ ```ruby
231
+ file = Increase::FileUpload.new(
232
+ '/path/to/file.jpg',
233
+ content_type: 'image/jpeg',
234
+ filename: 'my_file.jpg'
235
+ )
236
+
237
+ Increase::Files.create(
238
+ purpose: 'identity_document',
239
+ file: file
240
+ )
241
+ ```
242
+
243
+ If no content type or filename is provided, the client will try to guess it.
244
+
154
245
  ### Webhooks
155
246
 
156
- **Increase**'s webhooks include a `Increase-Webhook-Signature` header for securing your webhook endpoint. Although not
157
- required, it's strongly recommended that you verify the signature to ensure the request is coming from **Increase**.
247
+ **Increase**'s webhooks include a `Increase-Webhook-Signature` header for
248
+ securing your webhook endpoint. Although not required, it's strongly recommended
249
+ that you verify the signature to ensure the request is coming from **Increase**.
158
250
 
159
251
  Here is an example for Rails.
160
252
 
@@ -168,7 +260,7 @@ class IncreaseController < ApplicationController
168
260
  sig_header = request.headers['Increase-Webhook-Signature']
169
261
  secret = Rails.application.credentials.dig(:increase, :webhook_secret)
170
262
 
171
- Increase::Webhook::Signature.verify?(
263
+ Increase::Webhook::Signature.verify(
172
264
  payload: payload,
173
265
  signature_header: sig_header,
174
266
  secret: secret
@@ -177,6 +269,7 @@ class IncreaseController < ApplicationController
177
269
  # It's a valid webhook! Do something with it...
178
270
 
179
271
  render json: {success: true}
272
+
180
273
  rescue Increase::WebhookSignatureVerificationError => e
181
274
  render json: {error: 'Webhook signature verification failed'}, status: :bad_request
182
275
  end
@@ -185,8 +278,10 @@ end
185
278
 
186
279
  ### Idempotency
187
280
 
188
- **Increase** supports [idempotent requests](https://increase.com/documentation/api#idempotency) to allow for safely
189
- retrying requests without accidentally performing the same operation twice.
281
+ **Increase**
282
+ supports [idempotent requests](https://increase.com/documentation/api#idempotency)
283
+ to allow for safely retrying requests without accidentally performing the same
284
+ operation twice.
190
285
 
191
286
  ```ruby
192
287
  card = Increase::Cards.create(
@@ -202,35 +297,48 @@ card = Increase::Cards.create(
202
297
  )
203
298
  # => {"id"=>"card_1234abcd", "type"=>"card", ... }
204
299
 
205
- idempotent_replayed = card.response.headers['Idempotent-Replayed']
206
- # => "false"
300
+ card.idempotent_replayed
301
+ # => nil
302
+
303
+ # Repeat the exact same request
304
+ card = Increase::Cards.create(...)
305
+ # => {"id"=>"card_1234abcd", "type"=>"card", ... }
306
+
307
+ card.idempotent_replayed
308
+ # => "true"
207
309
  ```
208
310
 
209
- Reusing the key in subsequent requests will return the same response code and body as the original request along with an
210
- additional HTTP header (Idempotent-Replayed: true). This applies to both success and error responses. In situations
211
- where your request results in a validation error, you'll need to update your request and retry with a new idempotency
212
- key.
311
+ Reusing the key in subsequent requests will return the same response code and
312
+ body as the original request along with an additional HTTP
313
+ header (`Idempotent-Replayed: true`). This applies to both success and error
314
+ responses. In situations where your request results in a validation error,
315
+ you'll need to update your request and retry with a new idempotency key.
213
316
 
214
317
  ## Development
215
318
 
216
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
217
- also run `bin/console` for an interactive prompt that will allow you to experiment.
319
+ After checking out the repo, run `bin/setup` to install dependencies. Then,
320
+ run `rake spec` to run the tests. You can also run `bin/console` for an
321
+ interactive prompt that will allow you to experiment.
218
322
 
219
- You can also run `INCREASE_API_KEY=my_key_here INCREASE_BASE_URL=https://sandbox.increase.com bin/console` to run the
220
- console with your Increase sandbox API key pre-filled.
323
+ You can also
324
+ run `INCREASE_API_KEY=my_key_here INCREASE_BASE_URL=https://sandbox.increase.com bin/console`
325
+ to run the console with your Increase sandbox API key pre-filled.
221
326
 
222
327
  To install this gem onto your local machine, run `bundle exec rake install`.
223
328
 
224
- To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will
225
- create a git tag for the version, push git commits and the created tag, and push the `.gem` file
329
+ To release a new version, update the version number in `version.rb`, and then
330
+ run `bundle exec rake release`, which will create a git tag for the version,
331
+ push git commits and the created tag, and push the `.gem` file
226
332
  to [rubygems.org](https://rubygems.org).
227
333
 
228
334
  Alternatively, use [`gem-release`](https://github.com/svenfuchs/gem-release) and
229
- run `gem bump --version patch|minor|major`. Then release the gem by running `bundle exec rake release`.
335
+ run `gem bump --version patch|minor|major`. Then release the gem by
336
+ running `bundle exec rake release`.
230
337
 
231
338
  ## Contributing
232
339
 
233
- Bug reports and pull requests are welcome on GitHub at https://github.com/garyhtou/increase.
340
+ Bug reports and pull requests are welcome on GitHub
341
+ at https://github.com/garyhtou/increase.
234
342
 
235
343
  ## License
236
344
 
@@ -239,5 +347,5 @@ the [MIT License](https://github.com/garyhtou/increase-ruby/blob/main/LICENSE.tx
239
347
 
240
348
  ---
241
349
 
242
- Please note that this is not an official library written by **Increase**. Its written and maintained
243
- by [Gary Tou](https://garytou.com/) who just uses Increase at work!
350
+ Please note that this is not an official library by **Increase**. This gem was
351
+ created and maintained by [Gary Tou](https://garytou.com/).
data/bin/generate ADDED
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # OpenAPI client generators for Ruby seem to be a bit of a mess. I'm
5
+ # essentially writing my own crude generator here. It's not perfect, but it
6
+ # gets the job done :)
7
+
8
+ require 'bundler/setup'
9
+ require 'irb'
10
+
11
+ require 'json'
12
+ require 'erb'
13
+ require 'ostruct'
14
+ require 'pry'
15
+
16
+ spec = JSON.parse(File.read('openapi.json'))
17
+
18
+ # Parse OpenAPI spec
19
+ resources = Hash.new { |h, k| h[k] = [] } # Default value of new keys is []
20
+ spec['paths'].each do |path, methods|
21
+ methods.each do |method, details|
22
+ name = details['x-tag'] # Resource name
23
+
24
+ endpoint = {
25
+ http_method: method.to_sym,
26
+ path: path.split('/').reject(&:empty?),
27
+ operation: details['operationId'].split('_').first.downcase,
28
+
29
+ # Extra info
30
+ details: details,
31
+ }
32
+
33
+ # Convert path params to symbols
34
+ path_params = details['parameters'].select { |p| p['in'] == 'path' }
35
+ endpoint[:path].map! do |p|
36
+ # Find path param for this segment
37
+ param = path_params.find { |param| "{#{param['name']}}" == p }
38
+ param ? param['name'].to_sym : p
39
+ end
40
+
41
+ # Handle case for "/groups/current".
42
+ # Changes operation from :retrieve to :current
43
+ if endpoint[:path].size > 1 && endpoint[:path].last.is_a?(String)
44
+ endpoint[:operation] = endpoint[:path].last.to_sym
45
+ end
46
+
47
+ # Add endpoint to resource
48
+ resources[name] << endpoint
49
+ end
50
+ end
51
+
52
+ # Write OpenAPI version to file
53
+ api_version = spec['info']['version']
54
+ File.open('OPENAPI_VERSION', 'w') do |file|
55
+ file.write("v#{api_version}")
56
+ end
57
+
58
+ # Clear resources directory
59
+ Dir.glob('lib/increase/resources/*.rb').each do |file|
60
+ File.delete(file)
61
+ end
62
+
63
+ # Generate code
64
+ OPERATION_ALIASES = [
65
+ {
66
+ name: 'create',
67
+ operation: 'create',
68
+ http_method: :post,
69
+ path_regex: /^\w+$/
70
+ },
71
+ {
72
+ name: 'list',
73
+ operation: 'list',
74
+ http_method: :get,
75
+ path_regex: /^\w+$/
76
+ },
77
+ {
78
+ name: 'update',
79
+ operation: 'update',
80
+ http_method: :patch,
81
+ path_regex: /^\w+\/\w+_id$/
82
+ },
83
+ {
84
+ name: 'retrieve',
85
+ operation: 'retrieve',
86
+ http_method: :get,
87
+ path_regex: /^\w+\/\w+_id$/
88
+ }
89
+ ]
90
+
91
+ template = File.read('generate/resource.rb.erb')
92
+ render = ERB.new(template, trim_mode: '-')
93
+
94
+ resources.delete('Simulations') # TODO
95
+
96
+ resources.each do |name, operations|
97
+ # Convert name to class name (pascal case with no special characters)
98
+ class_name = name.split(/[\s\W]/).map(&:capitalize).join
99
+
100
+ # Resource type
101
+ resource_type = operations.first[:path].first
102
+
103
+ # Format operations
104
+ ops = operations.each do |op|
105
+ # Try to find an alias for this operation
106
+ op_alias = OPERATION_ALIASES.find do |alias_op|
107
+ op[:operation] == alias_op[:operation] &&
108
+ op[:http_method] == alias_op[:http_method] &&
109
+ alias_op[:path_regex].match(op[:path].join('/'))
110
+ end
111
+ op.merge!(alias: op_alias&.dig(:name))
112
+
113
+ # Check to make sure path doesn't not contain more than 1 param
114
+ if op[:path].select { |p| p.is_a?(Symbol) }.size > 1
115
+ raise StandardError, "Multiple path params for #{name} #{op[:path].inspect}"
116
+ end
117
+
118
+ # Remove resource root path segment
119
+ op[:path].shift
120
+ if op[:path].size == 1
121
+ op[:path] = op[:path].first
122
+ end
123
+ end
124
+
125
+ # Check operation uniqueness
126
+ if ops.map { |op| op[:operation] }.uniq.size != ops.size
127
+ raise StandardError, "Duplicate operations for #{name}"
128
+ end
129
+
130
+ # Render template
131
+ namespace = OpenStruct.new(
132
+ class_name: class_name,
133
+ name: name,
134
+ api_name: resource_type,
135
+ operations: ops
136
+ )
137
+ contents = render.result(namespace.instance_eval { binding })
138
+
139
+ # Write to file
140
+ File.open("lib/increase/resources/#{resource_type}.rb", 'w') do |file|
141
+ file.write(contents)
142
+ end
143
+
144
+ # Print messages
145
+ puts "Generated #{class_name}"
146
+ ops.each do |op|
147
+ puts " #{op[:operation]}"
148
+ end
149
+ puts
150
+ end
151
+
152
+ raise "TODO Reminder: Handle special case for Increase::Files.create"
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "increase/resource"
4
+
5
+ module Increase
6
+ class <%= class_name %> < Resource
7
+ NAME = <%= name.inspect %>
8
+ API_NAME = <%= api_name.inspect %>
9
+
10
+ <%- operations.each do |op| -%>
11
+ # <%= op[:details]['summary'] %>
12
+ <%- if op[:alias] -%>
13
+ <%= op[:alias] -%>
14
+ <%- else -%>
15
+ endpoint <%= op[:operation].inspect %>, <%= op[:http_method].inspect %>, path: <%= op[:path].inspect -%>
16
+ <%- end -%><%# close if %>
17
+ <%- end %><%# close loop %> end
18
+ end
@@ -4,6 +4,7 @@ require "increase/configuration"
4
4
 
5
5
  require "faraday"
6
6
  require "faraday/follow_redirects"
7
+ require "faraday/multipart"
7
8
 
8
9
  # Custom Faraday Middleware to handle raising errors
9
10
  require "faraday/raise_increase_api_error"
@@ -32,6 +33,7 @@ module Increase
32
33
  }
33
34
  ) do |f|
34
35
  f.request :json
36
+ f.request :multipart
35
37
 
36
38
  if @configuration.raise_api_errors
37
39
  # This custom middleware for raising Increase API errors must be
@@ -22,7 +22,7 @@ module Increase
22
22
  if config.is_a?(Hash)
23
23
  config.each do |key, value|
24
24
  unless respond_to?("#{key}=")
25
- raise Error, "Invalid configuration key: #{key}"
25
+ raise ArgumentError, "Invalid configuration: #{key}"
26
26
  end
27
27
  public_send("#{key}=", value)
28
28
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tempfile'
4
+ require 'marcel'
5
+ require 'faraday'
6
+ require 'pathname'
7
+
8
+ module Increase
9
+ class FileUpload
10
+ attr_reader :file, :filename, :content_type
11
+
12
+ def initialize(file_or_path, filename: nil, content_type: nil)
13
+ @filename = filename
14
+ @content_type = content_type
15
+
16
+ if file_or_path.is_a?(File) || file_or_path.is_a?(Tempfile)
17
+ @file = file_or_path
18
+ @filename ||= File.basename(file_or_path.path)
19
+ elsif file_or_path.is_a?(String)
20
+ # Treat string as a filepath
21
+ @file = File.open(file_or_path)
22
+ @filename ||= File.basename(file_or_path)
23
+ elsif file_or_path.respond_to?(:read)
24
+ @file = Tempfile.new(default_filename)
25
+ @file.write(file_or_path.read)
26
+ else
27
+ raise ArgumentError, "File or path required"
28
+ end
29
+
30
+ # Try to guess content type
31
+ @content_type ||= Marcel::MimeType.for(@file, name: @filename)
32
+ @filename ||= default_filename
33
+ end
34
+
35
+ def file_part
36
+ Faraday::Multipart::FilePart.new(
37
+ @file,
38
+ @content_type,
39
+ @filename
40
+ )
41
+ end
42
+
43
+ private
44
+
45
+ def default_filename
46
+ "file upload #{Time.now}"
47
+ end
48
+
49
+ end
50
+ end