shopify_api 13.0.0 → 14.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (643) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/workflows/build.yml +4 -1
  4. data/.rubocop.yml +2 -0
  5. data/BREAKING_CHANGES_FOR_V10.md +231 -0
  6. data/CHANGELOG.md +38 -1
  7. data/CODE_OF_CONDUCT.md +46 -0
  8. data/CONTRIBUTING.md +25 -0
  9. data/Gemfile.lock +56 -54
  10. data/README.md +10 -41
  11. data/ROADMAP.md +10 -0
  12. data/dev.yml +3 -2
  13. data/docs/README.md +0 -1
  14. data/docs/getting_started.md +21 -11
  15. data/docs/usage/custom_apps.md +75 -0
  16. data/docs/usage/graphql.md +91 -17
  17. data/docs/usage/oauth.md +160 -27
  18. data/docs/usage/rest.md +269 -59
  19. data/docs/usage/webhooks.md +54 -11
  20. data/lib/shopify_api/admin_versions.rb +4 -1
  21. data/lib/shopify_api/auth/jwt_payload.rb +2 -2
  22. data/lib/shopify_api/auth/oauth/access_token_response.rb +37 -0
  23. data/lib/shopify_api/auth/oauth.rb +17 -38
  24. data/lib/shopify_api/auth/session.rb +31 -0
  25. data/lib/shopify_api/auth/token_exchange.rb +80 -0
  26. data/lib/shopify_api/clients/graphql/client.rb +1 -0
  27. data/lib/shopify_api/clients/http_client.rb +12 -3
  28. data/lib/shopify_api/clients/http_response.rb +29 -2
  29. data/lib/shopify_api/context.rb +19 -5
  30. data/lib/shopify_api/logger.rb +1 -1
  31. data/lib/shopify_api/rest/base.rb +112 -29
  32. data/lib/shopify_api/rest/resources/2022_04/abandoned_checkout.rb +7 -3
  33. data/lib/shopify_api/rest/resources/2022_04/access_scope.rb +7 -3
  34. data/lib/shopify_api/rest/resources/2022_04/android_pay_key.rb +7 -3
  35. data/lib/shopify_api/rest/resources/2022_04/apple_pay_certificate.rb +7 -3
  36. data/lib/shopify_api/rest/resources/2022_04/application_charge.rb +7 -3
  37. data/lib/shopify_api/rest/resources/2022_04/application_credit.rb +7 -3
  38. data/lib/shopify_api/rest/resources/2022_04/article.rb +7 -3
  39. data/lib/shopify_api/rest/resources/2022_04/asset.rb +7 -3
  40. data/lib/shopify_api/rest/resources/2022_04/assigned_fulfillment_order.rb +12 -6
  41. data/lib/shopify_api/rest/resources/2022_04/balance.rb +6 -3
  42. data/lib/shopify_api/rest/resources/2022_04/blog.rb +7 -3
  43. data/lib/shopify_api/rest/resources/2022_04/cancellation_request.rb +7 -3
  44. data/lib/shopify_api/rest/resources/2022_04/carrier_service.rb +7 -3
  45. data/lib/shopify_api/rest/resources/2022_04/checkout.rb +7 -3
  46. data/lib/shopify_api/rest/resources/2022_04/collect.rb +7 -3
  47. data/lib/shopify_api/rest/resources/2022_04/collection.rb +7 -3
  48. data/lib/shopify_api/rest/resources/2022_04/collection_listing.rb +7 -3
  49. data/lib/shopify_api/rest/resources/2022_04/comment.rb +7 -3
  50. data/lib/shopify_api/rest/resources/2022_04/country.rb +7 -3
  51. data/lib/shopify_api/rest/resources/2022_04/currency.rb +7 -3
  52. data/lib/shopify_api/rest/resources/2022_04/custom_collection.rb +7 -3
  53. data/lib/shopify_api/rest/resources/2022_04/customer.rb +7 -3
  54. data/lib/shopify_api/rest/resources/2022_04/customer_address.rb +17 -3
  55. data/lib/shopify_api/rest/resources/2022_04/customer_saved_search.rb +7 -3
  56. data/lib/shopify_api/rest/resources/2022_04/deprecated_api_call.rb +7 -3
  57. data/lib/shopify_api/rest/resources/2022_04/discount_code.rb +7 -3
  58. data/lib/shopify_api/rest/resources/2022_04/dispute.rb +7 -3
  59. data/lib/shopify_api/rest/resources/2022_04/draft_order.rb +7 -3
  60. data/lib/shopify_api/rest/resources/2022_04/event.rb +7 -3
  61. data/lib/shopify_api/rest/resources/2022_04/fulfillment.rb +7 -3
  62. data/lib/shopify_api/rest/resources/2022_04/fulfillment_event.rb +7 -3
  63. data/lib/shopify_api/rest/resources/2022_04/fulfillment_order.rb +10 -10
  64. data/lib/shopify_api/rest/resources/2022_04/fulfillment_request.rb +17 -3
  65. data/lib/shopify_api/rest/resources/2022_04/fulfillment_service.rb +7 -3
  66. data/lib/shopify_api/rest/resources/2022_04/gift_card.rb +7 -3
  67. data/lib/shopify_api/rest/resources/2022_04/gift_card_adjustment.rb +7 -3
  68. data/lib/shopify_api/rest/resources/2022_04/image.rb +7 -3
  69. data/lib/shopify_api/rest/resources/2022_04/inventory_item.rb +7 -3
  70. data/lib/shopify_api/rest/resources/2022_04/inventory_level.rb +7 -3
  71. data/lib/shopify_api/rest/resources/2022_04/location.rb +7 -3
  72. data/lib/shopify_api/rest/resources/2022_04/locations_for_move.rb +7 -3
  73. data/lib/shopify_api/rest/resources/2022_04/marketing_event.rb +7 -3
  74. data/lib/shopify_api/rest/resources/2022_04/metafield.rb +7 -3
  75. data/lib/shopify_api/rest/resources/2022_04/mobile_platform_application.rb +7 -3
  76. data/lib/shopify_api/rest/resources/2022_04/order.rb +7 -3
  77. data/lib/shopify_api/rest/resources/2022_04/order_risk.rb +12 -6
  78. data/lib/shopify_api/rest/resources/2022_04/page.rb +7 -3
  79. data/lib/shopify_api/rest/resources/2022_04/payment.rb +7 -3
  80. data/lib/shopify_api/rest/resources/2022_04/payment_gateway.rb +7 -3
  81. data/lib/shopify_api/rest/resources/2022_04/payment_transaction.rb +7 -3
  82. data/lib/shopify_api/rest/resources/2022_04/payout.rb +7 -3
  83. data/lib/shopify_api/rest/resources/2022_04/policy.rb +7 -3
  84. data/lib/shopify_api/rest/resources/2022_04/price_rule.rb +7 -3
  85. data/lib/shopify_api/rest/resources/2022_04/product.rb +7 -3
  86. data/lib/shopify_api/rest/resources/2022_04/product_listing.rb +7 -3
  87. data/lib/shopify_api/rest/resources/2022_04/product_resource_feedback.rb +7 -3
  88. data/lib/shopify_api/rest/resources/2022_04/province.rb +7 -3
  89. data/lib/shopify_api/rest/resources/2022_04/recurring_application_charge.rb +7 -3
  90. data/lib/shopify_api/rest/resources/2022_04/redirect.rb +7 -3
  91. data/lib/shopify_api/rest/resources/2022_04/refund.rb +7 -3
  92. data/lib/shopify_api/rest/resources/2022_04/report.rb +7 -3
  93. data/lib/shopify_api/rest/resources/2022_04/resource_feedback.rb +7 -3
  94. data/lib/shopify_api/rest/resources/2022_04/script_tag.rb +7 -3
  95. data/lib/shopify_api/rest/resources/2022_04/shipping_zone.rb +7 -3
  96. data/lib/shopify_api/rest/resources/2022_04/shop.rb +9 -5
  97. data/lib/shopify_api/rest/resources/2022_04/smart_collection.rb +7 -3
  98. data/lib/shopify_api/rest/resources/2022_04/storefront_access_token.rb +7 -3
  99. data/lib/shopify_api/rest/resources/2022_04/tender_transaction.rb +7 -3
  100. data/lib/shopify_api/rest/resources/2022_04/theme.rb +7 -3
  101. data/lib/shopify_api/rest/resources/2022_04/transaction.rb +7 -3
  102. data/lib/shopify_api/rest/resources/2022_04/usage_charge.rb +7 -3
  103. data/lib/shopify_api/rest/resources/2022_04/user.rb +7 -3
  104. data/lib/shopify_api/rest/resources/2022_04/variant.rb +7 -3
  105. data/lib/shopify_api/rest/resources/2022_04/webhook.rb +7 -3
  106. data/lib/shopify_api/rest/resources/2022_07/abandoned_checkout.rb +7 -3
  107. data/lib/shopify_api/rest/resources/2022_07/access_scope.rb +7 -3
  108. data/lib/shopify_api/rest/resources/2022_07/android_pay_key.rb +7 -3
  109. data/lib/shopify_api/rest/resources/2022_07/apple_pay_certificate.rb +7 -3
  110. data/lib/shopify_api/rest/resources/2022_07/application_charge.rb +7 -3
  111. data/lib/shopify_api/rest/resources/2022_07/application_credit.rb +7 -3
  112. data/lib/shopify_api/rest/resources/2022_07/article.rb +7 -3
  113. data/lib/shopify_api/rest/resources/2022_07/asset.rb +7 -3
  114. data/lib/shopify_api/rest/resources/2022_07/assigned_fulfillment_order.rb +12 -6
  115. data/lib/shopify_api/rest/resources/2022_07/balance.rb +11 -3
  116. data/lib/shopify_api/rest/resources/2022_07/blog.rb +7 -3
  117. data/lib/shopify_api/rest/resources/2022_07/cancellation_request.rb +7 -3
  118. data/lib/shopify_api/rest/resources/2022_07/carrier_service.rb +7 -3
  119. data/lib/shopify_api/rest/resources/2022_07/checkout.rb +7 -3
  120. data/lib/shopify_api/rest/resources/2022_07/collect.rb +7 -3
  121. data/lib/shopify_api/rest/resources/2022_07/collection.rb +7 -3
  122. data/lib/shopify_api/rest/resources/2022_07/collection_listing.rb +7 -3
  123. data/lib/shopify_api/rest/resources/2022_07/comment.rb +7 -3
  124. data/lib/shopify_api/rest/resources/2022_07/country.rb +7 -3
  125. data/lib/shopify_api/rest/resources/2022_07/currency.rb +7 -3
  126. data/lib/shopify_api/rest/resources/2022_07/custom_collection.rb +7 -3
  127. data/lib/shopify_api/rest/resources/2022_07/customer.rb +7 -3
  128. data/lib/shopify_api/rest/resources/2022_07/customer_address.rb +17 -3
  129. data/lib/shopify_api/rest/resources/2022_07/deprecated_api_call.rb +7 -3
  130. data/lib/shopify_api/rest/resources/2022_07/discount_code.rb +7 -3
  131. data/lib/shopify_api/rest/resources/2022_07/dispute.rb +7 -3
  132. data/lib/shopify_api/rest/resources/2022_07/dispute_evidence.rb +7 -3
  133. data/lib/shopify_api/rest/resources/2022_07/dispute_file_upload.rb +7 -3
  134. data/lib/shopify_api/rest/resources/2022_07/draft_order.rb +7 -3
  135. data/lib/shopify_api/rest/resources/2022_07/event.rb +7 -3
  136. data/lib/shopify_api/rest/resources/2022_07/fulfillment.rb +7 -3
  137. data/lib/shopify_api/rest/resources/2022_07/fulfillment_event.rb +7 -3
  138. data/lib/shopify_api/rest/resources/2022_07/fulfillment_order.rb +10 -10
  139. data/lib/shopify_api/rest/resources/2022_07/fulfillment_request.rb +17 -3
  140. data/lib/shopify_api/rest/resources/2022_07/fulfillment_service.rb +7 -3
  141. data/lib/shopify_api/rest/resources/2022_07/gift_card.rb +7 -3
  142. data/lib/shopify_api/rest/resources/2022_07/gift_card_adjustment.rb +7 -3
  143. data/lib/shopify_api/rest/resources/2022_07/image.rb +7 -3
  144. data/lib/shopify_api/rest/resources/2022_07/inventory_item.rb +7 -3
  145. data/lib/shopify_api/rest/resources/2022_07/inventory_level.rb +7 -3
  146. data/lib/shopify_api/rest/resources/2022_07/location.rb +7 -3
  147. data/lib/shopify_api/rest/resources/2022_07/locations_for_move.rb +7 -3
  148. data/lib/shopify_api/rest/resources/2022_07/marketing_event.rb +7 -3
  149. data/lib/shopify_api/rest/resources/2022_07/metafield.rb +7 -3
  150. data/lib/shopify_api/rest/resources/2022_07/mobile_platform_application.rb +7 -3
  151. data/lib/shopify_api/rest/resources/2022_07/order.rb +10 -3
  152. data/lib/shopify_api/rest/resources/2022_07/order_risk.rb +12 -6
  153. data/lib/shopify_api/rest/resources/2022_07/page.rb +7 -3
  154. data/lib/shopify_api/rest/resources/2022_07/payment.rb +7 -3
  155. data/lib/shopify_api/rest/resources/2022_07/payment_gateway.rb +7 -3
  156. data/lib/shopify_api/rest/resources/2022_07/payment_transaction.rb +7 -3
  157. data/lib/shopify_api/rest/resources/2022_07/payout.rb +7 -3
  158. data/lib/shopify_api/rest/resources/2022_07/policy.rb +7 -3
  159. data/lib/shopify_api/rest/resources/2022_07/price_rule.rb +7 -3
  160. data/lib/shopify_api/rest/resources/2022_07/product.rb +7 -3
  161. data/lib/shopify_api/rest/resources/2022_07/product_listing.rb +7 -3
  162. data/lib/shopify_api/rest/resources/2022_07/product_resource_feedback.rb +7 -3
  163. data/lib/shopify_api/rest/resources/2022_07/province.rb +7 -3
  164. data/lib/shopify_api/rest/resources/2022_07/recurring_application_charge.rb +7 -3
  165. data/lib/shopify_api/rest/resources/2022_07/redirect.rb +7 -3
  166. data/lib/shopify_api/rest/resources/2022_07/refund.rb +7 -3
  167. data/lib/shopify_api/rest/resources/2022_07/report.rb +7 -3
  168. data/lib/shopify_api/rest/resources/2022_07/resource_feedback.rb +7 -3
  169. data/lib/shopify_api/rest/resources/2022_07/script_tag.rb +7 -3
  170. data/lib/shopify_api/rest/resources/2022_07/shipping_zone.rb +7 -3
  171. data/lib/shopify_api/rest/resources/2022_07/shop.rb +9 -5
  172. data/lib/shopify_api/rest/resources/2022_07/smart_collection.rb +7 -3
  173. data/lib/shopify_api/rest/resources/2022_07/storefront_access_token.rb +7 -3
  174. data/lib/shopify_api/rest/resources/2022_07/tender_transaction.rb +7 -3
  175. data/lib/shopify_api/rest/resources/2022_07/theme.rb +7 -3
  176. data/lib/shopify_api/rest/resources/2022_07/transaction.rb +7 -3
  177. data/lib/shopify_api/rest/resources/2022_07/usage_charge.rb +7 -3
  178. data/lib/shopify_api/rest/resources/2022_07/user.rb +7 -3
  179. data/lib/shopify_api/rest/resources/2022_07/variant.rb +7 -3
  180. data/lib/shopify_api/rest/resources/2022_07/webhook.rb +7 -3
  181. data/lib/shopify_api/rest/resources/2022_10/abandoned_checkout.rb +7 -3
  182. data/lib/shopify_api/rest/resources/2022_10/access_scope.rb +7 -3
  183. data/lib/shopify_api/rest/resources/2022_10/android_pay_key.rb +7 -3
  184. data/lib/shopify_api/rest/resources/2022_10/apple_pay_certificate.rb +7 -3
  185. data/lib/shopify_api/rest/resources/2022_10/application_charge.rb +7 -3
  186. data/lib/shopify_api/rest/resources/2022_10/application_credit.rb +7 -3
  187. data/lib/shopify_api/rest/resources/2022_10/article.rb +7 -3
  188. data/lib/shopify_api/rest/resources/2022_10/asset.rb +7 -3
  189. data/lib/shopify_api/rest/resources/2022_10/assigned_fulfillment_order.rb +12 -6
  190. data/lib/shopify_api/rest/resources/2022_10/balance.rb +11 -3
  191. data/lib/shopify_api/rest/resources/2022_10/blog.rb +7 -3
  192. data/lib/shopify_api/rest/resources/2022_10/cancellation_request.rb +7 -3
  193. data/lib/shopify_api/rest/resources/2022_10/carrier_service.rb +7 -3
  194. data/lib/shopify_api/rest/resources/2022_10/checkout.rb +7 -3
  195. data/lib/shopify_api/rest/resources/2022_10/collect.rb +7 -3
  196. data/lib/shopify_api/rest/resources/2022_10/collection.rb +7 -3
  197. data/lib/shopify_api/rest/resources/2022_10/collection_listing.rb +7 -3
  198. data/lib/shopify_api/rest/resources/2022_10/comment.rb +7 -3
  199. data/lib/shopify_api/rest/resources/2022_10/country.rb +7 -3
  200. data/lib/shopify_api/rest/resources/2022_10/currency.rb +7 -3
  201. data/lib/shopify_api/rest/resources/2022_10/custom_collection.rb +7 -3
  202. data/lib/shopify_api/rest/resources/2022_10/customer.rb +7 -3
  203. data/lib/shopify_api/rest/resources/2022_10/customer_address.rb +17 -3
  204. data/lib/shopify_api/rest/resources/2022_10/deprecated_api_call.rb +7 -3
  205. data/lib/shopify_api/rest/resources/2022_10/discount_code.rb +7 -3
  206. data/lib/shopify_api/rest/resources/2022_10/dispute.rb +7 -3
  207. data/lib/shopify_api/rest/resources/2022_10/dispute_evidence.rb +7 -3
  208. data/lib/shopify_api/rest/resources/2022_10/dispute_file_upload.rb +7 -3
  209. data/lib/shopify_api/rest/resources/2022_10/draft_order.rb +7 -3
  210. data/lib/shopify_api/rest/resources/2022_10/event.rb +7 -3
  211. data/lib/shopify_api/rest/resources/2022_10/fulfillment.rb +7 -3
  212. data/lib/shopify_api/rest/resources/2022_10/fulfillment_event.rb +7 -3
  213. data/lib/shopify_api/rest/resources/2022_10/fulfillment_order.rb +10 -10
  214. data/lib/shopify_api/rest/resources/2022_10/fulfillment_request.rb +17 -3
  215. data/lib/shopify_api/rest/resources/2022_10/fulfillment_service.rb +7 -3
  216. data/lib/shopify_api/rest/resources/2022_10/gift_card.rb +7 -3
  217. data/lib/shopify_api/rest/resources/2022_10/gift_card_adjustment.rb +7 -3
  218. data/lib/shopify_api/rest/resources/2022_10/image.rb +7 -3
  219. data/lib/shopify_api/rest/resources/2022_10/inventory_item.rb +7 -3
  220. data/lib/shopify_api/rest/resources/2022_10/inventory_level.rb +7 -3
  221. data/lib/shopify_api/rest/resources/2022_10/location.rb +7 -3
  222. data/lib/shopify_api/rest/resources/2022_10/locations_for_move.rb +7 -3
  223. data/lib/shopify_api/rest/resources/2022_10/marketing_event.rb +7 -3
  224. data/lib/shopify_api/rest/resources/2022_10/metafield.rb +7 -3
  225. data/lib/shopify_api/rest/resources/2022_10/mobile_platform_application.rb +7 -3
  226. data/lib/shopify_api/rest/resources/2022_10/order.rb +10 -3
  227. data/lib/shopify_api/rest/resources/2022_10/order_risk.rb +12 -6
  228. data/lib/shopify_api/rest/resources/2022_10/page.rb +7 -3
  229. data/lib/shopify_api/rest/resources/2022_10/payment.rb +7 -3
  230. data/lib/shopify_api/rest/resources/2022_10/payment_gateway.rb +7 -3
  231. data/lib/shopify_api/rest/resources/2022_10/payment_transaction.rb +7 -3
  232. data/lib/shopify_api/rest/resources/2022_10/payout.rb +7 -3
  233. data/lib/shopify_api/rest/resources/2022_10/policy.rb +7 -3
  234. data/lib/shopify_api/rest/resources/2022_10/price_rule.rb +7 -3
  235. data/lib/shopify_api/rest/resources/2022_10/product.rb +7 -3
  236. data/lib/shopify_api/rest/resources/2022_10/product_listing.rb +7 -3
  237. data/lib/shopify_api/rest/resources/2022_10/product_resource_feedback.rb +7 -3
  238. data/lib/shopify_api/rest/resources/2022_10/province.rb +7 -3
  239. data/lib/shopify_api/rest/resources/2022_10/recurring_application_charge.rb +7 -3
  240. data/lib/shopify_api/rest/resources/2022_10/redirect.rb +7 -3
  241. data/lib/shopify_api/rest/resources/2022_10/refund.rb +7 -3
  242. data/lib/shopify_api/rest/resources/2022_10/report.rb +7 -3
  243. data/lib/shopify_api/rest/resources/2022_10/resource_feedback.rb +7 -3
  244. data/lib/shopify_api/rest/resources/2022_10/script_tag.rb +7 -3
  245. data/lib/shopify_api/rest/resources/2022_10/shipping_zone.rb +7 -3
  246. data/lib/shopify_api/rest/resources/2022_10/shop.rb +9 -8
  247. data/lib/shopify_api/rest/resources/2022_10/smart_collection.rb +7 -3
  248. data/lib/shopify_api/rest/resources/2022_10/storefront_access_token.rb +7 -3
  249. data/lib/shopify_api/rest/resources/2022_10/tender_transaction.rb +7 -3
  250. data/lib/shopify_api/rest/resources/2022_10/theme.rb +7 -3
  251. data/lib/shopify_api/rest/resources/2022_10/transaction.rb +7 -3
  252. data/lib/shopify_api/rest/resources/2022_10/usage_charge.rb +7 -3
  253. data/lib/shopify_api/rest/resources/2022_10/user.rb +7 -3
  254. data/lib/shopify_api/rest/resources/2022_10/variant.rb +8 -8
  255. data/lib/shopify_api/rest/resources/2022_10/webhook.rb +7 -3
  256. data/lib/shopify_api/rest/resources/2023_01/abandoned_checkout.rb +7 -3
  257. data/lib/shopify_api/rest/resources/2023_01/access_scope.rb +7 -3
  258. data/lib/shopify_api/rest/resources/2023_01/apple_pay_certificate.rb +7 -3
  259. data/lib/shopify_api/rest/resources/2023_01/application_charge.rb +7 -3
  260. data/lib/shopify_api/rest/resources/2023_01/application_credit.rb +7 -3
  261. data/lib/shopify_api/rest/resources/2023_01/article.rb +7 -3
  262. data/lib/shopify_api/rest/resources/2023_01/asset.rb +7 -3
  263. data/lib/shopify_api/rest/resources/2023_01/assigned_fulfillment_order.rb +12 -6
  264. data/lib/shopify_api/rest/resources/2023_01/balance.rb +11 -3
  265. data/lib/shopify_api/rest/resources/2023_01/blog.rb +7 -3
  266. data/lib/shopify_api/rest/resources/2023_01/cancellation_request.rb +7 -3
  267. data/lib/shopify_api/rest/resources/2023_01/carrier_service.rb +7 -3
  268. data/lib/shopify_api/rest/resources/2023_01/checkout.rb +7 -3
  269. data/lib/shopify_api/rest/resources/2023_01/collect.rb +7 -3
  270. data/lib/shopify_api/rest/resources/2023_01/collection.rb +7 -3
  271. data/lib/shopify_api/rest/resources/2023_01/collection_listing.rb +7 -3
  272. data/lib/shopify_api/rest/resources/2023_01/comment.rb +7 -3
  273. data/lib/shopify_api/rest/resources/2023_01/country.rb +7 -3
  274. data/lib/shopify_api/rest/resources/2023_01/currency.rb +7 -3
  275. data/lib/shopify_api/rest/resources/2023_01/custom_collection.rb +7 -3
  276. data/lib/shopify_api/rest/resources/2023_01/customer.rb +7 -3
  277. data/lib/shopify_api/rest/resources/2023_01/customer_address.rb +17 -3
  278. data/lib/shopify_api/rest/resources/2023_01/customer_saved_search.rb +7 -3
  279. data/lib/shopify_api/rest/resources/2023_01/deprecated_api_call.rb +7 -3
  280. data/lib/shopify_api/rest/resources/2023_01/discount_code.rb +7 -3
  281. data/lib/shopify_api/rest/resources/2023_01/dispute.rb +7 -3
  282. data/lib/shopify_api/rest/resources/2023_01/dispute_evidence.rb +7 -3
  283. data/lib/shopify_api/rest/resources/2023_01/dispute_file_upload.rb +7 -3
  284. data/lib/shopify_api/rest/resources/2023_01/draft_order.rb +7 -3
  285. data/lib/shopify_api/rest/resources/2023_01/event.rb +7 -3
  286. data/lib/shopify_api/rest/resources/2023_01/fulfillment.rb +7 -3
  287. data/lib/shopify_api/rest/resources/2023_01/fulfillment_event.rb +7 -3
  288. data/lib/shopify_api/rest/resources/2023_01/fulfillment_order.rb +15 -13
  289. data/lib/shopify_api/rest/resources/2023_01/fulfillment_request.rb +17 -3
  290. data/lib/shopify_api/rest/resources/2023_01/fulfillment_service.rb +7 -3
  291. data/lib/shopify_api/rest/resources/2023_01/gift_card.rb +7 -3
  292. data/lib/shopify_api/rest/resources/2023_01/gift_card_adjustment.rb +7 -3
  293. data/lib/shopify_api/rest/resources/2023_01/image.rb +7 -3
  294. data/lib/shopify_api/rest/resources/2023_01/inventory_item.rb +7 -3
  295. data/lib/shopify_api/rest/resources/2023_01/inventory_level.rb +7 -3
  296. data/lib/shopify_api/rest/resources/2023_01/location.rb +7 -3
  297. data/lib/shopify_api/rest/resources/2023_01/locations_for_move.rb +7 -3
  298. data/lib/shopify_api/rest/resources/2023_01/marketing_event.rb +7 -3
  299. data/lib/shopify_api/rest/resources/2023_01/metafield.rb +7 -3
  300. data/lib/shopify_api/rest/resources/2023_01/mobile_platform_application.rb +7 -3
  301. data/lib/shopify_api/rest/resources/2023_01/order.rb +10 -3
  302. data/lib/shopify_api/rest/resources/2023_01/order_risk.rb +12 -6
  303. data/lib/shopify_api/rest/resources/2023_01/page.rb +7 -3
  304. data/lib/shopify_api/rest/resources/2023_01/payment.rb +7 -3
  305. data/lib/shopify_api/rest/resources/2023_01/payment_gateway.rb +7 -3
  306. data/lib/shopify_api/rest/resources/2023_01/payment_transaction.rb +12 -5
  307. data/lib/shopify_api/rest/resources/2023_01/payout.rb +7 -3
  308. data/lib/shopify_api/rest/resources/2023_01/policy.rb +7 -3
  309. data/lib/shopify_api/rest/resources/2023_01/price_rule.rb +7 -3
  310. data/lib/shopify_api/rest/resources/2023_01/product.rb +7 -3
  311. data/lib/shopify_api/rest/resources/2023_01/product_listing.rb +7 -3
  312. data/lib/shopify_api/rest/resources/2023_01/product_resource_feedback.rb +7 -3
  313. data/lib/shopify_api/rest/resources/2023_01/province.rb +7 -3
  314. data/lib/shopify_api/rest/resources/2023_01/recurring_application_charge.rb +7 -3
  315. data/lib/shopify_api/rest/resources/2023_01/redirect.rb +7 -3
  316. data/lib/shopify_api/rest/resources/2023_01/refund.rb +7 -3
  317. data/lib/shopify_api/rest/resources/2023_01/report.rb +7 -3
  318. data/lib/shopify_api/rest/resources/2023_01/resource_feedback.rb +7 -3
  319. data/lib/shopify_api/rest/resources/2023_01/script_tag.rb +7 -3
  320. data/lib/shopify_api/rest/resources/2023_01/shipping_zone.rb +7 -3
  321. data/lib/shopify_api/rest/resources/2023_01/shop.rb +9 -8
  322. data/lib/shopify_api/rest/resources/2023_01/smart_collection.rb +7 -3
  323. data/lib/shopify_api/rest/resources/2023_01/storefront_access_token.rb +7 -3
  324. data/lib/shopify_api/rest/resources/2023_01/tender_transaction.rb +7 -3
  325. data/lib/shopify_api/rest/resources/2023_01/theme.rb +7 -3
  326. data/lib/shopify_api/rest/resources/2023_01/transaction.rb +7 -3
  327. data/lib/shopify_api/rest/resources/2023_01/usage_charge.rb +7 -3
  328. data/lib/shopify_api/rest/resources/2023_01/user.rb +7 -3
  329. data/lib/shopify_api/rest/resources/2023_01/variant.rb +8 -8
  330. data/lib/shopify_api/rest/resources/2023_01/webhook.rb +7 -3
  331. data/lib/shopify_api/rest/resources/2023_04/abandoned_checkout.rb +7 -3
  332. data/lib/shopify_api/rest/resources/2023_04/access_scope.rb +7 -3
  333. data/lib/shopify_api/rest/resources/2023_04/apple_pay_certificate.rb +7 -3
  334. data/lib/shopify_api/rest/resources/2023_04/application_charge.rb +7 -3
  335. data/lib/shopify_api/rest/resources/2023_04/application_credit.rb +7 -3
  336. data/lib/shopify_api/rest/resources/2023_04/article.rb +7 -3
  337. data/lib/shopify_api/rest/resources/2023_04/asset.rb +7 -3
  338. data/lib/shopify_api/rest/resources/2023_04/assigned_fulfillment_order.rb +12 -6
  339. data/lib/shopify_api/rest/resources/2023_04/balance.rb +11 -3
  340. data/lib/shopify_api/rest/resources/2023_04/blog.rb +7 -3
  341. data/lib/shopify_api/rest/resources/2023_04/cancellation_request.rb +7 -3
  342. data/lib/shopify_api/rest/resources/2023_04/carrier_service.rb +7 -3
  343. data/lib/shopify_api/rest/resources/2023_04/checkout.rb +7 -3
  344. data/lib/shopify_api/rest/resources/2023_04/collect.rb +7 -3
  345. data/lib/shopify_api/rest/resources/2023_04/collection.rb +7 -3
  346. data/lib/shopify_api/rest/resources/2023_04/collection_listing.rb +7 -3
  347. data/lib/shopify_api/rest/resources/2023_04/comment.rb +7 -3
  348. data/lib/shopify_api/rest/resources/2023_04/country.rb +7 -3
  349. data/lib/shopify_api/rest/resources/2023_04/currency.rb +7 -3
  350. data/lib/shopify_api/rest/resources/2023_04/custom_collection.rb +7 -3
  351. data/lib/shopify_api/rest/resources/2023_04/customer.rb +7 -3
  352. data/lib/shopify_api/rest/resources/2023_04/customer_address.rb +17 -3
  353. data/lib/shopify_api/rest/resources/2023_04/customer_saved_search.rb +7 -3
  354. data/lib/shopify_api/rest/resources/2023_04/deprecated_api_call.rb +7 -3
  355. data/lib/shopify_api/rest/resources/2023_04/discount_code.rb +7 -3
  356. data/lib/shopify_api/rest/resources/2023_04/dispute.rb +7 -3
  357. data/lib/shopify_api/rest/resources/2023_04/dispute_evidence.rb +7 -3
  358. data/lib/shopify_api/rest/resources/2023_04/dispute_file_upload.rb +7 -3
  359. data/lib/shopify_api/rest/resources/2023_04/draft_order.rb +7 -3
  360. data/lib/shopify_api/rest/resources/2023_04/event.rb +7 -3
  361. data/lib/shopify_api/rest/resources/2023_04/fulfillment.rb +7 -3
  362. data/lib/shopify_api/rest/resources/2023_04/fulfillment_event.rb +7 -3
  363. data/lib/shopify_api/rest/resources/2023_04/fulfillment_order.rb +12 -6
  364. data/lib/shopify_api/rest/resources/2023_04/fulfillment_request.rb +17 -3
  365. data/lib/shopify_api/rest/resources/2023_04/fulfillment_service.rb +7 -3
  366. data/lib/shopify_api/rest/resources/2023_04/gift_card.rb +7 -3
  367. data/lib/shopify_api/rest/resources/2023_04/gift_card_adjustment.rb +7 -3
  368. data/lib/shopify_api/rest/resources/2023_04/image.rb +7 -3
  369. data/lib/shopify_api/rest/resources/2023_04/inventory_item.rb +7 -3
  370. data/lib/shopify_api/rest/resources/2023_04/inventory_level.rb +7 -3
  371. data/lib/shopify_api/rest/resources/2023_04/location.rb +7 -3
  372. data/lib/shopify_api/rest/resources/2023_04/locations_for_move.rb +7 -3
  373. data/lib/shopify_api/rest/resources/2023_04/marketing_event.rb +7 -3
  374. data/lib/shopify_api/rest/resources/2023_04/metafield.rb +7 -3
  375. data/lib/shopify_api/rest/resources/2023_04/mobile_platform_application.rb +7 -3
  376. data/lib/shopify_api/rest/resources/2023_04/order.rb +10 -9
  377. data/lib/shopify_api/rest/resources/2023_04/order_risk.rb +12 -6
  378. data/lib/shopify_api/rest/resources/2023_04/page.rb +7 -3
  379. data/lib/shopify_api/rest/resources/2023_04/payment.rb +7 -3
  380. data/lib/shopify_api/rest/resources/2023_04/payment_gateway.rb +7 -3
  381. data/lib/shopify_api/rest/resources/2023_04/payment_transaction.rb +12 -5
  382. data/lib/shopify_api/rest/resources/2023_04/payout.rb +7 -3
  383. data/lib/shopify_api/rest/resources/2023_04/policy.rb +7 -3
  384. data/lib/shopify_api/rest/resources/2023_04/price_rule.rb +7 -3
  385. data/lib/shopify_api/rest/resources/2023_04/product.rb +7 -3
  386. data/lib/shopify_api/rest/resources/2023_04/product_listing.rb +7 -3
  387. data/lib/shopify_api/rest/resources/2023_04/product_resource_feedback.rb +7 -3
  388. data/lib/shopify_api/rest/resources/2023_04/province.rb +7 -3
  389. data/lib/shopify_api/rest/resources/2023_04/recurring_application_charge.rb +7 -3
  390. data/lib/shopify_api/rest/resources/2023_04/redirect.rb +7 -3
  391. data/lib/shopify_api/rest/resources/2023_04/refund.rb +7 -3
  392. data/lib/shopify_api/rest/resources/2023_04/report.rb +7 -3
  393. data/lib/shopify_api/rest/resources/2023_04/resource_feedback.rb +7 -3
  394. data/lib/shopify_api/rest/resources/2023_04/script_tag.rb +7 -3
  395. data/lib/shopify_api/rest/resources/2023_04/shipping_zone.rb +7 -3
  396. data/lib/shopify_api/rest/resources/2023_04/shop.rb +9 -8
  397. data/lib/shopify_api/rest/resources/2023_04/smart_collection.rb +7 -3
  398. data/lib/shopify_api/rest/resources/2023_04/storefront_access_token.rb +7 -3
  399. data/lib/shopify_api/rest/resources/2023_04/tender_transaction.rb +7 -3
  400. data/lib/shopify_api/rest/resources/2023_04/theme.rb +7 -3
  401. data/lib/shopify_api/rest/resources/2023_04/transaction.rb +7 -3
  402. data/lib/shopify_api/rest/resources/2023_04/usage_charge.rb +7 -3
  403. data/lib/shopify_api/rest/resources/2023_04/user.rb +7 -3
  404. data/lib/shopify_api/rest/resources/2023_04/variant.rb +8 -8
  405. data/lib/shopify_api/rest/resources/2023_04/webhook.rb +7 -3
  406. data/lib/shopify_api/rest/resources/2023_07/abandoned_checkout.rb +194 -0
  407. data/lib/shopify_api/rest/resources/2023_07/access_scope.rb +62 -0
  408. data/lib/shopify_api/rest/resources/2023_07/apple_pay_certificate.rb +109 -0
  409. data/lib/shopify_api/rest/resources/2023_07/application_charge.rb +113 -0
  410. data/lib/shopify_api/rest/resources/2023_07/application_credit.rb +95 -0
  411. data/lib/shopify_api/rest/resources/2023_07/article.rb +269 -0
  412. data/lib/shopify_api/rest/resources/2023_07/asset.rb +122 -0
  413. data/lib/shopify_api/rest/resources/2023_07/assigned_fulfillment_order.rb +92 -0
  414. data/lib/shopify_api/rest/resources/2023_07/balance.rb +58 -0
  415. data/lib/shopify_api/rest/resources/2023_07/blog.rb +166 -0
  416. data/lib/shopify_api/rest/resources/2023_07/cancellation_request.rb +87 -0
  417. data/lib/shopify_api/rest/resources/2023_07/carrier_service.rb +120 -0
  418. data/lib/shopify_api/rest/resources/2023_07/checkout.rb +213 -0
  419. data/lib/shopify_api/rest/resources/{2022_07/customer_saved_search.rb → 2023_07/collect.rb} +29 -52
  420. data/lib/shopify_api/rest/resources/2023_07/collection.rb +114 -0
  421. data/lib/shopify_api/rest/resources/2023_07/collection_listing.rb +159 -0
  422. data/lib/shopify_api/rest/resources/2023_07/comment.rb +287 -0
  423. data/lib/shopify_api/rest/resources/2023_07/country.rb +141 -0
  424. data/lib/shopify_api/rest/resources/2023_07/currency.rb +61 -0
  425. data/lib/shopify_api/rest/resources/2023_07/custom_collection.rb +191 -0
  426. data/lib/shopify_api/rest/resources/2023_07/customer.rb +333 -0
  427. data/lib/shopify_api/rest/resources/2023_07/customer_address.rb +215 -0
  428. data/lib/shopify_api/rest/resources/{2022_10 → 2023_07}/customer_saved_search.rb +7 -3
  429. data/lib/shopify_api/rest/resources/2023_07/deprecated_api_call.rb +61 -0
  430. data/lib/shopify_api/rest/resources/2023_07/discount_code.rb +226 -0
  431. data/lib/shopify_api/rest/resources/2023_07/dispute.rb +115 -0
  432. data/lib/shopify_api/rest/resources/2023_07/dispute_evidence.rb +121 -0
  433. data/lib/shopify_api/rest/resources/2023_07/dispute_file_upload.rb +85 -0
  434. data/lib/shopify_api/rest/resources/2023_07/draft_order.rb +279 -0
  435. data/lib/shopify_api/rest/resources/2023_07/event.rb +152 -0
  436. data/lib/shopify_api/rest/resources/2023_07/fulfillment.rb +235 -0
  437. data/lib/shopify_api/rest/resources/2023_07/fulfillment_event.rb +170 -0
  438. data/lib/shopify_api/rest/resources/2023_07/fulfillment_order.rb +318 -0
  439. data/lib/shopify_api/rest/resources/2023_07/fulfillment_request.rb +101 -0
  440. data/lib/shopify_api/rest/resources/2023_07/fulfillment_service.rb +134 -0
  441. data/lib/shopify_api/rest/resources/2023_07/gift_card.rb +222 -0
  442. data/lib/shopify_api/rest/resources/2023_07/gift_card_adjustment.rb +122 -0
  443. data/lib/shopify_api/rest/resources/2023_07/image.rb +161 -0
  444. data/lib/shopify_api/rest/resources/2023_07/inventory_item.rb +112 -0
  445. data/lib/shopify_api/rest/resources/2023_07/inventory_level.rb +183 -0
  446. data/lib/shopify_api/rest/resources/2023_07/location.rb +171 -0
  447. data/lib/shopify_api/rest/resources/2023_07/locations_for_move.rb +60 -0
  448. data/lib/shopify_api/rest/resources/2023_07/marketing_event.rb +213 -0
  449. data/lib/shopify_api/rest/resources/2023_07/metafield.rb +348 -0
  450. data/lib/shopify_api/rest/resources/2023_07/mobile_platform_application.rb +114 -0
  451. data/lib/shopify_api/rest/resources/2023_07/order.rb +489 -0
  452. data/lib/shopify_api/rest/resources/2023_07/order_risk.rb +148 -0
  453. data/lib/shopify_api/rest/resources/2023_07/page.rb +198 -0
  454. data/lib/shopify_api/rest/resources/2023_07/payment.rb +144 -0
  455. data/lib/shopify_api/rest/resources/2023_07/payment_gateway.rb +147 -0
  456. data/lib/shopify_api/rest/resources/2023_07/payment_transaction.rb +114 -0
  457. data/lib/shopify_api/rest/resources/2023_07/payout.rb +101 -0
  458. data/lib/shopify_api/rest/resources/2023_07/policy.rb +73 -0
  459. data/lib/shopify_api/rest/resources/2023_07/price_rule.rb +227 -0
  460. data/lib/shopify_api/rest/resources/2023_07/product.rb +227 -0
  461. data/lib/shopify_api/rest/resources/2023_07/product_listing.rb +200 -0
  462. data/lib/shopify_api/rest/resources/2023_07/product_resource_feedback.rb +92 -0
  463. data/lib/shopify_api/rest/resources/2023_07/province.rb +136 -0
  464. data/lib/shopify_api/rest/resources/2023_07/recurring_application_charge.rb +176 -0
  465. data/lib/shopify_api/rest/resources/2023_07/redirect.rb +143 -0
  466. data/lib/shopify_api/rest/resources/2023_07/refund.rb +155 -0
  467. data/lib/shopify_api/rest/resources/2023_07/report.rb +125 -0
  468. data/lib/shopify_api/rest/resources/2023_07/resource_feedback.rb +77 -0
  469. data/lib/shopify_api/rest/resources/2023_07/script_tag.rb +159 -0
  470. data/lib/shopify_api/rest/resources/2023_07/shipping_zone.rb +87 -0
  471. data/lib/shopify_api/rest/resources/2023_07/shop.rb +222 -0
  472. data/lib/shopify_api/rest/resources/2023_07/smart_collection.rb +220 -0
  473. data/lib/shopify_api/rest/resources/2023_07/storefront_access_token.rb +91 -0
  474. data/lib/shopify_api/rest/resources/2023_07/tender_transaction.rb +97 -0
  475. data/lib/shopify_api/rest/resources/2023_07/theme.rb +127 -0
  476. data/lib/shopify_api/rest/resources/2023_07/transaction.rb +188 -0
  477. data/lib/shopify_api/rest/resources/2023_07/usage_charge.rb +106 -0
  478. data/lib/shopify_api/rest/resources/2023_07/user.rb +142 -0
  479. data/lib/shopify_api/rest/resources/2023_07/variant.rb +212 -0
  480. data/lib/shopify_api/rest/resources/2023_07/webhook.rb +172 -0
  481. data/lib/shopify_api/rest/resources/2023_10/abandoned_checkout.rb +194 -0
  482. data/lib/shopify_api/rest/resources/2023_10/access_scope.rb +62 -0
  483. data/lib/shopify_api/rest/resources/2023_10/apple_pay_certificate.rb +109 -0
  484. data/lib/shopify_api/rest/resources/2023_10/application_charge.rb +113 -0
  485. data/lib/shopify_api/rest/resources/2023_10/application_credit.rb +95 -0
  486. data/lib/shopify_api/rest/resources/2023_10/article.rb +269 -0
  487. data/lib/shopify_api/rest/resources/2023_10/asset.rb +122 -0
  488. data/lib/shopify_api/rest/resources/2023_10/assigned_fulfillment_order.rb +92 -0
  489. data/lib/shopify_api/rest/resources/2023_10/balance.rb +58 -0
  490. data/lib/shopify_api/rest/resources/2023_10/blog.rb +166 -0
  491. data/lib/shopify_api/rest/resources/2023_10/cancellation_request.rb +87 -0
  492. data/lib/shopify_api/rest/resources/2023_10/carrier_service.rb +120 -0
  493. data/lib/shopify_api/rest/resources/2023_10/checkout.rb +213 -0
  494. data/lib/shopify_api/rest/resources/2023_10/collect.rb +146 -0
  495. data/lib/shopify_api/rest/resources/2023_10/collection.rb +114 -0
  496. data/lib/shopify_api/rest/resources/2023_10/collection_listing.rb +159 -0
  497. data/lib/shopify_api/rest/resources/2023_10/comment.rb +287 -0
  498. data/lib/shopify_api/rest/resources/2023_10/country.rb +141 -0
  499. data/lib/shopify_api/rest/resources/2023_10/currency.rb +61 -0
  500. data/lib/shopify_api/rest/resources/2023_10/custom_collection.rb +191 -0
  501. data/lib/shopify_api/rest/resources/2023_10/customer.rb +333 -0
  502. data/lib/shopify_api/rest/resources/2023_10/customer_address.rb +215 -0
  503. data/lib/shopify_api/rest/resources/2023_10/deprecated_api_call.rb +61 -0
  504. data/lib/shopify_api/rest/resources/2023_10/discount_code.rb +226 -0
  505. data/lib/shopify_api/rest/resources/2023_10/dispute.rb +115 -0
  506. data/lib/shopify_api/rest/resources/2023_10/dispute_evidence.rb +121 -0
  507. data/lib/shopify_api/rest/resources/2023_10/dispute_file_upload.rb +85 -0
  508. data/lib/shopify_api/rest/resources/2023_10/draft_order.rb +279 -0
  509. data/lib/shopify_api/rest/resources/2023_10/event.rb +152 -0
  510. data/lib/shopify_api/rest/resources/2023_10/fulfillment.rb +235 -0
  511. data/lib/shopify_api/rest/resources/2023_10/fulfillment_event.rb +170 -0
  512. data/lib/shopify_api/rest/resources/2023_10/fulfillment_order.rb +318 -0
  513. data/lib/shopify_api/rest/resources/2023_10/fulfillment_request.rb +101 -0
  514. data/lib/shopify_api/rest/resources/2023_10/fulfillment_service.rb +134 -0
  515. data/lib/shopify_api/rest/resources/2023_10/gift_card.rb +222 -0
  516. data/lib/shopify_api/rest/resources/2023_10/gift_card_adjustment.rb +122 -0
  517. data/lib/shopify_api/rest/resources/2023_10/image.rb +161 -0
  518. data/lib/shopify_api/rest/resources/2023_10/inventory_item.rb +112 -0
  519. data/lib/shopify_api/rest/resources/2023_10/inventory_level.rb +183 -0
  520. data/lib/shopify_api/rest/resources/2023_10/location.rb +171 -0
  521. data/lib/shopify_api/rest/resources/2023_10/locations_for_move.rb +60 -0
  522. data/lib/shopify_api/rest/resources/2023_10/marketing_event.rb +213 -0
  523. data/lib/shopify_api/rest/resources/2023_10/metafield.rb +348 -0
  524. data/lib/shopify_api/rest/resources/2023_10/mobile_platform_application.rb +114 -0
  525. data/lib/shopify_api/rest/resources/2023_10/order.rb +489 -0
  526. data/lib/shopify_api/rest/resources/2023_10/order_risk.rb +148 -0
  527. data/lib/shopify_api/rest/resources/2023_10/page.rb +198 -0
  528. data/lib/shopify_api/rest/resources/2023_10/payment.rb +144 -0
  529. data/lib/shopify_api/rest/resources/2023_10/payment_gateway.rb +147 -0
  530. data/lib/shopify_api/rest/resources/2023_10/payment_transaction.rb +114 -0
  531. data/lib/shopify_api/rest/resources/2023_10/payout.rb +101 -0
  532. data/lib/shopify_api/rest/resources/2023_10/policy.rb +73 -0
  533. data/lib/shopify_api/rest/resources/2023_10/price_rule.rb +227 -0
  534. data/lib/shopify_api/rest/resources/2023_10/product.rb +227 -0
  535. data/lib/shopify_api/rest/resources/2023_10/product_listing.rb +200 -0
  536. data/lib/shopify_api/rest/resources/2023_10/product_resource_feedback.rb +92 -0
  537. data/lib/shopify_api/rest/resources/2023_10/province.rb +136 -0
  538. data/lib/shopify_api/rest/resources/2023_10/recurring_application_charge.rb +176 -0
  539. data/lib/shopify_api/rest/resources/2023_10/redirect.rb +143 -0
  540. data/lib/shopify_api/rest/resources/2023_10/refund.rb +155 -0
  541. data/lib/shopify_api/rest/resources/2023_10/report.rb +125 -0
  542. data/lib/shopify_api/rest/resources/2023_10/resource_feedback.rb +77 -0
  543. data/lib/shopify_api/rest/resources/2023_10/script_tag.rb +159 -0
  544. data/lib/shopify_api/rest/resources/2023_10/shipping_zone.rb +87 -0
  545. data/lib/shopify_api/rest/resources/2023_10/shop.rb +222 -0
  546. data/lib/shopify_api/rest/resources/2023_10/smart_collection.rb +220 -0
  547. data/lib/shopify_api/rest/resources/2023_10/storefront_access_token.rb +91 -0
  548. data/lib/shopify_api/rest/resources/2023_10/tender_transaction.rb +97 -0
  549. data/lib/shopify_api/rest/resources/2023_10/theme.rb +127 -0
  550. data/lib/shopify_api/rest/resources/2023_10/transaction.rb +188 -0
  551. data/lib/shopify_api/rest/resources/2023_10/usage_charge.rb +106 -0
  552. data/lib/shopify_api/rest/resources/2023_10/user.rb +142 -0
  553. data/lib/shopify_api/rest/resources/2023_10/variant.rb +212 -0
  554. data/lib/shopify_api/rest/resources/2023_10/webhook.rb +172 -0
  555. data/lib/shopify_api/rest/resources/2024_01/abandoned_checkout.rb +194 -0
  556. data/lib/shopify_api/rest/resources/2024_01/access_scope.rb +62 -0
  557. data/lib/shopify_api/rest/resources/2024_01/apple_pay_certificate.rb +109 -0
  558. data/lib/shopify_api/rest/resources/2024_01/application_charge.rb +113 -0
  559. data/lib/shopify_api/rest/resources/2024_01/application_credit.rb +95 -0
  560. data/lib/shopify_api/rest/resources/2024_01/article.rb +269 -0
  561. data/lib/shopify_api/rest/resources/2024_01/asset.rb +122 -0
  562. data/lib/shopify_api/rest/resources/2024_01/assigned_fulfillment_order.rb +92 -0
  563. data/lib/shopify_api/rest/resources/2024_01/balance.rb +58 -0
  564. data/lib/shopify_api/rest/resources/2024_01/blog.rb +166 -0
  565. data/lib/shopify_api/rest/resources/2024_01/cancellation_request.rb +87 -0
  566. data/lib/shopify_api/rest/resources/2024_01/carrier_service.rb +120 -0
  567. data/lib/shopify_api/rest/resources/2024_01/checkout.rb +213 -0
  568. data/lib/shopify_api/rest/resources/2024_01/collect.rb +146 -0
  569. data/lib/shopify_api/rest/resources/2024_01/collection.rb +114 -0
  570. data/lib/shopify_api/rest/resources/2024_01/collection_listing.rb +159 -0
  571. data/lib/shopify_api/rest/resources/2024_01/comment.rb +287 -0
  572. data/lib/shopify_api/rest/resources/2024_01/country.rb +141 -0
  573. data/lib/shopify_api/rest/resources/2024_01/currency.rb +61 -0
  574. data/lib/shopify_api/rest/resources/2024_01/custom_collection.rb +191 -0
  575. data/lib/shopify_api/rest/resources/2024_01/customer.rb +333 -0
  576. data/lib/shopify_api/rest/resources/2024_01/customer_address.rb +215 -0
  577. data/lib/shopify_api/rest/resources/2024_01/deprecated_api_call.rb +61 -0
  578. data/lib/shopify_api/rest/resources/2024_01/discount_code.rb +226 -0
  579. data/lib/shopify_api/rest/resources/2024_01/dispute.rb +115 -0
  580. data/lib/shopify_api/rest/resources/2024_01/dispute_evidence.rb +121 -0
  581. data/lib/shopify_api/rest/resources/2024_01/dispute_file_upload.rb +85 -0
  582. data/lib/shopify_api/rest/resources/2024_01/draft_order.rb +279 -0
  583. data/lib/shopify_api/rest/resources/2024_01/event.rb +152 -0
  584. data/lib/shopify_api/rest/resources/2024_01/fulfillment.rb +235 -0
  585. data/lib/shopify_api/rest/resources/2024_01/fulfillment_event.rb +170 -0
  586. data/lib/shopify_api/rest/resources/2024_01/fulfillment_order.rb +326 -0
  587. data/lib/shopify_api/rest/resources/2024_01/fulfillment_request.rb +101 -0
  588. data/lib/shopify_api/rest/resources/2024_01/fulfillment_service.rb +134 -0
  589. data/lib/shopify_api/rest/resources/2024_01/gift_card.rb +222 -0
  590. data/lib/shopify_api/rest/resources/2024_01/gift_card_adjustment.rb +122 -0
  591. data/lib/shopify_api/rest/resources/2024_01/image.rb +161 -0
  592. data/lib/shopify_api/rest/resources/2024_01/inventory_item.rb +112 -0
  593. data/lib/shopify_api/rest/resources/2024_01/inventory_level.rb +183 -0
  594. data/lib/shopify_api/rest/resources/2024_01/location.rb +171 -0
  595. data/lib/shopify_api/rest/resources/2024_01/locations_for_move.rb +60 -0
  596. data/lib/shopify_api/rest/resources/2024_01/marketing_event.rb +213 -0
  597. data/lib/shopify_api/rest/resources/2024_01/metafield.rb +348 -0
  598. data/lib/shopify_api/rest/resources/2024_01/mobile_platform_application.rb +114 -0
  599. data/lib/shopify_api/rest/resources/2024_01/order.rb +489 -0
  600. data/lib/shopify_api/rest/resources/2024_01/order_risk.rb +148 -0
  601. data/lib/shopify_api/rest/resources/2024_01/page.rb +198 -0
  602. data/lib/shopify_api/rest/resources/2024_01/payment.rb +144 -0
  603. data/lib/shopify_api/rest/resources/2024_01/payment_gateway.rb +147 -0
  604. data/lib/shopify_api/rest/resources/2024_01/payment_transaction.rb +114 -0
  605. data/lib/shopify_api/rest/resources/2024_01/payout.rb +101 -0
  606. data/lib/shopify_api/rest/resources/2024_01/policy.rb +73 -0
  607. data/lib/shopify_api/rest/resources/2024_01/price_rule.rb +227 -0
  608. data/lib/shopify_api/rest/resources/2024_01/product.rb +227 -0
  609. data/lib/shopify_api/rest/resources/2024_01/product_listing.rb +200 -0
  610. data/lib/shopify_api/rest/resources/2024_01/product_resource_feedback.rb +92 -0
  611. data/lib/shopify_api/rest/resources/2024_01/province.rb +136 -0
  612. data/lib/shopify_api/rest/resources/2024_01/recurring_application_charge.rb +176 -0
  613. data/lib/shopify_api/rest/resources/2024_01/redirect.rb +143 -0
  614. data/lib/shopify_api/rest/resources/2024_01/refund.rb +155 -0
  615. data/lib/shopify_api/rest/resources/2024_01/report.rb +125 -0
  616. data/lib/shopify_api/rest/resources/2024_01/resource_feedback.rb +77 -0
  617. data/lib/shopify_api/rest/resources/2024_01/script_tag.rb +159 -0
  618. data/lib/shopify_api/rest/resources/2024_01/shipping_zone.rb +87 -0
  619. data/lib/shopify_api/rest/resources/2024_01/shop.rb +222 -0
  620. data/lib/shopify_api/rest/resources/2024_01/smart_collection.rb +220 -0
  621. data/lib/shopify_api/rest/resources/2024_01/storefront_access_token.rb +91 -0
  622. data/lib/shopify_api/rest/resources/2024_01/tender_transaction.rb +97 -0
  623. data/lib/shopify_api/rest/resources/2024_01/theme.rb +127 -0
  624. data/lib/shopify_api/rest/resources/2024_01/transaction.rb +188 -0
  625. data/lib/shopify_api/rest/resources/2024_01/usage_charge.rb +106 -0
  626. data/lib/shopify_api/rest/resources/2024_01/user.rb +142 -0
  627. data/lib/shopify_api/rest/resources/2024_01/variant.rb +212 -0
  628. data/lib/shopify_api/rest/resources/2024_01/webhook.rb +172 -0
  629. data/lib/shopify_api/utils/attributes_comparator.rb +85 -0
  630. data/lib/shopify_api/utils/hmac_validator.rb +2 -2
  631. data/lib/shopify_api/version.rb +1 -1
  632. data/lib/shopify_api/webhooks/handler.rb +24 -1
  633. data/lib/shopify_api/webhooks/registration.rb +21 -6
  634. data/lib/shopify_api/webhooks/registrations/event_bridge.rb +1 -1
  635. data/lib/shopify_api/webhooks/registrations/http.rb +1 -1
  636. data/lib/shopify_api/webhooks/registrations/pub_sub.rb +2 -1
  637. data/lib/shopify_api/webhooks/registry.rb +49 -7
  638. data/lib/shopify_api/webhooks/request.rb +10 -0
  639. data/shopify_api.gemspec +2 -3
  640. metadata +234 -29
  641. data/.github/workflows/stale.yml +0 -43
  642. data/docs/issues.md +0 -39
  643. data/docs/usage/session_storage.md +0 -46
@@ -2,13 +2,43 @@
2
2
 
3
3
  The `shopify_api` gem provides webhook functionality to make it easy to both subscribe to and process webhooks. To implement in your app follow the steps outlined below.
4
4
 
5
+ ## Use with Rails
6
+ If using in the Rails framework, we highly recommend you use the [shopify_app](https://github.com/Shopify/shopify_app) gem to interact with this gem. That gem handles [webhooks with a declarative configuration](https://github.com/Shopify/shopify_app/blob/main/docs/shopify_app/webhooks.md).
7
+
5
8
  ## Create a Webhook Handler
6
9
 
7
- If you want to register for an http webhook you need to implement a webhook handler which the `shopify_api` gem can use to determine how to process your webhook. You can make multiple implementations (one per topic) or you can make one implementation capable of handling all the topics you want to subscribe to. To do this simply make a module or class that includes or extends `ShopifyAPI::Webhooks::WebhookHandler` and implement the handle method which accepts the following named parameters: topic: `String`, shop: `String`, and body: `Hash[String, untyped]`. An example implementation is shown below:
10
+ If you want to register for an http webhook you need to implement a webhook handler which the `shopify_api` gem can use to determine how to process your webhook. You can make multiple implementations (one per topic) or you can make one implementation capable of handling all the topics you want to subscribe to. To do this simply make a module or class that includes or extends `ShopifyAPI::Webhooks::WebhookHandler` and implement the `handle` method which accepts the following named parameters: data: `WebhookMetadata`. An example implementation is shown below:
11
+
12
+ `data` will have the following keys
13
+ - `topic`, `String` - The topic of the webhook
14
+ - `shop`, `String` - The shop domain of the webhook
15
+ - `body`, `T::Hash[String, T.untyped]`- The body of the webhook
16
+ - `webhook_id`, `String` - The id of the webhook event to [avoid duplicates](https://shopify.dev/docs/apps/webhooks/best-practices#ignore-duplicates)
17
+ - `api_version`, `String` - The api version of the webhook
8
18
 
9
19
  ```ruby
10
- module WebhookHandler
11
- include ShopifyAPI::Webhooks::Handler
20
+ module WebhookHandler
21
+ extend ShopifyAPI::Webhooks::Handler
22
+
23
+ class << self
24
+ def handle_webhook(data)
25
+ puts "Received webhook! topic: #{data.topic} shop: #{data.shop} body: #{data.body} webhook_id: #{data.webhook_id} api_version: #{data.api_version"
26
+ end
27
+ end
28
+ end
29
+ ```
30
+
31
+ **Note:** As of version 13.5.0 the `ShopifyAPI::Webhooks::Handler` class is still available to be used but will be removed in a future version of the gem.
32
+
33
+ ### Best Practices
34
+ It is recommended that in order to respond quickly to the Shopify webhook request that the handler not do any heavy logic or network calls, rather it should simply enqueue the work in some job queue in order to be executed later.
35
+
36
+ ### Webhook Handler for versions 13.4.0 and prior
37
+ If you want to register for an http webhook you need to implement a webhook handler which the `shopify_api` gem can use to determine how to process your webhook. You can make multiple implementations (one per topic) or you can make one implementation capable of handling all the topics you want to subscribe to. To do this simply make a module or class that includes or extends `ShopifyAPI::Webhooks::Handler` and implement the handle method which accepts the following named parameters: topic: `String`, shop: `String`, and body: `Hash[String, untyped]`. An example implementation is shown below:
38
+
39
+ ```ruby
40
+ module WebhookHandler
41
+ extend ShopifyAPI::Webhooks::Handler
12
42
 
13
43
  class << self
14
44
  def handle(topic:, shop:, body:)
@@ -18,24 +48,37 @@ module WebhookHandler
18
48
  end
19
49
  ```
20
50
 
21
- **Note:** It is recommended that in order to respond quickly to the Shopify webhook request that the handler not do any heavy logic or network calls, rather it should simply enqueue the work in some job queue in order to be executed later.
22
-
23
51
  ## Add to Webhook Registry
24
52
 
25
53
  The next step is to add all the webhooks you would like to subscribe to for any shop to the webhook registry. To do this you can call `ShopifyAPI::Webhooks::Registry.add_registration` for each webhook you would like to handle. `add_registration` accepts a topic string, a delivery_method symbol (currently supporting `:http`, `:event_bridge`, and `:pub_sub`), a webhook path (the relative path for an http webhook) and a handler. This only needs to be done once when the app is started and we recommend doing this at the same time that you setup `ShopifyAPI::Context`. An example is shown below to register an http webhook:
26
54
 
27
55
  ```ruby
28
- registration = ShopifyAPI::Webhooks::Registry.add_registration(topic: "orders/create", delivery_method: :http, handler: WebhookHandler)
56
+ registration = ShopifyAPI::Webhooks::Registry.add_registration(topic: "orders/create",
57
+ delivery_method: :http,
58
+ handler: WebhookHandler,
59
+ path: 'callback/orders/create')
29
60
  ```
30
61
  If you are only interested in particular fields, you can optionally filter the data sent by Shopify by specifying the `fields` parameter. Note that you will still receive a webhook request from Shopify every time the resource is updated, but only the specified fields will be sent:
31
62
 
32
63
  ```ruby
33
64
  registration = ShopifyAPI::Webhooks::Registry.add_registration(
34
- topic: "orders/create",
35
- delivery_method: :http,
36
- handler: WebhookHandler,
65
+ topic: "orders/create",
66
+ delivery_method: :http,
67
+ handler: WebhookHandler,
68
+ path: 'callback/orders/create',
37
69
  fields: ["number","note"] # this can also be a single comma separated string
38
- )
70
+ )
71
+ ```
72
+
73
+ If you are storing metafields on an object you are receiving webhooks for, you can specify them on registration to make sure that they are also sent through the `metafieldNamespaces` parameter. Note if you are also using the `fields` parameter you will need to add `metafields` into that as well.
74
+
75
+ ```ruby
76
+ registration = ShopifyAPI::Webhooks::Registry.add_registration(
77
+ topic: "orders/create",
78
+ delivery_method: :http,
79
+ handler: WebhookHandler,
80
+ metafieldNamespaces: ["custom"]
81
+ )
39
82
  ```
40
83
 
41
84
  **Note**: The webhooks you register with Shopify are saved in the Shopify platform, but the local `ShopifyAPI::Webhooks::Registry` needs to be reloaded whenever your server restarts.
@@ -75,7 +118,7 @@ ShopifyAPI::Webhooks::Registry.register(topic: "<specific-topic>", session: shop
75
118
 
76
119
  This will return a single `ShopifyAPI::Webhooks::RegisterResult`.
77
120
 
78
- ## Unregister a Webhook
121
+ ## Unregister a Webhook
79
122
 
80
123
  To unregister a topic from a shop you can simply call:
81
124
  ```ruby
@@ -5,6 +5,9 @@ module ShopifyAPI
5
5
  module AdminVersions
6
6
  SUPPORTED_ADMIN_VERSIONS = T.let([
7
7
  "unstable",
8
+ "2024-01",
9
+ "2023-10",
10
+ "2023-07",
8
11
  "2023-04",
9
12
  "2023-01",
10
13
  "2022-10",
@@ -13,7 +16,7 @@ module ShopifyAPI
13
16
  "2022-01",
14
17
  ], T::Array[String])
15
18
 
16
- LATEST_SUPPORTED_ADMIN_VERSION = T.let("2023-04", String)
19
+ LATEST_SUPPORTED_ADMIN_VERSION = T.let("2024-01", String)
17
20
  end
18
21
 
19
22
  SUPPORTED_ADMIN_VERSIONS = ShopifyAPI::AdminVersions::SUPPORTED_ADMIN_VERSIONS
@@ -75,8 +75,8 @@ module ShopifyAPI
75
75
  def decode_token(token, api_secret_key)
76
76
  JWT.decode(token, api_secret_key, true,
77
77
  { exp_leeway: JWT_EXPIRATION_LEEWAY, algorithm: "HS256" })[0]
78
- rescue
79
- raise ShopifyAPI::Errors::InvalidJwtTokenError, "Failed to parse session token '#{token}'"
78
+ rescue JWT::DecodeError => err
79
+ raise ShopifyAPI::Errors::InvalidJwtTokenError, "Error decoding session token: #{err.message}"
80
80
  end
81
81
  end
82
82
  end
@@ -0,0 +1,37 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Auth
6
+ module Oauth
7
+ class AccessTokenResponse < T::Struct
8
+ extend T::Sig
9
+
10
+ const :access_token, String
11
+ const :scope, String
12
+ const :session, T.nilable(String)
13
+ const :expires_in, T.nilable(Integer)
14
+ const :associated_user, T.nilable(AssociatedUser)
15
+ const :associated_user_scope, T.nilable(String)
16
+
17
+ sig { returns(T::Boolean) }
18
+ def online_token?
19
+ !associated_user.nil?
20
+ end
21
+
22
+ alias_method :eql?, :==
23
+ sig { params(other: T.nilable(AccessTokenResponse)).returns(T::Boolean) }
24
+ def ==(other)
25
+ return false unless other
26
+
27
+ access_token == other.access_token &&
28
+ scope == other.scope &&
29
+ session == other.session &&
30
+ expires_in == other.expires_in &&
31
+ associated_user == other.associated_user &&
32
+ associated_user_scope == other.associated_user_scope
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -70,16 +70,27 @@ module ShopifyAPI
70
70
  raise Errors::InvalidOauthError,
71
71
  "Invalid state in OAuth callback." unless state == auth_query.state
72
72
 
73
- # TODO: replace this call with the HTTP client once it is built
73
+ null_session = Auth::Session.new(shop: auth_query.shop)
74
74
  body = { client_id: Context.api_key, client_secret: Context.api_secret_key, code: auth_query.code }
75
- response = HTTParty.post("https://#{auth_query.shop}/admin/oauth/access_token", body: body)
76
- unless response.ok?
75
+
76
+ client = Clients::HttpClient.new(session: null_session, base_path: "/admin/oauth")
77
+ response = begin
78
+ client.request(
79
+ Clients::HttpRequest.new(
80
+ http_method: :post,
81
+ path: "access_token",
82
+ body: body,
83
+ body_type: "application/json",
84
+ ),
85
+ )
86
+ rescue ShopifyAPI::Errors::HttpResponseError => e
77
87
  raise Errors::RequestAccessTokenError,
78
- "Cannot complete OAuth process. Received a #{response.code} error while requesting access token."
88
+ "Cannot complete OAuth process. Received a #{e.code} error while requesting access token."
79
89
  end
80
- session_params = response.to_h
81
90
 
82
- session = create_new_session(session_params, auth_query.shop)
91
+ session_params = T.cast(response.body, T::Hash[String, T.untyped]).to_h
92
+ session = Session.from(shop: auth_query.shop,
93
+ access_token_response: Oauth::AccessTokenResponse.from_hash(session_params))
83
94
 
84
95
  cookie = if Context.embedded?
85
96
  SessionCookie.new(
@@ -95,38 +106,6 @@ module ShopifyAPI
95
106
 
96
107
  { session: session, cookie: cookie }
97
108
  end
98
-
99
- private
100
-
101
- sig { params(session_params: T::Hash[String, T.untyped], shop: String).returns(Session) }
102
- def create_new_session(session_params, shop)
103
- session_params = session_params.to_h { |k, v| [k.to_sym, v] }
104
-
105
- scope = session_params[:scope]
106
-
107
- is_online = !session_params[:associated_user].nil?
108
-
109
- if is_online
110
- associated_user = AssociatedUser.new(session_params[:associated_user].to_h { |k, v| [k.to_sym, v] })
111
- expires = Time.now + session_params[:expires_in].to_i
112
- associated_user_scope = session_params[:associated_user_scope]
113
- id = "#{shop}_#{associated_user.id}"
114
- else
115
- id = "offline_#{shop}"
116
- end
117
-
118
- Session.new(
119
- id: id,
120
- shop: shop,
121
- access_token: session_params[:access_token],
122
- scope: scope,
123
- is_online: is_online,
124
- associated_user_scope: associated_user_scope,
125
- associated_user: associated_user,
126
- expires: expires,
127
- shopify_session_id: session_params[:session],
128
- )
129
- end
130
109
  end
131
110
  end
132
111
  end
@@ -35,6 +35,11 @@ module ShopifyAPI
35
35
  @is_online
36
36
  end
37
37
 
38
+ sig { returns(T::Boolean) }
39
+ def expired?
40
+ @expires ? @expires < Time.now : false
41
+ end
42
+
38
43
  sig do
39
44
  params(
40
45
  shop: String,
@@ -84,6 +89,32 @@ module ShopifyAPI
84
89
  end
85
90
  end
86
91
 
92
+ sig { params(shop: String, access_token_response: Oauth::AccessTokenResponse).returns(Session) }
93
+ def from(shop:, access_token_response:)
94
+ is_online = access_token_response.online_token?
95
+
96
+ if is_online
97
+ associated_user = T.must(access_token_response.associated_user)
98
+ expires = Time.now + access_token_response.expires_in.to_i
99
+ associated_user_scope = access_token_response.associated_user_scope
100
+ id = "#{shop}_#{associated_user.id}"
101
+ else
102
+ id = "offline_#{shop}"
103
+ end
104
+
105
+ new(
106
+ id: id,
107
+ shop: shop,
108
+ access_token: access_token_response.access_token,
109
+ scope: access_token_response.scope,
110
+ is_online: is_online,
111
+ associated_user_scope: associated_user_scope,
112
+ associated_user: associated_user,
113
+ expires: expires,
114
+ shopify_session_id: access_token_response.session,
115
+ )
116
+ end
117
+
87
118
  sig { params(str: String).returns(Session) }
88
119
  def deserialize(str)
89
120
  Oj.load(str)
@@ -0,0 +1,80 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Auth
6
+ module TokenExchange
7
+ extend T::Sig
8
+
9
+ TOKEN_EXCHANGE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange"
10
+ ID_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:id_token"
11
+
12
+ class RequestedTokenType < T::Enum
13
+ enums do
14
+ ONLINE_ACCESS_TOKEN = new("urn:shopify:params:oauth:token-type:online-access-token")
15
+ OFFLINE_ACCESS_TOKEN = new("urn:shopify:params:oauth:token-type:offline-access-token")
16
+ end
17
+ end
18
+
19
+ class << self
20
+ extend T::Sig
21
+
22
+ sig do
23
+ params(
24
+ shop: String,
25
+ session_token: String,
26
+ requested_token_type: RequestedTokenType,
27
+ ).returns(ShopifyAPI::Auth::Session)
28
+ end
29
+ def exchange_token(shop:, session_token:, requested_token_type:)
30
+ unless ShopifyAPI::Context.setup?
31
+ raise ShopifyAPI::Errors::ContextNotSetupError,
32
+ "ShopifyAPI::Context not setup, please call ShopifyAPI::Context.setup"
33
+ end
34
+ raise ShopifyAPI::Errors::UnsupportedOauthError,
35
+ "Cannot perform OAuth Token Exchange for private apps." if ShopifyAPI::Context.private?
36
+ raise ShopifyAPI::Errors::UnsupportedOauthError,
37
+ "Cannot perform OAuth Token Exchange for non embedded apps." unless ShopifyAPI::Context.embedded?
38
+
39
+ # Validate the session token content
40
+ ShopifyAPI::Auth::JwtPayload.new(session_token)
41
+
42
+ shop_session = ShopifyAPI::Auth::Session.new(shop: shop)
43
+ body = {
44
+ client_id: ShopifyAPI::Context.api_key,
45
+ client_secret: ShopifyAPI::Context.api_secret_key,
46
+ grant_type: TOKEN_EXCHANGE_GRANT_TYPE,
47
+ subject_token: session_token,
48
+ subject_token_type: ID_TOKEN_TYPE,
49
+ requested_token_type: requested_token_type.serialize,
50
+ }
51
+
52
+ client = Clients::HttpClient.new(session: shop_session, base_path: "/admin/oauth")
53
+ response = begin
54
+ client.request(
55
+ Clients::HttpRequest.new(
56
+ http_method: :post,
57
+ path: "access_token",
58
+ body: body,
59
+ body_type: "application/json",
60
+ ),
61
+ )
62
+ rescue ShopifyAPI::Errors::HttpResponseError => error
63
+ if error.code == 400 && error.response.body["error"] == "invalid_subject_token"
64
+ raise ShopifyAPI::Errors::InvalidJwtTokenError, "Session token was rejected by token exchange"
65
+ end
66
+
67
+ raise error
68
+ end
69
+
70
+ session_params = T.cast(response.body, T::Hash[String, T.untyped]).to_h
71
+
72
+ Session.from(
73
+ shop: shop,
74
+ access_token_response: Oauth::AccessTokenResponse.from_hash(session_params),
75
+ )
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -42,6 +42,7 @@ module ShopifyAPI
42
42
  body_type: "application/json",
43
43
  tries: tries,
44
44
  ),
45
+ response_as_struct: Context.response_as_struct || false,
45
46
  )
46
47
  end
47
48
  end
@@ -13,7 +13,9 @@ module ShopifyAPI
13
13
  session ||= Context.active_session
14
14
  raise Errors::NoActiveSessionError, "No passed or active session" unless session
15
15
 
16
- @base_uri = T.let("https://#{session.shop}", String)
16
+ api_host = Context.api_host
17
+
18
+ @base_uri = T.let("https://#{api_host || session.shop}", String)
17
19
  @base_uri_and_path = T.let("#{@base_uri}#{base_path}", String)
18
20
 
19
21
  user_agent_prefix = Context.user_agent_prefix.nil? ? "" : "#{Context.user_agent_prefix} | "
@@ -23,13 +25,15 @@ module ShopifyAPI
23
25
  "Accept": "application/json",
24
26
  }, T::Hash[T.any(Symbol, String), T.untyped])
25
27
 
28
+ @headers["Host"] = session.shop unless api_host.nil?
29
+
26
30
  unless session.access_token.nil? || T.must(session.access_token).empty?
27
31
  @headers["X-Shopify-Access-Token"] = T.cast(session.access_token, String)
28
32
  end
29
33
  end
30
34
 
31
- sig { params(request: HttpRequest).returns(HttpResponse) }
32
- def request(request)
35
+ sig { params(request: HttpRequest, response_as_struct: T::Boolean).returns(HttpResponse) }
36
+ def request(request, response_as_struct: false)
33
37
  request.verify
34
38
 
35
39
  headers = @headers
@@ -56,6 +60,11 @@ module ShopifyAPI
56
60
  body = res.body
57
61
  end
58
62
 
63
+ if response_as_struct && body.is_a?(Hash)
64
+ json_body = body.to_json
65
+ body = JSON.parse(json_body, object_class: OpenStruct)
66
+ end
67
+
59
68
  response = HttpResponse.new(code: res.code.to_i, headers: res.headers.to_h, body: body)
60
69
 
61
70
  if response.headers["x-shopify-api-deprecated-reason"]
@@ -12,17 +12,23 @@ module ShopifyAPI
12
12
  sig { returns(T::Hash[String, T::Array[String]]) }
13
13
  attr_reader :headers
14
14
 
15
- sig { returns(T.any(T::Hash[String, T.untyped], String)) }
15
+ sig { returns(T.any(T::Hash[String, T.untyped], String, OpenStruct)) }
16
16
  attr_reader :body
17
17
 
18
18
  sig { returns(T.nilable(String)) }
19
19
  attr_reader :prev_page_info, :next_page_info
20
20
 
21
+ sig { returns(T.nilable(T::Hash[String, Integer])) }
22
+ attr_reader :api_call_limit
23
+
24
+ sig { returns(T.nilable(Float)) }
25
+ attr_reader :retry_request_after
26
+
21
27
  sig do
22
28
  params(
23
29
  code: Integer,
24
30
  headers: T::Hash[String, T::Array[String]],
25
- body: T.any(T::Hash[String, T.untyped], String),
31
+ body: T.any(T::Hash[String, T.untyped], String, OpenStruct),
26
32
  ).void
27
33
  end
28
34
  def initialize(code:, headers:, body:)
@@ -33,6 +39,11 @@ module ShopifyAPI
33
39
  @prev_page_info = T.let(nil, T.nilable(String))
34
40
  @next_page_info = T.let(nil, T.nilable(String))
35
41
  @prev_page_info, @next_page_info = parse_link_header
42
+
43
+ @api_call_limit = T.let(nil, T.nilable(T::Hash[String, Integer]))
44
+ @retry_request_after = T.let(nil, T.nilable(Float))
45
+ @api_call_limit = parse_api_call_limit_header
46
+ @retry_request_after = parse_retry_header
36
47
  end
37
48
 
38
49
  sig { returns(T::Boolean) }
@@ -61,6 +72,22 @@ module ShopifyAPI
61
72
 
62
73
  [page_info["previous"], page_info["next"]]
63
74
  end
75
+
76
+ sig { returns(T.nilable(Float)) }
77
+ def parse_retry_header
78
+ return nil if @headers["retry-after"].nil?
79
+
80
+ T.must(@headers["retry-after"])[0].to_f
81
+ end
82
+
83
+ sig { returns(T.nilable(T::Hash[String, Integer])) }
84
+ def parse_api_call_limit_header
85
+ rate_limit_info = headers["x-shopify-shop-api-call-limit"]&.first
86
+ return if rate_limit_info.nil?
87
+
88
+ request_count, bucket_size = rate_limit_info.split("/").map(&:to_i)
89
+ { request_count: request_count, bucket_size: bucket_size }
90
+ end
64
91
  end
65
92
  end
66
93
  end
@@ -8,16 +8,20 @@ module ShopifyAPI
8
8
  @api_key = T.let("", String)
9
9
  @api_secret_key = T.let("", String)
10
10
  @api_version = T.let(LATEST_SUPPORTED_ADMIN_VERSION, String)
11
+ @api_host = T.let(nil, T.nilable(String))
11
12
  @scope = T.let(Auth::AuthScopes.new, Auth::AuthScopes)
12
13
  @is_private = T.let(false, T::Boolean)
13
14
  @private_shop = T.let(nil, T.nilable(String))
14
15
  @is_embedded = T.let(true, T::Boolean)
15
- @logger = T.let(::Logger.new($stdout), ::Logger)
16
+ # Logger can either be a Logger or an ActiveSupport::BroadcastLogger, which is new in Rails 7.1.0. To avoid adding a
17
+ # dependency Active Support >= 7.1.0, we go with T.untyped
18
+ @logger = T.let(::Logger.new($stdout), T.untyped)
16
19
  @log_level = T.let(:info, Symbol)
17
20
  @notified_missing_resources_folder = T.let({}, T::Hash[String, T::Boolean])
18
21
  @active_session = T.let(Concurrent::ThreadLocalVar.new { nil }, T.nilable(Concurrent::ThreadLocalVar))
19
22
  @user_agent_prefix = T.let(nil, T.nilable(String))
20
23
  @old_api_secret_key = T.let(nil, T.nilable(String))
24
+ @response_as_struct = T.let(false, T.nilable(T::Boolean))
21
25
 
22
26
  @rest_resource_loader = T.let(nil, T.nilable(Zeitwerk::Loader))
23
27
 
@@ -33,12 +37,14 @@ module ShopifyAPI
33
37
  is_private: T::Boolean,
34
38
  is_embedded: T::Boolean,
35
39
  log_level: T.any(String, Symbol),
36
- logger: ::Logger,
40
+ logger: T.untyped,
37
41
  host_name: T.nilable(String),
38
42
  host: T.nilable(String),
39
43
  private_shop: T.nilable(String),
40
44
  user_agent_prefix: T.nilable(String),
41
45
  old_api_secret_key: T.nilable(String),
46
+ api_host: T.nilable(String),
47
+ response_as_struct: T.nilable(T::Boolean),
42
48
  ).void
43
49
  end
44
50
  def setup(
@@ -54,7 +60,9 @@ module ShopifyAPI
54
60
  host: ENV["HOST"] || "https://#{host_name}",
55
61
  private_shop: nil,
56
62
  user_agent_prefix: nil,
57
- old_api_secret_key: nil
63
+ old_api_secret_key: nil,
64
+ api_host: nil,
65
+ response_as_struct: false
58
66
  )
59
67
  unless ShopifyAPI::AdminVersions::SUPPORTED_ADMIN_VERSIONS.include?(api_version)
60
68
  raise Errors::UnsupportedVersionError,
@@ -64,6 +72,7 @@ module ShopifyAPI
64
72
  @api_key = api_key
65
73
  @api_secret_key = api_secret_key
66
74
  @api_version = api_version
75
+ @api_host = api_host
67
76
  @host = T.let(host, T.nilable(String))
68
77
  @is_private = is_private
69
78
  @scope = Auth::AuthScopes.new(scope)
@@ -72,6 +81,7 @@ module ShopifyAPI
72
81
  @private_shop = private_shop
73
82
  @user_agent_prefix = user_agent_prefix
74
83
  @old_api_secret_key = old_api_secret_key
84
+ @response_as_struct = response_as_struct
75
85
  @log_level = if valid_log_level?(log_level)
76
86
  log_level.to_sym
77
87
  else
@@ -84,6 +94,7 @@ module ShopifyAPI
84
94
  sig { params(api_version: String).void }
85
95
  def load_rest_resources(api_version:)
86
96
  # Unload any previous instances - mostly useful for tests where we need to reset the version
97
+ @rest_resource_loader&.setup
87
98
  @rest_resource_loader&.unload
88
99
 
89
100
  # No resources for the unstable version
@@ -115,19 +126,22 @@ module ShopifyAPI
115
126
  sig { returns(Auth::AuthScopes) }
116
127
  attr_reader :scope
117
128
 
118
- sig { returns(::Logger) }
129
+ sig { returns(T.untyped) }
119
130
  attr_reader :logger
120
131
 
121
132
  sig { returns(Symbol) }
122
133
  attr_reader :log_level
123
134
 
135
+ sig { returns T.nilable(T::Boolean) }
136
+ attr_reader :response_as_struct
137
+
124
138
  sig { returns(T::Boolean) }
125
139
  def private?
126
140
  @is_private
127
141
  end
128
142
 
129
143
  sig { returns(T.nilable(String)) }
130
- attr_reader :private_shop, :user_agent_prefix, :old_api_secret_key, :host
144
+ attr_reader :private_shop, :user_agent_prefix, :old_api_secret_key, :host, :api_host
131
145
 
132
146
  sig { returns(T::Boolean) }
133
147
  def embedded?
@@ -75,7 +75,7 @@ module ShopifyAPI
75
75
  def valid_version(version)
76
76
  current_version = Gem::Version.create(ShopifyAPI::VERSION)
77
77
  deprecate_version = Gem::Version.create(version)
78
- current_version < deprecate_version
78
+ T.must(current_version) < deprecate_version
79
79
  end
80
80
  end
81
81
  end