shopify_api 1.0.4 → 12.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (459) hide show
  1. checksums.yaml +7 -0
  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 +59 -0
  12. data/BREAKING_CHANGES_FOR_OLDER_VERSIONS.md +110 -0
  13. data/CHANGELOG.md +574 -0
  14. data/CONTRIBUTING.md +9 -0
  15. data/Gemfile +13 -0
  16. data/Gemfile.lock +159 -0
  17. data/LICENSE +2 -2
  18. data/README.md +138 -0
  19. data/RELEASING.md +19 -0
  20. data/Rakefile +16 -50
  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 +104 -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 +135 -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 +196 -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/feature_deprecated_error.rb +9 -0
  55. data/lib/shopify_api/errors/http_response_error.rb +23 -0
  56. data/lib/shopify_api/errors/invalid_graphql_request_error.rb +9 -0
  57. data/lib/shopify_api/errors/invalid_http_request_error.rb +9 -0
  58. data/lib/shopify_api/errors/invalid_jwt_token_error.rb +9 -0
  59. data/lib/shopify_api/errors/invalid_oauth_error.rb +9 -0
  60. data/lib/shopify_api/errors/invalid_webhook_error.rb +9 -0
  61. data/lib/shopify_api/errors/invalid_webhook_registration_error.rb +9 -0
  62. data/lib/shopify_api/errors/log_level_not_found_error.rb +9 -0
  63. data/lib/shopify_api/errors/max_http_retries_exceeded_error.rb +9 -0
  64. data/lib/shopify_api/errors/missing_jwt_token_error.rb +9 -0
  65. data/lib/shopify_api/errors/missing_required_argument_error.rb +9 -0
  66. data/lib/shopify_api/errors/no_active_session_error.rb +9 -0
  67. data/lib/shopify_api/errors/no_session_cookie_error.rb +9 -0
  68. data/lib/shopify_api/errors/no_webhook_handler.rb +9 -0
  69. data/lib/shopify_api/errors/private_app_error.rb +9 -0
  70. data/lib/shopify_api/errors/request_access_token_error.rb +9 -0
  71. data/lib/shopify_api/errors/session_not_found_error.rb +9 -0
  72. data/lib/shopify_api/errors/session_storage_error.rb +9 -0
  73. data/lib/shopify_api/errors/unsupported_oauth_error.rb +9 -0
  74. data/lib/shopify_api/errors/unsupported_version_error.rb +9 -0
  75. data/lib/shopify_api/errors/webhook_registration_error.rb +9 -0
  76. data/lib/shopify_api/inflector.rb +17 -0
  77. data/lib/shopify_api/logger.rb +82 -0
  78. data/lib/shopify_api/rest/base.rb +387 -0
  79. data/lib/shopify_api/rest/base_errors.rb +32 -0
  80. data/lib/shopify_api/rest/resources/2022_01/abandoned_checkout.rb +190 -0
  81. data/lib/shopify_api/rest/resources/2022_01/access_scope.rb +58 -0
  82. data/lib/shopify_api/rest/resources/2022_01/android_pay_key.rb +77 -0
  83. data/lib/shopify_api/rest/resources/2022_01/apple_pay_certificate.rb +105 -0
  84. data/lib/shopify_api/rest/resources/2022_01/application_charge.rb +104 -0
  85. data/lib/shopify_api/rest/resources/2022_01/application_credit.rb +87 -0
  86. data/lib/shopify_api/rest/resources/2022_01/article.rb +265 -0
  87. data/lib/shopify_api/rest/resources/2022_01/asset.rb +118 -0
  88. data/lib/shopify_api/rest/resources/2022_01/assigned_fulfillment_order.rb +79 -0
  89. data/lib/shopify_api/rest/resources/2022_01/balance.rb +50 -0
  90. data/lib/shopify_api/rest/resources/2022_01/blog.rb +162 -0
  91. data/lib/shopify_api/rest/resources/2022_01/cancellation_request.rb +83 -0
  92. data/lib/shopify_api/rest/resources/2022_01/carrier_service.rb +116 -0
  93. data/lib/shopify_api/rest/resources/2022_01/checkout.rb +209 -0
  94. data/lib/shopify_api/rest/resources/2022_01/collect.rb +142 -0
  95. data/lib/shopify_api/rest/resources/2022_01/collection.rb +110 -0
  96. data/lib/shopify_api/rest/resources/2022_01/collection_listing.rb +155 -0
  97. data/lib/shopify_api/rest/resources/2022_01/comment.rb +283 -0
  98. data/lib/shopify_api/rest/resources/2022_01/country.rb +137 -0
  99. data/lib/shopify_api/rest/resources/2022_01/currency.rb +57 -0
  100. data/lib/shopify_api/rest/resources/2022_01/custom_collection.rb +187 -0
  101. data/lib/shopify_api/rest/resources/2022_01/customer.rb +318 -0
  102. data/lib/shopify_api/rest/resources/2022_01/customer_address.rb +201 -0
  103. data/lib/shopify_api/rest/resources/2022_01/customer_saved_search.rb +169 -0
  104. data/lib/shopify_api/rest/resources/2022_01/deprecated_api_call.rb +57 -0
  105. data/lib/shopify_api/rest/resources/2022_01/discount_code.rb +219 -0
  106. data/lib/shopify_api/rest/resources/2022_01/dispute.rb +111 -0
  107. data/lib/shopify_api/rest/resources/2022_01/draft_order.rb +275 -0
  108. data/lib/shopify_api/rest/resources/2022_01/event.rb +148 -0
  109. data/lib/shopify_api/rest/resources/2022_01/fulfillment.rb +268 -0
  110. data/lib/shopify_api/rest/resources/2022_01/fulfillment_event.rb +166 -0
  111. data/lib/shopify_api/rest/resources/2022_01/fulfillment_order.rb +281 -0
  112. data/lib/shopify_api/rest/resources/2022_01/fulfillment_request.rb +87 -0
  113. data/lib/shopify_api/rest/resources/2022_01/fulfillment_service.rb +130 -0
  114. data/lib/shopify_api/rest/resources/2022_01/gift_card.rb +215 -0
  115. data/lib/shopify_api/rest/resources/2022_01/gift_card_adjustment.rb +118 -0
  116. data/lib/shopify_api/rest/resources/2022_01/image.rb +157 -0
  117. data/lib/shopify_api/rest/resources/2022_01/inventory_item.rb +108 -0
  118. data/lib/shopify_api/rest/resources/2022_01/inventory_level.rb +179 -0
  119. data/lib/shopify_api/rest/resources/2022_01/location.rb +167 -0
  120. data/lib/shopify_api/rest/resources/2022_01/locations_for_move.rb +56 -0
  121. data/lib/shopify_api/rest/resources/2022_01/marketing_event.rb +209 -0
  122. data/lib/shopify_api/rest/resources/2022_01/metafield.rb +349 -0
  123. data/lib/shopify_api/rest/resources/2022_01/mobile_platform_application.rb +110 -0
  124. data/lib/shopify_api/rest/resources/2022_01/order.rb +473 -0
  125. data/lib/shopify_api/rest/resources/2022_01/order_risk.rb +135 -0
  126. data/lib/shopify_api/rest/resources/2022_01/page.rb +194 -0
  127. data/lib/shopify_api/rest/resources/2022_01/payment.rb +140 -0
  128. data/lib/shopify_api/rest/resources/2022_01/payment_gateway.rb +143 -0
  129. data/lib/shopify_api/rest/resources/2022_01/payment_transaction.rb +107 -0
  130. data/lib/shopify_api/rest/resources/2022_01/payout.rb +97 -0
  131. data/lib/shopify_api/rest/resources/2022_01/policy.rb +69 -0
  132. data/lib/shopify_api/rest/resources/2022_01/price_rule.rb +223 -0
  133. data/lib/shopify_api/rest/resources/2022_01/product.rb +223 -0
  134. data/lib/shopify_api/rest/resources/2022_01/product_listing.rb +196 -0
  135. data/lib/shopify_api/rest/resources/2022_01/product_resource_feedback.rb +88 -0
  136. data/lib/shopify_api/rest/resources/2022_01/province.rb +132 -0
  137. data/lib/shopify_api/rest/resources/2022_01/recurring_application_charge.rb +167 -0
  138. data/lib/shopify_api/rest/resources/2022_01/redirect.rb +139 -0
  139. data/lib/shopify_api/rest/resources/2022_01/refund.rb +151 -0
  140. data/lib/shopify_api/rest/resources/2022_01/report.rb +121 -0
  141. data/lib/shopify_api/rest/resources/2022_01/resource_feedback.rb +73 -0
  142. data/lib/shopify_api/rest/resources/2022_01/script_tag.rb +155 -0
  143. data/lib/shopify_api/rest/resources/2022_01/shipping_zone.rb +83 -0
  144. data/lib/shopify_api/rest/resources/2022_01/shop.rb +218 -0
  145. data/lib/shopify_api/rest/resources/2022_01/smart_collection.rb +216 -0
  146. data/lib/shopify_api/rest/resources/2022_01/storefront_access_token.rb +87 -0
  147. data/lib/shopify_api/rest/resources/2022_01/tender_transaction.rb +93 -0
  148. data/lib/shopify_api/rest/resources/2022_01/theme.rb +120 -0
  149. data/lib/shopify_api/rest/resources/2022_01/transaction.rb +181 -0
  150. data/lib/shopify_api/rest/resources/2022_01/usage_charge.rb +97 -0
  151. data/lib/shopify_api/rest/resources/2022_01/user.rb +138 -0
  152. data/lib/shopify_api/rest/resources/2022_01/variant.rb +212 -0
  153. data/lib/shopify_api/rest/resources/2022_01/webhook.rb +168 -0
  154. data/lib/shopify_api/rest/resources/2022_04/abandoned_checkout.rb +190 -0
  155. data/lib/shopify_api/rest/resources/2022_04/access_scope.rb +58 -0
  156. data/lib/shopify_api/rest/resources/2022_04/android_pay_key.rb +77 -0
  157. data/lib/shopify_api/rest/resources/2022_04/apple_pay_certificate.rb +105 -0
  158. data/lib/shopify_api/rest/resources/2022_04/application_charge.rb +104 -0
  159. data/lib/shopify_api/rest/resources/2022_04/application_credit.rb +87 -0
  160. data/lib/shopify_api/rest/resources/2022_04/article.rb +265 -0
  161. data/lib/shopify_api/rest/resources/2022_04/asset.rb +118 -0
  162. data/lib/shopify_api/rest/resources/2022_04/assigned_fulfillment_order.rb +79 -0
  163. data/lib/shopify_api/rest/resources/2022_04/balance.rb +50 -0
  164. data/lib/shopify_api/rest/resources/2022_04/blog.rb +162 -0
  165. data/lib/shopify_api/rest/resources/2022_04/cancellation_request.rb +83 -0
  166. data/lib/shopify_api/rest/resources/2022_04/carrier_service.rb +116 -0
  167. data/lib/shopify_api/rest/resources/2022_04/checkout.rb +209 -0
  168. data/lib/shopify_api/rest/resources/2022_04/collect.rb +142 -0
  169. data/lib/shopify_api/rest/resources/2022_04/collection.rb +110 -0
  170. data/lib/shopify_api/rest/resources/2022_04/collection_listing.rb +155 -0
  171. data/lib/shopify_api/rest/resources/2022_04/comment.rb +283 -0
  172. data/lib/shopify_api/rest/resources/2022_04/country.rb +137 -0
  173. data/lib/shopify_api/rest/resources/2022_04/currency.rb +57 -0
  174. data/lib/shopify_api/rest/resources/2022_04/custom_collection.rb +187 -0
  175. data/lib/shopify_api/rest/resources/2022_04/customer.rb +321 -0
  176. data/lib/shopify_api/rest/resources/2022_04/customer_address.rb +201 -0
  177. data/lib/shopify_api/rest/resources/2022_04/customer_saved_search.rb +169 -0
  178. data/lib/shopify_api/rest/resources/2022_04/deprecated_api_call.rb +57 -0
  179. data/lib/shopify_api/rest/resources/2022_04/discount_code.rb +219 -0
  180. data/lib/shopify_api/rest/resources/2022_04/dispute.rb +111 -0
  181. data/lib/shopify_api/rest/resources/2022_04/draft_order.rb +275 -0
  182. data/lib/shopify_api/rest/resources/2022_04/event.rb +148 -0
  183. data/lib/shopify_api/rest/resources/2022_04/fulfillment.rb +268 -0
  184. data/lib/shopify_api/rest/resources/2022_04/fulfillment_event.rb +166 -0
  185. data/lib/shopify_api/rest/resources/2022_04/fulfillment_order.rb +284 -0
  186. data/lib/shopify_api/rest/resources/2022_04/fulfillment_request.rb +87 -0
  187. data/lib/shopify_api/rest/resources/2022_04/fulfillment_service.rb +130 -0
  188. data/lib/shopify_api/rest/resources/2022_04/gift_card.rb +215 -0
  189. data/lib/shopify_api/rest/resources/2022_04/gift_card_adjustment.rb +118 -0
  190. data/lib/shopify_api/rest/resources/2022_04/image.rb +157 -0
  191. data/lib/shopify_api/rest/resources/2022_04/inventory_item.rb +108 -0
  192. data/lib/shopify_api/rest/resources/2022_04/inventory_level.rb +179 -0
  193. data/lib/shopify_api/rest/resources/2022_04/location.rb +167 -0
  194. data/lib/shopify_api/rest/resources/2022_04/locations_for_move.rb +56 -0
  195. data/lib/shopify_api/rest/resources/2022_04/marketing_event.rb +209 -0
  196. data/lib/shopify_api/rest/resources/2022_04/metafield.rb +342 -0
  197. data/lib/shopify_api/rest/resources/2022_04/mobile_platform_application.rb +110 -0
  198. data/lib/shopify_api/rest/resources/2022_04/order.rb +473 -0
  199. data/lib/shopify_api/rest/resources/2022_04/order_risk.rb +135 -0
  200. data/lib/shopify_api/rest/resources/2022_04/page.rb +194 -0
  201. data/lib/shopify_api/rest/resources/2022_04/payment.rb +140 -0
  202. data/lib/shopify_api/rest/resources/2022_04/payment_gateway.rb +143 -0
  203. data/lib/shopify_api/rest/resources/2022_04/payment_transaction.rb +107 -0
  204. data/lib/shopify_api/rest/resources/2022_04/payout.rb +97 -0
  205. data/lib/shopify_api/rest/resources/2022_04/policy.rb +69 -0
  206. data/lib/shopify_api/rest/resources/2022_04/price_rule.rb +223 -0
  207. data/lib/shopify_api/rest/resources/2022_04/product.rb +223 -0
  208. data/lib/shopify_api/rest/resources/2022_04/product_listing.rb +196 -0
  209. data/lib/shopify_api/rest/resources/2022_04/product_resource_feedback.rb +88 -0
  210. data/lib/shopify_api/rest/resources/2022_04/province.rb +132 -0
  211. data/lib/shopify_api/rest/resources/2022_04/recurring_application_charge.rb +167 -0
  212. data/lib/shopify_api/rest/resources/2022_04/redirect.rb +139 -0
  213. data/lib/shopify_api/rest/resources/2022_04/refund.rb +151 -0
  214. data/lib/shopify_api/rest/resources/2022_04/report.rb +121 -0
  215. data/lib/shopify_api/rest/resources/2022_04/resource_feedback.rb +73 -0
  216. data/lib/shopify_api/rest/resources/2022_04/script_tag.rb +155 -0
  217. data/lib/shopify_api/rest/resources/2022_04/shipping_zone.rb +83 -0
  218. data/lib/shopify_api/rest/resources/2022_04/shop.rb +218 -0
  219. data/lib/shopify_api/rest/resources/2022_04/smart_collection.rb +216 -0
  220. data/lib/shopify_api/rest/resources/2022_04/storefront_access_token.rb +87 -0
  221. data/lib/shopify_api/rest/resources/2022_04/tender_transaction.rb +93 -0
  222. data/lib/shopify_api/rest/resources/2022_04/theme.rb +120 -0
  223. data/lib/shopify_api/rest/resources/2022_04/transaction.rb +181 -0
  224. data/lib/shopify_api/rest/resources/2022_04/usage_charge.rb +97 -0
  225. data/lib/shopify_api/rest/resources/2022_04/user.rb +138 -0
  226. data/lib/shopify_api/rest/resources/2022_04/variant.rb +212 -0
  227. data/lib/shopify_api/rest/resources/2022_04/webhook.rb +168 -0
  228. data/lib/shopify_api/rest/resources/2022_07/abandoned_checkout.rb +190 -0
  229. data/lib/shopify_api/rest/resources/2022_07/access_scope.rb +58 -0
  230. data/lib/shopify_api/rest/resources/2022_07/android_pay_key.rb +77 -0
  231. data/lib/shopify_api/rest/resources/2022_07/apple_pay_certificate.rb +105 -0
  232. data/lib/shopify_api/rest/resources/2022_07/application_charge.rb +104 -0
  233. data/lib/shopify_api/rest/resources/2022_07/application_credit.rb +87 -0
  234. data/lib/shopify_api/rest/resources/2022_07/article.rb +265 -0
  235. data/lib/shopify_api/rest/resources/2022_07/asset.rb +118 -0
  236. data/lib/shopify_api/rest/resources/2022_07/assigned_fulfillment_order.rb +79 -0
  237. data/lib/shopify_api/rest/resources/2022_07/balance.rb +50 -0
  238. data/lib/shopify_api/rest/resources/2022_07/blog.rb +162 -0
  239. data/lib/shopify_api/rest/resources/2022_07/cancellation_request.rb +83 -0
  240. data/lib/shopify_api/rest/resources/2022_07/carrier_service.rb +113 -0
  241. data/lib/shopify_api/rest/resources/2022_07/checkout.rb +209 -0
  242. data/lib/shopify_api/rest/resources/2022_07/collect.rb +142 -0
  243. data/lib/shopify_api/rest/resources/2022_07/collection.rb +110 -0
  244. data/lib/shopify_api/rest/resources/2022_07/collection_listing.rb +155 -0
  245. data/lib/shopify_api/rest/resources/2022_07/comment.rb +283 -0
  246. data/lib/shopify_api/rest/resources/2022_07/country.rb +137 -0
  247. data/lib/shopify_api/rest/resources/2022_07/currency.rb +57 -0
  248. data/lib/shopify_api/rest/resources/2022_07/custom_collection.rb +187 -0
  249. data/lib/shopify_api/rest/resources/2022_07/customer.rb +321 -0
  250. data/lib/shopify_api/rest/resources/2022_07/customer_address.rb +201 -0
  251. data/lib/shopify_api/rest/resources/2022_07/customer_saved_search.rb +169 -0
  252. data/lib/shopify_api/rest/resources/2022_07/deprecated_api_call.rb +57 -0
  253. data/lib/shopify_api/rest/resources/2022_07/discount_code.rb +219 -0
  254. data/lib/shopify_api/rest/resources/2022_07/dispute.rb +111 -0
  255. data/lib/shopify_api/rest/resources/2022_07/dispute_evidence.rb +117 -0
  256. data/lib/shopify_api/rest/resources/2022_07/dispute_file_upload.rb +81 -0
  257. data/lib/shopify_api/rest/resources/2022_07/draft_order.rb +275 -0
  258. data/lib/shopify_api/rest/resources/2022_07/event.rb +148 -0
  259. data/lib/shopify_api/rest/resources/2022_07/fulfillment.rb +221 -0
  260. data/lib/shopify_api/rest/resources/2022_07/fulfillment_event.rb +166 -0
  261. data/lib/shopify_api/rest/resources/2022_07/fulfillment_order.rb +310 -0
  262. data/lib/shopify_api/rest/resources/2022_07/fulfillment_request.rb +87 -0
  263. data/lib/shopify_api/rest/resources/2022_07/fulfillment_service.rb +130 -0
  264. data/lib/shopify_api/rest/resources/2022_07/gift_card.rb +215 -0
  265. data/lib/shopify_api/rest/resources/2022_07/gift_card_adjustment.rb +118 -0
  266. data/lib/shopify_api/rest/resources/2022_07/image.rb +157 -0
  267. data/lib/shopify_api/rest/resources/2022_07/inventory_item.rb +108 -0
  268. data/lib/shopify_api/rest/resources/2022_07/inventory_level.rb +179 -0
  269. data/lib/shopify_api/rest/resources/2022_07/location.rb +167 -0
  270. data/lib/shopify_api/rest/resources/2022_07/locations_for_move.rb +56 -0
  271. data/lib/shopify_api/rest/resources/2022_07/marketing_event.rb +209 -0
  272. data/lib/shopify_api/rest/resources/2022_07/metafield.rb +342 -0
  273. data/lib/shopify_api/rest/resources/2022_07/mobile_platform_application.rb +110 -0
  274. data/lib/shopify_api/rest/resources/2022_07/order.rb +473 -0
  275. data/lib/shopify_api/rest/resources/2022_07/order_risk.rb +135 -0
  276. data/lib/shopify_api/rest/resources/2022_07/page.rb +194 -0
  277. data/lib/shopify_api/rest/resources/2022_07/payment.rb +140 -0
  278. data/lib/shopify_api/rest/resources/2022_07/payment_gateway.rb +143 -0
  279. data/lib/shopify_api/rest/resources/2022_07/payment_transaction.rb +107 -0
  280. data/lib/shopify_api/rest/resources/2022_07/payout.rb +97 -0
  281. data/lib/shopify_api/rest/resources/2022_07/policy.rb +69 -0
  282. data/lib/shopify_api/rest/resources/2022_07/price_rule.rb +223 -0
  283. data/lib/shopify_api/rest/resources/2022_07/product.rb +223 -0
  284. data/lib/shopify_api/rest/resources/2022_07/product_listing.rb +196 -0
  285. data/lib/shopify_api/rest/resources/2022_07/product_resource_feedback.rb +88 -0
  286. data/lib/shopify_api/rest/resources/2022_07/province.rb +132 -0
  287. data/lib/shopify_api/rest/resources/2022_07/recurring_application_charge.rb +167 -0
  288. data/lib/shopify_api/rest/resources/2022_07/redirect.rb +139 -0
  289. data/lib/shopify_api/rest/resources/2022_07/refund.rb +151 -0
  290. data/lib/shopify_api/rest/resources/2022_07/report.rb +121 -0
  291. data/lib/shopify_api/rest/resources/2022_07/resource_feedback.rb +73 -0
  292. data/lib/shopify_api/rest/resources/2022_07/script_tag.rb +155 -0
  293. data/lib/shopify_api/rest/resources/2022_07/shipping_zone.rb +83 -0
  294. data/lib/shopify_api/rest/resources/2022_07/shop.rb +218 -0
  295. data/lib/shopify_api/rest/resources/2022_07/smart_collection.rb +216 -0
  296. data/lib/shopify_api/rest/resources/2022_07/storefront_access_token.rb +87 -0
  297. data/lib/shopify_api/rest/resources/2022_07/tender_transaction.rb +93 -0
  298. data/lib/shopify_api/rest/resources/2022_07/theme.rb +120 -0
  299. data/lib/shopify_api/rest/resources/2022_07/transaction.rb +181 -0
  300. data/lib/shopify_api/rest/resources/2022_07/usage_charge.rb +97 -0
  301. data/lib/shopify_api/rest/resources/2022_07/user.rb +138 -0
  302. data/lib/shopify_api/rest/resources/2022_07/variant.rb +212 -0
  303. data/lib/shopify_api/rest/resources/2022_07/webhook.rb +168 -0
  304. data/lib/shopify_api/rest/resources/2022_10/abandoned_checkout.rb +190 -0
  305. data/lib/shopify_api/rest/resources/2022_10/access_scope.rb +58 -0
  306. data/lib/shopify_api/rest/resources/2022_10/android_pay_key.rb +77 -0
  307. data/lib/shopify_api/rest/resources/2022_10/apple_pay_certificate.rb +105 -0
  308. data/lib/shopify_api/rest/resources/2022_10/application_charge.rb +104 -0
  309. data/lib/shopify_api/rest/resources/2022_10/application_credit.rb +87 -0
  310. data/lib/shopify_api/rest/resources/2022_10/article.rb +265 -0
  311. data/lib/shopify_api/rest/resources/2022_10/asset.rb +118 -0
  312. data/lib/shopify_api/rest/resources/2022_10/assigned_fulfillment_order.rb +79 -0
  313. data/lib/shopify_api/rest/resources/2022_10/balance.rb +50 -0
  314. data/lib/shopify_api/rest/resources/2022_10/blog.rb +162 -0
  315. data/lib/shopify_api/rest/resources/2022_10/cancellation_request.rb +83 -0
  316. data/lib/shopify_api/rest/resources/2022_10/carrier_service.rb +113 -0
  317. data/lib/shopify_api/rest/resources/2022_10/checkout.rb +209 -0
  318. data/lib/shopify_api/rest/resources/2022_10/collect.rb +142 -0
  319. data/lib/shopify_api/rest/resources/2022_10/collection.rb +110 -0
  320. data/lib/shopify_api/rest/resources/2022_10/collection_listing.rb +155 -0
  321. data/lib/shopify_api/rest/resources/2022_10/comment.rb +283 -0
  322. data/lib/shopify_api/rest/resources/2022_10/country.rb +137 -0
  323. data/lib/shopify_api/rest/resources/2022_10/currency.rb +57 -0
  324. data/lib/shopify_api/rest/resources/2022_10/custom_collection.rb +187 -0
  325. data/lib/shopify_api/rest/resources/2022_10/customer.rb +321 -0
  326. data/lib/shopify_api/rest/resources/2022_10/customer_address.rb +201 -0
  327. data/lib/shopify_api/rest/resources/2022_10/customer_saved_search.rb +169 -0
  328. data/lib/shopify_api/rest/resources/2022_10/deprecated_api_call.rb +57 -0
  329. data/lib/shopify_api/rest/resources/2022_10/discount_code.rb +219 -0
  330. data/lib/shopify_api/rest/resources/2022_10/dispute.rb +111 -0
  331. data/lib/shopify_api/rest/resources/2022_10/dispute_evidence.rb +117 -0
  332. data/lib/shopify_api/rest/resources/2022_10/dispute_file_upload.rb +81 -0
  333. data/lib/shopify_api/rest/resources/2022_10/draft_order.rb +275 -0
  334. data/lib/shopify_api/rest/resources/2022_10/event.rb +148 -0
  335. data/lib/shopify_api/rest/resources/2022_10/fulfillment.rb +221 -0
  336. data/lib/shopify_api/rest/resources/2022_10/fulfillment_event.rb +166 -0
  337. data/lib/shopify_api/rest/resources/2022_10/fulfillment_order.rb +310 -0
  338. data/lib/shopify_api/rest/resources/2022_10/fulfillment_request.rb +87 -0
  339. data/lib/shopify_api/rest/resources/2022_10/fulfillment_service.rb +130 -0
  340. data/lib/shopify_api/rest/resources/2022_10/gift_card.rb +215 -0
  341. data/lib/shopify_api/rest/resources/2022_10/gift_card_adjustment.rb +118 -0
  342. data/lib/shopify_api/rest/resources/2022_10/image.rb +157 -0
  343. data/lib/shopify_api/rest/resources/2022_10/inventory_item.rb +108 -0
  344. data/lib/shopify_api/rest/resources/2022_10/inventory_level.rb +179 -0
  345. data/lib/shopify_api/rest/resources/2022_10/location.rb +167 -0
  346. data/lib/shopify_api/rest/resources/2022_10/locations_for_move.rb +56 -0
  347. data/lib/shopify_api/rest/resources/2022_10/marketing_event.rb +209 -0
  348. data/lib/shopify_api/rest/resources/2022_10/metafield.rb +342 -0
  349. data/lib/shopify_api/rest/resources/2022_10/mobile_platform_application.rb +110 -0
  350. data/lib/shopify_api/rest/resources/2022_10/order.rb +476 -0
  351. data/lib/shopify_api/rest/resources/2022_10/order_risk.rb +135 -0
  352. data/lib/shopify_api/rest/resources/2022_10/page.rb +194 -0
  353. data/lib/shopify_api/rest/resources/2022_10/payment.rb +140 -0
  354. data/lib/shopify_api/rest/resources/2022_10/payment_gateway.rb +143 -0
  355. data/lib/shopify_api/rest/resources/2022_10/payment_transaction.rb +107 -0
  356. data/lib/shopify_api/rest/resources/2022_10/payout.rb +97 -0
  357. data/lib/shopify_api/rest/resources/2022_10/policy.rb +69 -0
  358. data/lib/shopify_api/rest/resources/2022_10/price_rule.rb +223 -0
  359. data/lib/shopify_api/rest/resources/2022_10/product.rb +223 -0
  360. data/lib/shopify_api/rest/resources/2022_10/product_listing.rb +196 -0
  361. data/lib/shopify_api/rest/resources/2022_10/product_resource_feedback.rb +88 -0
  362. data/lib/shopify_api/rest/resources/2022_10/province.rb +132 -0
  363. data/lib/shopify_api/rest/resources/2022_10/recurring_application_charge.rb +167 -0
  364. data/lib/shopify_api/rest/resources/2022_10/redirect.rb +139 -0
  365. data/lib/shopify_api/rest/resources/2022_10/refund.rb +151 -0
  366. data/lib/shopify_api/rest/resources/2022_10/report.rb +121 -0
  367. data/lib/shopify_api/rest/resources/2022_10/resource_feedback.rb +73 -0
  368. data/lib/shopify_api/rest/resources/2022_10/script_tag.rb +155 -0
  369. data/lib/shopify_api/rest/resources/2022_10/shipping_zone.rb +83 -0
  370. data/lib/shopify_api/rest/resources/2022_10/shop.rb +221 -0
  371. data/lib/shopify_api/rest/resources/2022_10/smart_collection.rb +216 -0
  372. data/lib/shopify_api/rest/resources/2022_10/storefront_access_token.rb +87 -0
  373. data/lib/shopify_api/rest/resources/2022_10/tender_transaction.rb +93 -0
  374. data/lib/shopify_api/rest/resources/2022_10/theme.rb +120 -0
  375. data/lib/shopify_api/rest/resources/2022_10/transaction.rb +181 -0
  376. data/lib/shopify_api/rest/resources/2022_10/usage_charge.rb +97 -0
  377. data/lib/shopify_api/rest/resources/2022_10/user.rb +138 -0
  378. data/lib/shopify_api/rest/resources/2022_10/variant.rb +212 -0
  379. data/lib/shopify_api/rest/resources/2022_10/webhook.rb +168 -0
  380. data/lib/shopify_api/utils/graphql_proxy.rb +52 -0
  381. data/lib/shopify_api/utils/hmac_validator.rb +44 -0
  382. data/lib/shopify_api/utils/http_utils.rb +17 -0
  383. data/lib/shopify_api/utils/session_utils.rb +152 -0
  384. data/lib/shopify_api/utils/verifiable_query.rb +18 -0
  385. data/lib/shopify_api/version.rb +6 -0
  386. data/lib/shopify_api/webhooks/handler.rb +15 -0
  387. data/lib/shopify_api/webhooks/register_result.rb +14 -0
  388. data/lib/shopify_api/webhooks/registration.rb +73 -0
  389. data/lib/shopify_api/webhooks/registrations/event_bridge.rb +61 -0
  390. data/lib/shopify_api/webhooks/registrations/http.rb +72 -0
  391. data/lib/shopify_api/webhooks/registrations/pub_sub.rb +65 -0
  392. data/lib/shopify_api/webhooks/registry.rb +215 -0
  393. data/lib/shopify_api/webhooks/request.rb +56 -0
  394. data/lib/shopify_api.rb +23 -472
  395. data/service.yml +1 -0
  396. data/shipit.rubygems.yml +1 -0
  397. data/shopify_api.gemspec +43 -102
  398. data/sorbet/config +3 -0
  399. data/sorbet/rbi/gems/activesupport@7.0.1.rbi +654 -0
  400. data/sorbet/rbi/gems/addressable@2.8.0.rbi +290 -0
  401. data/sorbet/rbi/gems/ast@2.4.2.rbi +54 -0
  402. data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
  403. data/sorbet/rbi/gems/concurrent-ruby@1.1.9.rbi +2401 -0
  404. data/sorbet/rbi/gems/crack@0.4.5.rbi +57 -0
  405. data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +185 -0
  406. data/sorbet/rbi/gems/fakefs@1.4.1.rbi +571 -0
  407. data/sorbet/rbi/gems/hash_diff@1.0.0.rbi +47 -0
  408. data/sorbet/rbi/gems/hashdiff@1.0.1.rbi +82 -0
  409. data/sorbet/rbi/gems/httparty@0.20.0.rbi +573 -0
  410. data/sorbet/rbi/gems/i18n@1.8.11.rbi +25 -0
  411. data/sorbet/rbi/gems/jwt@2.3.0.rbi +437 -0
  412. data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
  413. data/sorbet/rbi/gems/mime-types-data@3.2022.0105.rbi +73 -0
  414. data/sorbet/rbi/gems/mime-types@3.4.1.rbi +295 -0
  415. data/sorbet/rbi/gems/minitest@5.15.0.rbi +541 -0
  416. data/sorbet/rbi/gems/mocha@1.13.0.rbi +986 -0
  417. data/sorbet/rbi/gems/multi_xml@0.6.0.rbi +36 -0
  418. data/sorbet/rbi/gems/oj@3.13.11.rbi +274 -0
  419. data/sorbet/rbi/gems/openssl@3.0.0.rbi +581 -0
  420. data/sorbet/rbi/gems/parallel@1.21.0.rbi +113 -0
  421. data/sorbet/rbi/gems/parser@3.1.0.0.rbi +1741 -0
  422. data/sorbet/rbi/gems/pry@0.14.1.rbi +8 -0
  423. data/sorbet/rbi/gems/public_suffix@4.0.6.rbi +145 -0
  424. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +157 -0
  425. data/sorbet/rbi/gems/rake@13.0.6.rbi +814 -0
  426. data/sorbet/rbi/gems/rbi@0.0.11.rbi +1646 -0
  427. data/sorbet/rbi/gems/regexp_parser@2.2.0.rbi +1130 -0
  428. data/sorbet/rbi/gems/rexml@3.2.5.rbi +709 -0
  429. data/sorbet/rbi/gems/rubocop-ast@1.15.1.rbi +1921 -0
  430. data/sorbet/rbi/gems/rubocop-shopify@2.4.0.rbi +8 -0
  431. data/sorbet/rbi/gems/rubocop-sorbet@0.6.5.rbi +295 -0
  432. data/sorbet/rbi/gems/rubocop@1.25.1.rbi +13507 -0
  433. data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +405 -0
  434. data/sorbet/rbi/gems/securerandom@0.1.1.rbi +10 -0
  435. data/sorbet/rbi/gems/spoom@1.1.8.rbi +1252 -0
  436. data/sorbet/rbi/gems/tapioca@0.6.3.rbi +1238 -0
  437. data/sorbet/rbi/gems/thor@1.2.1.rbi +844 -0
  438. data/sorbet/rbi/gems/tzinfo@2.0.4.rbi +858 -0
  439. data/sorbet/rbi/gems/unicode-display_width@2.1.0.rbi +26 -0
  440. data/sorbet/rbi/gems/unparser@0.6.3.rbi +1816 -0
  441. data/sorbet/rbi/gems/webmock@3.14.0.rbi +683 -0
  442. data/sorbet/rbi/gems/webrick@1.7.0.rbi +601 -0
  443. data/sorbet/rbi/gems/yard-sorbet@0.6.1.rbi +199 -0
  444. data/sorbet/rbi/gems/yard@0.9.27.rbi +4145 -0
  445. data/sorbet/rbi/gems/zeitwerk@2.5.4.rbi +200 -0
  446. data/sorbet/rbi/shims/fakefs.rbi +1 -0
  447. data/sorbet/rbi/shims/openssl.rb +3 -0
  448. data/sorbet/rbi/todo.rbi +8 -0
  449. data/sorbet/tapioca/config.yml +4 -0
  450. data/sorbet/tapioca/require.rb +20 -0
  451. metadata +736 -80
  452. data/.document +0 -5
  453. data/.gitignore +0 -5
  454. data/CHANGELOG +0 -5
  455. data/README.rdoc +0 -55
  456. data/VERSION +0 -1
  457. data/test/order_test.rb +0 -48
  458. data/test/shopify_api_test.rb +0 -21
  459. data/test/test_helper.rb +0 -28
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class NoSessionCookieError < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class NoWebhookHandler < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class PrivateAppError < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class RequestAccessTokenError < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class SessionNotFoundError < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class SessionStorageError < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class UnsupportedOauthError < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class UnsupportedVersionError < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class WebhookRegistrationError < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ class Inflector < Zeitwerk::GemInflector
6
+ extend T::Sig
7
+
8
+ sig { params(basename: String, abspath: String).returns(String) }
9
+ def camelize(basename, abspath)
10
+ if basename =~ /\Ashopify_api(.*)/
11
+ "ShopifyAPI" + super(Regexp.last_match(1), abspath)
12
+ else
13
+ super
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,82 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ class Logger
6
+ LOG_LEVELS = T.let({ debug: 0, info: 1, warn: 2, error: 3, off: 6 }, T::Hash[Symbol, Integer])
7
+ DEFAULT_LOG_LEVEL = :info
8
+
9
+ class << self
10
+ extend T::Sig
11
+
12
+ sig { params(message: String).void }
13
+ def debug(message)
14
+ send_to_logger(:debug, message)
15
+ end
16
+
17
+ sig { params(message: String).void }
18
+ def info(message)
19
+ send_to_logger(:info, message)
20
+ end
21
+
22
+ sig { params(message: String).void }
23
+ def warn(message)
24
+ send_to_logger(:warn, message)
25
+ end
26
+
27
+ sig { params(message: String).void }
28
+ def error(message)
29
+ send_to_logger(:error, message)
30
+ end
31
+
32
+ sig { params(message: String, version: String).void }
33
+ def deprecated(message, version)
34
+ return unless enabled_for_log_level?(:warn)
35
+
36
+ raise Errors::FeatureDeprecatedError unless valid_version(version)
37
+
38
+ send_to_logger(:warn, message)
39
+ end
40
+
41
+ sig { returns(T::Array[Symbol]) }
42
+ def levels
43
+ LOG_LEVELS.keys
44
+ end
45
+
46
+ private
47
+
48
+ sig { params(log_level: Symbol).returns(String) }
49
+ def context(log_level)
50
+ current_shop = ShopifyAPI::Context.active_session&.shop
51
+
52
+ if current_shop.nil?
53
+ "[ ShopifyAPI | #{log_level.to_s.upcase} ]"
54
+ else
55
+ "[ ShopifyAPI | #{log_level.to_s.upcase} | #{current_shop} ]"
56
+ end
57
+ end
58
+
59
+ sig { params(log_level: Symbol, message: String).void }
60
+ def send_to_logger(log_level, message)
61
+ return unless enabled_for_log_level?(log_level)
62
+
63
+ full_message = "#{context(log_level)} #{message}"
64
+
65
+ ShopifyAPI::Context.logger.public_send(log_level, full_message)
66
+ end
67
+
68
+ sig { params(log_level: Symbol).returns(T::Boolean) }
69
+ def enabled_for_log_level?(log_level)
70
+ T.must(LOG_LEVELS[log_level]) >= T.must(LOG_LEVELS[ShopifyAPI::Context.log_level] ||
71
+ LOG_LEVELS[DEFAULT_LOG_LEVEL])
72
+ end
73
+
74
+ sig { params(version: String).returns(T::Boolean) }
75
+ def valid_version(version)
76
+ current_version = Gem::Version.create(ShopifyAPI::VERSION)
77
+ deprecate_version = Gem::Version.create(version)
78
+ current_version < deprecate_version
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,387 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require "active_support/inflector"
5
+ require "hash_diff"
6
+
7
+ module ShopifyAPI
8
+ module Rest
9
+ class Base
10
+ extend T::Sig
11
+ extend T::Helpers
12
+ abstract!
13
+
14
+ @has_one = T.let({}, T::Hash[Symbol, Class])
15
+ @has_many = T.let({}, T::Hash[Symbol, Class])
16
+ @paths = T.let([], T::Array[T::Hash[Symbol, T.any(T::Array[Symbol], String, Symbol)]])
17
+ @custom_prefix = T.let(nil, T.nilable(String))
18
+ @read_only_attributes = T.let([], T.nilable(T::Array[Symbol]))
19
+ @aliased_properties = T.let({}, T::Hash[String, String])
20
+
21
+ sig { returns(T::Hash[Symbol, T.untyped]) }
22
+ attr_accessor :original_state
23
+
24
+ sig { returns(Rest::BaseErrors) }
25
+ attr_reader :errors
26
+
27
+ sig do
28
+ params(
29
+ session: T.nilable(Auth::Session),
30
+ from_hash: T.nilable(T::Hash[Symbol, T.untyped]),
31
+ ).void
32
+ end
33
+ def initialize(session: nil, from_hash: nil)
34
+ @original_state = T.let({}, T::Hash[Symbol, T.untyped])
35
+ @custom_prefix = T.let(nil, T.nilable(String))
36
+ @forced_nils = T.let({}, T::Hash[String, T::Boolean])
37
+ @aliased_properties = T.let({}, T::Hash[String, String])
38
+
39
+ session ||= ShopifyAPI::Context.active_session
40
+
41
+ client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
42
+
43
+ @session = T.let(T.must(session), Auth::Session)
44
+ @client = T.let(client, Clients::Rest::Admin)
45
+ @errors = T.let(Rest::BaseErrors.new, Rest::BaseErrors)
46
+
47
+ from_hash&.each do |key, value|
48
+ set_property(key, value)
49
+ end
50
+ end
51
+
52
+ class << self
53
+ extend T::Sig
54
+
55
+ sig { returns(T.nilable(String)) }
56
+ attr_reader :custom_prefix
57
+
58
+ sig { returns(T::Hash[Symbol, Class]) }
59
+ attr_reader :has_many
60
+
61
+ sig { returns(T::Hash[Symbol, Class]) }
62
+ attr_reader :has_one
63
+
64
+ sig do
65
+ params(
66
+ session: T.nilable(Auth::Session),
67
+ ids: T::Hash[Symbol, String],
68
+ params: T::Hash[Symbol, T.untyped],
69
+ ).returns(T::Array[Base])
70
+ end
71
+ def base_find(session: nil, ids: {}, params: {})
72
+ session ||= ShopifyAPI::Context.active_session
73
+
74
+ client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
75
+
76
+ path = T.must(get_path(http_method: :get, operation: :get, ids: ids))
77
+ response = client.get(path: path, query: params.compact)
78
+
79
+ instance_variable_get(:"@prev_page_info").value = response.prev_page_info
80
+ instance_variable_get(:"@next_page_info").value = response.next_page_info
81
+
82
+ create_instances_from_response(response: response, session: T.must(session))
83
+ end
84
+
85
+ sig { returns(String) }
86
+ def class_name
87
+ T.must(name).demodulize.underscore
88
+ end
89
+
90
+ sig { returns(String) }
91
+ def primary_key
92
+ "id"
93
+ end
94
+
95
+ sig { returns(String) }
96
+ def json_body_name
97
+ class_name.underscore
98
+ end
99
+
100
+ sig { returns(T.nilable(String)) }
101
+ def prev_page_info
102
+ instance_variable_get(:"@prev_page_info").value
103
+ end
104
+
105
+ sig { returns(T.nilable(String)) }
106
+ def next_page_info
107
+ instance_variable_get(:"@next_page_info").value
108
+ end
109
+
110
+ sig { returns(T::Boolean) }
111
+ def prev_page?
112
+ !instance_variable_get(:"@prev_page_info").value.nil?
113
+ end
114
+
115
+ sig { returns(T::Boolean) }
116
+ def next_page?
117
+ !instance_variable_get(:"@next_page_info").value.nil?
118
+ end
119
+
120
+ sig { params(attribute: Symbol).returns(T::Boolean) }
121
+ def has_many?(attribute)
122
+ @has_many.include?(attribute)
123
+ end
124
+
125
+ sig { params(attribute: Symbol).returns(T::Boolean) }
126
+ def has_one?(attribute)
127
+ @has_one.include?(attribute)
128
+ end
129
+
130
+ sig { returns(T.nilable(T::Array[Symbol])) }
131
+ def read_only_attributes
132
+ @read_only_attributes&.map { |a| :"@#{a}" }
133
+ end
134
+
135
+ sig do
136
+ params(
137
+ http_method: Symbol,
138
+ operation: Symbol,
139
+ entity: T.nilable(Base),
140
+ ids: T::Hash[Symbol, T.any(Integer, String)],
141
+ ).returns(T.nilable(String))
142
+ end
143
+ def get_path(http_method:, operation:, entity: nil, ids: {})
144
+ match = T.let(nil, T.nilable(String))
145
+ max_ids = T.let(-1, Integer)
146
+ @paths.each do |path|
147
+ next if http_method != path[:http_method] || operation != path[:operation]
148
+
149
+ path_ids = T.cast(path[:ids], T::Array[Symbol])
150
+
151
+ url_ids = ids.transform_keys(&:to_sym)
152
+ path_ids.each do |id|
153
+ if url_ids[id].nil? && (entity_id = entity&.public_send(id))
154
+ url_ids[id] = entity_id
155
+ end
156
+ end
157
+
158
+ url_ids.compact!
159
+
160
+ # We haven't found all the required ids or we have a more specific match
161
+ next if !(path_ids - url_ids.keys).empty? || path_ids.length <= max_ids
162
+
163
+ max_ids = path_ids.length
164
+ match = T.cast(path[:path], String).gsub(/(<([^>]+)>)/) do
165
+ url_ids[T.unsafe(Regexp.last_match)[2].to_sym]
166
+ end
167
+ end
168
+
169
+ custom_prefix ? "#{T.must(custom_prefix).sub(%r{\A/}, "")}/#{match}" : match
170
+ end
171
+
172
+ sig do
173
+ params(
174
+ http_method: Symbol,
175
+ operation: T.any(String, Symbol),
176
+ session: T.nilable(Auth::Session),
177
+ ids: T::Hash[Symbol, String],
178
+ params: T::Hash[Symbol, T.untyped],
179
+ body: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
180
+ entity: T.untyped,
181
+ ).returns(Clients::HttpResponse)
182
+ end
183
+ def request(http_method:, operation:, session:, ids: {}, params: {}, body: nil, entity: nil)
184
+ client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
185
+
186
+ path = get_path(http_method: http_method, operation: operation.to_sym, ids: ids)
187
+
188
+ case http_method
189
+ when :get
190
+ client.get(path: T.must(path), query: params.compact)
191
+ when :post
192
+ client.post(path: T.must(path), query: params.compact, body: body || {})
193
+ when :put
194
+ client.put(path: T.must(path), query: params.compact, body: body || {})
195
+ when :delete
196
+ client.delete(path: T.must(path), query: params.compact)
197
+ else
198
+ raise Errors::InvalidHttpRequestError, "Invalid HTTP method: #{http_method}"
199
+ end
200
+ end
201
+
202
+ sig { params(response: Clients::HttpResponse, session: Auth::Session).returns(T::Array[Base]) }
203
+ def create_instances_from_response(response:, session:)
204
+ objects = []
205
+
206
+ body = T.cast(response.body, T::Hash[String, T.untyped])
207
+
208
+ if body.key?(class_name.pluralize) || (body.key?(class_name) && body[class_name].is_a?(Array))
209
+ (body[class_name.pluralize] || body[class_name]).each do |entry|
210
+ objects << create_instance(data: entry, session: session)
211
+ end
212
+ elsif body.key?(class_name)
213
+ objects << create_instance(data: body[class_name], session: session)
214
+ end
215
+
216
+ objects
217
+ end
218
+
219
+ sig do
220
+ params(data: T::Hash[String, T.untyped], session: Auth::Session, instance: T.nilable(Base)).returns(Base)
221
+ end
222
+ def create_instance(data:, session:, instance: nil)
223
+ instance ||= new(session: session)
224
+ instance.original_state = {}
225
+
226
+ data.each do |attribute, value|
227
+ attr_sym = attribute.to_sym
228
+
229
+ if has_many?(attr_sym) && value
230
+ attr_list = []
231
+ value.each do |element|
232
+ attr_list << T.unsafe(@has_many[attr_sym]).create_instance(data: element, session: session)
233
+ end
234
+ instance.public_send("#{attribute}=", attr_list)
235
+ elsif has_one?(attr_sym) && value
236
+ instance.public_send("#{attribute}=",
237
+ T.unsafe(@has_one[attr_sym]).create_instance(data: value, session: session))
238
+ else
239
+ instance.public_send("#{attribute}=", value)
240
+ instance.original_state[attr_sym] = value
241
+ end
242
+ end
243
+
244
+ instance
245
+ end
246
+ end
247
+
248
+ sig { params(meth_id: Symbol, val: T.untyped).returns(T.untyped) }
249
+ def method_missing(meth_id, val = nil)
250
+ match = meth_id.id2name.match(/([^=]+)(=)?/)
251
+
252
+ var = T.must(T.must(match)[1])
253
+
254
+ if T.must(match)[2]
255
+ set_property(var, val)
256
+ @forced_nils[var] = val.nil?
257
+ else
258
+ get_property(var)
259
+ end
260
+ end
261
+
262
+ sig { params(meth_id: Symbol, args: T.untyped).void }
263
+ def respond_to_missing?(meth_id, *args)
264
+ str = meth_id.id2name
265
+ match = str.match(/([^=]+)=/)
266
+
267
+ match.nil? ? true : super
268
+ end
269
+
270
+ sig { params(saving: T::Boolean).returns(T::Hash[String, T.untyped]) }
271
+ def to_hash(saving = false)
272
+ hash = {}
273
+ instance_variables.each do |var|
274
+ next if [
275
+ :"@original_state",
276
+ :"@session",
277
+ :"@client",
278
+ :"@forced_nils",
279
+ :"@errors",
280
+ :"@aliased_properties",
281
+ ].include?(var)
282
+ next if saving && self.class.read_only_attributes&.include?(var)
283
+
284
+ var = var.to_s.delete("@")
285
+ attribute = if @aliased_properties.value?(var)
286
+ T.must(@aliased_properties.key(var))
287
+ else
288
+ var
289
+ end.to_sym
290
+
291
+ if self.class.has_many?(attribute)
292
+ attribute_class = self.class.has_many[attribute]
293
+ hash[attribute.to_s] = get_property(attribute).map do |element|
294
+ get_element_hash(element, T.unsafe(attribute_class), saving)
295
+ end.to_a if get_property(attribute)
296
+ elsif self.class.has_one?(attribute)
297
+ element_hash = get_element_hash(
298
+ get_property(attribute),
299
+ T.unsafe(self.class.has_one[attribute]),
300
+ saving,
301
+ )
302
+ hash[attribute.to_s] = element_hash if element_hash || @forced_nils[attribute.to_s]
303
+ elsif !get_property(attribute).nil? || @forced_nils[attribute.to_s]
304
+ hash[attribute.to_s] =
305
+ get_property(attribute)
306
+ end
307
+ end
308
+ hash
309
+ end
310
+
311
+ sig { params(params: T::Hash[T.untyped, T.untyped]).void }
312
+ def delete(params: {})
313
+ @client.delete(
314
+ path: T.must(self.class.get_path(http_method: :delete, operation: :delete, entity: self)),
315
+ query: params.compact,
316
+ )
317
+ rescue ShopifyAPI::Errors::HttpResponseError => e
318
+ @errors.errors << e
319
+ raise
320
+ end
321
+
322
+ sig { void }
323
+ def save!
324
+ save(update_object: true)
325
+ end
326
+
327
+ sig { params(update_object: T::Boolean).void }
328
+ def save(update_object: false)
329
+ hash = HashDiff::Comparison.new(original_state, to_hash(true)).left_diff
330
+ method = hash[self.class.primary_key] ? :put : :post
331
+
332
+ path = self.class.get_path(http_method: method, operation: method, entity: self)
333
+ if path.nil?
334
+ method = method == :post ? :put : :post
335
+ path = self.class.get_path(http_method: method, operation: method, entity: self)
336
+ end
337
+
338
+ response = @client.public_send(method, body: { self.class.json_body_name => hash }, path: path)
339
+
340
+ if update_object
341
+ self.class.create_instance(
342
+ data: response.body[self.class.class_name.downcase],
343
+ session: @session, instance: self
344
+ )
345
+ end
346
+ rescue ShopifyAPI::Errors::HttpResponseError => e
347
+ @errors.errors << e
348
+ raise
349
+ end
350
+
351
+ private
352
+
353
+ sig { params(key: T.any(String, Symbol), val: T.untyped).void }
354
+ def set_property(key, val)
355
+ # Some API fields contain invalid characters, like `?`, which causes issues when setting them as instance
356
+ # variables. To work around that, we're cleaning them up here but keeping track of the properties that were
357
+ # aliased this way. When loading up the property, we can map back from the "invalid" field so that it is
358
+ # transparent to outside callers
359
+ clean_key = key.to_s.gsub(/[\?\s]/, "")
360
+ @aliased_properties[key.to_s] = clean_key if clean_key != key
361
+
362
+ instance_variable_set("@#{clean_key}", val)
363
+ end
364
+
365
+ sig { params(key: T.any(String, Symbol)).returns(T.untyped) }
366
+ def get_property(key)
367
+ clean_key = @aliased_properties.key?(key.to_s) ? @aliased_properties[key.to_s] : key
368
+
369
+ instance_variable_get("@#{clean_key}")
370
+ end
371
+
372
+ sig do
373
+ params(
374
+ element: T.nilable(T.any(T::Hash[String, T.untyped], ShopifyAPI::Rest::Base)),
375
+ attribute_class: Class,
376
+ saving: T::Boolean,
377
+ ).returns(T.nilable(T::Hash[String, T.untyped]))
378
+ end
379
+ def get_element_hash(element, attribute_class, saving)
380
+ return nil if element.nil?
381
+ return element.to_hash(saving) unless element.is_a?(Hash)
382
+
383
+ T.unsafe(attribute_class).create_instance(session: @session, data: element).to_hash(saving)
384
+ end
385
+ end
386
+ end
387
+ end
@@ -0,0 +1,32 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Rest
6
+ class BaseErrors
7
+ extend T::Sig
8
+
9
+ sig { returns(T::Array[ShopifyAPI::Errors::HttpResponseError]) }
10
+ attr_accessor :errors
11
+
12
+ sig { void }
13
+ def initialize
14
+ @errors = T.let([], T::Array[ShopifyAPI::Errors::HttpResponseError])
15
+ end
16
+
17
+ sig { returns(String) }
18
+ def full_messages
19
+ @errors.join("\n")
20
+ end
21
+
22
+ sig { returns(T::Array[T.untyped]) }
23
+ def codes
24
+ codes = []
25
+ @errors.each do |error|
26
+ codes << error.code
27
+ end
28
+ codes
29
+ end
30
+ end
31
+ end
32
+ end