recurly 3.4.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.bumpversion.cfg +5 -1
- data/.github/workflows/docs.yml +28 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +107 -13
- data/GETTING_STARTED.md +61 -1
- data/README.md +1 -1
- data/lib/recurly/client.rb +126 -52
- data/lib/recurly/client/operations.rb +314 -1
- data/lib/recurly/http.rb +3 -2
- data/lib/recurly/pager.rb +31 -12
- data/lib/recurly/requests/add_on_create.rb +15 -3
- data/lib/recurly/requests/add_on_update.rb +9 -1
- data/lib/recurly/requests/billing_info_create.rb +26 -2
- data/lib/recurly/requests/external_transaction.rb +26 -0
- data/lib/recurly/requests/plan_create.rb +8 -0
- data/lib/recurly/requests/plan_update.rb +8 -0
- data/lib/recurly/requests/shipping_method_create.rb +26 -0
- data/lib/recurly/requests/shipping_method_update.rb +26 -0
- data/lib/recurly/requests/subscription_add_on_create.rb +9 -1
- data/lib/recurly/requests/subscription_add_on_tier.rb +18 -0
- data/lib/recurly/requests/subscription_add_on_update.rb +6 -2
- data/lib/recurly/requests/subscription_change_create.rb +1 -1
- data/lib/recurly/requests/tier.rb +18 -0
- data/lib/recurly/resources/add_on.rb +8 -0
- data/lib/recurly/resources/line_item.rb +1 -1
- data/lib/recurly/resources/payment_method.rb +4 -0
- data/lib/recurly/resources/plan.rb +8 -0
- data/lib/recurly/resources/shipping_method.rb +4 -0
- data/lib/recurly/resources/subscription_add_on.rb +16 -0
- data/lib/recurly/resources/subscription_add_on_tier.rb +18 -0
- data/lib/recurly/resources/subscription_change_preview.rb +74 -0
- data/lib/recurly/resources/tier.rb +18 -0
- data/lib/recurly/resources/transaction.rb +4 -0
- data/lib/recurly/version.rb +1 -1
- data/openapi/api.yaml +5407 -2794
- data/recurly.gemspec +8 -0
- data/scripts/changelog +2 -0
- data/scripts/format +5 -1
- data/scripts/release +5 -3
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e07115aaa76b090899e7a8b3fbd473aa4c3d9b53f1a0c2e6610bb48e3cfd2c0
|
4
|
+
data.tar.gz: 0e9dd8516ed793916175fb8e500894925cfe030f8fa6a3b1457420ab3b23a12f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b159f6322d33ebdac54a9645c9f791c2bbbc22f42b1b398c4f478b657322f001bfc3275870918e2bca88d599d2409fdf3863a485afd0ee5e2d17c67db012362
|
7
|
+
data.tar.gz: 06ed96e99e5e910accf623edd708d36bfa38d439ee4ec7b7e59cdfb8b13cba09e4061ce827e03e66144823c5cd95df4c2741e9e5dd9ee746611ba4a8ef55e817
|
data/.bumpversion.cfg
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
[bumpversion]
|
2
|
-
current_version = 3.
|
2
|
+
current_version = 3.8.0
|
3
3
|
parse = (?P<major>\d+)
|
4
4
|
\.(?P<minor>\d+)
|
5
5
|
\.(?P<patch>\d+)
|
@@ -10,3 +10,7 @@ serialize =
|
|
10
10
|
|
11
11
|
[bumpversion:file:lib/recurly/version.rb]
|
12
12
|
|
13
|
+
[bumpversion:file:GETTING_STARTED.md]
|
14
|
+
parse = (?P<major>\d+)\.(?P<minor>\d+)
|
15
|
+
serialize = {major}.{minor}
|
16
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
on:
|
2
|
+
release:
|
3
|
+
types:
|
4
|
+
- published
|
5
|
+
name: Documentation
|
6
|
+
jobs:
|
7
|
+
build:
|
8
|
+
name: Publish
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v2
|
12
|
+
|
13
|
+
- uses: ruby/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
ruby-version: '2.6'
|
16
|
+
|
17
|
+
- name: Build Library and Docs
|
18
|
+
run: ./scripts/build
|
19
|
+
|
20
|
+
- name: Deploy
|
21
|
+
if: success()
|
22
|
+
uses: crazy-max/ghaction-github-pages@v1
|
23
|
+
with:
|
24
|
+
target_branch: gh-pages
|
25
|
+
build_dir: ./doc
|
26
|
+
env:
|
27
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
28
|
+
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,98 @@
|
|
1
|
-
#
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## [3.8.0](https://github.com/recurly/recurly-client-ruby/tree/HEAD)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.7.0...HEAD)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Wed Jul 1 02:06:24 UTC 2020 Upgrade API version v2019-10-10 [\#605](https://github.com/recurly/recurly-client-ruby/pull/605) ([douglasmiller](https://github.com/douglasmiller))
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- Release 3.8.0 [\#606](https://github.com/recurly/recurly-client-ruby/pull/606) ([douglasmiller](https://github.com/douglasmiller))
|
14
|
+
|
15
|
+
## [3.7.0](https://github.com/recurly/recurly-client-ruby/tree/3.7.0) (2020-06-30)
|
16
|
+
|
17
|
+
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.6.0...3.7.0)
|
18
|
+
|
19
|
+
**Implemented enhancements:**
|
20
|
+
|
21
|
+
- Mon Jun 29 17:01:25 UTC 2020 Upgrade API version v2019-10-10 [\#601](https://github.com/recurly/recurly-client-ruby/pull/601) ([douglasmiller](https://github.com/douglasmiller))
|
22
|
+
|
23
|
+
**Fixed bugs:**
|
24
|
+
|
25
|
+
- Allow :headers to be included in operations [\#597](https://github.com/recurly/recurly-client-ruby/pull/597) ([douglasmiller](https://github.com/douglasmiller))
|
26
|
+
|
27
|
+
**Merged pull requests:**
|
28
|
+
|
29
|
+
- Release 3.7.0 [\#602](https://github.com/recurly/recurly-client-ruby/pull/602) ([douglasmiller](https://github.com/douglasmiller))
|
30
|
+
- Fix doc link [\#596](https://github.com/recurly/recurly-client-ruby/pull/596) ([bhelx](https://github.com/bhelx))
|
31
|
+
|
32
|
+
## [3.6.0](https://github.com/recurly/recurly-client-ruby/tree/3.6.0) (2020-06-01)
|
33
|
+
|
34
|
+
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.5.0...3.6.0)
|
35
|
+
|
36
|
+
**Implemented enhancements:**
|
37
|
+
|
38
|
+
- Latest Features [\#592](https://github.com/recurly/recurly-client-ruby/pull/592) ([bhelx](https://github.com/bhelx))
|
39
|
+
- Support the programmer passing their own logger [\#590](https://github.com/recurly/recurly-client-ruby/pull/590) ([bhelx](https://github.com/bhelx))
|
40
|
+
|
41
|
+
**Merged pull requests:**
|
42
|
+
|
43
|
+
- Release 3.6.0 [\#594](https://github.com/recurly/recurly-client-ruby/pull/594) ([bhelx](https://github.com/bhelx))
|
44
|
+
- Better format error message [\#593](https://github.com/recurly/recurly-client-ruby/pull/593) ([bhelx](https://github.com/bhelx))
|
45
|
+
- Let bump2version manage the getting started doc [\#591](https://github.com/recurly/recurly-client-ruby/pull/591) ([bhelx](https://github.com/bhelx))
|
46
|
+
- Document `Pager#first` and `Pager#count` [\#589](https://github.com/recurly/recurly-client-ruby/pull/589) ([bhelx](https://github.com/bhelx))
|
47
|
+
- Ensure that path parameters are not empty strings [\#587](https://github.com/recurly/recurly-client-ruby/pull/587) ([douglasmiller](https://github.com/douglasmiller))
|
48
|
+
|
49
|
+
## [3.5.0](https://github.com/recurly/recurly-client-ruby/tree/3.5.0) (2020-04-20)
|
50
|
+
|
51
|
+
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.4.1...3.5.0)
|
52
|
+
|
53
|
+
**Implemented enhancements:**
|
54
|
+
|
55
|
+
- Tue Apr 14 20:21:21 UTC 2020 Upgrade API version v2019-10-10 [\#585](https://github.com/recurly/recurly-client-ruby/pull/585) ([bhelx](https://github.com/bhelx))
|
56
|
+
- Set an Idempotency-Key header, retry GET requests after 5xx errors [\#579](https://github.com/recurly/recurly-client-ruby/pull/579) ([isaachall](https://github.com/isaachall))
|
57
|
+
- Adding \#first and \#count methods to Pager [\#560](https://github.com/recurly/recurly-client-ruby/pull/560) ([douglasmiller](https://github.com/douglasmiller))
|
58
|
+
|
59
|
+
**Fixed bugs:**
|
60
|
+
|
61
|
+
- Fixing the omission of query params [\#581](https://github.com/recurly/recurly-client-ruby/pull/581) ([douglasmiller](https://github.com/douglasmiller))
|
62
|
+
|
63
|
+
**Merged pull requests:**
|
64
|
+
|
65
|
+
- Release 3.5.0 [\#586](https://github.com/recurly/recurly-client-ruby/pull/586) ([douglasmiller](https://github.com/douglasmiller))
|
66
|
+
- Included the to-be released changes in the changelog [\#584](https://github.com/recurly/recurly-client-ruby/pull/584) ([douglasmiller](https://github.com/douglasmiller))
|
67
|
+
- Add 2.7 to test matrix [\#582](https://github.com/recurly/recurly-client-ruby/pull/582) ([bhelx](https://github.com/bhelx))
|
68
|
+
- Use github pages for docs [\#580](https://github.com/recurly/recurly-client-ruby/pull/580) ([bhelx](https://github.com/bhelx))
|
69
|
+
- Add project metadata to the gemspec [\#578](https://github.com/recurly/recurly-client-ruby/pull/578) ([orien](https://github.com/orien))
|
70
|
+
- Updating release script to be uniform across all clients [\#577](https://github.com/recurly/recurly-client-ruby/pull/577) ([douglasmiller](https://github.com/douglasmiller))
|
71
|
+
- Thu Mar 26 20:41:10 UTC 2020 Upgrade API version v2019-10-10 [\#573](https://github.com/recurly/recurly-client-ruby/pull/573) ([bhelx](https://github.com/bhelx))
|
72
|
+
|
73
|
+
## [3.4.1](https://github.com/recurly/recurly-client-ruby/tree/3.4.1) (2020-03-26)
|
74
|
+
|
75
|
+
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.4.0...3.4.1)
|
76
|
+
|
77
|
+
**Merged pull requests:**
|
78
|
+
|
79
|
+
- Release 3.4.1 [\#571](https://github.com/recurly/recurly-client-ruby/pull/571) ([bhelx](https://github.com/bhelx))
|
80
|
+
- Follow up bug fixes for \#568 [\#570](https://github.com/recurly/recurly-client-ruby/pull/570) ([bhelx](https://github.com/bhelx))
|
81
|
+
|
82
|
+
## [3.4.0](https://github.com/recurly/recurly-client-ruby/tree/3.4.0) (2020-03-23)
|
83
|
+
|
84
|
+
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.3.1...3.4.0)
|
85
|
+
|
86
|
+
**Implemented enhancements:**
|
87
|
+
|
88
|
+
- Replace Faraday gem with Net::HTTP, add connection pooling & keep-alive, update CA roots [\#568](https://github.com/recurly/recurly-client-ruby/pull/568) ([isaachall](https://github.com/isaachall))
|
89
|
+
|
90
|
+
**Merged pull requests:**
|
91
|
+
|
92
|
+
- Release 3.4.0 [\#569](https://github.com/recurly/recurly-client-ruby/pull/569) ([bhelx](https://github.com/bhelx))
|
2
93
|
|
3
94
|
## [3.3.1](https://github.com/recurly/recurly-client-ruby/tree/3.3.1) (2020-03-20)
|
95
|
+
|
4
96
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.3.0...3.3.1)
|
5
97
|
|
6
98
|
**Merged pull requests:**
|
@@ -12,6 +104,7 @@
|
|
12
104
|
- Add request for stack trace in issue report [\#558](https://github.com/recurly/recurly-client-ruby/pull/558) ([bhelx](https://github.com/bhelx))
|
13
105
|
|
14
106
|
## [3.3.0](https://github.com/recurly/recurly-client-ruby/tree/3.3.0) (2020-02-20)
|
107
|
+
|
15
108
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.2.2...3.3.0)
|
16
109
|
|
17
110
|
**Merged pull requests:**
|
@@ -22,6 +115,7 @@
|
|
22
115
|
- Latest v2019-10-10 Changes [\#552](https://github.com/recurly/recurly-client-ruby/pull/552) ([bhelx](https://github.com/bhelx))
|
23
116
|
|
24
117
|
## [3.2.2](https://github.com/recurly/recurly-client-ruby/tree/3.2.2) (2020-02-03)
|
118
|
+
|
25
119
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.2.1...3.2.2)
|
26
120
|
|
27
121
|
**Merged pull requests:**
|
@@ -30,6 +124,7 @@
|
|
30
124
|
- Loosen version restriction on faraday [\#549](https://github.com/recurly/recurly-client-ruby/pull/549) ([bhelx](https://github.com/bhelx))
|
31
125
|
|
32
126
|
## [3.2.1](https://github.com/recurly/recurly-client-ruby/tree/3.2.1) (2019-12-10)
|
127
|
+
|
33
128
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.2.0...3.2.1)
|
34
129
|
|
35
130
|
**Fixed bugs:**
|
@@ -37,6 +132,7 @@
|
|
37
132
|
- Convert Array params to CSV strings [\#545](https://github.com/recurly/recurly-client-ruby/pull/545) ([douglasmiller](https://github.com/douglasmiller))
|
38
133
|
|
39
134
|
## [3.2.0](https://github.com/recurly/recurly-client-ruby/tree/3.2.0) (2019-12-03)
|
135
|
+
|
40
136
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.1.3...3.2.0)
|
41
137
|
|
42
138
|
**Fixed bugs:**
|
@@ -50,6 +146,7 @@
|
|
50
146
|
- Allow object attributes through [\#542](https://github.com/recurly/recurly-client-ruby/pull/542) ([bhelx](https://github.com/bhelx))
|
51
147
|
|
52
148
|
## [3.1.3](https://github.com/recurly/recurly-client-ruby/tree/3.1.3) (2019-12-02)
|
149
|
+
|
53
150
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.1.2...3.1.3)
|
54
151
|
|
55
152
|
**Fixed bugs:**
|
@@ -58,6 +155,7 @@
|
|
58
155
|
- Issue 540 error may have transaction [\#541](https://github.com/recurly/recurly-client-ruby/pull/541) ([bhelx](https://github.com/bhelx))
|
59
156
|
|
60
157
|
## [3.1.2](https://github.com/recurly/recurly-client-ruby/tree/3.1.2) (2019-12-02)
|
158
|
+
|
61
159
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.1.1...3.1.2)
|
62
160
|
|
63
161
|
**Fixed bugs:**
|
@@ -65,6 +163,7 @@
|
|
65
163
|
- Skip request property type validation for nil values [\#539](https://github.com/recurly/recurly-client-ruby/pull/539) ([bhelx](https://github.com/bhelx))
|
66
164
|
|
67
165
|
## [3.1.1](https://github.com/recurly/recurly-client-ruby/tree/3.1.1) (2019-11-27)
|
166
|
+
|
68
167
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.1.0...3.1.1)
|
69
168
|
|
70
169
|
**Fixed bugs:**
|
@@ -73,6 +172,7 @@
|
|
73
172
|
- Disable searching ancestors when looking up constants [\#537](https://github.com/recurly/recurly-client-ruby/pull/537) ([douglasmiller](https://github.com/douglasmiller))
|
74
173
|
|
75
174
|
## [3.1.0](https://github.com/recurly/recurly-client-ruby/tree/3.1.0) (2019-11-18)
|
175
|
+
|
76
176
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.0.0...3.1.0)
|
77
177
|
|
78
178
|
**Merged pull requests:**
|
@@ -82,6 +182,7 @@
|
|
82
182
|
- Generated Updates for API version v2019-10-10 [\#528](https://github.com/recurly/recurly-client-ruby/pull/528) ([bhelx](https://github.com/bhelx))
|
83
183
|
|
84
184
|
## [3.0.0](https://github.com/recurly/recurly-client-ruby/tree/3.0.0) (2019-10-09)
|
185
|
+
|
85
186
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.0.0.beta.5...3.0.0)
|
86
187
|
|
87
188
|
**Merged pull requests:**
|
@@ -103,13 +204,14 @@
|
|
103
204
|
- Add CONTRIBUTING.md [\#486](https://github.com/recurly/recurly-client-ruby/pull/486) ([bhelx](https://github.com/bhelx))
|
104
205
|
- Bump 3.0.0.beta.6 [\#485](https://github.com/recurly/recurly-client-ruby/pull/485) ([bhelx](https://github.com/bhelx))
|
105
206
|
- Latest v2018-08-09 Changes [\#484](https://github.com/recurly/recurly-client-ruby/pull/484) ([bhelx](https://github.com/bhelx))
|
106
|
-
- 3.0.0.beta.5 [\#483](https://github.com/recurly/recurly-client-ruby/pull/483) ([bhelx](https://github.com/bhelx))
|
107
207
|
|
108
208
|
## [3.0.0.beta.5](https://github.com/recurly/recurly-client-ruby/tree/3.0.0.beta.5) (2019-06-28)
|
209
|
+
|
109
210
|
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.0.0.beta.4...3.0.0.beta.5)
|
110
211
|
|
111
212
|
**Merged pull requests:**
|
112
213
|
|
214
|
+
- 3.0.0.beta.5 [\#483](https://github.com/recurly/recurly-client-ruby/pull/483) ([bhelx](https://github.com/bhelx))
|
113
215
|
- Latest v2018-08-09 Changes [\#482](https://github.com/recurly/recurly-client-ruby/pull/482) ([bhelx](https://github.com/bhelx))
|
114
216
|
- no longer need dep scripts [\#476](https://github.com/recurly/recurly-client-ruby/pull/476) ([bhelx](https://github.com/bhelx))
|
115
217
|
- Add format script and check in specs [\#474](https://github.com/recurly/recurly-client-ruby/pull/474) ([bhelx](https://github.com/bhelx))
|
@@ -117,28 +219,20 @@
|
|
117
219
|
- Add strict mode for json deserializer [\#469](https://github.com/recurly/recurly-client-ruby/pull/469) ([bhelx](https://github.com/bhelx))
|
118
220
|
|
119
221
|
## [3.0.0.beta.4](https://github.com/recurly/recurly-client-ruby/tree/3.0.0.beta.4) (2019-04-04)
|
120
|
-
|
222
|
+
|
223
|
+
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.0.0.beta.1...3.0.0.beta.4)
|
121
224
|
|
122
225
|
**Merged pull requests:**
|
123
226
|
|
124
227
|
- V3 Update v2018-08-09 [\#460](https://github.com/recurly/recurly-client-ruby/pull/460) ([aaron-suarez](https://github.com/aaron-suarez))
|
125
228
|
- Small fixes for private beta [\#458](https://github.com/recurly/recurly-client-ruby/pull/458) ([bhelx](https://github.com/bhelx))
|
126
229
|
- Use Net-http-persistent for persistent connection [\#408](https://github.com/recurly/recurly-client-ruby/pull/408) ([bhelx](https://github.com/bhelx))
|
127
|
-
|
128
|
-
## [3.0.0.beta.3](https://github.com/recurly/recurly-client-ruby/tree/3.0.0.beta.3) (2018-08-27)
|
129
|
-
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.0.0.beta.2...3.0.0.beta.3)
|
130
|
-
|
131
|
-
**Merged pull requests:**
|
132
|
-
|
133
230
|
- Update to API 2018-06-06 [\#407](https://github.com/recurly/recurly-client-ruby/pull/407) ([bhelx](https://github.com/bhelx))
|
134
231
|
- Regenerating the client [\#406](https://github.com/recurly/recurly-client-ruby/pull/406) ([drewish](https://github.com/drewish))
|
135
232
|
- V3 Pager can error [\#401](https://github.com/recurly/recurly-client-ruby/pull/401) ([drewish](https://github.com/drewish))
|
136
233
|
- \[V3\] Test more versions of ruby [\#397](https://github.com/recurly/recurly-client-ruby/pull/397) ([drewish](https://github.com/drewish))
|
137
234
|
- Allow faraday 0.12 for compatibility with oauth2 gem [\#396](https://github.com/recurly/recurly-client-ruby/pull/396) ([drewish](https://github.com/drewish))
|
138
235
|
|
139
|
-
## [3.0.0.beta.2](https://github.com/recurly/recurly-client-ruby/tree/3.0.0.beta.2) (2018-07-17)
|
140
|
-
[Full Changelog](https://github.com/recurly/recurly-client-ruby/compare/3.0.0.beta.1...3.0.0.beta.2)
|
141
|
-
|
142
236
|
|
143
237
|
|
144
|
-
\* *This
|
238
|
+
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
|
data/GETTING_STARTED.md
CHANGED
@@ -5,7 +5,7 @@ This repository houses the official ruby client for Recurly's V3 API.
|
|
5
5
|
In your Gemfile, add `recurly` as a dependency.
|
6
6
|
|
7
7
|
```ruby
|
8
|
-
gem 'recurly', '~> 3.
|
8
|
+
gem 'recurly', '~> 3.8'
|
9
9
|
```
|
10
10
|
|
11
11
|
> *Note*: We try to follow [semantic versioning](https://semver.org/) and will only apply breaking changes to major versions.
|
@@ -41,6 +41,27 @@ client = Recurly::Client.new(api_key: API_KEY2)
|
|
41
41
|
sub = client.get_subscription(subscription_id: 'abcd7890')
|
42
42
|
```
|
43
43
|
|
44
|
+
## Logging
|
45
|
+
|
46
|
+
The client constructor optionally accepts a logger provided by the programmer. The logger you pass should be an instance of ruby stdlib's [Logger](https://ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger.html)
|
47
|
+
or follow the same interface. By default, the client creates a logger to `STDOUT` with level `WARN`.
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
require 'logger'
|
51
|
+
|
52
|
+
# Create a logger to STDOUT
|
53
|
+
logger = Logger.new(STDOUT)
|
54
|
+
logger.level = Logger::INFO
|
55
|
+
|
56
|
+
# You could also use an existing logger
|
57
|
+
# If you are using Rails you may want to use your application's logger
|
58
|
+
logger = Rails.logger
|
59
|
+
|
60
|
+
client = Recurly::Client.new(api_key: API_KEY, logger: logger)
|
61
|
+
```
|
62
|
+
|
63
|
+
> *SECURITY WARNING*: The log level should never be set to DEBUG in production. This could potentially result in sensitive data in your logging system.
|
64
|
+
|
44
65
|
# Operations
|
45
66
|
|
46
67
|
The {Recurly::Client} contains every `operation` you can perform on the site as a list of methods. Each method is documented explaining
|
@@ -109,6 +130,45 @@ end
|
|
109
130
|
`limit` defaults to 20 items per page and can be set from 1 to 200. Choosing a lower limit means more network requests but smaller payloads.
|
110
131
|
We recommend keeping the default for most cases but increasing the limit if you are planning on iterating through many pages of items (e.g. all transactions in your site).
|
111
132
|
|
133
|
+
## Efficiently Fetch the First or Last Resource
|
134
|
+
|
135
|
+
The Pager class implements a first method which allows you to fetch just the first or last resource from the server. On top of being a convenient abstraction, this is implemented efficiently by only asking the server for the 1 item you want.
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
accounts = client.list_accounts(
|
139
|
+
subscriber: true,
|
140
|
+
order: :desc
|
141
|
+
)
|
142
|
+
|
143
|
+
last_subscriber = accounts.first
|
144
|
+
```
|
145
|
+
|
146
|
+
If you want to fetch the last account in this scenario, invert the order from descending `desc` to ascending `asc`:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
accounts = client.list_accounts(
|
150
|
+
subscriber: true,
|
151
|
+
order: :asc
|
152
|
+
)
|
153
|
+
|
154
|
+
first_subscriber = accounts.first
|
155
|
+
```
|
156
|
+
|
157
|
+
## Counting Resources
|
158
|
+
|
159
|
+
The Pager class implements a `count` method which allows you to count the resources the pager would return. It does so by calling the endpoint with `HEAD` and parsing and returning the `Recurly-Total-Records` header. This method respects any filtering parameters you apply to the pager, but the sorting parameters will have no effect.
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
accounts = client.list_accounts(
|
163
|
+
subscriber: true,
|
164
|
+
begin_time: DateTime.new(2017,1,1)
|
165
|
+
)
|
166
|
+
|
167
|
+
# Calling count here will return an integer indicating
|
168
|
+
# the number of subscribers since 2017
|
169
|
+
count = accounts.count
|
170
|
+
# => 573
|
171
|
+
```
|
112
172
|
|
113
173
|
# Creating Resources
|
114
174
|
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@ This repository houses the official ruby client for Recurly's V3 API.
|
|
7
7
|
|
8
8
|
## Reference Documentation
|
9
9
|
|
10
|
-
Getting Started Guide and reference documentation can be found on [
|
10
|
+
Getting Started Guide and reference documentation can be found on [Github Pages](https://recurly.github.io/recurly-client-ruby/).
|
11
11
|
|
12
12
|
## Contributing
|
13
13
|
|
data/lib/recurly/client.rb
CHANGED
@@ -2,6 +2,7 @@ require "logger"
|
|
2
2
|
require "erb"
|
3
3
|
require "net/https"
|
4
4
|
require "base64"
|
5
|
+
require "securerandom"
|
5
6
|
require_relative "./schema/json_parser"
|
6
7
|
require_relative "./schema/file_parser"
|
7
8
|
|
@@ -14,9 +15,12 @@ module Recurly
|
|
14
15
|
CA_FILE = File.join(File.dirname(__FILE__), "../data/ca-certificates.crt")
|
15
16
|
BINARY_TYPES = [
|
16
17
|
"application/pdf",
|
17
|
-
]
|
18
|
+
].freeze
|
18
19
|
JSON_CONTENT_TYPE = "application/json"
|
19
20
|
MAX_RETRIES = 3
|
21
|
+
LOG_LEVELS = %i(debug info warn error fatal).freeze
|
22
|
+
BASE36_ALPHABET = (("0".."9").to_a + ("a".."z").to_a).freeze
|
23
|
+
REQUEST_OPTIONS = [:headers].freeze
|
20
24
|
|
21
25
|
# Initialize a client. It requires an API key.
|
22
26
|
#
|
@@ -42,29 +46,42 @@ module Recurly
|
|
42
46
|
# sub = client.get_subscription(subscription_id: 'uuid-abcd7890')
|
43
47
|
#
|
44
48
|
# @param api_key [String] The private API key
|
45
|
-
# @param
|
46
|
-
|
47
|
-
def initialize(api_key:, site_id: nil, subdomain: nil, **options)
|
49
|
+
# @param logger [Logger] A logger to use. Defaults to creating a new STDOUT logger with level WARN.
|
50
|
+
def initialize(api_key:, site_id: nil, subdomain: nil, logger: nil)
|
48
51
|
set_site_id(site_id, subdomain)
|
49
52
|
set_api_key(api_key)
|
50
|
-
|
53
|
+
|
54
|
+
if logger.nil?
|
55
|
+
@logger = Logger.new(STDOUT).tap do |l|
|
56
|
+
l.level = Logger::WARN
|
57
|
+
end
|
58
|
+
else
|
59
|
+
unless LOG_LEVELS.all? { |lev| logger.respond_to?(lev) }
|
60
|
+
raise ArgumentError, "You must pass in a logger implementation that responds to the following messages: #{LOG_LEVELS}"
|
61
|
+
end
|
62
|
+
@logger = logger
|
63
|
+
end
|
64
|
+
|
65
|
+
if @logger.level < Logger::INFO
|
66
|
+
msg = <<-MSG
|
67
|
+
The Recurly logger should not be initialized
|
68
|
+
beyond the level INFO. It is currently configured to emit
|
69
|
+
headers and request / response bodies. This has the potential to leak
|
70
|
+
PII and other sensitive information and should never be used in production.
|
71
|
+
MSG
|
72
|
+
log_warn("SECURITY_WARNING", message: msg)
|
73
|
+
end
|
51
74
|
|
52
75
|
# execute block with this client if given
|
53
76
|
yield(self) if block_given?
|
54
77
|
end
|
55
78
|
|
56
|
-
def next_page(pager)
|
57
|
-
path = extract_path(pager.next)
|
58
|
-
request = Net::HTTP::Get.new path
|
59
|
-
set_headers(request)
|
60
|
-
http_response = run_request(request)
|
61
|
-
handle_response! request, http_response
|
62
|
-
end
|
63
|
-
|
64
79
|
protected
|
65
80
|
|
81
|
+
# Used by the operations.rb file to interpolate paths
|
82
|
+
attr_reader :site_id
|
83
|
+
|
66
84
|
def pager(path, **options)
|
67
|
-
path = scope_by_site(path, **options)
|
68
85
|
Pager.new(
|
69
86
|
client: self,
|
70
87
|
path: path,
|
@@ -72,9 +89,15 @@ module Recurly
|
|
72
89
|
)
|
73
90
|
end
|
74
91
|
|
92
|
+
def head(path, **options)
|
93
|
+
request = Net::HTTP::Head.new build_url(path, options)
|
94
|
+
set_headers(request, options[:headers])
|
95
|
+
http_response = run_request(request, options)
|
96
|
+
handle_response! request, http_response
|
97
|
+
end
|
98
|
+
|
75
99
|
def get(path, **options)
|
76
|
-
|
77
|
-
request = Net::HTTP::Get.new path
|
100
|
+
request = Net::HTTP::Get.new build_url(path, options)
|
78
101
|
set_headers(request, options[:headers])
|
79
102
|
http_response = run_request(request, options)
|
80
103
|
handle_response! request, http_response
|
@@ -82,8 +105,7 @@ module Recurly
|
|
82
105
|
|
83
106
|
def post(path, request_data, request_class, **options)
|
84
107
|
request_class.new(request_data).validate!
|
85
|
-
|
86
|
-
request = Net::HTTP::Post.new path
|
108
|
+
request = Net::HTTP::Post.new build_url(path, options)
|
87
109
|
request.set_content_type(JSON_CONTENT_TYPE)
|
88
110
|
set_headers(request, options[:headers])
|
89
111
|
request.body = JSON.dump(request_data)
|
@@ -92,14 +114,12 @@ module Recurly
|
|
92
114
|
end
|
93
115
|
|
94
116
|
def put(path, request_data = nil, request_class = nil, **options)
|
95
|
-
|
96
|
-
request = Net::HTTP::Put.new path
|
117
|
+
request = Net::HTTP::Put.new build_url(path, options)
|
97
118
|
request.set_content_type(JSON_CONTENT_TYPE)
|
98
119
|
set_headers(request, options[:headers])
|
99
120
|
if request_data
|
100
121
|
request_class.new(request_data).validate!
|
101
122
|
json_body = JSON.dump(request_data)
|
102
|
-
logger.info("PUT BODY #{json_body}")
|
103
123
|
request.body = json_body
|
104
124
|
end
|
105
125
|
http_response = run_request(request, options)
|
@@ -107,23 +127,14 @@ module Recurly
|
|
107
127
|
end
|
108
128
|
|
109
129
|
def delete(path, **options)
|
110
|
-
|
111
|
-
request = Net::HTTP::Delete.new path
|
130
|
+
request = Net::HTTP::Delete.new build_url(path, options)
|
112
131
|
set_headers(request, options[:headers])
|
113
132
|
http_response = run_request(request, options)
|
114
133
|
handle_response! request, http_response
|
115
134
|
end
|
116
135
|
|
117
|
-
protected
|
118
|
-
|
119
|
-
# Used by the operations.rb file to interpolate paths
|
120
|
-
attr_reader :site_id
|
121
|
-
|
122
136
|
private
|
123
137
|
|
124
|
-
# @return [Logger]
|
125
|
-
attr_reader :logger
|
126
|
-
|
127
138
|
@connection_pool = Recurly::ConnectionPool.new
|
128
139
|
|
129
140
|
class << self
|
@@ -139,7 +150,38 @@ module Recurly
|
|
139
150
|
|
140
151
|
begin
|
141
152
|
http.start unless http.started?
|
142
|
-
|
153
|
+
log_attrs = {
|
154
|
+
method: request.method,
|
155
|
+
path: request.path,
|
156
|
+
}
|
157
|
+
if @logger.level < Logger::INFO
|
158
|
+
log_attrs[:request_body] = request.body
|
159
|
+
# No need to log the authorization header
|
160
|
+
headers = request.to_hash.reject { |k, _| k&.downcase == "authorization" }
|
161
|
+
log_attrs[:request_headers] = headers
|
162
|
+
end
|
163
|
+
|
164
|
+
log_info("Request", **log_attrs)
|
165
|
+
start = Time.now
|
166
|
+
response = http.request(request)
|
167
|
+
elapsed = Time.now - start
|
168
|
+
|
169
|
+
# GETs are safe to retry after a server error, requests with an Idempotency-Key will return the prior response
|
170
|
+
if response.kind_of?(Net::HTTPServerError) && request.is_a?(Net::HTTP::Get)
|
171
|
+
retries += 1
|
172
|
+
log_info("Retrying", retries: retries, **log_attrs)
|
173
|
+
start = Time.now
|
174
|
+
response = http.request(request) if retries < MAX_RETRIES
|
175
|
+
elapsed = Time.now - start
|
176
|
+
end
|
177
|
+
|
178
|
+
if @logger.level < Logger::INFO
|
179
|
+
log_attrs[:response_body] = response.body
|
180
|
+
log_attrs[:response_headers] = response.to_hash
|
181
|
+
end
|
182
|
+
log_info("Response", time_ms: (elapsed * 1_000).floor, status: response.code, **log_attrs)
|
183
|
+
|
184
|
+
response
|
143
185
|
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::ECONNABORTED,
|
144
186
|
Errno::EPIPE, Errno::ETIMEDOUT, Net::OpenTimeout, EOFError, SocketError => ex
|
145
187
|
retries += 1
|
@@ -163,26 +205,37 @@ module Recurly
|
|
163
205
|
end
|
164
206
|
|
165
207
|
def set_headers(request, additional_headers = {})
|
208
|
+
# TODO this is undocumented until we finalize it
|
209
|
+
additional_headers.each { |header, v| request[header] = v } if additional_headers
|
210
|
+
|
166
211
|
request["Accept"] = "application/vnd.recurly.#{api_version}".chomp # got this method from operations.rb
|
167
212
|
request["Authorization"] = "Basic #{Base64.encode64(@api_key)}".chomp
|
168
213
|
request["User-Agent"] = "Recurly/#{VERSION}; #{RUBY_DESCRIPTION}"
|
169
214
|
|
170
|
-
|
171
|
-
|
215
|
+
unless request.is_a?(Net::HTTP::Get) || request.is_a?(Net::HTTP::Head)
|
216
|
+
request["Idempotency-Key"] ||= generate_idempotency_key
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# from https://github.com/rails/rails/blob/6-0-stable/activesupport/lib/active_support/core_ext/securerandom.rb
|
221
|
+
def generate_idempotency_key(n = 16)
|
222
|
+
SecureRandom.random_bytes(n).unpack("C*").map do |byte|
|
223
|
+
idx = byte % 64
|
224
|
+
idx = SecureRandom.random_number(36) if idx >= 36
|
225
|
+
BASE36_ALPHABET[idx]
|
226
|
+
end.join
|
172
227
|
end
|
173
228
|
|
174
229
|
def set_http_options(http, options)
|
175
230
|
http.open_timeout = options[:open_timeout] || 20
|
176
231
|
http.read_timeout = options[:read_timeout] || 60
|
177
|
-
|
178
|
-
http.set_debug_output(logger) if @log_level <= Logger::INFO && !http.started?
|
179
232
|
end
|
180
233
|
|
181
234
|
def handle_response!(request, http_response)
|
182
235
|
response = HTTP::Response.new(http_response, request)
|
183
236
|
raise_api_error!(http_response, response) unless http_response.kind_of?(Net::HTTPSuccess)
|
184
237
|
resource = if response.body
|
185
|
-
if http_response.content_type
|
238
|
+
if http_response.content_type&.include?(JSON_CONTENT_TYPE)
|
186
239
|
JSONParser.parse(self, response.body)
|
187
240
|
elsif BINARY_TYPES.include?(http_response.content_type)
|
188
241
|
FileParser.parse(response.body)
|
@@ -216,15 +269,15 @@ module Recurly
|
|
216
269
|
|
217
270
|
def read_headers(response)
|
218
271
|
if !@_ignore_deprecation_warning && response.headers["Recurly-Deprecated"]&.upcase == "TRUE"
|
219
|
-
|
272
|
+
log_warn("DEPRECTATION WARNING", message: "Your current API version \"#{api_version}\" is deprecated and will be sunset on #{response.headers["Recurly-Sunset-Date"]}")
|
220
273
|
end
|
221
274
|
response
|
222
275
|
end
|
223
276
|
|
224
|
-
def
|
277
|
+
def validate_path_parameters!(**options)
|
278
|
+
# Check to see that we are passing the correct data types
|
279
|
+
# This prevents a confusing error if the user passes in a non-primitive by mistake
|
225
280
|
options.each do |k, v|
|
226
|
-
# Check to see that we are passing the correct data types
|
227
|
-
# This prevents a confusing error if the user passes in a non-primitive by mistake
|
228
281
|
unless [String, Symbol, Integer, Float].include?(v.class)
|
229
282
|
message = "We cannot build the url with the given argument #{k}=#{v.inspect}."
|
230
283
|
if k =~ /_id$/
|
@@ -232,6 +285,17 @@ module Recurly
|
|
232
285
|
end
|
233
286
|
raise ArgumentError, message
|
234
287
|
end
|
288
|
+
end
|
289
|
+
# Check to make sure that parameters are not empty string values
|
290
|
+
empty_strings = options.select { |_, v| v.is_a?(String) && v.strip.empty? }
|
291
|
+
if empty_strings.any?
|
292
|
+
raise ArgumentError, "#{empty_strings.keys.join(", ")} cannot be an empty string"
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
def interpolate_path(path, **options)
|
297
|
+
validate_path_parameters!(options)
|
298
|
+
options.each do |k, v|
|
235
299
|
# We need to encode the values for the url
|
236
300
|
options[k] = ERB::Util.url_encode(v.to_s)
|
237
301
|
end
|
@@ -251,24 +315,34 @@ module Recurly
|
|
251
315
|
@api_key = api_key
|
252
316
|
end
|
253
317
|
|
254
|
-
def
|
255
|
-
|
256
|
-
|
318
|
+
def build_url(path, options)
|
319
|
+
path = scope_by_site(path, options)
|
320
|
+
query_params = options.reject { |k, _| REQUEST_OPTIONS.include?(k.to_sym) }
|
321
|
+
if query_params.any?
|
322
|
+
"#{path}?#{URI.encode_www_form(query_params)}"
|
257
323
|
else
|
258
324
|
path
|
259
325
|
end
|
260
326
|
end
|
261
327
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
328
|
+
def scope_by_site(path, **options)
|
329
|
+
if site = site_id || options[:site_id]
|
330
|
+
# Ensure that we are only including the site_id once because the Pager operations
|
331
|
+
# will use the cursor returned from the API which may already have these components
|
332
|
+
path.start_with?("/sites/#{site}") ? path : "/sites/#{site}#{path}"
|
333
|
+
else
|
334
|
+
path
|
335
|
+
end
|
266
336
|
end
|
267
337
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
338
|
+
# Define a private `log_<level>` method for each log level
|
339
|
+
LOG_LEVELS.each do |level|
|
340
|
+
define_method "log_#{level}" do |tag, **attrs|
|
341
|
+
@logger.send(level, "Recurly") do
|
342
|
+
msg = attrs.each_pair.map { |k, v| "#{k}=#{v.inspect}" }.join(" ")
|
343
|
+
"[#{tag}] #{msg}"
|
344
|
+
end
|
345
|
+
end
|
272
346
|
end
|
273
347
|
end
|
274
348
|
end
|