dodopayments 0.0.1.pre.alpha.0 → 1.16.1

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 (381) hide show
  1. checksums.yaml +4 -4
  2. data/.ignore +2 -0
  3. data/CHANGELOG.md +132 -0
  4. data/README.md +84 -23
  5. data/SECURITY.md +27 -0
  6. data/lib/dodopayments/client.rb +15 -19
  7. data/lib/dodopayments/errors.rb +168 -159
  8. data/lib/dodopayments/internal/default_page_number_pagination.rb +91 -0
  9. data/lib/dodopayments/internal/transport/base_client.rb +486 -0
  10. data/lib/dodopayments/internal/transport/pooled_net_requester.rb +197 -0
  11. data/lib/dodopayments/internal/type/array_of.rb +143 -0
  12. data/lib/dodopayments/internal/type/base_model.rb +423 -0
  13. data/lib/dodopayments/internal/type/base_page.rb +47 -0
  14. data/lib/dodopayments/internal/type/boolean.rb +60 -0
  15. data/lib/dodopayments/internal/type/converter.rb +271 -0
  16. data/lib/dodopayments/internal/type/enum.rb +129 -0
  17. data/lib/dodopayments/internal/type/hash_of.rb +163 -0
  18. data/lib/dodopayments/internal/type/io_like.rb +77 -0
  19. data/lib/dodopayments/internal/type/request_parameters.rb +49 -0
  20. data/lib/dodopayments/internal/type/union.rb +232 -0
  21. data/lib/dodopayments/internal/type/unknown.rb +64 -0
  22. data/lib/dodopayments/internal/util.rb +782 -0
  23. data/lib/dodopayments/internal.rb +12 -0
  24. data/lib/dodopayments/models/attach_existing_customer.rb +2 -2
  25. data/lib/dodopayments/models/billing_address.rb +2 -2
  26. data/lib/dodopayments/models/country_code.rb +7 -3
  27. data/lib/dodopayments/models/create_new_customer.rb +5 -5
  28. data/lib/dodopayments/models/customer.rb +3 -2
  29. data/lib/dodopayments/models/customer_create_params.rb +5 -4
  30. data/lib/dodopayments/models/customer_limited_details.rb +2 -2
  31. data/lib/dodopayments/models/customer_list_params.rb +5 -4
  32. data/lib/dodopayments/models/customer_portal_session.rb +2 -2
  33. data/lib/dodopayments/models/customer_request.rb +5 -6
  34. data/lib/dodopayments/models/customer_retrieve_params.rb +5 -4
  35. data/lib/dodopayments/models/customer_update_params.rb +5 -4
  36. data/lib/dodopayments/models/customers/customer_portal_create_params.rb +6 -5
  37. data/lib/dodopayments/models/discount.rb +7 -6
  38. data/lib/dodopayments/models/discount_create_params.rb +13 -12
  39. data/lib/dodopayments/models/discount_delete_params.rb +5 -4
  40. data/lib/dodopayments/models/discount_list_params.rb +5 -4
  41. data/lib/dodopayments/models/discount_retrieve_params.rb +5 -4
  42. data/lib/dodopayments/models/discount_type.rb +7 -2
  43. data/lib/dodopayments/models/discount_update_params.rb +11 -10
  44. data/lib/dodopayments/models/dispute.rb +4 -3
  45. data/lib/dodopayments/models/dispute_list_params.rb +5 -4
  46. data/lib/dodopayments/models/dispute_retrieve_params.rb +5 -4
  47. data/lib/dodopayments/models/dispute_stage.rb +7 -2
  48. data/lib/dodopayments/models/dispute_status.rb +7 -2
  49. data/lib/dodopayments/models/intent_status.rb +7 -2
  50. data/lib/dodopayments/models/invoices/payment_retrieve_params.rb +5 -4
  51. data/lib/dodopayments/models/license_activate_params.rb +5 -4
  52. data/lib/dodopayments/models/license_deactivate_params.rb +5 -4
  53. data/lib/dodopayments/models/license_key.rb +4 -3
  54. data/lib/dodopayments/models/license_key_duration.rb +2 -2
  55. data/lib/dodopayments/models/license_key_instance.rb +3 -2
  56. data/lib/dodopayments/models/license_key_instance_list_params.rb +5 -4
  57. data/lib/dodopayments/models/license_key_instance_retrieve_params.rb +5 -4
  58. data/lib/dodopayments/models/license_key_instance_update_params.rb +5 -4
  59. data/lib/dodopayments/models/license_key_list_params.rb +5 -4
  60. data/lib/dodopayments/models/license_key_retrieve_params.rb +5 -4
  61. data/lib/dodopayments/models/license_key_status.rb +7 -2
  62. data/lib/dodopayments/models/license_key_update_params.rb +9 -8
  63. data/lib/dodopayments/models/license_validate_params.rb +5 -4
  64. data/lib/dodopayments/models/license_validate_response.rb +4 -3
  65. data/lib/dodopayments/models/misc_list_supported_countries_params.rb +5 -4
  66. data/lib/dodopayments/models/misc_list_supported_countries_response.rb +2 -1
  67. data/lib/dodopayments/models/one_time_product_cart_item.rb +4 -3
  68. data/lib/dodopayments/models/payment.rb +18 -11
  69. data/lib/dodopayments/models/payment_create_params.rb +232 -9
  70. data/lib/dodopayments/models/payment_create_response.rb +6 -5
  71. data/lib/dodopayments/models/payment_list_params.rb +5 -4
  72. data/lib/dodopayments/models/payment_list_response.rb +12 -5
  73. data/lib/dodopayments/models/payment_retrieve_params.rb +5 -4
  74. data/lib/dodopayments/models/payout_list_params.rb +5 -4
  75. data/lib/dodopayments/models/payout_list_response.rb +21 -6
  76. data/lib/dodopayments/models/price.rb +41 -30
  77. data/lib/dodopayments/models/product.rb +17 -10
  78. data/lib/dodopayments/models/product_create_params.rb +16 -11
  79. data/lib/dodopayments/models/product_delete_params.rb +5 -4
  80. data/lib/dodopayments/models/product_list_params.rb +10 -9
  81. data/lib/dodopayments/models/product_list_response.rb +30 -17
  82. data/lib/dodopayments/models/product_retrieve_params.rb +5 -4
  83. data/lib/dodopayments/models/product_unarchive_params.rb +5 -4
  84. data/lib/dodopayments/models/product_update_params.rb +22 -17
  85. data/lib/dodopayments/models/products/image_update_params.rb +6 -5
  86. data/lib/dodopayments/models/products/image_update_response.rb +3 -2
  87. data/lib/dodopayments/models/refund.rb +11 -4
  88. data/lib/dodopayments/models/refund_create_params.rb +6 -13
  89. data/lib/dodopayments/models/refund_list_params.rb +5 -4
  90. data/lib/dodopayments/models/refund_retrieve_params.rb +5 -4
  91. data/lib/dodopayments/models/refund_status.rb +7 -2
  92. data/lib/dodopayments/models/subscription.rb +21 -7
  93. data/lib/dodopayments/models/subscription_charge_params.rb +27 -0
  94. data/lib/dodopayments/models/subscription_charge_response.rb +20 -0
  95. data/lib/dodopayments/models/subscription_create_params.rb +262 -8
  96. data/lib/dodopayments/models/subscription_create_response.rb +6 -5
  97. data/lib/dodopayments/models/subscription_list_params.rb +5 -4
  98. data/lib/dodopayments/models/subscription_retrieve_params.rb +5 -4
  99. data/lib/dodopayments/models/subscription_status.rb +7 -2
  100. data/lib/dodopayments/models/subscription_update_params.rb +19 -6
  101. data/lib/dodopayments/models/time_interval.rb +7 -2
  102. data/lib/dodopayments/models/webhook_event.rb +3 -2
  103. data/lib/dodopayments/models/webhook_event_list_params.rb +6 -5
  104. data/lib/dodopayments/models/webhook_event_retrieve_params.rb +5 -4
  105. data/lib/dodopayments/request_options.rb +12 -47
  106. data/lib/dodopayments/resources/customers/customer_portal.rb +10 -8
  107. data/lib/dodopayments/resources/customers.rb +30 -29
  108. data/lib/dodopayments/resources/discounts.rb +45 -69
  109. data/lib/dodopayments/resources/disputes.rb +20 -22
  110. data/lib/dodopayments/resources/invoices/payments.rb +8 -5
  111. data/lib/dodopayments/resources/invoices.rb +2 -0
  112. data/lib/dodopayments/resources/license_key_instances.rb +23 -21
  113. data/lib/dodopayments/resources/license_keys.rb +27 -32
  114. data/lib/dodopayments/resources/licenses.rb +20 -18
  115. data/lib/dodopayments/resources/misc.rb +7 -3
  116. data/lib/dodopayments/resources/payments.rb +36 -43
  117. data/lib/dodopayments/resources/payouts.rb +9 -7
  118. data/lib/dodopayments/resources/products/images.rb +9 -7
  119. data/lib/dodopayments/resources/products.rb +59 -87
  120. data/lib/dodopayments/resources/refunds.rb +25 -29
  121. data/lib/dodopayments/resources/subscriptions.rb +68 -54
  122. data/lib/dodopayments/resources/webhook_events.rb +20 -21
  123. data/lib/dodopayments/version.rb +1 -1
  124. data/lib/dodopayments.rb +34 -7
  125. data/manifest.yaml +1 -0
  126. data/rbi/lib/dodopayments/client.rbi +32 -47
  127. data/rbi/lib/dodopayments/errors.rbi +125 -161
  128. data/rbi/lib/dodopayments/internal/default_page_number_pagination.rbi +18 -0
  129. data/rbi/lib/dodopayments/internal/transport/base_client.rbi +199 -0
  130. data/rbi/lib/dodopayments/internal/transport/pooled_net_requester.rbi +60 -0
  131. data/rbi/lib/dodopayments/internal/type/array_of.rbi +85 -0
  132. data/rbi/lib/dodopayments/internal/type/base_model.rbi +214 -0
  133. data/rbi/lib/dodopayments/internal/type/base_page.rbi +36 -0
  134. data/rbi/lib/dodopayments/internal/type/boolean.rbi +48 -0
  135. data/rbi/lib/dodopayments/internal/type/converter.rbi +120 -0
  136. data/rbi/lib/dodopayments/internal/type/enum.rbi +69 -0
  137. data/rbi/lib/dodopayments/internal/type/hash_of.rbi +85 -0
  138. data/rbi/lib/dodopayments/internal/type/io_like.rbi +46 -0
  139. data/rbi/lib/dodopayments/internal/type/request_parameters.rbi +21 -0
  140. data/rbi/lib/dodopayments/internal/type/union.rbi +77 -0
  141. data/rbi/lib/dodopayments/internal/type/unknown.rbi +40 -0
  142. data/rbi/lib/dodopayments/internal/util.rbi +297 -0
  143. data/rbi/lib/dodopayments/internal.rbi +12 -0
  144. data/rbi/lib/dodopayments/models/attach_existing_customer.rbi +4 -11
  145. data/rbi/lib/dodopayments/models/billing_address.rbi +20 -38
  146. data/rbi/lib/dodopayments/models/country_code.rbi +256 -256
  147. data/rbi/lib/dodopayments/models/create_new_customer.rbi +11 -30
  148. data/rbi/lib/dodopayments/models/customer.rbi +9 -41
  149. data/rbi/lib/dodopayments/models/customer_create_params.rbi +9 -26
  150. data/rbi/lib/dodopayments/models/customer_limited_details.rbi +6 -23
  151. data/rbi/lib/dodopayments/models/customer_list_params.rbi +8 -20
  152. data/rbi/lib/dodopayments/models/customer_portal_session.rbi +4 -11
  153. data/rbi/lib/dodopayments/models/customer_request.rbi +4 -7
  154. data/rbi/lib/dodopayments/models/customer_retrieve_params.rbi +6 -8
  155. data/rbi/lib/dodopayments/models/customer_update_params.rbi +8 -20
  156. data/rbi/lib/dodopayments/models/customers/customer_portal_create_params.rbi +7 -14
  157. data/rbi/lib/dodopayments/models/discount.rbi +20 -78
  158. data/rbi/lib/dodopayments/models/discount_create_params.rbi +23 -61
  159. data/rbi/lib/dodopayments/models/discount_delete_params.rbi +6 -8
  160. data/rbi/lib/dodopayments/models/discount_list_params.rbi +8 -20
  161. data/rbi/lib/dodopayments/models/discount_retrieve_params.rbi +6 -8
  162. data/rbi/lib/dodopayments/models/discount_type.rbi +8 -8
  163. data/rbi/lib/dodopayments/models/discount_update_params.rbi +21 -59
  164. data/rbi/lib/dodopayments/models/dispute.rbi +27 -59
  165. data/rbi/lib/dodopayments/models/dispute_list_params.rbi +19 -57
  166. data/rbi/lib/dodopayments/models/dispute_retrieve_params.rbi +6 -8
  167. data/rbi/lib/dodopayments/models/dispute_stage.rbi +10 -10
  168. data/rbi/lib/dodopayments/models/dispute_status.rbi +14 -14
  169. data/rbi/lib/dodopayments/models/intent_status.rbi +22 -18
  170. data/rbi/lib/dodopayments/models/invoices/payment_retrieve_params.rbi +6 -8
  171. data/rbi/lib/dodopayments/models/license_activate_params.rbi +8 -20
  172. data/rbi/lib/dodopayments/models/license_deactivate_params.rbi +8 -20
  173. data/rbi/lib/dodopayments/models/license_key.rbi +19 -82
  174. data/rbi/lib/dodopayments/models/license_key_duration.rbi +8 -20
  175. data/rbi/lib/dodopayments/models/license_key_instance.rbi +8 -35
  176. data/rbi/lib/dodopayments/models/license_key_instance_list_params.rbi +9 -26
  177. data/rbi/lib/dodopayments/models/license_key_instance_retrieve_params.rbi +6 -8
  178. data/rbi/lib/dodopayments/models/license_key_instance_update_params.rbi +7 -17
  179. data/rbi/lib/dodopayments/models/license_key_list_params.rbi +21 -40
  180. data/rbi/lib/dodopayments/models/license_key_retrieve_params.rbi +6 -8
  181. data/rbi/lib/dodopayments/models/license_key_status.rbi +10 -10
  182. data/rbi/lib/dodopayments/models/license_key_update_params.rbi +12 -29
  183. data/rbi/lib/dodopayments/models/license_validate_params.rbi +8 -20
  184. data/rbi/lib/dodopayments/models/license_validate_response.rbi +4 -11
  185. data/rbi/lib/dodopayments/models/misc_list_supported_countries_params.rbi +6 -8
  186. data/rbi/lib/dodopayments/models/misc_list_supported_countries_response.rbi +5 -1
  187. data/rbi/lib/dodopayments/models/one_time_product_cart_item.rbi +8 -24
  188. data/rbi/lib/dodopayments/models/payment.rbi +197 -308
  189. data/rbi/lib/dodopayments/models/payment_create_params.rbi +261 -61
  190. data/rbi/lib/dodopayments/models/payment_create_response.rbi +16 -60
  191. data/rbi/lib/dodopayments/models/payment_list_params.rbi +16 -54
  192. data/rbi/lib/dodopayments/models/payment_list_response.rbi +178 -228
  193. data/rbi/lib/dodopayments/models/payment_retrieve_params.rbi +6 -8
  194. data/rbi/lib/dodopayments/models/payout_list_params.rbi +8 -20
  195. data/rbi/lib/dodopayments/models/payout_list_response.rbi +197 -271
  196. data/rbi/lib/dodopayments/models/price.rbi +368 -464
  197. data/rbi/lib/dodopayments/models/product.rbi +48 -119
  198. data/rbi/lib/dodopayments/models/product_create_params.rbi +46 -86
  199. data/rbi/lib/dodopayments/models/product_delete_params.rbi +6 -8
  200. data/rbi/lib/dodopayments/models/product_list_params.rbi +15 -34
  201. data/rbi/lib/dodopayments/models/product_list_response.rbi +209 -275
  202. data/rbi/lib/dodopayments/models/product_retrieve_params.rbi +6 -8
  203. data/rbi/lib/dodopayments/models/product_unarchive_params.rbi +6 -8
  204. data/rbi/lib/dodopayments/models/product_update_params.rbi +55 -102
  205. data/rbi/lib/dodopayments/models/products/image_update_params.rbi +7 -14
  206. data/rbi/lib/dodopayments/models/products/image_update_response.rbi +5 -17
  207. data/rbi/lib/dodopayments/models/refund.rbi +181 -213
  208. data/rbi/lib/dodopayments/models/refund_create_params.rbi +13 -39
  209. data/rbi/lib/dodopayments/models/refund_list_params.rbi +15 -48
  210. data/rbi/lib/dodopayments/models/refund_retrieve_params.rbi +6 -8
  211. data/rbi/lib/dodopayments/models/refund_status.rbi +11 -11
  212. data/rbi/lib/dodopayments/models/subscription.rbi +202 -283
  213. data/rbi/lib/dodopayments/models/subscription_charge_params.rbi +27 -0
  214. data/rbi/lib/dodopayments/models/subscription_charge_response.rbi +16 -0
  215. data/rbi/lib/dodopayments/models/subscription_create_params.rbi +315 -69
  216. data/rbi/lib/dodopayments/models/subscription_create_response.rbi +15 -51
  217. data/rbi/lib/dodopayments/models/subscription_list_params.rbi +15 -48
  218. data/rbi/lib/dodopayments/models/subscription_retrieve_params.rbi +6 -8
  219. data/rbi/lib/dodopayments/models/subscription_status.rbi +14 -14
  220. data/rbi/lib/dodopayments/models/subscription_update_params.rbi +25 -21
  221. data/rbi/lib/dodopayments/models/time_interval.rbi +11 -11
  222. data/rbi/lib/dodopayments/models/webhook_event.rbi +11 -54
  223. data/rbi/lib/dodopayments/models/webhook_event_list_params.rbi +12 -45
  224. data/rbi/lib/dodopayments/models/webhook_event_retrieve_params.rbi +6 -8
  225. data/rbi/lib/dodopayments/request_options.rbi +18 -81
  226. data/rbi/lib/dodopayments/resources/customers/customer_portal.rbi +5 -7
  227. data/rbi/lib/dodopayments/resources/customers.rbi +12 -20
  228. data/rbi/lib/dodopayments/resources/discounts.rbi +27 -37
  229. data/rbi/lib/dodopayments/resources/disputes.rbi +9 -13
  230. data/rbi/lib/dodopayments/resources/invoices/payments.rbi +4 -5
  231. data/rbi/lib/dodopayments/resources/invoices.rbi +3 -4
  232. data/rbi/lib/dodopayments/resources/license_key_instances.rbi +9 -15
  233. data/rbi/lib/dodopayments/resources/license_keys.rbi +13 -19
  234. data/rbi/lib/dodopayments/resources/licenses.rbi +8 -11
  235. data/rbi/lib/dodopayments/resources/misc.rbi +12 -6
  236. data/rbi/lib/dodopayments/resources/payments.rbi +32 -21
  237. data/rbi/lib/dodopayments/resources/payouts.rbi +5 -7
  238. data/rbi/lib/dodopayments/resources/products/images.rbi +4 -6
  239. data/rbi/lib/dodopayments/resources/products.rbi +43 -44
  240. data/rbi/lib/dodopayments/resources/refunds.rbi +10 -20
  241. data/rbi/lib/dodopayments/resources/subscriptions.rbi +57 -24
  242. data/rbi/lib/dodopayments/resources/webhook_events.rbi +7 -10
  243. data/rbi/lib/dodopayments/version.rbi +1 -1
  244. data/sig/dodopayments/client.rbs +8 -8
  245. data/sig/dodopayments/errors.rbs +98 -96
  246. data/sig/dodopayments/internal/default_page_number_pagination.rbs +11 -0
  247. data/sig/dodopayments/internal/transport/base_client.rbs +110 -0
  248. data/sig/dodopayments/internal/transport/pooled_net_requester.rbs +41 -0
  249. data/sig/dodopayments/internal/type/array_of.rbs +43 -0
  250. data/sig/dodopayments/internal/type/base_model.rbs +92 -0
  251. data/sig/dodopayments/internal/type/base_page.rbs +24 -0
  252. data/sig/dodopayments/internal/type/boolean.rbs +23 -0
  253. data/sig/dodopayments/internal/type/converter.rbs +54 -0
  254. data/sig/dodopayments/internal/type/enum.rbs +29 -0
  255. data/sig/dodopayments/internal/type/hash_of.rbs +43 -0
  256. data/sig/dodopayments/internal/type/io_like.rbs +23 -0
  257. data/sig/dodopayments/internal/type/request_parameters.rbs +15 -0
  258. data/sig/dodopayments/internal/type/union.rbs +47 -0
  259. data/sig/dodopayments/internal/type/unknown.rbs +23 -0
  260. data/sig/dodopayments/internal/util.rbs +156 -0
  261. data/sig/dodopayments/internal.rbs +5 -0
  262. data/sig/dodopayments/models/attach_existing_customer.rbs +2 -7
  263. data/sig/dodopayments/models/billing_address.rbs +8 -12
  264. data/sig/dodopayments/models/country_code.rbs +4 -2
  265. data/sig/dodopayments/models/create_new_customer.rbs +7 -12
  266. data/sig/dodopayments/models/customer.rbs +9 -13
  267. data/sig/dodopayments/models/customer_create_params.rbs +10 -15
  268. data/sig/dodopayments/models/customer_limited_details.rbs +2 -7
  269. data/sig/dodopayments/models/customer_list_params.rbs +9 -14
  270. data/sig/dodopayments/models/customer_portal_session.rbs +2 -7
  271. data/sig/dodopayments/models/customer_request.rbs +4 -2
  272. data/sig/dodopayments/models/customer_retrieve_params.rbs +6 -10
  273. data/sig/dodopayments/models/customer_update_params.rbs +9 -14
  274. data/sig/dodopayments/models/customers/customer_portal_create_params.rbs +8 -13
  275. data/sig/dodopayments/models/discount.rbs +14 -18
  276. data/sig/dodopayments/models/discount_create_params.rbs +14 -19
  277. data/sig/dodopayments/models/discount_delete_params.rbs +6 -10
  278. data/sig/dodopayments/models/discount_list_params.rbs +9 -14
  279. data/sig/dodopayments/models/discount_retrieve_params.rbs +6 -10
  280. data/sig/dodopayments/models/discount_type.rbs +4 -2
  281. data/sig/dodopayments/models/discount_update_params.rbs +14 -19
  282. data/sig/dodopayments/models/dispute.rbs +11 -15
  283. data/sig/dodopayments/models/dispute_list_params.rbs +14 -19
  284. data/sig/dodopayments/models/dispute_retrieve_params.rbs +6 -10
  285. data/sig/dodopayments/models/dispute_stage.rbs +4 -2
  286. data/sig/dodopayments/models/dispute_status.rbs +4 -2
  287. data/sig/dodopayments/models/intent_status.rbs +4 -2
  288. data/sig/dodopayments/models/invoices/payment_retrieve_params.rbs +6 -10
  289. data/sig/dodopayments/models/license_activate_params.rbs +10 -14
  290. data/sig/dodopayments/models/license_deactivate_params.rbs +9 -14
  291. data/sig/dodopayments/models/license_key.rbs +15 -19
  292. data/sig/dodopayments/models/license_key_duration.rbs +5 -7
  293. data/sig/dodopayments/models/license_key_instance.rbs +8 -13
  294. data/sig/dodopayments/models/license_key_instance_list_params.rbs +10 -15
  295. data/sig/dodopayments/models/license_key_instance_retrieve_params.rbs +5 -10
  296. data/sig/dodopayments/models/license_key_instance_update_params.rbs +8 -10
  297. data/sig/dodopayments/models/license_key_list_params.rbs +12 -17
  298. data/sig/dodopayments/models/license_key_retrieve_params.rbs +6 -10
  299. data/sig/dodopayments/models/license_key_status.rbs +4 -2
  300. data/sig/dodopayments/models/license_key_update_params.rbs +10 -15
  301. data/sig/dodopayments/models/license_validate_params.rbs +9 -14
  302. data/sig/dodopayments/models/license_validate_response.rbs +2 -7
  303. data/sig/dodopayments/models/misc_list_supported_countries_params.rbs +5 -10
  304. data/sig/dodopayments/models/one_time_product_cart_item.rbs +6 -7
  305. data/sig/dodopayments/models/payment.rbs +28 -35
  306. data/sig/dodopayments/models/payment_create_params.rbs +373 -20
  307. data/sig/dodopayments/models/payment_create_response.rbs +11 -16
  308. data/sig/dodopayments/models/payment_list_params.rbs +14 -19
  309. data/sig/dodopayments/models/payment_list_response.rbs +17 -20
  310. data/sig/dodopayments/models/payment_retrieve_params.rbs +6 -10
  311. data/sig/dodopayments/models/payout_list_params.rbs +9 -14
  312. data/sig/dodopayments/models/payout_list_response.rbs +30 -28
  313. data/sig/dodopayments/models/price.rbs +37 -41
  314. data/sig/dodopayments/models/product.rbs +22 -24
  315. data/sig/dodopayments/models/product_create_params.rbs +20 -23
  316. data/sig/dodopayments/models/product_delete_params.rbs +6 -10
  317. data/sig/dodopayments/models/product_list_params.rbs +11 -16
  318. data/sig/dodopayments/models/product_list_response.rbs +24 -25
  319. data/sig/dodopayments/models/product_retrieve_params.rbs +6 -10
  320. data/sig/dodopayments/models/product_unarchive_params.rbs +6 -10
  321. data/sig/dodopayments/models/product_update_params.rbs +21 -24
  322. data/sig/dodopayments/models/products/image_update_params.rbs +9 -13
  323. data/sig/dodopayments/models/products/image_update_response.rbs +2 -7
  324. data/sig/dodopayments/models/refund.rbs +15 -15
  325. data/sig/dodopayments/models/refund_create_params.rbs +10 -18
  326. data/sig/dodopayments/models/refund_list_params.rbs +13 -18
  327. data/sig/dodopayments/models/refund_retrieve_params.rbs +6 -10
  328. data/sig/dodopayments/models/refund_status.rbs +4 -2
  329. data/sig/dodopayments/models/subscription.rbs +29 -27
  330. data/sig/dodopayments/models/subscription_charge_params.rbs +21 -0
  331. data/sig/dodopayments/models/subscription_charge_response.rbs +13 -0
  332. data/sig/dodopayments/models/subscription_create_params.rbs +391 -22
  333. data/sig/dodopayments/models/subscription_create_response.rbs +10 -15
  334. data/sig/dodopayments/models/subscription_list_params.rbs +13 -18
  335. data/sig/dodopayments/models/subscription_retrieve_params.rbs +6 -10
  336. data/sig/dodopayments/models/subscription_status.rbs +4 -2
  337. data/sig/dodopayments/models/subscription_update_params.rbs +18 -15
  338. data/sig/dodopayments/models/time_interval.rbs +4 -2
  339. data/sig/dodopayments/models/webhook_event.rbs +11 -15
  340. data/sig/dodopayments/models/webhook_event_list_params.rbs +13 -18
  341. data/sig/dodopayments/models/webhook_event_retrieve_params.rbs +6 -10
  342. data/sig/dodopayments/request_options.rbs +3 -13
  343. data/sig/dodopayments/resources/customers/customer_portal.rbs +5 -11
  344. data/sig/dodopayments/resources/customers.rbs +21 -42
  345. data/sig/dodopayments/resources/discounts.rbs +34 -61
  346. data/sig/dodopayments/resources/disputes.rbs +14 -24
  347. data/sig/dodopayments/resources/invoices/payments.rbs +4 -10
  348. data/sig/dodopayments/resources/license_key_instances.rbs +15 -32
  349. data/sig/dodopayments/resources/license_keys.rbs +19 -36
  350. data/sig/dodopayments/resources/licenses.rbs +15 -30
  351. data/sig/dodopayments/resources/misc.rbs +3 -8
  352. data/sig/dodopayments/resources/payments.rbs +28 -39
  353. data/sig/dodopayments/resources/payouts.rbs +5 -9
  354. data/sig/dodopayments/resources/products/images.rbs +5 -11
  355. data/sig/dodopayments/resources/products.rbs +45 -71
  356. data/sig/dodopayments/resources/refunds.rbs +18 -33
  357. data/sig/dodopayments/resources/subscriptions.rbs +44 -54
  358. data/sig/dodopayments/resources/webhook_events.rbs +13 -24
  359. data/sig/dodopayments/version.rbs +1 -1
  360. metadata +63 -27
  361. data/lib/dodopayments/base_client.rb +0 -453
  362. data/lib/dodopayments/base_model.rb +0 -1217
  363. data/lib/dodopayments/base_page.rb +0 -62
  364. data/lib/dodopayments/default_page_number_pagination.rb +0 -97
  365. data/lib/dodopayments/extern.rb +0 -9
  366. data/lib/dodopayments/pooled_net_requester.rb +0 -164
  367. data/lib/dodopayments/util.rb +0 -717
  368. data/rbi/lib/dodopayments/base_client.rbi +0 -186
  369. data/rbi/lib/dodopayments/base_model.rbi +0 -606
  370. data/rbi/lib/dodopayments/base_page.rbi +0 -40
  371. data/rbi/lib/dodopayments/default_page_number_pagination.rbi +0 -17
  372. data/rbi/lib/dodopayments/extern.rbi +0 -8
  373. data/rbi/lib/dodopayments/pooled_net_requester.rbi +0 -47
  374. data/rbi/lib/dodopayments/util.rbi +0 -270
  375. data/sig/dodopayments/base_client.rbs +0 -103
  376. data/sig/dodopayments/base_model.rbs +0 -246
  377. data/sig/dodopayments/base_page.rbs +0 -20
  378. data/sig/dodopayments/default_page_number_pagination.rbs +0 -7
  379. data/sig/dodopayments/extern.rbs +0 -4
  380. data/sig/dodopayments/pooled_net_requester.rbs +0 -30
  381. data/sig/dodopayments/util.rbs +0 -136
@@ -0,0 +1,486 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dodopayments
4
+ module Internal
5
+ module Transport
6
+ # @api private
7
+ #
8
+ # @abstract
9
+ class BaseClient
10
+ # from whatwg fetch spec
11
+ MAX_REDIRECTS = 20
12
+
13
+ # rubocop:disable Style/MutableConstant
14
+ PLATFORM_HEADERS =
15
+ {
16
+ "x-stainless-arch" => Dodopayments::Internal::Util.arch,
17
+ "x-stainless-lang" => "ruby",
18
+ "x-stainless-os" => Dodopayments::Internal::Util.os,
19
+ "x-stainless-package-version" => Dodopayments::VERSION,
20
+ "x-stainless-runtime" => ::RUBY_ENGINE,
21
+ "x-stainless-runtime-version" => ::RUBY_ENGINE_VERSION
22
+ }
23
+ # rubocop:enable Style/MutableConstant
24
+
25
+ class << self
26
+ # @api private
27
+ #
28
+ # @param req [Hash{Symbol=>Object}]
29
+ #
30
+ # @raise [ArgumentError]
31
+ def validate!(req)
32
+ keys = [:method, :path, :query, :headers, :body, :unwrap, :page, :stream, :model, :options]
33
+ case req
34
+ in Hash
35
+ req.each_key do |k|
36
+ unless keys.include?(k)
37
+ raise ArgumentError.new("Request `req` keys must be one of #{keys}, got #{k.inspect}")
38
+ end
39
+ end
40
+ else
41
+ raise ArgumentError.new("Request `req` must be a Hash or RequestOptions, got #{req.inspect}")
42
+ end
43
+ end
44
+
45
+ # @api private
46
+ #
47
+ # @param status [Integer]
48
+ # @param headers [Hash{String=>String}, Net::HTTPHeader]
49
+ #
50
+ # @return [Boolean]
51
+ def should_retry?(status, headers:)
52
+ coerced = Dodopayments::Internal::Util.coerce_boolean(headers["x-should-retry"])
53
+ case [coerced, status]
54
+ in [true | false, _]
55
+ coerced
56
+ in [_, 408 | 409 | 429 | (500..)]
57
+ # retry on:
58
+ # 408: timeouts
59
+ # 409: locks
60
+ # 429: rate limits
61
+ # 500+: unknown errors
62
+ true
63
+ else
64
+ false
65
+ end
66
+ end
67
+
68
+ # @api private
69
+ #
70
+ # @param request [Hash{Symbol=>Object}] .
71
+ #
72
+ # @option request [Symbol] :method
73
+ #
74
+ # @option request [URI::Generic] :url
75
+ #
76
+ # @option request [Hash{String=>String}] :headers
77
+ #
78
+ # @option request [Object] :body
79
+ #
80
+ # @option request [Integer] :max_retries
81
+ #
82
+ # @option request [Float] :timeout
83
+ #
84
+ # @param status [Integer]
85
+ #
86
+ # @param response_headers [Hash{String=>String}, Net::HTTPHeader]
87
+ #
88
+ # @return [Hash{Symbol=>Object}]
89
+ def follow_redirect(request, status:, response_headers:)
90
+ method, url, headers = request.fetch_values(:method, :url, :headers)
91
+ location =
92
+ Kernel.then do
93
+ URI.join(url, response_headers["location"])
94
+ rescue ArgumentError
95
+ message = "Server responded with status #{status} but no valid location header."
96
+ raise Dodopayments::Errors::APIConnectionError.new(
97
+ url: url,
98
+ response: response_headers,
99
+ message: message
100
+ )
101
+ end
102
+
103
+ request = {**request, url: location}
104
+
105
+ case [url.scheme, location.scheme]
106
+ in ["https", "http"]
107
+ message = "Tried to redirect to a insecure URL"
108
+ raise Dodopayments::Errors::APIConnectionError.new(
109
+ url: url,
110
+ response: response_headers,
111
+ message: message
112
+ )
113
+ else
114
+ nil
115
+ end
116
+
117
+ # from whatwg fetch spec
118
+ case [status, method]
119
+ in [301 | 302, :post] | [303, _]
120
+ drop = %w[content-encoding content-language content-length content-location content-type]
121
+ request = {
122
+ **request,
123
+ method: method == :head ? :head : :get,
124
+ headers: headers.except(*drop),
125
+ body: nil
126
+ }
127
+ else
128
+ end
129
+
130
+ # from undici
131
+ if Dodopayments::Internal::Util.uri_origin(url) != Dodopayments::Internal::Util.uri_origin(location)
132
+ drop = %w[authorization cookie host proxy-authorization]
133
+ request = {**request, headers: request.fetch(:headers).except(*drop)}
134
+ end
135
+
136
+ request
137
+ end
138
+
139
+ # @api private
140
+ #
141
+ # @param status [Integer, Dodopayments::Errors::APIConnectionError]
142
+ # @param stream [Enumerable<String>, nil]
143
+ def reap_connection!(status, stream:)
144
+ case status
145
+ in (..199) | (300..499)
146
+ stream&.each { next }
147
+ in Dodopayments::Errors::APIConnectionError | (500..)
148
+ Dodopayments::Internal::Util.close_fused!(stream)
149
+ else
150
+ end
151
+ end
152
+ end
153
+
154
+ # @api private
155
+ # @return [Dodopayments::Internal::Transport::PooledNetRequester]
156
+ attr_accessor :requester
157
+
158
+ # @api private
159
+ #
160
+ # @param base_url [String]
161
+ # @param timeout [Float]
162
+ # @param max_retries [Integer]
163
+ # @param initial_retry_delay [Float]
164
+ # @param max_retry_delay [Float]
165
+ # @param headers [Hash{String=>String, Integer, Array<String, Integer, nil>, nil}]
166
+ # @param idempotency_header [String, nil]
167
+ def initialize(
168
+ base_url:,
169
+ timeout: 0.0,
170
+ max_retries: 0,
171
+ initial_retry_delay: 0.0,
172
+ max_retry_delay: 0.0,
173
+ headers: {},
174
+ idempotency_header: nil
175
+ )
176
+ @requester = Dodopayments::Internal::Transport::PooledNetRequester.new
177
+ @headers = Dodopayments::Internal::Util.normalized_headers(
178
+ self.class::PLATFORM_HEADERS,
179
+ {
180
+ "accept" => "application/json",
181
+ "content-type" => "application/json"
182
+ },
183
+ headers
184
+ )
185
+ @base_url = Dodopayments::Internal::Util.parse_uri(base_url)
186
+ @idempotency_header = idempotency_header&.to_s&.downcase
187
+ @max_retries = max_retries
188
+ @timeout = timeout
189
+ @initial_retry_delay = initial_retry_delay
190
+ @max_retry_delay = max_retry_delay
191
+ end
192
+
193
+ # @api private
194
+ #
195
+ # @return [Hash{String=>String}]
196
+ private def auth_headers = {}
197
+
198
+ # @api private
199
+ #
200
+ # @return [String]
201
+ private def generate_idempotency_key = "stainless-ruby-retry-#{SecureRandom.uuid}"
202
+
203
+ # @api private
204
+ #
205
+ # @param req [Hash{Symbol=>Object}] .
206
+ #
207
+ # @option req [Symbol] :method
208
+ #
209
+ # @option req [String, Array<String>] :path
210
+ #
211
+ # @option req [Hash{String=>Array<String>, String, nil}, nil] :query
212
+ #
213
+ # @option req [Hash{String=>String, Integer, Array<String, Integer, nil>, nil}, nil] :headers
214
+ #
215
+ # @option req [Object, nil] :body
216
+ #
217
+ # @option req [Symbol, nil] :unwrap
218
+ #
219
+ # @option req [Class, nil] :page
220
+ #
221
+ # @option req [Class, nil] :stream
222
+ #
223
+ # @option req [Dodopayments::Internal::Type::Converter, Class, nil] :model
224
+ #
225
+ # @param opts [Hash{Symbol=>Object}] .
226
+ #
227
+ # @option opts [String, nil] :idempotency_key
228
+ #
229
+ # @option opts [Hash{String=>Array<String>, String, nil}, nil] :extra_query
230
+ #
231
+ # @option opts [Hash{String=>String, nil}, nil] :extra_headers
232
+ #
233
+ # @option opts [Object, nil] :extra_body
234
+ #
235
+ # @option opts [Integer, nil] :max_retries
236
+ #
237
+ # @option opts [Float, nil] :timeout
238
+ #
239
+ # @return [Hash{Symbol=>Object}]
240
+ private def build_request(req, opts)
241
+ method, uninterpolated_path = req.fetch_values(:method, :path)
242
+
243
+ path = Dodopayments::Internal::Util.interpolate_path(uninterpolated_path)
244
+
245
+ query = Dodopayments::Internal::Util.deep_merge(req[:query].to_h, opts[:extra_query].to_h)
246
+
247
+ headers = Dodopayments::Internal::Util.normalized_headers(
248
+ @headers,
249
+ auth_headers,
250
+ req[:headers].to_h,
251
+ opts[:extra_headers].to_h
252
+ )
253
+
254
+ if @idempotency_header &&
255
+ !headers.key?(@idempotency_header) &&
256
+ (!Net::HTTP::IDEMPOTENT_METHODS_.include?(method.to_s.upcase) || opts.key?(:idempotency_key))
257
+ headers[@idempotency_header] = opts.fetch(:idempotency_key) { generate_idempotency_key }
258
+ end
259
+
260
+ unless headers.key?("x-stainless-retry-count")
261
+ headers["x-stainless-retry-count"] = "0"
262
+ end
263
+
264
+ timeout = opts.fetch(:timeout, @timeout).to_f.clamp((0..))
265
+ unless headers.key?("x-stainless-timeout") || timeout.zero?
266
+ headers["x-stainless-timeout"] = timeout.to_s
267
+ end
268
+
269
+ headers.reject! { |_, v| v.to_s.empty? }
270
+
271
+ body =
272
+ case method
273
+ in :get | :head | :options | :trace
274
+ nil
275
+ else
276
+ Dodopayments::Internal::Util.deep_merge(*[req[:body], opts[:extra_body]].compact)
277
+ end
278
+
279
+ headers, encoded = Dodopayments::Internal::Util.encode_content(headers, body)
280
+ {
281
+ method: method,
282
+ url: Dodopayments::Internal::Util.join_parsed_uri(@base_url, {**req, path: path, query: query}),
283
+ headers: headers,
284
+ body: encoded,
285
+ max_retries: opts.fetch(:max_retries, @max_retries),
286
+ timeout: timeout
287
+ }
288
+ end
289
+
290
+ # @api private
291
+ #
292
+ # @param headers [Hash{String=>String}]
293
+ # @param retry_count [Integer]
294
+ #
295
+ # @return [Float]
296
+ private def retry_delay(headers, retry_count:)
297
+ # Non-standard extension
298
+ span = Float(headers["retry-after-ms"], exception: false)&.then { _1 / 1000 }
299
+ return span if span
300
+
301
+ retry_header = headers["retry-after"]
302
+ return span if (span = Float(retry_header, exception: false))
303
+
304
+ span = retry_header&.then do
305
+ Time.httpdate(_1) - Time.now
306
+ rescue ArgumentError
307
+ nil
308
+ end
309
+ return span if span
310
+
311
+ scale = retry_count**2
312
+ jitter = 1 - (0.25 * rand)
313
+ (@initial_retry_delay * scale * jitter).clamp(0, @max_retry_delay)
314
+ end
315
+
316
+ # @api private
317
+ #
318
+ # @param request [Hash{Symbol=>Object}] .
319
+ #
320
+ # @option request [Symbol] :method
321
+ #
322
+ # @option request [URI::Generic] :url
323
+ #
324
+ # @option request [Hash{String=>String}] :headers
325
+ #
326
+ # @option request [Object] :body
327
+ #
328
+ # @option request [Integer] :max_retries
329
+ #
330
+ # @option request [Float] :timeout
331
+ #
332
+ # @param redirect_count [Integer]
333
+ #
334
+ # @param retry_count [Integer]
335
+ #
336
+ # @param send_retry_header [Boolean]
337
+ #
338
+ # @raise [Dodopayments::Errors::APIError]
339
+ # @return [Array(Integer, Net::HTTPResponse, Enumerable<String>)]
340
+ private def send_request(request, redirect_count:, retry_count:, send_retry_header:)
341
+ url, headers, max_retries, timeout = request.fetch_values(:url, :headers, :max_retries, :timeout)
342
+ input = {
343
+ **request.except(:timeout),
344
+ deadline: Dodopayments::Internal::Util.monotonic_secs + timeout
345
+ }
346
+
347
+ if send_retry_header
348
+ headers["x-stainless-retry-count"] = retry_count.to_s
349
+ end
350
+
351
+ begin
352
+ status, response, stream = @requester.execute(input)
353
+ rescue Dodopayments::Errors::APIConnectionError => e
354
+ status = e
355
+ end
356
+
357
+ case status
358
+ in ..299
359
+ [status, response, stream]
360
+ in 300..399 if redirect_count >= self.class::MAX_REDIRECTS
361
+ self.class.reap_connection!(status, stream: stream)
362
+
363
+ message = "Failed to complete the request within #{self.class::MAX_REDIRECTS} redirects."
364
+ raise Dodopayments::Errors::APIConnectionError.new(url: url, response: response, message: message)
365
+ in 300..399
366
+ self.class.reap_connection!(status, stream: stream)
367
+
368
+ request = self.class.follow_redirect(request, status: status, response_headers: response)
369
+ send_request(
370
+ request,
371
+ redirect_count: redirect_count + 1,
372
+ retry_count: retry_count,
373
+ send_retry_header: send_retry_header
374
+ )
375
+ in Dodopayments::Errors::APIConnectionError if retry_count >= max_retries
376
+ raise status
377
+ in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: response)
378
+ decoded = Kernel.then do
379
+ Dodopayments::Internal::Util.decode_content(response, stream: stream, suppress_error: true)
380
+ ensure
381
+ self.class.reap_connection!(status, stream: stream)
382
+ end
383
+
384
+ raise Dodopayments::Errors::APIStatusError.for(
385
+ url: url,
386
+ status: status,
387
+ body: decoded,
388
+ request: nil,
389
+ response: response
390
+ )
391
+ in (400..) | Dodopayments::Errors::APIConnectionError
392
+ self.class.reap_connection!(status, stream: stream)
393
+
394
+ delay = retry_delay(response || {}, retry_count: retry_count)
395
+ sleep(delay)
396
+
397
+ send_request(
398
+ request,
399
+ redirect_count: redirect_count,
400
+ retry_count: retry_count + 1,
401
+ send_retry_header: send_retry_header
402
+ )
403
+ end
404
+ end
405
+
406
+ # Execute the request specified by `req`. This is the method that all resource
407
+ # methods call into.
408
+ #
409
+ # @overload request(method, path, query: {}, headers: {}, body: nil, unwrap: nil, page: nil, stream: nil, model: Dodopayments::Internal::Type::Unknown, options: {})
410
+ #
411
+ # @param method [Symbol]
412
+ #
413
+ # @param path [String, Array<String>]
414
+ #
415
+ # @param query [Hash{String=>Array<String>, String, nil}, nil]
416
+ #
417
+ # @param headers [Hash{String=>String, Integer, Array<String, Integer, nil>, nil}, nil]
418
+ #
419
+ # @param body [Object, nil]
420
+ #
421
+ # @param unwrap [Symbol, nil]
422
+ #
423
+ # @param page [Class, nil]
424
+ #
425
+ # @param stream [Class, nil]
426
+ #
427
+ # @param model [Dodopayments::Internal::Type::Converter, Class, nil]
428
+ #
429
+ # @param options [Dodopayments::RequestOptions, Hash{Symbol=>Object}, nil] .
430
+ #
431
+ # @option options [String, nil] :idempotency_key
432
+ #
433
+ # @option options [Hash{String=>Array<String>, String, nil}, nil] :extra_query
434
+ #
435
+ # @option options [Hash{String=>String, nil}, nil] :extra_headers
436
+ #
437
+ # @option options [Object, nil] :extra_body
438
+ #
439
+ # @option options [Integer, nil] :max_retries
440
+ #
441
+ # @option options [Float, nil] :timeout
442
+ #
443
+ # @raise [Dodopayments::Errors::APIError]
444
+ # @return [Object]
445
+ def request(req)
446
+ self.class.validate!(req)
447
+ model = req.fetch(:model) { Dodopayments::Internal::Type::Unknown }
448
+ opts = req[:options].to_h
449
+ Dodopayments::RequestOptions.validate!(opts)
450
+ request = build_request(req.except(:options), opts)
451
+ url = request.fetch(:url)
452
+
453
+ # Don't send the current retry count in the headers if the caller modified the header defaults.
454
+ send_retry_header = request.fetch(:headers)["x-stainless-retry-count"] == "0"
455
+ status, response, stream = send_request(
456
+ request,
457
+ redirect_count: 0,
458
+ retry_count: 0,
459
+ send_retry_header: send_retry_header
460
+ )
461
+
462
+ decoded = Dodopayments::Internal::Util.decode_content(response, stream: stream)
463
+ case req
464
+ in { stream: Class => st }
465
+ st.new(model: model, url: url, status: status, response: response, stream: decoded)
466
+ in { page: Class => page }
467
+ page.new(client: self, req: req, headers: response, page_data: decoded)
468
+ else
469
+ unwrapped = Dodopayments::Internal::Util.dig(decoded, req[:unwrap])
470
+ Dodopayments::Internal::Type::Converter.coerce(model, unwrapped)
471
+ end
472
+ end
473
+
474
+ # @api private
475
+ #
476
+ # @return [String]
477
+ def inspect
478
+ # rubocop:disable Layout/LineLength
479
+ base_url = Dodopayments::Internal::Util.unparse_uri(@base_url)
480
+ "#<#{self.class.name}:0x#{object_id.to_s(16)} base_url=#{base_url} max_retries=#{@max_retries} timeout=#{@timeout}>"
481
+ # rubocop:enable Layout/LineLength
482
+ end
483
+ end
484
+ end
485
+ end
486
+ end
@@ -0,0 +1,197 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dodopayments
4
+ module Internal
5
+ module Transport
6
+ # @api private
7
+ class PooledNetRequester
8
+ # from the golang stdlib
9
+ # https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49
10
+ KEEP_ALIVE_TIMEOUT = 30
11
+
12
+ class << self
13
+ # @api private
14
+ #
15
+ # @param url [URI::Generic]
16
+ #
17
+ # @return [Net::HTTP]
18
+ def connect(url)
19
+ port =
20
+ case [url.port, url.scheme]
21
+ in [Integer, _]
22
+ url.port
23
+ in [nil, "http" | "ws"]
24
+ Net::HTTP.http_default_port
25
+ in [nil, "https" | "wss"]
26
+ Net::HTTP.https_default_port
27
+ end
28
+
29
+ Net::HTTP.new(url.host, port).tap do
30
+ _1.use_ssl = %w[https wss].include?(url.scheme)
31
+ _1.max_retries = 0
32
+ end
33
+ end
34
+
35
+ # @api private
36
+ #
37
+ # @param conn [Net::HTTP]
38
+ # @param deadline [Float]
39
+ def calibrate_socket_timeout(conn, deadline)
40
+ timeout = deadline - Dodopayments::Internal::Util.monotonic_secs
41
+ conn.open_timeout = conn.read_timeout = conn.write_timeout = conn.continue_timeout = timeout
42
+ end
43
+
44
+ # @api private
45
+ #
46
+ # @param request [Hash{Symbol=>Object}] .
47
+ #
48
+ # @option request [Symbol] :method
49
+ #
50
+ # @option request [URI::Generic] :url
51
+ #
52
+ # @option request [Hash{String=>String}] :headers
53
+ #
54
+ # @param blk [Proc]
55
+ #
56
+ # @yieldparam [String]
57
+ # @return [Array(Net::HTTPGenericRequest, Proc)]
58
+ def build_request(request, &blk)
59
+ method, url, headers, body = request.fetch_values(:method, :url, :headers, :body)
60
+
61
+ # ensure we construct a URI class of the right scheme
62
+ url = URI(url.to_s)
63
+
64
+ req = Net::HTTPGenericRequest.new(
65
+ method.to_s.upcase,
66
+ !body.nil?,
67
+ method != :head,
68
+ url
69
+ )
70
+
71
+ headers.each { req[_1] = _2 }
72
+
73
+ case body
74
+ in nil
75
+ nil
76
+ in String
77
+ req["content-length"] ||= body.bytesize.to_s unless req["transfer-encoding"]
78
+ req.body_stream = Dodopayments::Internal::Util::ReadIOAdapter.new(body, &blk)
79
+ in StringIO
80
+ req["content-length"] ||= body.size.to_s unless req["transfer-encoding"]
81
+ req.body_stream = Dodopayments::Internal::Util::ReadIOAdapter.new(body, &blk)
82
+ in Pathname | IO | Enumerator
83
+ req["transfer-encoding"] ||= "chunked" unless req["content-length"]
84
+ req.body_stream = Dodopayments::Internal::Util::ReadIOAdapter.new(body, &blk)
85
+ end
86
+
87
+ [req, req.body_stream&.method(:close)]
88
+ end
89
+ end
90
+
91
+ # @api private
92
+ #
93
+ # @param url [URI::Generic]
94
+ # @param deadline [Float]
95
+ # @param blk [Proc]
96
+ #
97
+ # @raise [Timeout::Error]
98
+ # @yieldparam [Net::HTTP]
99
+ private def with_pool(url, deadline:, &blk)
100
+ origin = Dodopayments::Internal::Util.uri_origin(url)
101
+ timeout = deadline - Dodopayments::Internal::Util.monotonic_secs
102
+ pool =
103
+ @mutex.synchronize do
104
+ @pools[origin] ||= ConnectionPool.new(size: @size) do
105
+ self.class.connect(url)
106
+ end
107
+ end
108
+
109
+ pool.with(timeout: timeout, &blk)
110
+ end
111
+
112
+ # @api private
113
+ #
114
+ # @param request [Hash{Symbol=>Object}] .
115
+ #
116
+ # @option request [Symbol] :method
117
+ #
118
+ # @option request [URI::Generic] :url
119
+ #
120
+ # @option request [Hash{String=>String}] :headers
121
+ #
122
+ # @option request [Object] :body
123
+ #
124
+ # @option request [Float] :deadline
125
+ #
126
+ # @return [Array(Integer, Net::HTTPResponse, Enumerable<String>)]
127
+ def execute(request)
128
+ url, deadline = request.fetch_values(:url, :deadline)
129
+
130
+ req = nil
131
+ eof = false
132
+ finished = false
133
+ closing = nil
134
+
135
+ # rubocop:disable Metrics/BlockLength
136
+ enum = Enumerator.new do |y|
137
+ with_pool(url, deadline: deadline) do |conn|
138
+ next if finished
139
+
140
+ req, closing = self.class.build_request(request) do
141
+ self.class.calibrate_socket_timeout(conn, deadline)
142
+ end
143
+
144
+ self.class.calibrate_socket_timeout(conn, deadline)
145
+ unless conn.started?
146
+ conn.keep_alive_timeout = self.class::KEEP_ALIVE_TIMEOUT
147
+ conn.start
148
+ end
149
+
150
+ self.class.calibrate_socket_timeout(conn, deadline)
151
+ conn.request(req) do |rsp|
152
+ y << [conn, req, rsp]
153
+ break if finished
154
+
155
+ rsp.read_body do |bytes|
156
+ y << bytes.force_encoding(Encoding::BINARY)
157
+ break if finished
158
+
159
+ self.class.calibrate_socket_timeout(conn, deadline)
160
+ end
161
+ eof = true
162
+ end
163
+ end
164
+ rescue Timeout::Error
165
+ raise Dodopayments::Errors::APITimeoutError.new(url: url, request: req)
166
+ rescue StandardError
167
+ raise Dodopayments::Errors::APIConnectionError.new(url: url, request: req)
168
+ end
169
+ # rubocop:enable Metrics/BlockLength
170
+
171
+ conn, _, response = enum.next
172
+ body = Dodopayments::Internal::Util.fused_enum(enum, external: true) do
173
+ finished = true
174
+ tap do
175
+ enum.next
176
+ rescue StopIteration
177
+ nil
178
+ end
179
+ ensure
180
+ conn.finish if !eof && conn&.started?
181
+ closing&.call
182
+ end
183
+ [Integer(response.code), response, (response.body = body)]
184
+ end
185
+
186
+ # @api private
187
+ #
188
+ # @param size [Integer]
189
+ def initialize(size: Etc.nprocessors)
190
+ @mutex = Mutex.new
191
+ @size = size
192
+ @pools = {}
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end