dodopayments 1.14.0 → 1.17.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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/.ignore +2 -0
  3. data/CHANGELOG.md +41 -0
  4. data/README.md +58 -49
  5. data/lib/dodopayments/client.rb +7 -6
  6. data/lib/dodopayments/internal/default_page_number_pagination.rb +1 -1
  7. data/lib/dodopayments/internal/transport/base_client.rb +5 -5
  8. data/lib/dodopayments/internal/transport/pooled_net_requester.rb +1 -1
  9. data/lib/dodopayments/internal/type/array_of.rb +11 -0
  10. data/lib/dodopayments/internal/type/base_model.rb +63 -27
  11. data/lib/dodopayments/internal/type/base_page.rb +9 -1
  12. data/lib/dodopayments/internal/type/boolean.rb +4 -0
  13. data/lib/dodopayments/internal/type/enum.rb +9 -5
  14. data/lib/dodopayments/internal/type/hash_of.rb +11 -0
  15. data/lib/dodopayments/internal/type/io_like.rb +4 -0
  16. data/lib/dodopayments/internal/type/request_parameters.rb +1 -2
  17. data/lib/dodopayments/internal/type/union.rb +10 -1
  18. data/lib/dodopayments/internal/type/unknown.rb +4 -0
  19. data/lib/dodopayments/internal.rb +0 -1
  20. data/lib/dodopayments/models/attach_existing_customer.rb +2 -6
  21. data/lib/dodopayments/models/billing_address.rb +6 -10
  22. data/lib/dodopayments/models/country_code.rb +2 -5
  23. data/lib/dodopayments/models/create_new_customer.rb +6 -14
  24. data/lib/dodopayments/models/customer.rb +7 -11
  25. data/lib/dodopayments/models/customer_create_params.rb +6 -11
  26. data/lib/dodopayments/models/customer_limited_details.rb +4 -8
  27. data/lib/dodopayments/models/customer_list_params.rb +5 -10
  28. data/lib/dodopayments/models/customer_portal_session.rb +2 -6
  29. data/lib/dodopayments/models/customer_request.rb +2 -3
  30. data/lib/dodopayments/models/customer_retrieve_params.rb +3 -8
  31. data/lib/dodopayments/models/customer_update_params.rb +5 -10
  32. data/lib/dodopayments/models/customers/customer_portal_create_params.rb +4 -9
  33. data/lib/dodopayments/models/discount.rb +12 -31
  34. data/lib/dodopayments/models/discount_create_params.rb +10 -27
  35. data/lib/dodopayments/models/discount_delete_params.rb +3 -8
  36. data/lib/dodopayments/models/discount_list_params.rb +5 -10
  37. data/lib/dodopayments/models/discount_retrieve_params.rb +3 -8
  38. data/lib/dodopayments/models/discount_type.rb +2 -5
  39. data/lib/dodopayments/models/discount_update_params.rb +10 -27
  40. data/lib/dodopayments/models/dispute.rb +9 -25
  41. data/lib/dodopayments/models/dispute_list_params.rb +10 -27
  42. data/lib/dodopayments/models/dispute_retrieve_params.rb +3 -8
  43. data/lib/dodopayments/models/dispute_stage.rb +2 -5
  44. data/lib/dodopayments/models/dispute_status.rb +2 -5
  45. data/lib/dodopayments/models/intent_status.rb +2 -5
  46. data/lib/dodopayments/models/invoices/payment_retrieve_params.rb +3 -8
  47. data/lib/dodopayments/models/license_activate_params.rb +5 -10
  48. data/lib/dodopayments/models/license_deactivate_params.rb +5 -10
  49. data/lib/dodopayments/models/license_key.rb +13 -33
  50. data/lib/dodopayments/models/license_key_duration.rb +3 -7
  51. data/lib/dodopayments/models/license_key_instance.rb +6 -10
  52. data/lib/dodopayments/models/license_key_instance_list_params.rb +6 -11
  53. data/lib/dodopayments/models/license_key_instance_retrieve_params.rb +3 -8
  54. data/lib/dodopayments/models/license_key_instance_update_params.rb +4 -9
  55. data/lib/dodopayments/models/license_key_list_params.rb +8 -13
  56. data/lib/dodopayments/models/license_key_retrieve_params.rb +3 -8
  57. data/lib/dodopayments/models/license_key_status.rb +2 -5
  58. data/lib/dodopayments/models/license_key_update_params.rb +6 -11
  59. data/lib/dodopayments/models/license_validate_params.rb +5 -10
  60. data/lib/dodopayments/models/license_validate_response.rb +2 -6
  61. data/lib/dodopayments/models/misc_list_supported_countries_params.rb +3 -8
  62. data/lib/dodopayments/models/one_time_product_cart_item.rb +4 -8
  63. data/lib/dodopayments/models/payment.rb +193 -58
  64. data/lib/dodopayments/models/payment_create_params.rb +21 -55
  65. data/lib/dodopayments/models/payment_create_response.rb +9 -25
  66. data/lib/dodopayments/models/payment_list_params.rb +10 -27
  67. data/lib/dodopayments/models/payment_list_response.rb +13 -34
  68. data/lib/dodopayments/models/payment_retrieve_params.rb +3 -8
  69. data/lib/dodopayments/models/payout_list_params.rb +5 -10
  70. data/lib/dodopayments/models/payout_list_response.rb +20 -49
  71. data/lib/dodopayments/models/price.rb +29 -79
  72. data/lib/dodopayments/models/product.rb +18 -44
  73. data/lib/dodopayments/models/product_create_params.rb +14 -36
  74. data/lib/dodopayments/models/product_delete_params.rb +3 -8
  75. data/lib/dodopayments/models/product_list_params.rb +8 -17
  76. data/lib/dodopayments/models/product_list_response.rb +18 -45
  77. data/lib/dodopayments/models/product_retrieve_params.rb +3 -8
  78. data/lib/dodopayments/models/product_unarchive_params.rb +3 -8
  79. data/lib/dodopayments/models/product_update_params.rb +15 -38
  80. data/lib/dodopayments/models/products/image_update_params.rb +4 -9
  81. data/lib/dodopayments/models/products/image_update_response.rb +3 -7
  82. data/lib/dodopayments/models/refund.rb +11 -18
  83. data/lib/dodopayments/models/refund_create_params.rb +5 -10
  84. data/lib/dodopayments/models/refund_list_params.rb +9 -25
  85. data/lib/dodopayments/models/refund_retrieve_params.rb +3 -8
  86. data/lib/dodopayments/models/refund_status.rb +2 -5
  87. data/lib/dodopayments/models/subscription.rb +24 -54
  88. data/lib/dodopayments/models/subscription_charge_params.rb +4 -9
  89. data/lib/dodopayments/models/subscription_charge_response.rb +2 -6
  90. data/lib/dodopayments/models/subscription_create_params.rb +27 -68
  91. data/lib/dodopayments/models/subscription_create_response.rb +8 -23
  92. data/lib/dodopayments/models/subscription_list_params.rb +9 -25
  93. data/lib/dodopayments/models/subscription_retrieve_params.rb +3 -8
  94. data/lib/dodopayments/models/subscription_status.rb +2 -5
  95. data/lib/dodopayments/models/subscription_update_params.rb +7 -12
  96. data/lib/dodopayments/models/time_interval.rb +2 -5
  97. data/lib/dodopayments/models/webhook_event.rb +9 -25
  98. data/lib/dodopayments/models/webhook_event_list_params.rb +9 -25
  99. data/lib/dodopayments/models/webhook_event_retrieve_params.rb +3 -8
  100. data/lib/dodopayments/request_options.rb +3 -4
  101. data/lib/dodopayments/version.rb +1 -1
  102. data/lib/dodopayments.rb +0 -9
  103. data/rbi/lib/dodopayments/client.rbi +4 -4
  104. data/rbi/lib/dodopayments/internal/type/array_of.rbi +3 -0
  105. data/rbi/lib/dodopayments/internal/type/base_model.rbi +17 -0
  106. data/rbi/lib/dodopayments/internal/type/base_page.rbi +2 -0
  107. data/rbi/lib/dodopayments/internal/type/enum.rbi +3 -6
  108. data/rbi/lib/dodopayments/internal/type/hash_of.rbi +3 -0
  109. data/rbi/lib/dodopayments/internal/type/union.rbi +3 -0
  110. data/rbi/lib/dodopayments/internal.rbi +0 -1
  111. data/rbi/lib/dodopayments/models/country_code.rbi +1 -1
  112. data/rbi/lib/dodopayments/models/discount_type.rbi +1 -1
  113. data/rbi/lib/dodopayments/models/dispute_stage.rbi +1 -1
  114. data/rbi/lib/dodopayments/models/dispute_status.rbi +1 -1
  115. data/rbi/lib/dodopayments/models/intent_status.rbi +1 -1
  116. data/rbi/lib/dodopayments/models/license_key_status.rbi +1 -1
  117. data/rbi/lib/dodopayments/models/payment.rbi +172 -1
  118. data/rbi/lib/dodopayments/models/payment_create_params.rbi +7 -4
  119. data/rbi/lib/dodopayments/models/payment_list_response.rbi +1 -2
  120. data/rbi/lib/dodopayments/models/payout_list_response.rbi +2 -4
  121. data/rbi/lib/dodopayments/models/price.rbi +2 -4
  122. data/rbi/lib/dodopayments/models/product.rbi +1 -2
  123. data/rbi/lib/dodopayments/models/product_create_params.rbi +1 -2
  124. data/rbi/lib/dodopayments/models/product_list_response.rbi +2 -4
  125. data/rbi/lib/dodopayments/models/product_update_params.rbi +1 -2
  126. data/rbi/lib/dodopayments/models/refund.rbi +1 -1
  127. data/rbi/lib/dodopayments/models/refund_status.rbi +1 -1
  128. data/rbi/lib/dodopayments/models/subscription.rbi +1 -2
  129. data/rbi/lib/dodopayments/models/subscription_create_params.rbi +7 -10
  130. data/rbi/lib/dodopayments/models/subscription_status.rbi +1 -1
  131. data/rbi/lib/dodopayments/models/time_interval.rbi +1 -1
  132. data/sig/dodopayments/internal/type/array_of.rbs +2 -0
  133. data/sig/dodopayments/internal/type/base_model.rbs +10 -0
  134. data/sig/dodopayments/internal/type/enum.rbs +2 -2
  135. data/sig/dodopayments/internal/type/hash_of.rbs +2 -0
  136. data/sig/dodopayments/internal/type/union.rbs +2 -0
  137. data/sig/dodopayments/models/payment.rbs +307 -0
  138. data/sig/dodopayments/models/payment_create_params.rbs +2 -0
  139. data/sig/dodopayments/models/subscription_create_params.rbs +2 -0
  140. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 302b2bf6170d705f608f0f5920a8d7faa4f56b8ca4fba0527d28b405d00fa21b
4
- data.tar.gz: fb1ccc49ff0df46c0fc51367b45c393e560e04c040eba513f48ce225344b0572
3
+ metadata.gz: b7d6a141291675cb8c695b5b88364058399a4f477d2f43eb851a80b4c81706f5
4
+ data.tar.gz: 57e2af01863ba772f020b0fb9a43b5941c04be6b138fcd5f1a78024d8bb19747
5
5
  SHA512:
6
- metadata.gz: 697a86c5196aa3312109a7ed5650313437ac5db4be1ce2b2f7d9845baae2915d8fe150e37e4410657dd70a5568c4938753e9afc1a37b6c67fde45ec3098abcb0
7
- data.tar.gz: 2a87db33ef9b75ca61352795acf6b8f9e88f6c8e3281beaa744bcd3bdcdbbf03b401aa2c5cadf325d5dd6ac5ac2fa0dd0321baaeb3e2bffeb20f6477794626f0
6
+ metadata.gz: acd5317d471d998c14ada88e83e99d6078bead9ba90108a6055b57040ba905381163339b03341207361aa289f08b4fb282bd5adca29eb7f4964eb3ee78370252
7
+ data.tar.gz: 633947d1f1d0bfa26a5658f69171ef894120e538e7066e37631a283db8b333d77f7c3ccf24606bc261dd93f6fa208ffa448d258ec6ee5b15ef4f37edfb35b0da
data/.ignore ADDED
@@ -0,0 +1,2 @@
1
+ rbi/*
2
+ sig/*
data/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.17.0 (2025-04-22)
4
+
5
+ Full Changelog: [v1.16.1...v1.17.0](https://github.com/dodopayments/dodopayments-ruby/compare/v1.16.1...v1.17.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** manual updates ([62a87c3](https://github.com/dodopayments/dodopayments-ruby/commit/62a87c3f8cdcfc59f5b93dc3dae02d0bb3712108))
10
+ * implement `#hash` for data containers ([34c3553](https://github.com/dodopayments/dodopayments-ruby/commit/34c35538d611b8b829f6e058531bf9f9c16a08d4))
11
+
12
+
13
+ ### Chores
14
+
15
+ * documentation improvements ([71c417b](https://github.com/dodopayments/dodopayments-ruby/commit/71c417bc885d00ab6e31067378e4a10ca1449aea))
16
+ * explicitly mark apis public under `Internal` module ([b5c432b](https://github.com/dodopayments/dodopayments-ruby/commit/b5c432b32debc84016858af1c7f2ec88899410ab))
17
+ * **internal:** minor type annotation improvements ([0356338](https://github.com/dodopayments/dodopayments-ruby/commit/0356338332f349cf9aaea6c7c309254af6bc96cc))
18
+ * make sorbet enums easier to read ([2fb5092](https://github.com/dodopayments/dodopayments-ruby/commit/2fb509272af690159ad22df97abd1854b617af7f))
19
+ * simplify yard annotations by removing most `@!parse` directives ([d54d094](https://github.com/dodopayments/dodopayments-ruby/commit/d54d094c00557b2730477cf86c9d835f2c256aee))
20
+ * update README with recommended editor plugins ([b5f54c9](https://github.com/dodopayments/dodopayments-ruby/commit/b5f54c9799d10e1e8b6126bb9c91182f0e4db59d))
21
+ * use `@!method` instead of `@!parse` for virtual method type definitions ([d890ce6](https://github.com/dodopayments/dodopayments-ruby/commit/d890ce641419ae2b7eaf32bf15e1b9a8990da53b))
22
+
23
+ ## 1.16.1 (2025-04-18)
24
+
25
+ Full Changelog: [v1.14.0...v1.16.1](https://github.com/dodopayments/dodopayments-ruby/compare/v1.14.0...v1.16.1)
26
+
27
+ ### Features
28
+
29
+ * **api:** manual updates ([e2b23a9](https://github.com/dodopayments/dodopayments-ruby/commit/e2b23a9dd83f0c56039c71b49f23bccec9e1def6))
30
+
31
+
32
+ ### Bug Fixes
33
+
34
+ * always send idempotency header when specified as a request option ([e666622](https://github.com/dodopayments/dodopayments-ruby/commit/e66662216d369a0553fe05943400645244270cbc))
35
+ * **client:** send correct HTTP path ([45d2036](https://github.com/dodopayments/dodopayments-ruby/commit/45d20360d35db21f868479dbb2186fdd2c09dfe3))
36
+ * restore ability to configure server environment as string during client construction ([684c1e2](https://github.com/dodopayments/dodopayments-ruby/commit/684c1e244a77b8af62ba1b47d9dd9511aa42be6c))
37
+
38
+
39
+ ### Chores
40
+
41
+ * **internal:** contribute.md and contributor QoL improvements ([360a982](https://github.com/dodopayments/dodopayments-ruby/commit/360a982c582c253c26ecb4038c75d204e8afdd01))
42
+ * refine `#inspect` and `#to_s` for model classes ([04244f9](https://github.com/dodopayments/dodopayments-ruby/commit/04244f9a079f650ab56b712cc4087c313cd52278))
43
+
3
44
  ## 1.14.0 (2025-04-17)
4
45
 
5
46
  Full Changelog: [v0.0.1-alpha.0...v1.14.0](https://github.com/dodopayments/dodopayments-ruby/compare/v0.0.1-alpha.0...v1.14.0)
data/README.md CHANGED
@@ -17,7 +17,7 @@ To use this gem, install via Bundler by adding the following to your application
17
17
  <!-- x-release-please-start-version -->
18
18
 
19
19
  ```ruby
20
- gem "dodopayments", "~> 1.14.0"
20
+ gem "dodopayments", "~> 1.17.0"
21
21
  ```
22
22
 
23
23
  <!-- x-release-please-end -->
@@ -38,6 +38,16 @@ payment = dodo_payments.payments.create
38
38
  puts(payment.payment_id)
39
39
  ```
40
40
 
41
+ ## Sorbet
42
+
43
+ This library is written with [Sorbet type definitions](https://sorbet.org/docs/rbi). However, there is no runtime dependency on the `sorbet-runtime`.
44
+
45
+ When using sorbet, it is recommended to use model classes as below. This provides stronger type checking and tooling integration.
46
+
47
+ ```ruby
48
+ dodo_payments.payments.create
49
+ ```
50
+
41
51
  ### Pagination
42
52
 
43
53
  List methods in the Dodo Payments API are paginated.
@@ -121,61 +131,32 @@ dodo_payments = Dodopayments::Client.new(
121
131
  dodo_payments.payments.create(request_options: {timeout: 5})
122
132
  ```
123
133
 
124
- ## LSP Support
125
-
126
- ### Solargraph
127
-
128
- This library includes [Solargraph](https://solargraph.org) support for both auto completion and go to definition.
129
-
130
- ```ruby
131
- gem "solargraph", group: :development
132
- ```
133
-
134
- After Solargraph is installed, **you must populate its index** either via the provided editor command, or by running the following in your terminal:
135
-
136
- ```sh
137
- bundle exec solargraph gems
138
- ```
139
-
140
- Note: if you had installed the gem either using a `git:` or `github:` URL, or had vendored the gem using bundler, you will need to set up your [`.solargraph.yml`](https://solargraph.org/guides/configuration) to include the path to the gem's `lib` directory.
141
-
142
- ```yaml
143
- include:
144
- - 'vendor/bundle/ruby/*/gems/dodopayments-*/lib/**/*.rb'
145
- ```
146
-
147
- Otherwise Solargraph will not be able to provide type information or auto-completion for any non-indexed libraries.
148
-
149
- ### Sorbet
150
-
151
- This library is written with [Sorbet type definitions](https://sorbet.org/docs/rbi). However, there is no runtime dependency on the `sorbet-runtime`.
134
+ ## Model DSL
152
135
 
153
- What this means is that while you can use Sorbet to type check your code statically, and benefit from the [Sorbet Language Server](https://sorbet.org/docs/lsp) in your editor, there is no runtime type checking and execution overhead from Sorbet itself.
136
+ This library uses a simple DSL to represent request parameters and response shapes in `lib/dodopayments/models`.
154
137
 
155
- Due to limitations with the Sorbet type system, where a method otherwise can take an instance of `Dodopayments::BaseModel` class, you will need to use the `**` splat operator to pass the arguments:
138
+ With the right [editor plugins](https://shopify.github.io/ruby-lsp), you can ctrl-click on elements of the DSL to navigate around and explore the library.
156
139
 
157
- Please follow Sorbet's [setup guides](https://sorbet.org/docs/adopting) for best experience.
140
+ In all places where a `BaseModel` type is specified, vanilla Ruby `Hash` can also be used. For example, the following are interchangeable as arguments:
158
141
 
159
142
  ```ruby
143
+ # This has tooling readability, for auto-completion, static analysis, and goto definition with supported language services
160
144
  params = Dodopayments::Models::PaymentCreateParams.new
161
145
 
162
- dodo_payments.payments.create(**params)
163
- ```
146
+ # This also works
147
+ params = {
164
148
 
165
- Note: **This library emits an intentional warning under the [`tapioca` toolchain](https://github.com/Shopify/tapioca)**. This is normal, and does not impact functionality.
149
+ }
150
+ ```
166
151
 
167
- ### Ruby LSP
152
+ ## Editor support
168
153
 
169
- The Ruby LSP has [best effort support](https://shopify.github.io/ruby-lsp/#guessed-types) for inferring type information from Ruby code, and as such it may not always be able to provide accurate type information.
154
+ A combination of [Shopify LSP](https://shopify.github.io/ruby-lsp) and [Solargraph](https://solargraph.org/) is recommended for non-[Sorbet](https://sorbet.org) users. The former is especially good at go to definition, while the latter has much better auto-completion support.
170
155
 
171
- ## Advanced
156
+ ## Advanced concepts
172
157
 
173
158
  ### Making custom/undocumented requests
174
159
 
175
- This library is typed for convenient access to the documented API.
176
-
177
- If you need to access undocumented endpoints, params, or response properties, the library can still be used.
178
-
179
160
  #### Undocumented request params
180
161
 
181
162
  If you want to explicitly send an extra param, you can do so with the `extra_query`, `extra_body`, and `extra_headers` under the `request_options:` parameter when making a requests as seen in examples above.
@@ -186,15 +167,15 @@ To make requests to undocumented endpoints, you can make requests using `client.
186
167
 
187
168
  ```ruby
188
169
  response = client.request(
189
- method: :post,
190
- path: '/undocumented/endpoint',
191
- query: {"dog": "woof"},
192
- headers: {"useful-header": "interesting-value"},
193
- body: {"he": "llo"},
194
- )
170
+ method: :post,
171
+ path: '/undocumented/endpoint',
172
+ query: {"dog": "woof"},
173
+ headers: {"useful-header": "interesting-value"},
174
+ body: {"he": "llo"},
175
+ )
195
176
  ```
196
177
 
197
- ### Concurrency & Connection Pooling
178
+ ### Concurrency & connection pooling
198
179
 
199
180
  The `Dodopayments::Client` instances are thread-safe, and should be re-used across multiple threads. By default, each `Client` have their own HTTP connection pool, with a maximum number of connections equal to thread count.
200
181
 
@@ -204,6 +185,30 @@ Unless otherwise specified, other classes in the SDK do not have locks protectin
204
185
 
205
186
  Currently, `Dodopayments::Client` instances are only fork-safe if there are no in-flight HTTP requests.
206
187
 
188
+ ### Sorbet
189
+
190
+ #### Enums
191
+
192
+ Sorbet's typed enums require sub-classing of the [`T::Enum` class](https://sorbet.org/docs/tenum) from the `sorbet-runtime` gem.
193
+
194
+ Since this library does not depend on `sorbet-runtime`, it uses a [`T.all` intersection type](https://sorbet.org/docs/intersection-types) with a ruby primitive type to construct a "tagged alias" instead.
195
+
196
+ ```ruby
197
+ module Dodopayments::Models::IntentStatus
198
+ # This alias aids language service driven navigation.
199
+ TaggedSymbol = T.type_alias { T.all(Symbol, Dodopayments::Models::IntentStatus) }
200
+ end
201
+ ```
202
+
203
+ #### Argument passing trick
204
+
205
+ It is possible to pass a compatible model / parameter class to a method that expects keyword arguments by using the `**` splat operator.
206
+
207
+ ```ruby
208
+ params = Dodopayments::Models::PaymentCreateParams.new
209
+ dodo_payments.payments.create(**params)
210
+ ```
211
+
207
212
  ## Versioning
208
213
 
209
214
  This package follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions. As the library is in initial development and has a major version of `0`, APIs may change at any time.
@@ -213,3 +218,7 @@ This package considers improvements to the (non-runtime) `*.rbi` and `*.rbs` typ
213
218
  ## Requirements
214
219
 
215
220
  Ruby 3.1.0 or higher.
221
+
222
+ ## Contributing
223
+
224
+ See [the contributing documentation](https://github.com/dodopayments/dodopayments-ruby/tree/main/CONTRIBUTING.md).
@@ -100,13 +100,14 @@ module Dodopayments
100
100
  bearer_token: ENV["DODO_PAYMENTS_API_KEY"],
101
101
  environment: nil,
102
102
  base_url: ENV["DODO_PAYMENTS_BASE_URL"],
103
- max_retries: DEFAULT_MAX_RETRIES,
104
- timeout: DEFAULT_TIMEOUT_IN_SECONDS,
105
- initial_retry_delay: DEFAULT_INITIAL_RETRY_DELAY,
106
- max_retry_delay: DEFAULT_MAX_RETRY_DELAY
103
+ max_retries: Dodopayments::Client::DEFAULT_MAX_RETRIES,
104
+ timeout: Dodopayments::Client::DEFAULT_TIMEOUT_IN_SECONDS,
105
+ initial_retry_delay: Dodopayments::Client::DEFAULT_INITIAL_RETRY_DELAY,
106
+ max_retry_delay: Dodopayments::Client::DEFAULT_MAX_RETRY_DELAY
107
107
  )
108
- base_url ||= ENVIRONMENTS.fetch(environment || :production) do
109
- raise ArgumentError.new("environment must be one of #{ENVIRONMENTS.keys}, got #{environment}")
108
+ base_url ||= Dodopayments::Client::ENVIRONMENTS.fetch(environment&.to_sym || :production) do
109
+ message = "environment must be one of #{Dodopayments::Client::ENVIRONMENTS.keys}, got #{environment}"
110
+ raise ArgumentError.new(message)
110
111
  end
111
112
 
112
113
  if bearer_token.nil?
@@ -25,7 +25,7 @@ module Dodopayments
25
25
  end
26
26
 
27
27
  # @raise [Dodopayments::HTTP::Error]
28
- # @return [Dodopayments::Internal::DefaultPageNumberPagination]
28
+ # @return [self]
29
29
  def next_page
30
30
  unless next_page?
31
31
  message = "No more pages available. Please check #next_page? before calling ##{__method__}"
@@ -216,9 +216,9 @@ module Dodopayments
216
216
  #
217
217
  # @option req [Symbol, nil] :unwrap
218
218
  #
219
- # @option req [Class, nil] :page
219
+ # @option req [Class<Dodopayments::Internal::Type::BasePage>, nil] :page
220
220
  #
221
- # @option req [Class, nil] :stream
221
+ # @option req [Class<Dodopayments::Internal::Type::BaseStream>, nil] :stream
222
222
  #
223
223
  # @option req [Dodopayments::Internal::Type::Converter, Class, nil] :model
224
224
  #
@@ -253,7 +253,7 @@ module Dodopayments
253
253
 
254
254
  if @idempotency_header &&
255
255
  !headers.key?(@idempotency_header) &&
256
- !Net::HTTP::IDEMPOTENT_METHODS_.include?(method.to_s.upcase)
256
+ (!Net::HTTP::IDEMPOTENT_METHODS_.include?(method.to_s.upcase) || opts.key?(:idempotency_key))
257
257
  headers[@idempotency_header] = opts.fetch(:idempotency_key) { generate_idempotency_key }
258
258
  end
259
259
 
@@ -420,9 +420,9 @@ module Dodopayments
420
420
  #
421
421
  # @param unwrap [Symbol, nil]
422
422
  #
423
- # @param page [Class, nil]
423
+ # @param page [Class<Dodopayments::Internal::Type::BasePage>, nil]
424
424
  #
425
- # @param stream [Class, nil]
425
+ # @param stream [Class<Dodopayments::Internal::Type::BaseStream>, nil]
426
426
  #
427
427
  # @param model [Dodopayments::Internal::Type::Converter, Class, nil]
428
428
  #
@@ -61,7 +61,7 @@ module Dodopayments
61
61
  method.to_s.upcase,
62
62
  !body.nil?,
63
63
  method != :head,
64
- url.to_s
64
+ URI(url.to_s) # ensure we construct a URI class of the right scheme
65
65
  )
66
66
 
67
67
  headers.each { req[_1] = _2 }
@@ -28,13 +28,19 @@ module Dodopayments
28
28
  # @option spec [Proc] :union
29
29
  #
30
30
  # @option spec [Boolean] :"nil?"
31
+ #
32
+ # @return [Dodopayments::Internal::Type::ArrayOf]
31
33
  def self.[](...) = new(...)
32
34
 
35
+ # @api public
36
+ #
33
37
  # @param other [Object]
34
38
  #
35
39
  # @return [Boolean]
36
40
  def ===(other) = other.is_a?(Array) && other.all?(item_type)
37
41
 
42
+ # @api public
43
+ #
38
44
  # @param other [Object]
39
45
  #
40
46
  # @return [Boolean]
@@ -44,6 +50,11 @@ module Dodopayments
44
50
  # rubocop:enable Layout/LineLength
45
51
  end
46
52
 
53
+ # @api public
54
+ #
55
+ # @return [Integer]
56
+ def hash = [self.class, item_type].hash
57
+
47
58
  # @api private
48
59
  #
49
60
  # @param value [Array<Object>, Object]
@@ -4,12 +4,6 @@ module Dodopayments
4
4
  module Internal
5
5
  module Type
6
6
  # @abstract
7
- #
8
- # @example
9
- # # `attach_existing_customer` is a `Dodopayments::Models::AttachExistingCustomer`
10
- # attach_existing_customer => {
11
- # customer_id: customer_id
12
- # }
13
7
  class BaseModel
14
8
  extend Dodopayments::Internal::Type::Converter
15
9
 
@@ -96,11 +90,13 @@ module Dodopayments
96
90
  target, value, state: state
97
91
  )
98
92
  end
99
- rescue StandardError
93
+ rescue StandardError => e
100
94
  cls = self.class.name.split("::").last
101
- # rubocop:disable Layout/LineLength
102
- message = "Failed to parse #{cls}.#{__method__} from #{value.class} to #{target.inspect}. To get the unparsed API response, use #{cls}[:#{__method__}]."
103
- # rubocop:enable Layout/LineLength
95
+ message = [
96
+ "Failed to parse #{cls}.#{__method__} from #{value.class} to #{target.inspect}.",
97
+ "To get the unparsed API response, use #{cls}[#{__method__.inspect}].",
98
+ "Cause: #{e.message}"
99
+ ].join(" ")
104
100
  raise Dodopayments::Errors::ConversionError.new(message)
105
101
  end
106
102
  end
@@ -168,19 +164,33 @@ module Dodopayments
168
164
  @mode = nil
169
165
  end
170
166
 
167
+ # @api public
168
+ #
171
169
  # @param other [Object]
172
170
  #
173
171
  # @return [Boolean]
174
172
  def ==(other)
175
173
  other.is_a?(Class) && other <= Dodopayments::Internal::Type::BaseModel && other.fields == fields
176
174
  end
175
+
176
+ # @api public
177
+ #
178
+ # @return [Integer]
179
+ def hash = fields.hash
177
180
  end
178
181
 
182
+ # @api public
183
+ #
179
184
  # @param other [Object]
180
185
  #
181
186
  # @return [Boolean]
182
187
  def ==(other) = self.class == other.class && @data == other.to_h
183
188
 
189
+ # @api public
190
+ #
191
+ # @return [Integer]
192
+ def hash = [self.class, @data].hash
193
+
184
194
  class << self
185
195
  # @api private
186
196
  #
@@ -294,6 +304,8 @@ module Dodopayments
294
304
  end
295
305
  end
296
306
 
307
+ # @api public
308
+ #
297
309
  # Returns the raw value associated with the given key, if found. Otherwise, nil is
298
310
  # returned.
299
311
  #
@@ -312,6 +324,8 @@ module Dodopayments
312
324
  @data[key]
313
325
  end
314
326
 
327
+ # @api public
328
+ #
315
329
  # Returns a Hash of the data underlying this object. O(1)
316
330
  #
317
331
  # Keys are Symbols and values are the raw values from the response. The return
@@ -341,11 +355,38 @@ module Dodopayments
341
355
  .to_h
342
356
  end
343
357
 
358
+ class << self
359
+ # @api private
360
+ #
361
+ # @param model [Dodopayments::Internal::Type::BaseModel]
362
+ #
363
+ # @return [Hash{Symbol=>Object}]
364
+ def walk(model)
365
+ walk = ->(x) do
366
+ case x
367
+ in Dodopayments::Internal::Type::BaseModel
368
+ walk.call(x.to_h)
369
+ in Hash
370
+ x.transform_values(&walk)
371
+ in Array
372
+ x.map(&walk)
373
+ else
374
+ x
375
+ end
376
+ end
377
+ walk.call(model)
378
+ end
379
+ end
380
+
381
+ # @api public
382
+ #
344
383
  # @param a [Object]
345
384
  #
346
385
  # @return [String]
347
386
  def to_json(*a) = Dodopayments::Internal::Type::Converter.dump(self.class, self).to_json(*a)
348
387
 
388
+ # @api public
389
+ #
349
390
  # @param a [Object]
350
391
  #
351
392
  # @return [String]
@@ -353,7 +394,7 @@ module Dodopayments
353
394
 
354
395
  # Create a new instance of a model.
355
396
  #
356
- # @param data [Hash{Symbol=>Object}, Dodopayments::Internal::Type::BaseModel]
397
+ # @param data [Hash{Symbol=>Object}, self]
357
398
  def initialize(data = {})
358
399
  case Dodopayments::Internal::Util.coerce_hash(data)
359
400
  in Hash => coerced
@@ -376,31 +417,26 @@ module Dodopayments
376
417
  depth = depth.succ
377
418
  deferred = fields.transform_values do |field|
378
419
  type, required, nilable = field.fetch_values(:type, :required, :nilable)
379
- -> do
380
- [
381
- Dodopayments::Internal::Type::Converter.inspect(type, depth: depth),
382
- !required || nilable ? "nil" : nil
383
- ].compact.join(" | ")
384
- end
385
- .tap { _1.define_singleton_method(:inspect) { call } }
420
+ inspected = [
421
+ Dodopayments::Internal::Type::Converter.inspect(type, depth: depth),
422
+ !required || nilable ? "nil" : nil
423
+ ].compact.join(" | ")
424
+ -> { inspected }.tap { _1.define_singleton_method(:inspect) { call } }
386
425
  end
387
426
 
388
427
  "#{name}[#{deferred.inspect}]"
389
428
  end
390
429
  end
391
430
 
392
- # @api private
431
+ # @api public
393
432
  #
394
433
  # @return [String]
395
- def inspect
396
- rows = @data.map do
397
- "#{_1}=#{self.class.known_fields.key?(_1) ? public_send(_1).inspect : ''}"
398
- rescue Dodopayments::Errors::ConversionError
399
- "#{_1}=#{_2.inspect}"
400
- end
434
+ def to_s = self.class.walk(@data).to_s
401
435
 
402
- "#<#{self.class}:0x#{object_id.to_s(16)} #{rows.join(' ')}>"
403
- end
436
+ # @api private
437
+ #
438
+ # @return [String]
439
+ def inspect = "#<#{self.class}:0x#{object_id.to_s(16)} #{self}>"
404
440
  end
405
441
  end
406
442
  end
@@ -3,19 +3,27 @@
3
3
  module Dodopayments
4
4
  module Internal
5
5
  module Type
6
+ # @api private
7
+ #
6
8
  # @generic Elem
7
9
  #
8
10
  # This module provides a base implementation for paginated responses in the SDK.
9
11
  module BasePage
10
12
  # rubocop:disable Lint/UnusedMethodArgument
11
13
 
14
+ # @api public
15
+ #
12
16
  # @return [Boolean]
13
17
  def next_page? = (raise NotImplementedError)
14
18
 
19
+ # @api public
20
+ #
15
21
  # @raise [Dodopayments::Errors::APIError]
16
- # @return [Dodopayments::Internal::Type::BasePage]
22
+ # @return [self]
17
23
  def next_page = (raise NotImplementedError)
18
24
 
25
+ # @api public
26
+ #
19
27
  # @param blk [Proc]
20
28
  #
21
29
  # @yieldparam [generic<Elem>]
@@ -13,11 +13,15 @@ module Dodopayments
13
13
 
14
14
  private_class_method :new
15
15
 
16
+ # @api public
17
+ #
16
18
  # @param other [Object]
17
19
  #
18
20
  # @return [Boolean]
19
21
  def self.===(other) = other == true || other == false
20
22
 
23
+ # @api public
24
+ #
21
25
  # @param other [Object]
22
26
  #
23
27
  # @return [Boolean]
@@ -46,18 +46,17 @@ module Dodopayments
46
46
  # All of the valid Symbol values for this enum.
47
47
  #
48
48
  # @return [Array<NilClass, Boolean, Integer, Float, Symbol>]
49
- def values = (@values ||= constants.map { const_get(_1) })
49
+ def values = constants.map { const_get(_1) }
50
50
 
51
- # @api private
51
+ # @api public
52
52
  #
53
- # Guard against thread safety issues by instantiating `@values`.
54
- private def finalize! = values
55
-
56
53
  # @param other [Object]
57
54
  #
58
55
  # @return [Boolean]
59
56
  def ===(other) = values.include?(other)
60
57
 
58
+ # @api public
59
+ #
61
60
  # @param other [Object]
62
61
  #
63
62
  # @return [Boolean]
@@ -67,6 +66,11 @@ module Dodopayments
67
66
  # rubocop:enable Style/CaseEquality
68
67
  end
69
68
 
69
+ # @api public
70
+ #
71
+ # @return [Integer]
72
+ def hash = values.to_set.hash
73
+
70
74
  # @api private
71
75
  #
72
76
  # Unlike with primitives, `Enum` additionally validates that the value is a member
@@ -28,8 +28,12 @@ module Dodopayments
28
28
  # @option spec [Proc] :union
29
29
  #
30
30
  # @option spec [Boolean] :"nil?"
31
+ #
32
+ # @return [Dodopayments::Internal::Type::HashOf]
31
33
  def self.[](...) = new(...)
32
34
 
35
+ # @api public
36
+ #
33
37
  # @param other [Object]
34
38
  #
35
39
  # @return [Boolean]
@@ -50,6 +54,8 @@ module Dodopayments
50
54
  end
51
55
  end
52
56
 
57
+ # @api public
58
+ #
53
59
  # @param other [Object]
54
60
  #
55
61
  # @return [Boolean]
@@ -59,6 +65,11 @@ module Dodopayments
59
65
  # rubocop:enable Layout/LineLength
60
66
  end
61
67
 
68
+ # @api public
69
+ #
70
+ # @return [Integer]
71
+ def hash = [self.class, item_type].hash
72
+
62
73
  # @api private
63
74
  #
64
75
  # @param value [Hash{Object=>Object}, Object]
@@ -13,6 +13,8 @@ module Dodopayments
13
13
 
14
14
  private_class_method :new
15
15
 
16
+ # @api public
17
+ #
16
18
  # @param other [Object]
17
19
  #
18
20
  # @return [Boolean]
@@ -25,6 +27,8 @@ module Dodopayments
25
27
  end
26
28
  end
27
29
 
30
+ # @api public
31
+ #
28
32
  # @param other [Object]
29
33
  #
30
34
  # @return [Boolean]
@@ -12,9 +12,8 @@ module Dodopayments
12
12
 
13
13
  # @param mod [Module]
14
14
  def self.included(mod)
15
- return unless mod <= Dodopayments::Internal::Type::BaseModel
15
+ raise ArgumentError.new(mod) unless mod <= Dodopayments::Internal::Type::BaseModel
16
16
 
17
- mod.extend(Dodopayments::Internal::Type::RequestParameters::Converter)
18
17
  mod.optional(:request_options, Dodopayments::RequestOptions)
19
18
  end
20
19