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.
- checksums.yaml +4 -4
- data/OPENAPI_VERSION +1 -0
- data/README.md +156 -48
- data/bin/generate +152 -0
- data/bin/setup +8 -0
- data/generate/resource.rb.erb +18 -0
- data/lib/increase/client.rb +2 -0
- data/lib/increase/configuration.rb +1 -1
- data/lib/increase/file_upload.rb +50 -0
- data/lib/increase/resource.rb +85 -119
- data/lib/increase/resources/account_numbers.rb +7 -0
- data/lib/increase/resources/account_statements.rb +15 -0
- data/lib/increase/resources/account_transfers.rb +10 -2
- data/lib/increase/resources/accounts.rb +9 -1
- data/lib/increase/resources/ach_prenotifications.rb +17 -0
- data/lib/increase/resources/ach_transfers.rb +10 -2
- data/lib/increase/resources/card_disputes.rb +17 -0
- data/lib/increase/resources/card_profiles.rb +17 -0
- data/lib/increase/resources/cards.rb +9 -1
- data/lib/increase/resources/check_deposits.rb +17 -0
- data/lib/increase/resources/check_transfers.rb +12 -3
- data/lib/increase/resources/declined_transactions.rb +15 -0
- data/lib/increase/resources/digital_wallet_tokens.rb +15 -0
- data/lib/increase/resources/documents.rb +15 -0
- data/lib/increase/resources/entities.rb +19 -0
- data/lib/increase/resources/event_subscriptions.rb +19 -0
- data/lib/increase/resources/events.rb +5 -0
- data/lib/increase/resources/external_accounts.rb +19 -0
- data/lib/increase/resources/files.rb +17 -0
- data/lib/increase/resources/groups.rb +13 -0
- data/lib/increase/resources/inbound_ach_transfer_returns.rb +17 -0
- data/lib/increase/resources/inbound_wire_drawdown_requests.rb +15 -0
- data/lib/increase/resources/limits.rb +7 -0
- data/lib/increase/resources/oauth_connections.rb +15 -0
- data/lib/increase/resources/pending_transactions.rb +5 -0
- data/lib/increase/resources/real_time_decisions.rb +15 -0
- data/lib/increase/resources/routing_numbers.rb +4 -0
- data/lib/increase/resources/transactions.rb +5 -0
- data/lib/increase/resources/wire_drawdown_requests.rb +17 -0
- data/lib/increase/resources/wire_transfers.rb +21 -0
- data/lib/increase/response_array.rb +19 -0
- data/lib/increase/version.rb +1 -1
- data/lib/increase/webhook/signature.rb +9 -1
- data/lib/increase.rb +2 -1
- data/openapi.json +32098 -0
- metadata +74 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a945cde9440a62a76cd7a95c5bc91b7dfea452fada50349e3d749c6fc95fa72e
|
|
4
|
+
data.tar.gz: b6ce6f53d72e35e027287feff54fc47c7e855fa364fc11040646efd92c8ce028
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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: '
|
|
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 (
|
|
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
|
-
|
|
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
|
|
71
|
-
|
|
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
|
-
|
|
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
|
|
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('
|
|
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
|
|
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
|
|
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
|
|
132
|
+
puts e.response # This contains the full response, including headers!
|
|
133
|
+
# => #<Faraday::Response:0x000000010b1fe2b0 ...>
|
|
102
134
|
|
|
103
|
-
puts e.class # Increase::ObjectNotFoundError (
|
|
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
|
|
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('
|
|
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
|
|
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
|
-
|
|
150
|
-
|
|
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
|
|
157
|
-
required, it's strongly recommended
|
|
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**
|
|
189
|
-
|
|
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
|
-
|
|
206
|
-
# =>
|
|
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
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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,
|
|
217
|
-
|
|
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
|
|
220
|
-
|
|
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
|
|
225
|
-
|
|
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
|
|
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
|
|
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
|
|
243
|
-
by [Gary Tou](https://garytou.com/)
|
|
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,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
|
data/lib/increase/client.rb
CHANGED
|
@@ -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
|
|
@@ -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
|