shopify_api 4.13.0 → 12.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (698) hide show
  1. checksums.yaml +5 -5
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE.md +35 -0
  4. data/.github/dependabot.yml +20 -0
  5. data/.github/pull_request_template.md +20 -0
  6. data/.github/workflows/build.yml +42 -0
  7. data/.github/workflows/cla.yml +22 -0
  8. data/.github/workflows/close-waiting-for-response-issues.yml +20 -0
  9. data/.github/workflows/remove-labels-on-activity.yml +16 -0
  10. data/.github/workflows/stale.yml +32 -0
  11. data/.rubocop.yml +56 -5
  12. data/BREAKING_CHANGES_FOR_OLDER_VERSIONS.md +110 -0
  13. data/CHANGELOG.md +568 -0
  14. data/CONTRIBUTING.md +4 -3
  15. data/Gemfile +9 -2
  16. data/Gemfile.lock +159 -0
  17. data/LICENSE +2 -2
  18. data/README.md +86 -218
  19. data/RELEASING.md +19 -0
  20. data/Rakefile +16 -32
  21. data/SECURITY.md +59 -0
  22. data/bin/tapioca +29 -0
  23. data/dev.yml +32 -0
  24. data/docs/README.md +13 -0
  25. data/docs/getting_started.md +53 -0
  26. data/docs/issues.md +39 -0
  27. data/docs/usage/graphql.md +115 -0
  28. data/docs/usage/graphql_storefront.md +42 -0
  29. data/docs/usage/oauth.md +105 -0
  30. data/docs/usage/rest.md +137 -0
  31. data/docs/usage/session_storage.md +46 -0
  32. data/docs/usage/webhooks.md +98 -0
  33. data/lib/shopify_api/admin_versions.rb +19 -0
  34. data/lib/shopify_api/auth/associated_user.rb +36 -0
  35. data/lib/shopify_api/auth/auth_scopes.rb +75 -0
  36. data/lib/shopify_api/auth/file_session_storage.rb +72 -0
  37. data/lib/shopify_api/auth/jwt_payload.rb +83 -0
  38. data/lib/shopify_api/auth/oauth/auth_query.rb +47 -0
  39. data/lib/shopify_api/auth/oauth/session_cookie.rb +28 -0
  40. data/lib/shopify_api/auth/oauth.rb +138 -0
  41. data/lib/shopify_api/auth/session.rb +119 -0
  42. data/lib/shopify_api/auth/session_storage.rb +30 -0
  43. data/lib/shopify_api/auth.rb +26 -0
  44. data/lib/shopify_api/clients/graphql/admin.rb +15 -0
  45. data/lib/shopify_api/clients/graphql/client.rb +40 -0
  46. data/lib/shopify_api/clients/graphql/storefront.rb +35 -0
  47. data/lib/shopify_api/clients/http_client.rb +100 -0
  48. data/lib/shopify_api/clients/http_request.rb +35 -0
  49. data/lib/shopify_api/clients/http_response.rb +66 -0
  50. data/lib/shopify_api/clients/rest/admin.rb +118 -0
  51. data/lib/shopify_api/context.rb +166 -0
  52. data/lib/shopify_api/errors/context_not_setup_error.rb +9 -0
  53. data/lib/shopify_api/errors/cookie_not_found_error.rb +9 -0
  54. data/lib/shopify_api/errors/http_response_error.rb +19 -0
  55. data/lib/shopify_api/errors/invalid_graphql_request_error.rb +9 -0
  56. data/lib/shopify_api/errors/invalid_http_request_error.rb +9 -0
  57. data/lib/shopify_api/errors/invalid_jwt_token_error.rb +9 -0
  58. data/lib/shopify_api/errors/invalid_oauth_error.rb +9 -0
  59. data/lib/shopify_api/errors/invalid_webhook_error.rb +9 -0
  60. data/lib/shopify_api/errors/invalid_webhook_registration_error.rb +9 -0
  61. data/lib/shopify_api/errors/max_http_retries_exceeded_error.rb +9 -0
  62. data/lib/shopify_api/errors/missing_jwt_token_error.rb +9 -0
  63. data/lib/shopify_api/errors/missing_required_argument_error.rb +9 -0
  64. data/lib/shopify_api/errors/no_active_session_error.rb +9 -0
  65. data/lib/shopify_api/errors/no_session_cookie_error.rb +9 -0
  66. data/lib/shopify_api/errors/no_webhook_handler.rb +9 -0
  67. data/lib/shopify_api/errors/private_app_error.rb +9 -0
  68. data/lib/shopify_api/errors/request_access_token_error.rb +9 -0
  69. data/lib/shopify_api/errors/session_not_found_error.rb +9 -0
  70. data/lib/shopify_api/errors/session_storage_error.rb +9 -0
  71. data/lib/shopify_api/errors/unsupported_oauth_error.rb +9 -0
  72. data/lib/shopify_api/errors/unsupported_version_error.rb +9 -0
  73. data/lib/shopify_api/errors/webhook_registration_error.rb +9 -0
  74. data/lib/shopify_api/inflector.rb +17 -0
  75. data/lib/shopify_api/rest/base.rb +387 -0
  76. data/lib/shopify_api/rest/base_errors.rb +32 -0
  77. data/lib/shopify_api/rest/resources/2022_01/abandoned_checkout.rb +190 -0
  78. data/lib/shopify_api/rest/resources/2022_01/access_scope.rb +58 -0
  79. data/lib/shopify_api/rest/resources/2022_01/android_pay_key.rb +77 -0
  80. data/lib/shopify_api/rest/resources/2022_01/apple_pay_certificate.rb +105 -0
  81. data/lib/shopify_api/rest/resources/2022_01/application_charge.rb +104 -0
  82. data/lib/shopify_api/rest/resources/2022_01/application_credit.rb +87 -0
  83. data/lib/shopify_api/rest/resources/2022_01/article.rb +265 -0
  84. data/lib/shopify_api/rest/resources/2022_01/asset.rb +118 -0
  85. data/lib/shopify_api/rest/resources/2022_01/assigned_fulfillment_order.rb +79 -0
  86. data/lib/shopify_api/rest/resources/2022_01/balance.rb +50 -0
  87. data/lib/shopify_api/rest/resources/2022_01/blog.rb +162 -0
  88. data/lib/shopify_api/rest/resources/2022_01/cancellation_request.rb +83 -0
  89. data/lib/shopify_api/rest/resources/2022_01/carrier_service.rb +116 -0
  90. data/lib/shopify_api/rest/resources/2022_01/checkout.rb +209 -0
  91. data/lib/shopify_api/rest/resources/2022_01/collect.rb +142 -0
  92. data/lib/shopify_api/rest/resources/2022_01/collection.rb +110 -0
  93. data/lib/shopify_api/rest/resources/2022_01/collection_listing.rb +155 -0
  94. data/lib/shopify_api/rest/resources/2022_01/comment.rb +283 -0
  95. data/lib/shopify_api/rest/resources/2022_01/country.rb +137 -0
  96. data/lib/shopify_api/rest/resources/2022_01/currency.rb +57 -0
  97. data/lib/shopify_api/rest/resources/2022_01/custom_collection.rb +187 -0
  98. data/lib/shopify_api/rest/resources/2022_01/customer.rb +318 -0
  99. data/lib/shopify_api/rest/resources/2022_01/customer_address.rb +201 -0
  100. data/lib/shopify_api/rest/resources/2022_01/customer_saved_search.rb +169 -0
  101. data/lib/shopify_api/rest/resources/2022_01/deprecated_api_call.rb +57 -0
  102. data/lib/shopify_api/rest/resources/2022_01/discount_code.rb +219 -0
  103. data/lib/shopify_api/rest/resources/2022_01/dispute.rb +111 -0
  104. data/lib/shopify_api/rest/resources/2022_01/draft_order.rb +275 -0
  105. data/lib/shopify_api/rest/resources/2022_01/event.rb +148 -0
  106. data/lib/shopify_api/rest/resources/2022_01/fulfillment.rb +268 -0
  107. data/lib/shopify_api/rest/resources/2022_01/fulfillment_event.rb +166 -0
  108. data/lib/shopify_api/rest/resources/2022_01/fulfillment_order.rb +281 -0
  109. data/lib/shopify_api/rest/resources/2022_01/fulfillment_request.rb +87 -0
  110. data/lib/shopify_api/rest/resources/2022_01/fulfillment_service.rb +130 -0
  111. data/lib/shopify_api/rest/resources/2022_01/gift_card.rb +215 -0
  112. data/lib/shopify_api/rest/resources/2022_01/gift_card_adjustment.rb +118 -0
  113. data/lib/shopify_api/rest/resources/2022_01/image.rb +157 -0
  114. data/lib/shopify_api/rest/resources/2022_01/inventory_item.rb +108 -0
  115. data/lib/shopify_api/rest/resources/2022_01/inventory_level.rb +179 -0
  116. data/lib/shopify_api/rest/resources/2022_01/location.rb +167 -0
  117. data/lib/shopify_api/rest/resources/2022_01/locations_for_move.rb +56 -0
  118. data/lib/shopify_api/rest/resources/2022_01/marketing_event.rb +209 -0
  119. data/lib/shopify_api/rest/resources/2022_01/metafield.rb +349 -0
  120. data/lib/shopify_api/rest/resources/2022_01/mobile_platform_application.rb +110 -0
  121. data/lib/shopify_api/rest/resources/2022_01/order.rb +473 -0
  122. data/lib/shopify_api/rest/resources/2022_01/order_risk.rb +135 -0
  123. data/lib/shopify_api/rest/resources/2022_01/page.rb +194 -0
  124. data/lib/shopify_api/rest/resources/2022_01/payment.rb +140 -0
  125. data/lib/shopify_api/rest/resources/2022_01/payment_gateway.rb +143 -0
  126. data/lib/shopify_api/rest/resources/2022_01/payment_transaction.rb +107 -0
  127. data/lib/shopify_api/rest/resources/2022_01/payout.rb +97 -0
  128. data/lib/shopify_api/rest/resources/2022_01/policy.rb +69 -0
  129. data/lib/shopify_api/rest/resources/2022_01/price_rule.rb +223 -0
  130. data/lib/shopify_api/rest/resources/2022_01/product.rb +223 -0
  131. data/lib/shopify_api/rest/resources/2022_01/product_listing.rb +196 -0
  132. data/lib/shopify_api/rest/resources/2022_01/product_resource_feedback.rb +88 -0
  133. data/lib/shopify_api/rest/resources/2022_01/province.rb +132 -0
  134. data/lib/shopify_api/rest/resources/2022_01/recurring_application_charge.rb +167 -0
  135. data/lib/shopify_api/rest/resources/2022_01/redirect.rb +139 -0
  136. data/lib/shopify_api/rest/resources/2022_01/refund.rb +151 -0
  137. data/lib/shopify_api/rest/resources/2022_01/report.rb +121 -0
  138. data/lib/shopify_api/rest/resources/2022_01/resource_feedback.rb +73 -0
  139. data/lib/shopify_api/rest/resources/2022_01/script_tag.rb +155 -0
  140. data/lib/shopify_api/rest/resources/2022_01/shipping_zone.rb +83 -0
  141. data/lib/shopify_api/rest/resources/2022_01/shop.rb +218 -0
  142. data/lib/shopify_api/rest/resources/2022_01/smart_collection.rb +216 -0
  143. data/lib/shopify_api/rest/resources/2022_01/storefront_access_token.rb +87 -0
  144. data/lib/shopify_api/rest/resources/2022_01/tender_transaction.rb +93 -0
  145. data/lib/shopify_api/rest/resources/2022_01/theme.rb +120 -0
  146. data/lib/shopify_api/rest/resources/2022_01/transaction.rb +181 -0
  147. data/lib/shopify_api/rest/resources/2022_01/usage_charge.rb +97 -0
  148. data/lib/shopify_api/rest/resources/2022_01/user.rb +138 -0
  149. data/lib/shopify_api/rest/resources/2022_01/variant.rb +212 -0
  150. data/lib/shopify_api/rest/resources/2022_01/webhook.rb +168 -0
  151. data/lib/shopify_api/rest/resources/2022_04/abandoned_checkout.rb +190 -0
  152. data/lib/shopify_api/rest/resources/2022_04/access_scope.rb +58 -0
  153. data/lib/shopify_api/rest/resources/2022_04/android_pay_key.rb +77 -0
  154. data/lib/shopify_api/rest/resources/2022_04/apple_pay_certificate.rb +105 -0
  155. data/lib/shopify_api/rest/resources/2022_04/application_charge.rb +104 -0
  156. data/lib/shopify_api/rest/resources/2022_04/application_credit.rb +87 -0
  157. data/lib/shopify_api/rest/resources/2022_04/article.rb +265 -0
  158. data/lib/shopify_api/rest/resources/2022_04/asset.rb +118 -0
  159. data/lib/shopify_api/rest/resources/2022_04/assigned_fulfillment_order.rb +79 -0
  160. data/lib/shopify_api/rest/resources/2022_04/balance.rb +50 -0
  161. data/lib/shopify_api/rest/resources/2022_04/blog.rb +162 -0
  162. data/lib/shopify_api/rest/resources/2022_04/cancellation_request.rb +83 -0
  163. data/lib/shopify_api/rest/resources/2022_04/carrier_service.rb +116 -0
  164. data/lib/shopify_api/rest/resources/2022_04/checkout.rb +209 -0
  165. data/lib/shopify_api/rest/resources/2022_04/collect.rb +142 -0
  166. data/lib/shopify_api/rest/resources/2022_04/collection.rb +110 -0
  167. data/lib/shopify_api/rest/resources/2022_04/collection_listing.rb +155 -0
  168. data/lib/shopify_api/rest/resources/2022_04/comment.rb +283 -0
  169. data/lib/shopify_api/rest/resources/2022_04/country.rb +137 -0
  170. data/lib/shopify_api/rest/resources/2022_04/currency.rb +57 -0
  171. data/lib/shopify_api/rest/resources/2022_04/custom_collection.rb +187 -0
  172. data/lib/shopify_api/rest/resources/2022_04/customer.rb +321 -0
  173. data/lib/shopify_api/rest/resources/2022_04/customer_address.rb +201 -0
  174. data/lib/shopify_api/rest/resources/2022_04/customer_saved_search.rb +169 -0
  175. data/lib/shopify_api/rest/resources/2022_04/deprecated_api_call.rb +57 -0
  176. data/lib/shopify_api/rest/resources/2022_04/discount_code.rb +219 -0
  177. data/lib/shopify_api/rest/resources/2022_04/dispute.rb +111 -0
  178. data/lib/shopify_api/rest/resources/2022_04/draft_order.rb +275 -0
  179. data/lib/shopify_api/rest/resources/2022_04/event.rb +148 -0
  180. data/lib/shopify_api/rest/resources/2022_04/fulfillment.rb +268 -0
  181. data/lib/shopify_api/rest/resources/2022_04/fulfillment_event.rb +166 -0
  182. data/lib/shopify_api/rest/resources/2022_04/fulfillment_order.rb +284 -0
  183. data/lib/shopify_api/rest/resources/2022_04/fulfillment_request.rb +87 -0
  184. data/lib/shopify_api/rest/resources/2022_04/fulfillment_service.rb +130 -0
  185. data/lib/shopify_api/rest/resources/2022_04/gift_card.rb +215 -0
  186. data/lib/shopify_api/rest/resources/2022_04/gift_card_adjustment.rb +118 -0
  187. data/lib/shopify_api/rest/resources/2022_04/image.rb +157 -0
  188. data/lib/shopify_api/rest/resources/2022_04/inventory_item.rb +108 -0
  189. data/lib/shopify_api/rest/resources/2022_04/inventory_level.rb +179 -0
  190. data/lib/shopify_api/rest/resources/2022_04/location.rb +167 -0
  191. data/lib/shopify_api/rest/resources/2022_04/locations_for_move.rb +56 -0
  192. data/lib/shopify_api/rest/resources/2022_04/marketing_event.rb +209 -0
  193. data/lib/shopify_api/rest/resources/2022_04/metafield.rb +342 -0
  194. data/lib/shopify_api/rest/resources/2022_04/mobile_platform_application.rb +110 -0
  195. data/lib/shopify_api/rest/resources/2022_04/order.rb +473 -0
  196. data/lib/shopify_api/rest/resources/2022_04/order_risk.rb +135 -0
  197. data/lib/shopify_api/rest/resources/2022_04/page.rb +194 -0
  198. data/lib/shopify_api/rest/resources/2022_04/payment.rb +140 -0
  199. data/lib/shopify_api/rest/resources/2022_04/payment_gateway.rb +143 -0
  200. data/lib/shopify_api/rest/resources/2022_04/payment_transaction.rb +107 -0
  201. data/lib/shopify_api/rest/resources/2022_04/payout.rb +97 -0
  202. data/lib/shopify_api/rest/resources/2022_04/policy.rb +69 -0
  203. data/lib/shopify_api/rest/resources/2022_04/price_rule.rb +223 -0
  204. data/lib/shopify_api/rest/resources/2022_04/product.rb +223 -0
  205. data/lib/shopify_api/rest/resources/2022_04/product_listing.rb +196 -0
  206. data/lib/shopify_api/rest/resources/2022_04/product_resource_feedback.rb +88 -0
  207. data/lib/shopify_api/rest/resources/2022_04/province.rb +132 -0
  208. data/lib/shopify_api/rest/resources/2022_04/recurring_application_charge.rb +167 -0
  209. data/lib/shopify_api/rest/resources/2022_04/redirect.rb +139 -0
  210. data/lib/shopify_api/rest/resources/2022_04/refund.rb +151 -0
  211. data/lib/shopify_api/rest/resources/2022_04/report.rb +121 -0
  212. data/lib/shopify_api/rest/resources/2022_04/resource_feedback.rb +73 -0
  213. data/lib/shopify_api/rest/resources/2022_04/script_tag.rb +155 -0
  214. data/lib/shopify_api/rest/resources/2022_04/shipping_zone.rb +83 -0
  215. data/lib/shopify_api/rest/resources/2022_04/shop.rb +218 -0
  216. data/lib/shopify_api/rest/resources/2022_04/smart_collection.rb +216 -0
  217. data/lib/shopify_api/rest/resources/2022_04/storefront_access_token.rb +87 -0
  218. data/lib/shopify_api/rest/resources/2022_04/tender_transaction.rb +93 -0
  219. data/lib/shopify_api/rest/resources/2022_04/theme.rb +120 -0
  220. data/lib/shopify_api/rest/resources/2022_04/transaction.rb +181 -0
  221. data/lib/shopify_api/rest/resources/2022_04/usage_charge.rb +97 -0
  222. data/lib/shopify_api/rest/resources/2022_04/user.rb +138 -0
  223. data/lib/shopify_api/rest/resources/2022_04/variant.rb +212 -0
  224. data/lib/shopify_api/rest/resources/2022_04/webhook.rb +168 -0
  225. data/lib/shopify_api/rest/resources/2022_07/abandoned_checkout.rb +190 -0
  226. data/lib/shopify_api/rest/resources/2022_07/access_scope.rb +58 -0
  227. data/lib/shopify_api/rest/resources/2022_07/android_pay_key.rb +77 -0
  228. data/lib/shopify_api/rest/resources/2022_07/apple_pay_certificate.rb +105 -0
  229. data/lib/shopify_api/rest/resources/2022_07/application_charge.rb +104 -0
  230. data/lib/shopify_api/rest/resources/2022_07/application_credit.rb +87 -0
  231. data/lib/shopify_api/rest/resources/2022_07/article.rb +265 -0
  232. data/lib/shopify_api/rest/resources/2022_07/asset.rb +118 -0
  233. data/lib/shopify_api/rest/resources/2022_07/assigned_fulfillment_order.rb +79 -0
  234. data/lib/shopify_api/rest/resources/2022_07/balance.rb +50 -0
  235. data/lib/shopify_api/rest/resources/2022_07/blog.rb +162 -0
  236. data/lib/shopify_api/rest/resources/2022_07/cancellation_request.rb +83 -0
  237. data/lib/shopify_api/rest/resources/2022_07/carrier_service.rb +113 -0
  238. data/lib/shopify_api/rest/resources/2022_07/checkout.rb +209 -0
  239. data/lib/shopify_api/rest/resources/2022_07/collect.rb +142 -0
  240. data/lib/shopify_api/rest/resources/2022_07/collection.rb +110 -0
  241. data/lib/shopify_api/rest/resources/2022_07/collection_listing.rb +155 -0
  242. data/lib/shopify_api/rest/resources/2022_07/comment.rb +283 -0
  243. data/lib/shopify_api/rest/resources/2022_07/country.rb +137 -0
  244. data/lib/shopify_api/rest/resources/2022_07/currency.rb +57 -0
  245. data/lib/shopify_api/rest/resources/2022_07/custom_collection.rb +187 -0
  246. data/lib/shopify_api/rest/resources/2022_07/customer.rb +321 -0
  247. data/lib/shopify_api/rest/resources/2022_07/customer_address.rb +201 -0
  248. data/lib/shopify_api/rest/resources/2022_07/customer_saved_search.rb +169 -0
  249. data/lib/shopify_api/rest/resources/2022_07/deprecated_api_call.rb +57 -0
  250. data/lib/shopify_api/rest/resources/2022_07/discount_code.rb +219 -0
  251. data/lib/shopify_api/rest/resources/2022_07/dispute.rb +111 -0
  252. data/lib/shopify_api/rest/resources/2022_07/dispute_evidence.rb +117 -0
  253. data/lib/shopify_api/rest/resources/2022_07/dispute_file_upload.rb +81 -0
  254. data/lib/shopify_api/rest/resources/2022_07/draft_order.rb +275 -0
  255. data/lib/shopify_api/rest/resources/2022_07/event.rb +148 -0
  256. data/lib/shopify_api/rest/resources/2022_07/fulfillment.rb +221 -0
  257. data/lib/shopify_api/rest/resources/2022_07/fulfillment_event.rb +166 -0
  258. data/lib/shopify_api/rest/resources/2022_07/fulfillment_order.rb +310 -0
  259. data/lib/shopify_api/rest/resources/2022_07/fulfillment_request.rb +87 -0
  260. data/lib/shopify_api/rest/resources/2022_07/fulfillment_service.rb +130 -0
  261. data/lib/shopify_api/rest/resources/2022_07/gift_card.rb +215 -0
  262. data/lib/shopify_api/rest/resources/2022_07/gift_card_adjustment.rb +118 -0
  263. data/lib/shopify_api/rest/resources/2022_07/image.rb +157 -0
  264. data/lib/shopify_api/rest/resources/2022_07/inventory_item.rb +108 -0
  265. data/lib/shopify_api/rest/resources/2022_07/inventory_level.rb +179 -0
  266. data/lib/shopify_api/rest/resources/2022_07/location.rb +167 -0
  267. data/lib/shopify_api/rest/resources/2022_07/locations_for_move.rb +56 -0
  268. data/lib/shopify_api/rest/resources/2022_07/marketing_event.rb +209 -0
  269. data/lib/shopify_api/rest/resources/2022_07/metafield.rb +342 -0
  270. data/lib/shopify_api/rest/resources/2022_07/mobile_platform_application.rb +110 -0
  271. data/lib/shopify_api/rest/resources/2022_07/order.rb +473 -0
  272. data/lib/shopify_api/rest/resources/2022_07/order_risk.rb +135 -0
  273. data/lib/shopify_api/rest/resources/2022_07/page.rb +194 -0
  274. data/lib/shopify_api/rest/resources/2022_07/payment.rb +140 -0
  275. data/lib/shopify_api/rest/resources/2022_07/payment_gateway.rb +143 -0
  276. data/lib/shopify_api/rest/resources/2022_07/payment_transaction.rb +107 -0
  277. data/lib/shopify_api/rest/resources/2022_07/payout.rb +97 -0
  278. data/lib/shopify_api/rest/resources/2022_07/policy.rb +69 -0
  279. data/lib/shopify_api/rest/resources/2022_07/price_rule.rb +223 -0
  280. data/lib/shopify_api/rest/resources/2022_07/product.rb +223 -0
  281. data/lib/shopify_api/rest/resources/2022_07/product_listing.rb +196 -0
  282. data/lib/shopify_api/rest/resources/2022_07/product_resource_feedback.rb +88 -0
  283. data/lib/shopify_api/rest/resources/2022_07/province.rb +132 -0
  284. data/lib/shopify_api/rest/resources/2022_07/recurring_application_charge.rb +167 -0
  285. data/lib/shopify_api/rest/resources/2022_07/redirect.rb +139 -0
  286. data/lib/shopify_api/rest/resources/2022_07/refund.rb +151 -0
  287. data/lib/shopify_api/rest/resources/2022_07/report.rb +121 -0
  288. data/lib/shopify_api/rest/resources/2022_07/resource_feedback.rb +73 -0
  289. data/lib/shopify_api/rest/resources/2022_07/script_tag.rb +155 -0
  290. data/lib/shopify_api/rest/resources/2022_07/shipping_zone.rb +83 -0
  291. data/lib/shopify_api/rest/resources/2022_07/shop.rb +218 -0
  292. data/lib/shopify_api/rest/resources/2022_07/smart_collection.rb +216 -0
  293. data/lib/shopify_api/rest/resources/2022_07/storefront_access_token.rb +87 -0
  294. data/lib/shopify_api/rest/resources/2022_07/tender_transaction.rb +93 -0
  295. data/lib/shopify_api/rest/resources/2022_07/theme.rb +120 -0
  296. data/lib/shopify_api/rest/resources/2022_07/transaction.rb +181 -0
  297. data/lib/shopify_api/rest/resources/2022_07/usage_charge.rb +97 -0
  298. data/lib/shopify_api/rest/resources/2022_07/user.rb +138 -0
  299. data/lib/shopify_api/rest/resources/2022_07/variant.rb +212 -0
  300. data/lib/shopify_api/rest/resources/2022_07/webhook.rb +168 -0
  301. data/lib/shopify_api/rest/resources/2022_10/abandoned_checkout.rb +190 -0
  302. data/lib/shopify_api/rest/resources/2022_10/access_scope.rb +58 -0
  303. data/lib/shopify_api/rest/resources/2022_10/android_pay_key.rb +77 -0
  304. data/lib/shopify_api/rest/resources/2022_10/apple_pay_certificate.rb +105 -0
  305. data/lib/shopify_api/rest/resources/2022_10/application_charge.rb +104 -0
  306. data/lib/shopify_api/rest/resources/2022_10/application_credit.rb +87 -0
  307. data/lib/shopify_api/rest/resources/2022_10/article.rb +265 -0
  308. data/lib/shopify_api/rest/resources/2022_10/asset.rb +118 -0
  309. data/lib/shopify_api/rest/resources/2022_10/assigned_fulfillment_order.rb +79 -0
  310. data/lib/shopify_api/rest/resources/2022_10/balance.rb +50 -0
  311. data/lib/shopify_api/rest/resources/2022_10/blog.rb +162 -0
  312. data/lib/shopify_api/rest/resources/2022_10/cancellation_request.rb +83 -0
  313. data/lib/shopify_api/rest/resources/2022_10/carrier_service.rb +113 -0
  314. data/lib/shopify_api/rest/resources/2022_10/checkout.rb +209 -0
  315. data/lib/shopify_api/rest/resources/2022_10/collect.rb +142 -0
  316. data/lib/shopify_api/rest/resources/2022_10/collection.rb +110 -0
  317. data/lib/shopify_api/rest/resources/2022_10/collection_listing.rb +155 -0
  318. data/lib/shopify_api/rest/resources/2022_10/comment.rb +283 -0
  319. data/lib/shopify_api/rest/resources/2022_10/country.rb +137 -0
  320. data/lib/shopify_api/rest/resources/2022_10/currency.rb +57 -0
  321. data/lib/shopify_api/rest/resources/2022_10/custom_collection.rb +187 -0
  322. data/lib/shopify_api/rest/resources/2022_10/customer.rb +321 -0
  323. data/lib/shopify_api/rest/resources/2022_10/customer_address.rb +201 -0
  324. data/lib/shopify_api/rest/resources/2022_10/customer_saved_search.rb +169 -0
  325. data/lib/shopify_api/rest/resources/2022_10/deprecated_api_call.rb +57 -0
  326. data/lib/shopify_api/rest/resources/2022_10/discount_code.rb +219 -0
  327. data/lib/shopify_api/rest/resources/2022_10/dispute.rb +111 -0
  328. data/lib/shopify_api/rest/resources/2022_10/dispute_evidence.rb +117 -0
  329. data/lib/shopify_api/rest/resources/2022_10/dispute_file_upload.rb +81 -0
  330. data/lib/shopify_api/rest/resources/2022_10/draft_order.rb +275 -0
  331. data/lib/shopify_api/rest/resources/2022_10/event.rb +148 -0
  332. data/lib/shopify_api/rest/resources/2022_10/fulfillment.rb +221 -0
  333. data/lib/shopify_api/rest/resources/2022_10/fulfillment_event.rb +166 -0
  334. data/lib/shopify_api/rest/resources/2022_10/fulfillment_order.rb +310 -0
  335. data/lib/shopify_api/rest/resources/2022_10/fulfillment_request.rb +87 -0
  336. data/lib/shopify_api/rest/resources/2022_10/fulfillment_service.rb +130 -0
  337. data/lib/shopify_api/rest/resources/2022_10/gift_card.rb +215 -0
  338. data/lib/shopify_api/rest/resources/2022_10/gift_card_adjustment.rb +118 -0
  339. data/lib/shopify_api/rest/resources/2022_10/image.rb +157 -0
  340. data/lib/shopify_api/rest/resources/2022_10/inventory_item.rb +108 -0
  341. data/lib/shopify_api/rest/resources/2022_10/inventory_level.rb +179 -0
  342. data/lib/shopify_api/rest/resources/2022_10/location.rb +167 -0
  343. data/lib/shopify_api/rest/resources/2022_10/locations_for_move.rb +56 -0
  344. data/lib/shopify_api/rest/resources/2022_10/marketing_event.rb +209 -0
  345. data/lib/shopify_api/rest/resources/2022_10/metafield.rb +342 -0
  346. data/lib/shopify_api/rest/resources/2022_10/mobile_platform_application.rb +110 -0
  347. data/lib/shopify_api/rest/resources/2022_10/order.rb +476 -0
  348. data/lib/shopify_api/rest/resources/2022_10/order_risk.rb +135 -0
  349. data/lib/shopify_api/rest/resources/2022_10/page.rb +194 -0
  350. data/lib/shopify_api/rest/resources/2022_10/payment.rb +140 -0
  351. data/lib/shopify_api/rest/resources/2022_10/payment_gateway.rb +143 -0
  352. data/lib/shopify_api/rest/resources/2022_10/payment_transaction.rb +107 -0
  353. data/lib/shopify_api/rest/resources/2022_10/payout.rb +97 -0
  354. data/lib/shopify_api/rest/resources/2022_10/policy.rb +69 -0
  355. data/lib/shopify_api/rest/resources/2022_10/price_rule.rb +223 -0
  356. data/lib/shopify_api/rest/resources/2022_10/product.rb +223 -0
  357. data/lib/shopify_api/rest/resources/2022_10/product_listing.rb +196 -0
  358. data/lib/shopify_api/rest/resources/2022_10/product_resource_feedback.rb +88 -0
  359. data/lib/shopify_api/rest/resources/2022_10/province.rb +132 -0
  360. data/lib/shopify_api/rest/resources/2022_10/recurring_application_charge.rb +167 -0
  361. data/lib/shopify_api/rest/resources/2022_10/redirect.rb +139 -0
  362. data/lib/shopify_api/rest/resources/2022_10/refund.rb +151 -0
  363. data/lib/shopify_api/rest/resources/2022_10/report.rb +121 -0
  364. data/lib/shopify_api/rest/resources/2022_10/resource_feedback.rb +73 -0
  365. data/lib/shopify_api/rest/resources/2022_10/script_tag.rb +155 -0
  366. data/lib/shopify_api/rest/resources/2022_10/shipping_zone.rb +83 -0
  367. data/lib/shopify_api/rest/resources/2022_10/shop.rb +221 -0
  368. data/lib/shopify_api/rest/resources/2022_10/smart_collection.rb +216 -0
  369. data/lib/shopify_api/rest/resources/2022_10/storefront_access_token.rb +87 -0
  370. data/lib/shopify_api/rest/resources/2022_10/tender_transaction.rb +93 -0
  371. data/lib/shopify_api/rest/resources/2022_10/theme.rb +120 -0
  372. data/lib/shopify_api/rest/resources/2022_10/transaction.rb +181 -0
  373. data/lib/shopify_api/rest/resources/2022_10/usage_charge.rb +97 -0
  374. data/lib/shopify_api/rest/resources/2022_10/user.rb +138 -0
  375. data/lib/shopify_api/rest/resources/2022_10/variant.rb +212 -0
  376. data/lib/shopify_api/rest/resources/2022_10/webhook.rb +168 -0
  377. data/lib/shopify_api/utils/graphql_proxy.rb +52 -0
  378. data/lib/shopify_api/utils/hmac_validator.rb +44 -0
  379. data/lib/shopify_api/utils/http_utils.rb +17 -0
  380. data/lib/shopify_api/utils/session_utils.rb +135 -0
  381. data/lib/shopify_api/utils/verifiable_query.rb +18 -0
  382. data/lib/shopify_api/version.rb +4 -1
  383. data/lib/shopify_api/webhooks/handler.rb +15 -0
  384. data/lib/shopify_api/webhooks/register_result.rb +14 -0
  385. data/lib/shopify_api/webhooks/registration.rb +73 -0
  386. data/lib/shopify_api/webhooks/registrations/event_bridge.rb +61 -0
  387. data/lib/shopify_api/webhooks/registrations/http.rb +72 -0
  388. data/lib/shopify_api/webhooks/registrations/pub_sub.rb +65 -0
  389. data/lib/shopify_api/webhooks/registry.rb +215 -0
  390. data/lib/shopify_api/webhooks/request.rb +56 -0
  391. data/lib/shopify_api.rb +19 -26
  392. data/service.yml +1 -0
  393. data/shipit.rubygems.yml +1 -1
  394. data/shopify_api.gemspec +36 -19
  395. data/sorbet/config +3 -0
  396. data/sorbet/rbi/gems/activesupport@7.0.1.rbi +654 -0
  397. data/sorbet/rbi/gems/addressable@2.8.0.rbi +290 -0
  398. data/sorbet/rbi/gems/ast@2.4.2.rbi +54 -0
  399. data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
  400. data/sorbet/rbi/gems/concurrent-ruby@1.1.9.rbi +2401 -0
  401. data/sorbet/rbi/gems/crack@0.4.5.rbi +57 -0
  402. data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +185 -0
  403. data/sorbet/rbi/gems/fakefs@1.4.1.rbi +571 -0
  404. data/sorbet/rbi/gems/hash_diff@1.0.0.rbi +47 -0
  405. data/sorbet/rbi/gems/hashdiff@1.0.1.rbi +82 -0
  406. data/sorbet/rbi/gems/httparty@0.20.0.rbi +573 -0
  407. data/sorbet/rbi/gems/i18n@1.8.11.rbi +25 -0
  408. data/sorbet/rbi/gems/jwt@2.3.0.rbi +437 -0
  409. data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
  410. data/sorbet/rbi/gems/mime-types-data@3.2022.0105.rbi +73 -0
  411. data/sorbet/rbi/gems/mime-types@3.4.1.rbi +295 -0
  412. data/sorbet/rbi/gems/minitest@5.15.0.rbi +541 -0
  413. data/sorbet/rbi/gems/mocha@1.13.0.rbi +986 -0
  414. data/sorbet/rbi/gems/multi_xml@0.6.0.rbi +36 -0
  415. data/sorbet/rbi/gems/oj@3.13.11.rbi +274 -0
  416. data/sorbet/rbi/gems/openssl@3.0.0.rbi +581 -0
  417. data/sorbet/rbi/gems/parallel@1.21.0.rbi +113 -0
  418. data/sorbet/rbi/gems/parser@3.1.0.0.rbi +1741 -0
  419. data/sorbet/rbi/gems/pry@0.14.1.rbi +8 -0
  420. data/sorbet/rbi/gems/public_suffix@4.0.6.rbi +145 -0
  421. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +157 -0
  422. data/sorbet/rbi/gems/rake@13.0.6.rbi +814 -0
  423. data/sorbet/rbi/gems/rbi@0.0.11.rbi +1646 -0
  424. data/sorbet/rbi/gems/regexp_parser@2.2.0.rbi +1130 -0
  425. data/sorbet/rbi/gems/rexml@3.2.5.rbi +709 -0
  426. data/sorbet/rbi/gems/rubocop-ast@1.15.1.rbi +1921 -0
  427. data/sorbet/rbi/gems/rubocop-shopify@2.4.0.rbi +8 -0
  428. data/sorbet/rbi/gems/rubocop-sorbet@0.6.5.rbi +295 -0
  429. data/sorbet/rbi/gems/rubocop@1.25.1.rbi +13507 -0
  430. data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +405 -0
  431. data/sorbet/rbi/gems/securerandom@0.1.1.rbi +10 -0
  432. data/sorbet/rbi/gems/spoom@1.1.8.rbi +1252 -0
  433. data/sorbet/rbi/gems/tapioca@0.6.3.rbi +1238 -0
  434. data/sorbet/rbi/gems/thor@1.2.1.rbi +844 -0
  435. data/sorbet/rbi/gems/tzinfo@2.0.4.rbi +858 -0
  436. data/sorbet/rbi/gems/unicode-display_width@2.1.0.rbi +26 -0
  437. data/sorbet/rbi/gems/unparser@0.6.3.rbi +1816 -0
  438. data/sorbet/rbi/gems/webmock@3.14.0.rbi +683 -0
  439. data/sorbet/rbi/gems/webrick@1.7.0.rbi +601 -0
  440. data/sorbet/rbi/gems/yard-sorbet@0.6.1.rbi +199 -0
  441. data/sorbet/rbi/gems/yard@0.9.27.rbi +4145 -0
  442. data/sorbet/rbi/gems/zeitwerk@2.5.4.rbi +200 -0
  443. data/sorbet/rbi/shims/fakefs.rbi +1 -0
  444. data/sorbet/rbi/shims/openssl.rb +3 -0
  445. data/sorbet/rbi/todo.rbi +8 -0
  446. data/sorbet/tapioca/config.yml +4 -0
  447. data/sorbet/tapioca/require.rb +20 -0
  448. metadata +603 -280
  449. data/.document +0 -5
  450. data/.gitignore +0 -10
  451. data/.travis.yml +0 -32
  452. data/CHANGELOG +0 -310
  453. data/CONTRIBUTORS +0 -3
  454. data/Gemfile_ar30 +0 -6
  455. data/Gemfile_ar31 +0 -6
  456. data/Gemfile_ar32 +0 -6
  457. data/Gemfile_ar40 +0 -6
  458. data/Gemfile_ar_master +0 -6
  459. data/RELEASING +0 -16
  460. data/bin/shopify +0 -3
  461. data/lib/active_resource/base_ext.rb +0 -21
  462. data/lib/active_resource/connection_ext.rb +0 -10
  463. data/lib/active_resource/detailed_log_subscriber.rb +0 -19
  464. data/lib/active_resource/disable_prefix_check.rb +0 -36
  465. data/lib/active_resource/json_errors.rb +0 -31
  466. data/lib/active_resource/to_query.rb +0 -10
  467. data/lib/shopify_api/connection.rb +0 -33
  468. data/lib/shopify_api/countable.rb +0 -14
  469. data/lib/shopify_api/events.rb +0 -7
  470. data/lib/shopify_api/json_format.rb +0 -18
  471. data/lib/shopify_api/limits.rb +0 -76
  472. data/lib/shopify_api/metafields.rb +0 -20
  473. data/lib/shopify_api/resources/access_scope.rb +0 -5
  474. data/lib/shopify_api/resources/access_token.rb +0 -8
  475. data/lib/shopify_api/resources/address.rb +0 -4
  476. data/lib/shopify_api/resources/announcement.rb +0 -4
  477. data/lib/shopify_api/resources/api_permission.rb +0 -9
  478. data/lib/shopify_api/resources/application_charge.rb +0 -15
  479. data/lib/shopify_api/resources/application_credit.rb +0 -4
  480. data/lib/shopify_api/resources/article.rb +0 -21
  481. data/lib/shopify_api/resources/asset.rb +0 -96
  482. data/lib/shopify_api/resources/base.rb +0 -89
  483. data/lib/shopify_api/resources/billing_address.rb +0 -4
  484. data/lib/shopify_api/resources/blog.rb +0 -10
  485. data/lib/shopify_api/resources/carrier_service.rb +0 -4
  486. data/lib/shopify_api/resources/cart.rb +0 -4
  487. data/lib/shopify_api/resources/checkout.rb +0 -4
  488. data/lib/shopify_api/resources/collect.rb +0 -5
  489. data/lib/shopify_api/resources/collection_listing.rb +0 -9
  490. data/lib/shopify_api/resources/comment.rb +0 -9
  491. data/lib/shopify_api/resources/country.rb +0 -4
  492. data/lib/shopify_api/resources/custom_collection.rb +0 -19
  493. data/lib/shopify_api/resources/customer.rb +0 -29
  494. data/lib/shopify_api/resources/customer_group.rb +0 -5
  495. data/lib/shopify_api/resources/customer_invite.rb +0 -4
  496. data/lib/shopify_api/resources/customer_saved_search.rb +0 -9
  497. data/lib/shopify_api/resources/discount_code.rb +0 -9
  498. data/lib/shopify_api/resources/draft_order.rb +0 -14
  499. data/lib/shopify_api/resources/draft_order_invoice.rb +0 -4
  500. data/lib/shopify_api/resources/event.rb +0 -7
  501. data/lib/shopify_api/resources/fulfillment.rb +0 -13
  502. data/lib/shopify_api/resources/fulfillment_event.rb +0 -15
  503. data/lib/shopify_api/resources/fulfillment_request.rb +0 -15
  504. data/lib/shopify_api/resources/fulfillment_service.rb +0 -4
  505. data/lib/shopify_api/resources/gift_card.rb +0 -7
  506. data/lib/shopify_api/resources/graphql.rb +0 -22
  507. data/lib/shopify_api/resources/image.rb +0 -16
  508. data/lib/shopify_api/resources/inventory_item.rb +0 -6
  509. data/lib/shopify_api/resources/inventory_level.rb +0 -55
  510. data/lib/shopify_api/resources/line_item.rb +0 -14
  511. data/lib/shopify_api/resources/location.rb +0 -8
  512. data/lib/shopify_api/resources/marketing_event.rb +0 -8
  513. data/lib/shopify_api/resources/metafield.rb +0 -12
  514. data/lib/shopify_api/resources/note_attribute.rb +0 -4
  515. data/lib/shopify_api/resources/o_auth.rb +0 -17
  516. data/lib/shopify_api/resources/option.rb +0 -4
  517. data/lib/shopify_api/resources/order.rb +0 -29
  518. data/lib/shopify_api/resources/order_risk.rb +0 -8
  519. data/lib/shopify_api/resources/page.rb +0 -6
  520. data/lib/shopify_api/resources/payment_details.rb +0 -4
  521. data/lib/shopify_api/resources/ping/conversation.rb +0 -18
  522. data/lib/shopify_api/resources/ping/message.rb +0 -9
  523. data/lib/shopify_api/resources/ping.rb +0 -3
  524. data/lib/shopify_api/resources/policy.rb +0 -7
  525. data/lib/shopify_api/resources/price_rule.rb +0 -8
  526. data/lib/shopify_api/resources/product.rb +0 -33
  527. data/lib/shopify_api/resources/product_listing.rb +0 -9
  528. data/lib/shopify_api/resources/province.rb +0 -5
  529. data/lib/shopify_api/resources/receipt.rb +0 -4
  530. data/lib/shopify_api/resources/recurring_application_charge.rb +0 -31
  531. data/lib/shopify_api/resources/redirect.rb +0 -4
  532. data/lib/shopify_api/resources/refund.rb +0 -13
  533. data/lib/shopify_api/resources/report.rb +0 -4
  534. data/lib/shopify_api/resources/resource_feedback.rb +0 -19
  535. data/lib/shopify_api/resources/rule.rb +0 -4
  536. data/lib/shopify_api/resources/script_tag.rb +0 -4
  537. data/lib/shopify_api/resources/shipping_address.rb +0 -4
  538. data/lib/shopify_api/resources/shipping_line.rb +0 -4
  539. data/lib/shopify_api/resources/shipping_zone.rb +0 -4
  540. data/lib/shopify_api/resources/shop.rb +0 -23
  541. data/lib/shopify_api/resources/smart_collection.rb +0 -15
  542. data/lib/shopify_api/resources/storefront_access_token.rb +0 -4
  543. data/lib/shopify_api/resources/tax_line.rb +0 -4
  544. data/lib/shopify_api/resources/tax_service.rb +0 -4
  545. data/lib/shopify_api/resources/theme.rb +0 -4
  546. data/lib/shopify_api/resources/transaction.rb +0 -5
  547. data/lib/shopify_api/resources/usage_charge.rb +0 -5
  548. data/lib/shopify_api/resources/user.rb +0 -4
  549. data/lib/shopify_api/resources/variant.rb +0 -8
  550. data/lib/shopify_api/resources/webhook.rb +0 -4
  551. data/lib/shopify_api/resources.rb +0 -2
  552. data/lib/shopify_api/session.rb +0 -144
  553. data/test/access_token_test.rb +0 -19
  554. data/test/active_resource/json_errors_test.rb +0 -19
  555. data/test/api_permission_test.rb +0 -9
  556. data/test/application_charge_test.rb +0 -79
  557. data/test/application_credit_test.rb +0 -35
  558. data/test/article_test.rb +0 -73
  559. data/test/asset_test.rb +0 -18
  560. data/test/base_test.rb +0 -125
  561. data/test/blog_test.rb +0 -8
  562. data/test/carrier_service_test.rb +0 -17
  563. data/test/cart_test.rb +0 -13
  564. data/test/checkouts_test.rb +0 -9
  565. data/test/collect_test.rb +0 -9
  566. data/test/collection_listing_test.rb +0 -41
  567. data/test/countable_test.rb +0 -13
  568. data/test/custom_collection_test.rb +0 -9
  569. data/test/customer_saved_search_test.rb +0 -27
  570. data/test/customer_test.rb +0 -50
  571. data/test/detailed_log_subscriber_test.rb +0 -49
  572. data/test/discount_code_test.rb +0 -53
  573. data/test/draft_order_test.rb +0 -151
  574. data/test/fixtures/access_token_delegate.json +0 -4
  575. data/test/fixtures/application_charge.json +0 -16
  576. data/test/fixtures/application_charges.json +0 -57
  577. data/test/fixtures/application_credit.json +0 -12
  578. data/test/fixtures/application_credits.json +0 -24
  579. data/test/fixtures/article.json +0 -15
  580. data/test/fixtures/articles.json +0 -39
  581. data/test/fixtures/asset.json +0 -9
  582. data/test/fixtures/assets.json +0 -136
  583. data/test/fixtures/authors.json +0 -1
  584. data/test/fixtures/blog.json +0 -13
  585. data/test/fixtures/blogs.json +0 -13
  586. data/test/fixtures/carrier_service.json +0 -9
  587. data/test/fixtures/carts.json +0 -43
  588. data/test/fixtures/checkouts.json +0 -186
  589. data/test/fixtures/collect.json +0 -12
  590. data/test/fixtures/collection_listing.json +0 -11
  591. data/test/fixtures/collection_listing_product_ids.json +0 -1
  592. data/test/fixtures/collection_listings.json +0 -13
  593. data/test/fixtures/custom_collection.json +0 -17
  594. data/test/fixtures/customer_invite.json +0 -9
  595. data/test/fixtures/customer_saved_search.json +0 -9
  596. data/test/fixtures/customer_saved_search_customers.json +0 -60
  597. data/test/fixtures/customers.json +0 -59
  598. data/test/fixtures/customers_account_activation_url.json +0 -3
  599. data/test/fixtures/customers_search.json +0 -60
  600. data/test/fixtures/discount_code.json +0 -10
  601. data/test/fixtures/discount_codes.json +0 -12
  602. data/test/fixtures/draft_order.json +0 -159
  603. data/test/fixtures/draft_order_completed.json +0 -159
  604. data/test/fixtures/draft_order_invoice.json +0 -9
  605. data/test/fixtures/draft_orders.json +0 -161
  606. data/test/fixtures/engagement.json +0 -15
  607. data/test/fixtures/events.json +0 -31
  608. data/test/fixtures/fulfillment.json +0 -49
  609. data/test/fixtures/fulfillment_event.json +0 -12
  610. data/test/fixtures/fulfillment_request.json +0 -28
  611. data/test/fixtures/fulfillment_service.json +0 -10
  612. data/test/fixtures/gift_card.json +0 -20
  613. data/test/fixtures/gift_card_disabled.json +0 -20
  614. data/test/fixtures/image.json +0 -10
  615. data/test/fixtures/images.json +0 -20
  616. data/test/fixtures/inventory_level.json +0 -7
  617. data/test/fixtures/inventory_levels.json +0 -24
  618. data/test/fixtures/marketing_event.json +0 -28
  619. data/test/fixtures/marketing_events.json +0 -54
  620. data/test/fixtures/metafield.json +0 -12
  621. data/test/fixtures/metafields.json +0 -34
  622. data/test/fixtures/o_auth_revoke.json +0 -5
  623. data/test/fixtures/order.json +0 -297
  624. data/test/fixtures/order_risk.json +0 -14
  625. data/test/fixtures/order_risks.json +0 -28
  626. data/test/fixtures/order_with_properties.json +0 -373
  627. data/test/fixtures/orders.json +0 -299
  628. data/test/fixtures/ping/conversation.json +0 -1
  629. data/test/fixtures/ping/message.json +0 -1
  630. data/test/fixtures/policies.json +0 -8
  631. data/test/fixtures/price_rule.json +0 -27
  632. data/test/fixtures/price_rules.json +0 -28
  633. data/test/fixtures/product.json +0 -116
  634. data/test/fixtures/product_listing.json +0 -86
  635. data/test/fixtures/product_listing_product_ids.json +0 -1
  636. data/test/fixtures/product_listings.json +0 -174
  637. data/test/fixtures/recurring_application_charge.json +0 -22
  638. data/test/fixtures/recurring_application_charge_adjustment.json +0 -5
  639. data/test/fixtures/recurring_application_charges.json +0 -106
  640. data/test/fixtures/redirect.json +0 -7
  641. data/test/fixtures/refund.json +0 -112
  642. data/test/fixtures/report.json +0 -9
  643. data/test/fixtures/reports.json +0 -11
  644. data/test/fixtures/script_tag.json +0 -10
  645. data/test/fixtures/script_tags.json +0 -18
  646. data/test/fixtures/shipping_zones.json +0 -315
  647. data/test/fixtures/shop.json +0 -26
  648. data/test/fixtures/smart_collection.json +0 -21
  649. data/test/fixtures/storefront_access_token.json +0 -9
  650. data/test/fixtures/storefront_access_tokens.json +0 -18
  651. data/test/fixtures/tags.json +0 -1
  652. data/test/fixtures/tax_service.json +0 -9
  653. data/test/fixtures/transaction.json +0 -29
  654. data/test/fixtures/usage_charge.json +0 -11
  655. data/test/fixtures/usage_charges.json +0 -23
  656. data/test/fixtures/user.json +0 -21
  657. data/test/fixtures/users.json +0 -42
  658. data/test/fixtures/variant.json +0 -23
  659. data/test/fixtures/variants.json +0 -88
  660. data/test/fixtures/webhook.json +0 -10
  661. data/test/fixtures/webhooks.json +0 -18
  662. data/test/fulfillment_event_test.rb +0 -69
  663. data/test/fulfillment_request_test.rb +0 -33
  664. data/test/fulfillment_service_test.rb +0 -17
  665. data/test/fulfillment_test.rb +0 -61
  666. data/test/gift_card_test.rb +0 -22
  667. data/test/image_test.rb +0 -39
  668. data/test/inventory_level_test.rb +0 -59
  669. data/test/limits_test.rb +0 -38
  670. data/test/location_test.rb +0 -14
  671. data/test/marketing_event_test.rb +0 -68
  672. data/test/metafield_test.rb +0 -46
  673. data/test/o_auth_test.rb +0 -8
  674. data/test/order_risk_test.rb +0 -46
  675. data/test/order_test.rb +0 -59
  676. data/test/ping/conversation_test.rb +0 -39
  677. data/test/policy_test.rb +0 -19
  678. data/test/price_rule_test.rb +0 -65
  679. data/test/product_listing_test.rb +0 -40
  680. data/test/product_test.rb +0 -50
  681. data/test/recurring_application_charge_test.rb +0 -149
  682. data/test/redirect_test.rb +0 -9
  683. data/test/refund_test.rb +0 -32
  684. data/test/report_test.rb +0 -35
  685. data/test/resource_feedback_test.rb +0 -42
  686. data/test/script_tag_test.rb +0 -30
  687. data/test/session_test.rb +0 -250
  688. data/test/shipping_zone_test.rb +0 -10
  689. data/test/shop_test.rb +0 -68
  690. data/test/smart_collection_test.rb +0 -10
  691. data/test/storefront_access_token_test.rb +0 -32
  692. data/test/tax_service_test.rb +0 -8
  693. data/test/test_helper.rb +0 -97
  694. data/test/transaction_test.rb +0 -17
  695. data/test/usage_charge_test.rb +0 -21
  696. data/test/user_test.rb +0 -17
  697. data/test/variant_test.rb +0 -46
  698. data/test/webhook_test.rb +0 -21
@@ -0,0 +1,46 @@
1
+
2
+ # Create a Session Storage Implementation
3
+
4
+ The implementation of session storage that you pass in `ShopifyAPI::Context.setup` is what the Shopify gem will use to store and load sessions. [Shopify::Auth::FileSessionStorage](../../lib/shopify_api/auth/file_session_storage.rb) can be used for testing purposes and as an example of how to make an implementation in your app. This is not recommended for production, we recommend you implement a solution that will store and load serialized sessions from a more ideal store such as a database like MySQL or MongoDB.
5
+
6
+ ## Create a New Session Storage Class
7
+
8
+ You can create a session storage class that includes `ShopifyAPI::Auth::SessionStorage` and override the methods as shown in the table and example below:
9
+
10
+ | Method Name | Input Type | Return Type |
11
+ | ---------------------- | --------------------------------- | ------------------------------ |
12
+ | `store_session` | `ShopifyAPI::Auth::Session` | `Boolean` (true if successful) |
13
+ | `load_session` | `String` (session id) | `ShopifyAPI::Auth::Session` |
14
+ | `delete_session` | `String` (session id) | `Boolean` (true if successful) |
15
+
16
+
17
+ ```ruby
18
+ class CustomSessionStorage
19
+ include ShopifyAPI::Auth::SessionStorage
20
+
21
+ def initialize
22
+ # Initialize as needed
23
+ end
24
+
25
+ def store_session(session)
26
+ # Implement a store function
27
+ some_store_function(id: session.id, session_data: session.serialize)
28
+ end
29
+
30
+ def load_session(id)
31
+ # Implement a fetch function
32
+ session_data = some_fetch_function(id)
33
+ ShopifyAPI::Auth::Session.deserialize(session_data)
34
+ end
35
+
36
+ def delete_session(id)
37
+ # Implement a delete function
38
+ some_delete_function(id)
39
+ true
40
+ end
41
+ end
42
+ ```
43
+
44
+ **Note:** We recommend utilizing the Session `serialize` and `deserialize` functions to make storing and loading sessions easier.
45
+
46
+ Once this is complete you can pass an instance of this session storage class as `session_storage` in `ShopifyAPI::Context.setup`
@@ -0,0 +1,98 @@
1
+ # Webhooks
2
+
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
+
5
+ ## Create a Webhook Handler
6
+
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:
8
+
9
+ ```ruby
10
+ module WebhookHandler
11
+ include ShopifyAPI::Webhooks::Handler
12
+
13
+ class << self
14
+ def handle(topic:, shop:, body:)
15
+ puts "Received webhook! topic: #{topic} shop: #{shop} body: #{body}"
16
+ end
17
+ end
18
+ end
19
+ ```
20
+
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
+ ## Add to Webhook Registry
24
+
25
+ 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
+
27
+ ```ruby
28
+ registration = ShopifyAPI::Webhooks::Registry.add_registration(topic: "orders/create", delivery_method: :http, handler: WebhookHandler)
29
+ ```
30
+ 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
+
32
+ ```ruby
33
+ registration = ShopifyAPI::Webhooks::Registry.add_registration(
34
+ topic: "orders/create",
35
+ delivery_method: :http,
36
+ handler: WebhookHandler,
37
+ fields: ["number","note"] # this can also be a single comma separated string
38
+ )
39
+ ```
40
+
41
+ **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.
42
+
43
+ ### EventBridge and PubSub Webhooks
44
+
45
+ You can also register webhooks for delivery to Amazon EventBridge or Google Cloud
46
+ Pub/Sub. In this case the `path` argument to
47
+ `Shopify.Webhooks.Registry.register` needs to be of a specific form.
48
+
49
+ For EventBridge, the `path` must be the [ARN of the partner event
50
+ source](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_EventSource.html).
51
+
52
+ For Pub/Sub, the `path` must be of the form
53
+ `pubsub://[PROJECT-ID]:[PUB-SUB-TOPIC-ID]`. For example, if you created a topic
54
+ with id `red` in the project `blue`, then the value of `path` would be
55
+ `pubsub://blue:red`.
56
+
57
+ When registering for an EventBridge or PubSub Webhook you do not need to specify a handler as this is only used for handling Http webhooks.
58
+
59
+ ## Register a Webhook for a Shop
60
+ At any point that you have a session for a shop you can register to receive webhooks for that shop. We recommend registering for webhooks immediately after [OAuth](./oauth.md).
61
+
62
+ This can be done in one of two ways:
63
+
64
+ If you would like to register to receive webhooks for all topics you have added to the registry for a specific shop you can simply call:
65
+ ```ruby
66
+ ShopifyAPI::Webhooks::Registry.register_all(session: shop_session)
67
+ ```
68
+
69
+ This will return an Array of `ShopifyAPI::Webhooks::RegisterResult`s that have fields `topic`, `success`, and `body` which can be used to see which webhooks were successfully registered.
70
+
71
+ Or if you would like to register to receive webhooks for specific topics that have been added to the registry for a specific shop you can simply call `register` for any needed topics:
72
+ ```ruby
73
+ ShopifyAPI::Webhooks::Registry.register(topic: "<specific-topic>", session: shop_session)
74
+ ```
75
+
76
+ This will return a single `ShopifyAPI::Webhooks::RegisterResult`.
77
+
78
+ ## Unregister a Webhook
79
+
80
+ To unregister a topic from a shop you can simply call:
81
+ ```ruby
82
+ ShopifyAPI::Webhooks::Registry.unregister(topic: "orders/create", session: shop_session)
83
+ ```
84
+
85
+ ## Process a Webhook
86
+
87
+ To process an http webhook, you need to listen on the route(s) you provided during the Webhook registration process, then when the route is hit construct a `ShopifyAPI::Webhooks::Request` and call `ShopifyAPI::Webhooks::Registry.process`. This will verify the request did indeed come from Shopify and then call the specified handler for that webhook. An example in Rails is shown below:
88
+
89
+ ```ruby
90
+ class WebhookController < ApplicationController
91
+ def webhook
92
+ ShopifyAPI::Webhooks::Registry.process(
93
+ ShopifyAPI::Webhooks::WebhookRequest.new(raw_body: request.raw_post, headers: request.headers.to_h)
94
+ )
95
+ render json: {success: true}.to_json
96
+ end
97
+ end
98
+ ```
@@ -0,0 +1,19 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module AdminVersions
6
+ SUPPORTED_ADMIN_VERSIONS = T.let([
7
+ "unstable",
8
+ "2022-10",
9
+ "2022-07",
10
+ "2022-04",
11
+ "2022-01",
12
+ ], T::Array[String])
13
+
14
+ LATEST_SUPPORTED_ADMIN_VERSION = T.let("2022-10", String)
15
+ end
16
+
17
+ SUPPORTED_ADMIN_VERSIONS = ShopifyAPI::AdminVersions::SUPPORTED_ADMIN_VERSIONS
18
+ LATEST_SUPPORTED_ADMIN_VERSION = ShopifyAPI::AdminVersions::LATEST_SUPPORTED_ADMIN_VERSION
19
+ end
@@ -0,0 +1,36 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Auth
6
+ class AssociatedUser < T::Struct
7
+ extend T::Sig
8
+
9
+ prop :id, Integer
10
+ prop :first_name, String
11
+ prop :last_name, String
12
+ prop :email, String
13
+ prop :email_verified, T::Boolean
14
+ prop :account_owner, T::Boolean
15
+ prop :locale, String
16
+ prop :collaborator, T::Boolean
17
+
18
+ alias_method :eql?, :==
19
+ sig { params(other: T.nilable(AssociatedUser)).returns(T::Boolean) }
20
+ def ==(other)
21
+ if other
22
+ id == other.id &&
23
+ first_name == other.first_name &&
24
+ last_name == other.last_name &&
25
+ email == other.email &&
26
+ email_verified == other.email_verified &&
27
+ account_owner == other.account_owner &&
28
+ locale == other.locale &&
29
+ collaborator == other.collaborator
30
+ else
31
+ false
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,75 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Auth
6
+ class AuthScopes
7
+ extend T::Sig
8
+
9
+ SCOPE_DELIMITER = ","
10
+
11
+ sig { params(scope_names: T.any(String, T::Array[String])).void }
12
+ def initialize(scope_names = [])
13
+ @compressed_scopes = T.let([].to_set, T::Set[String])
14
+ @expanded_scopes = T.let([].to_set, T::Set[String])
15
+
16
+ if scope_names.is_a?(String)
17
+ scope_names = scope_names.to_s.split(SCOPE_DELIMITER)
18
+ end
19
+
20
+ store_scopes(scope_names)
21
+ end
22
+
23
+ sig { params(auth_scopes: AuthScopes).returns(T::Boolean) }
24
+ def covers?(auth_scopes)
25
+ auth_scopes.compressed_scopes <= expanded_scopes
26
+ end
27
+
28
+ sig { returns(String) }
29
+ def to_s
30
+ to_a.join(SCOPE_DELIMITER)
31
+ end
32
+
33
+ sig { returns(T::Array[String]) }
34
+ def to_a
35
+ compressed_scopes.to_a
36
+ end
37
+
38
+ sig { params(other: T.nilable(AuthScopes)).returns(T::Boolean) }
39
+ def ==(other)
40
+ !other.nil? &&
41
+ other.class == self.class &&
42
+ compressed_scopes == other.compressed_scopes
43
+ end
44
+
45
+ alias_method :eql?, :==
46
+
47
+ sig { returns(Integer) }
48
+ def hash
49
+ compressed_scopes.hash
50
+ end
51
+
52
+ protected
53
+
54
+ sig { returns(T::Set[String]) }
55
+ attr_reader :compressed_scopes, :expanded_scopes
56
+
57
+ private
58
+
59
+ sig { params(scope_names: T::Array[String]).void }
60
+ def store_scopes(scope_names)
61
+ scopes = scope_names.map(&:strip).reject(&:empty?).to_set
62
+ implied_scopes = scopes.map { |scope| implied_scope(scope) }.compact
63
+
64
+ @compressed_scopes = scopes - implied_scopes
65
+ @expanded_scopes = scopes + implied_scopes
66
+ end
67
+
68
+ sig { params(scope: String).returns(T.nilable(String)) }
69
+ def implied_scope(scope)
70
+ is_write_scope = scope =~ /\A(unauthenticated_)?write_(.*)\z/
71
+ "#{Regexp.last_match(1)}read_#{Regexp.last_match(2)}" if is_write_scope
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,72 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "fileutils"
5
+
6
+ module ShopifyAPI
7
+ module Auth
8
+ class FileSessionStorage
9
+ extend T::Sig
10
+ extend T::Helpers
11
+ include ShopifyAPI::Auth::SessionStorage
12
+
13
+ sig { returns(String) }
14
+ attr_accessor :path
15
+
16
+ sig { params(path: String).void }
17
+ def initialize(path: "/tmp/shopify_api_sessions")
18
+ @path = path
19
+ FileUtils.mkdir_p(path) unless Dir.exist?(path)
20
+ end
21
+
22
+ sig do
23
+ override.params(session: Session)
24
+ .returns(T::Boolean)
25
+ end
26
+ def store_session(session)
27
+ File.write(session_file_path(session.id), session.serialize) > 0
28
+ end
29
+
30
+ sig do
31
+ override.params(id: String)
32
+ .returns(T.nilable(Session))
33
+ end
34
+ def load_session(id)
35
+ session_path = session_file_path(id)
36
+ if File.exist?(session_path)
37
+ ShopifyAPI::Auth::Session.deserialize(File.read(session_path))
38
+ end
39
+ end
40
+
41
+ sig do
42
+ override.params(id: String)
43
+ .returns(T::Boolean)
44
+ end
45
+ def delete_session(id)
46
+ session_path = session_file_path(id)
47
+ File.delete(session_path) if File.exist?(session_path)
48
+ true
49
+ end
50
+
51
+ alias_method :eql?, :==
52
+ sig { params(other: T.nilable(FileSessionStorage)).returns(T::Boolean) }
53
+ def ==(other)
54
+ if other
55
+ @path == other.path
56
+ else
57
+ false
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ sig do
64
+ params(id: String)
65
+ .returns(String)
66
+ end
67
+ def session_file_path(id)
68
+ "#{@path}/#{id}"
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,83 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Auth
6
+ class JwtPayload
7
+ extend T::Sig
8
+
9
+ JWT_EXPIRATION_LEEWAY = 10
10
+
11
+ sig { returns(String) }
12
+ attr_reader :iss, :dest, :aud, :sub, :jti, :sid
13
+
14
+ sig { returns(Integer) }
15
+ attr_reader :exp, :nbf, :iat
16
+
17
+ sig { params(token: String).void }
18
+ def initialize(token)
19
+ payload_hash = begin
20
+ decode_token(token, Context.api_secret_key)
21
+ rescue ShopifyAPI::Errors::InvalidJwtTokenError
22
+ raise unless Context.old_api_secret_key
23
+
24
+ decode_token(token, T.must(Context.old_api_secret_key))
25
+ end
26
+
27
+ @iss = T.let(payload_hash["iss"], String)
28
+ @dest = T.let(payload_hash["dest"], String)
29
+ @aud = T.let(payload_hash["aud"], String)
30
+ @sub = T.let(payload_hash["sub"], String)
31
+ @exp = T.let(payload_hash["exp"], Integer)
32
+ @nbf = T.let(payload_hash["nbf"], Integer)
33
+ @iat = T.let(payload_hash["iat"], Integer)
34
+ @jti = T.let(payload_hash["jti"], String)
35
+ @sid = T.let(payload_hash["sid"], String)
36
+
37
+ raise ShopifyAPI::Errors::InvalidJwtTokenError,
38
+ "Session token had invalid API key" unless @aud == Context.api_key
39
+ end
40
+
41
+ sig { returns(String) }
42
+ def shop
43
+ @dest.gsub("https://", "")
44
+ end
45
+
46
+ # TODO: Remove before releasing v11
47
+ sig { params(shop: String).returns(T::Boolean) }
48
+ def validate_shop(shop)
49
+ Context.logger.warn(
50
+ "Deprecation notice: ShopifyAPI::Auth::JwtPayload.validate_shop no longer checks the given shop and always " \
51
+ "returns true. It will be removed in v11.",
52
+ )
53
+ true
54
+ end
55
+
56
+ alias_method :eql?, :==
57
+ sig { params(other: T.nilable(JwtPayload)).returns(T::Boolean) }
58
+ def ==(other)
59
+ return false unless other
60
+
61
+ iss == other.iss &&
62
+ dest == other.dest &&
63
+ aud == other.aud &&
64
+ sub == other.sub &&
65
+ exp == other.exp &&
66
+ nbf == other.nbf &&
67
+ iat == other.iat &&
68
+ jti == other.jti &&
69
+ sid == other.sid
70
+ end
71
+
72
+ private
73
+
74
+ sig { params(token: String, api_secret_key: String).returns(T::Hash[String, T.untyped]) }
75
+ def decode_token(token, api_secret_key)
76
+ JWT.decode(token, api_secret_key, true,
77
+ { exp_leeway: JWT_EXPIRATION_LEEWAY, algorithm: "HS256" })[0]
78
+ rescue
79
+ raise ShopifyAPI::Errors::InvalidJwtTokenError, "Failed to parse session token '#{token}'"
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,47 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Auth
6
+ module Oauth
7
+ class AuthQuery
8
+ extend T::Sig
9
+ include Utils::VerifiableQuery
10
+
11
+ sig { returns(String) }
12
+ attr_reader :code, :host, :hmac, :shop, :state, :timestamp
13
+
14
+ sig do
15
+ params(
16
+ code: String,
17
+ shop: String,
18
+ timestamp: String,
19
+ state: String,
20
+ host: String,
21
+ hmac: String,
22
+ ).void
23
+ end
24
+ def initialize(code:, shop:, timestamp:, state:, host:, hmac:)
25
+ @code = code
26
+ @shop = shop
27
+ @timestamp = timestamp
28
+ @state = state
29
+ @host = host
30
+ @hmac = hmac
31
+ end
32
+
33
+ sig { override.returns(String) }
34
+ def to_signable_string
35
+ params = {
36
+ code: code,
37
+ host: host,
38
+ shop: shop,
39
+ state: state,
40
+ timestamp: timestamp,
41
+ }
42
+ URI.encode_www_form(params)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Auth
6
+ module Oauth
7
+ class SessionCookie < T::Struct
8
+ extend T::Sig
9
+
10
+ SESSION_COOKIE_NAME = "shopify_app_session"
11
+
12
+ const :name, String, default: SESSION_COOKIE_NAME
13
+ const :value, String
14
+ const :expires, T.nilable(Time)
15
+
16
+ alias_method :eql?, :==
17
+ sig { params(other: T.nilable(SessionCookie)).returns(T::Boolean) }
18
+ def ==(other)
19
+ return false unless other
20
+
21
+ name == other.name &&
22
+ value == other.value &&
23
+ expires == other.expires
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,138 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Auth
6
+ module Oauth
7
+ extend T::Sig
8
+
9
+ NONCE_LENGTH = 15
10
+
11
+ class << self
12
+ extend T::Sig
13
+
14
+ sig do
15
+ params(
16
+ shop: String,
17
+ redirect_path: String,
18
+ is_online: T.nilable(T::Boolean),
19
+ scope_override: T.nilable(T.any(ShopifyAPI::Auth::AuthScopes, T::Array[String], String)),
20
+ ).returns(T::Hash[Symbol, T.any(String, SessionCookie)])
21
+ end
22
+ def begin_auth(shop:, redirect_path:, is_online: true, scope_override: nil)
23
+ scope = if scope_override.nil?
24
+ ShopifyAPI::Context.scope
25
+ elsif scope_override.is_a?(ShopifyAPI::Auth::AuthScopes)
26
+ scope_override
27
+ else
28
+ ShopifyAPI::Auth::AuthScopes.new(scope_override)
29
+ end
30
+
31
+ unless Context.setup?
32
+ raise Errors::ContextNotSetupError, "ShopifyAPI::Context not setup, please call ShopifyAPI::Context.setup"
33
+ end
34
+ raise Errors::UnsupportedOauthError, "Cannot perform OAuth for private apps." if Context.private?
35
+
36
+ state = SecureRandom.alphanumeric(NONCE_LENGTH)
37
+
38
+ cookie = SessionCookie.new(value: state, expires: Time.now + 60)
39
+
40
+ query = {
41
+ client_id: ShopifyAPI::Context.api_key,
42
+ scope: scope.to_s,
43
+ redirect_uri: "#{ShopifyAPI::Context.host}#{redirect_path}",
44
+ state: state,
45
+ "grant_options[]": is_online ? "per-user" : "",
46
+ }
47
+
48
+ query_string = URI.encode_www_form(query)
49
+
50
+ auth_route = "https://#{shop}/admin/oauth/authorize?#{query_string}"
51
+ { auth_route: auth_route, cookie: cookie }
52
+ end
53
+
54
+ sig do
55
+ params(
56
+ cookies: T::Hash[String, String],
57
+ auth_query: AuthQuery,
58
+ ).returns(T::Hash[Symbol, T.any(Session, SessionCookie)])
59
+ end
60
+ def validate_auth_callback(cookies:, auth_query:)
61
+ unless Context.setup?
62
+ raise Errors::ContextNotSetupError, "ShopifyAPI::Context not setup, please call ShopifyAPI::Context.setup"
63
+ end
64
+ raise Errors::InvalidOauthError, "Invalid OAuth callback." unless Utils::HmacValidator.validate(auth_query)
65
+ raise Errors::UnsupportedOauthError, "Cannot perform OAuth for private apps." if Context.private?
66
+
67
+ state = cookies[SessionCookie::SESSION_COOKIE_NAME]
68
+ raise Errors::NoSessionCookieError unless state
69
+
70
+ raise Errors::InvalidOauthError,
71
+ "Invalid state in OAuth callback." unless state == auth_query.state
72
+
73
+ # TODO: replace this call with the HTTP client once it is built
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?
77
+ raise Errors::RequestAccessTokenError,
78
+ "Cannot complete OAuth process. Received a #{response.code} error while requesting access token."
79
+ end
80
+ session_params = response.to_h
81
+
82
+ session = create_new_session(session_params, auth_query.shop)
83
+
84
+ cookie = if Context.embedded?
85
+ SessionCookie.new(
86
+ value: "",
87
+ expires: Time.now,
88
+ )
89
+ else
90
+ SessionCookie.new(
91
+ value: session.id,
92
+ expires: session.online? ? session.expires : nil,
93
+ )
94
+ end
95
+
96
+ unless Context.session_storage.store_session(session)
97
+ raise Errors::SessionStorageError,
98
+ "Session could not be saved. Please check your session storage implementation."
99
+ end
100
+
101
+ { session: session, cookie: cookie }
102
+ end
103
+
104
+ private
105
+
106
+ sig { params(session_params: T::Hash[String, T.untyped], shop: String).returns(Session) }
107
+ def create_new_session(session_params, shop)
108
+ session_params = session_params.to_h { |k, v| [k.to_sym, v] }
109
+
110
+ scope = session_params[:scope]
111
+
112
+ is_online = !session_params[:associated_user].nil?
113
+
114
+ if is_online
115
+ associated_user = AssociatedUser.new(session_params[:associated_user].to_h { |k, v| [k.to_sym, v] })
116
+ expires = Time.now + session_params[:expires_in].to_i
117
+ associated_user_scope = session_params[:associated_user_scope]
118
+ id = "#{shop}_#{associated_user.id}"
119
+ else
120
+ id = "offline_#{shop}"
121
+ end
122
+
123
+ Session.new(
124
+ id: id,
125
+ shop: shop,
126
+ access_token: session_params[:access_token],
127
+ scope: scope,
128
+ is_online: is_online,
129
+ associated_user_scope: associated_user_scope,
130
+ associated_user: associated_user,
131
+ expires: expires,
132
+ shopify_session_id: session_params[:session],
133
+ )
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end