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.
- checksums.yaml +7 -0
- data/.github/CODEOWNERS +1 -0
- data/.github/ISSUE_TEMPLATE.md +35 -0
- data/.github/dependabot.yml +20 -0
- data/.github/pull_request_template.md +20 -0
- data/.github/workflows/build.yml +42 -0
- data/.github/workflows/cla.yml +22 -0
- data/.github/workflows/close-waiting-for-response-issues.yml +20 -0
- data/.github/workflows/remove-labels-on-activity.yml +16 -0
- data/.github/workflows/stale.yml +32 -0
- data/.rubocop.yml +59 -0
- data/BREAKING_CHANGES_FOR_OLDER_VERSIONS.md +110 -0
- data/CHANGELOG.md +574 -0
- data/CONTRIBUTING.md +9 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +159 -0
- data/LICENSE +2 -2
- data/README.md +138 -0
- data/RELEASING.md +19 -0
- data/Rakefile +16 -50
- data/SECURITY.md +59 -0
- data/bin/tapioca +29 -0
- data/dev.yml +32 -0
- data/docs/README.md +13 -0
- data/docs/getting_started.md +53 -0
- data/docs/issues.md +39 -0
- data/docs/usage/graphql.md +115 -0
- data/docs/usage/graphql_storefront.md +42 -0
- data/docs/usage/oauth.md +104 -0
- data/docs/usage/rest.md +137 -0
- data/docs/usage/session_storage.md +46 -0
- data/docs/usage/webhooks.md +98 -0
- data/lib/shopify_api/admin_versions.rb +19 -0
- data/lib/shopify_api/auth/associated_user.rb +36 -0
- data/lib/shopify_api/auth/auth_scopes.rb +75 -0
- data/lib/shopify_api/auth/file_session_storage.rb +72 -0
- data/lib/shopify_api/auth/jwt_payload.rb +83 -0
- data/lib/shopify_api/auth/oauth/auth_query.rb +47 -0
- data/lib/shopify_api/auth/oauth/session_cookie.rb +28 -0
- data/lib/shopify_api/auth/oauth.rb +135 -0
- data/lib/shopify_api/auth/session.rb +119 -0
- data/lib/shopify_api/auth/session_storage.rb +30 -0
- data/lib/shopify_api/auth.rb +26 -0
- data/lib/shopify_api/clients/graphql/admin.rb +15 -0
- data/lib/shopify_api/clients/graphql/client.rb +40 -0
- data/lib/shopify_api/clients/graphql/storefront.rb +35 -0
- data/lib/shopify_api/clients/http_client.rb +100 -0
- data/lib/shopify_api/clients/http_request.rb +35 -0
- data/lib/shopify_api/clients/http_response.rb +66 -0
- data/lib/shopify_api/clients/rest/admin.rb +118 -0
- data/lib/shopify_api/context.rb +196 -0
- data/lib/shopify_api/errors/context_not_setup_error.rb +9 -0
- data/lib/shopify_api/errors/cookie_not_found_error.rb +9 -0
- data/lib/shopify_api/errors/feature_deprecated_error.rb +9 -0
- data/lib/shopify_api/errors/http_response_error.rb +23 -0
- data/lib/shopify_api/errors/invalid_graphql_request_error.rb +9 -0
- data/lib/shopify_api/errors/invalid_http_request_error.rb +9 -0
- data/lib/shopify_api/errors/invalid_jwt_token_error.rb +9 -0
- data/lib/shopify_api/errors/invalid_oauth_error.rb +9 -0
- data/lib/shopify_api/errors/invalid_webhook_error.rb +9 -0
- data/lib/shopify_api/errors/invalid_webhook_registration_error.rb +9 -0
- data/lib/shopify_api/errors/log_level_not_found_error.rb +9 -0
- data/lib/shopify_api/errors/max_http_retries_exceeded_error.rb +9 -0
- data/lib/shopify_api/errors/missing_jwt_token_error.rb +9 -0
- data/lib/shopify_api/errors/missing_required_argument_error.rb +9 -0
- data/lib/shopify_api/errors/no_active_session_error.rb +9 -0
- data/lib/shopify_api/errors/no_session_cookie_error.rb +9 -0
- data/lib/shopify_api/errors/no_webhook_handler.rb +9 -0
- data/lib/shopify_api/errors/private_app_error.rb +9 -0
- data/lib/shopify_api/errors/request_access_token_error.rb +9 -0
- data/lib/shopify_api/errors/session_not_found_error.rb +9 -0
- data/lib/shopify_api/errors/session_storage_error.rb +9 -0
- data/lib/shopify_api/errors/unsupported_oauth_error.rb +9 -0
- data/lib/shopify_api/errors/unsupported_version_error.rb +9 -0
- data/lib/shopify_api/errors/webhook_registration_error.rb +9 -0
- data/lib/shopify_api/inflector.rb +17 -0
- data/lib/shopify_api/logger.rb +82 -0
- data/lib/shopify_api/rest/base.rb +387 -0
- data/lib/shopify_api/rest/base_errors.rb +32 -0
- data/lib/shopify_api/rest/resources/2022_01/abandoned_checkout.rb +190 -0
- data/lib/shopify_api/rest/resources/2022_01/access_scope.rb +58 -0
- data/lib/shopify_api/rest/resources/2022_01/android_pay_key.rb +77 -0
- data/lib/shopify_api/rest/resources/2022_01/apple_pay_certificate.rb +105 -0
- data/lib/shopify_api/rest/resources/2022_01/application_charge.rb +104 -0
- data/lib/shopify_api/rest/resources/2022_01/application_credit.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_01/article.rb +265 -0
- data/lib/shopify_api/rest/resources/2022_01/asset.rb +118 -0
- data/lib/shopify_api/rest/resources/2022_01/assigned_fulfillment_order.rb +79 -0
- data/lib/shopify_api/rest/resources/2022_01/balance.rb +50 -0
- data/lib/shopify_api/rest/resources/2022_01/blog.rb +162 -0
- data/lib/shopify_api/rest/resources/2022_01/cancellation_request.rb +83 -0
- data/lib/shopify_api/rest/resources/2022_01/carrier_service.rb +116 -0
- data/lib/shopify_api/rest/resources/2022_01/checkout.rb +209 -0
- data/lib/shopify_api/rest/resources/2022_01/collect.rb +142 -0
- data/lib/shopify_api/rest/resources/2022_01/collection.rb +110 -0
- data/lib/shopify_api/rest/resources/2022_01/collection_listing.rb +155 -0
- data/lib/shopify_api/rest/resources/2022_01/comment.rb +283 -0
- data/lib/shopify_api/rest/resources/2022_01/country.rb +137 -0
- data/lib/shopify_api/rest/resources/2022_01/currency.rb +57 -0
- data/lib/shopify_api/rest/resources/2022_01/custom_collection.rb +187 -0
- data/lib/shopify_api/rest/resources/2022_01/customer.rb +318 -0
- data/lib/shopify_api/rest/resources/2022_01/customer_address.rb +201 -0
- data/lib/shopify_api/rest/resources/2022_01/customer_saved_search.rb +169 -0
- data/lib/shopify_api/rest/resources/2022_01/deprecated_api_call.rb +57 -0
- data/lib/shopify_api/rest/resources/2022_01/discount_code.rb +219 -0
- data/lib/shopify_api/rest/resources/2022_01/dispute.rb +111 -0
- data/lib/shopify_api/rest/resources/2022_01/draft_order.rb +275 -0
- data/lib/shopify_api/rest/resources/2022_01/event.rb +148 -0
- data/lib/shopify_api/rest/resources/2022_01/fulfillment.rb +268 -0
- data/lib/shopify_api/rest/resources/2022_01/fulfillment_event.rb +166 -0
- data/lib/shopify_api/rest/resources/2022_01/fulfillment_order.rb +281 -0
- data/lib/shopify_api/rest/resources/2022_01/fulfillment_request.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_01/fulfillment_service.rb +130 -0
- data/lib/shopify_api/rest/resources/2022_01/gift_card.rb +215 -0
- data/lib/shopify_api/rest/resources/2022_01/gift_card_adjustment.rb +118 -0
- data/lib/shopify_api/rest/resources/2022_01/image.rb +157 -0
- data/lib/shopify_api/rest/resources/2022_01/inventory_item.rb +108 -0
- data/lib/shopify_api/rest/resources/2022_01/inventory_level.rb +179 -0
- data/lib/shopify_api/rest/resources/2022_01/location.rb +167 -0
- data/lib/shopify_api/rest/resources/2022_01/locations_for_move.rb +56 -0
- data/lib/shopify_api/rest/resources/2022_01/marketing_event.rb +209 -0
- data/lib/shopify_api/rest/resources/2022_01/metafield.rb +349 -0
- data/lib/shopify_api/rest/resources/2022_01/mobile_platform_application.rb +110 -0
- data/lib/shopify_api/rest/resources/2022_01/order.rb +473 -0
- data/lib/shopify_api/rest/resources/2022_01/order_risk.rb +135 -0
- data/lib/shopify_api/rest/resources/2022_01/page.rb +194 -0
- data/lib/shopify_api/rest/resources/2022_01/payment.rb +140 -0
- data/lib/shopify_api/rest/resources/2022_01/payment_gateway.rb +143 -0
- data/lib/shopify_api/rest/resources/2022_01/payment_transaction.rb +107 -0
- data/lib/shopify_api/rest/resources/2022_01/payout.rb +97 -0
- data/lib/shopify_api/rest/resources/2022_01/policy.rb +69 -0
- data/lib/shopify_api/rest/resources/2022_01/price_rule.rb +223 -0
- data/lib/shopify_api/rest/resources/2022_01/product.rb +223 -0
- data/lib/shopify_api/rest/resources/2022_01/product_listing.rb +196 -0
- data/lib/shopify_api/rest/resources/2022_01/product_resource_feedback.rb +88 -0
- data/lib/shopify_api/rest/resources/2022_01/province.rb +132 -0
- data/lib/shopify_api/rest/resources/2022_01/recurring_application_charge.rb +167 -0
- data/lib/shopify_api/rest/resources/2022_01/redirect.rb +139 -0
- data/lib/shopify_api/rest/resources/2022_01/refund.rb +151 -0
- data/lib/shopify_api/rest/resources/2022_01/report.rb +121 -0
- data/lib/shopify_api/rest/resources/2022_01/resource_feedback.rb +73 -0
- data/lib/shopify_api/rest/resources/2022_01/script_tag.rb +155 -0
- data/lib/shopify_api/rest/resources/2022_01/shipping_zone.rb +83 -0
- data/lib/shopify_api/rest/resources/2022_01/shop.rb +218 -0
- data/lib/shopify_api/rest/resources/2022_01/smart_collection.rb +216 -0
- data/lib/shopify_api/rest/resources/2022_01/storefront_access_token.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_01/tender_transaction.rb +93 -0
- data/lib/shopify_api/rest/resources/2022_01/theme.rb +120 -0
- data/lib/shopify_api/rest/resources/2022_01/transaction.rb +181 -0
- data/lib/shopify_api/rest/resources/2022_01/usage_charge.rb +97 -0
- data/lib/shopify_api/rest/resources/2022_01/user.rb +138 -0
- data/lib/shopify_api/rest/resources/2022_01/variant.rb +212 -0
- data/lib/shopify_api/rest/resources/2022_01/webhook.rb +168 -0
- data/lib/shopify_api/rest/resources/2022_04/abandoned_checkout.rb +190 -0
- data/lib/shopify_api/rest/resources/2022_04/access_scope.rb +58 -0
- data/lib/shopify_api/rest/resources/2022_04/android_pay_key.rb +77 -0
- data/lib/shopify_api/rest/resources/2022_04/apple_pay_certificate.rb +105 -0
- data/lib/shopify_api/rest/resources/2022_04/application_charge.rb +104 -0
- data/lib/shopify_api/rest/resources/2022_04/application_credit.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_04/article.rb +265 -0
- data/lib/shopify_api/rest/resources/2022_04/asset.rb +118 -0
- data/lib/shopify_api/rest/resources/2022_04/assigned_fulfillment_order.rb +79 -0
- data/lib/shopify_api/rest/resources/2022_04/balance.rb +50 -0
- data/lib/shopify_api/rest/resources/2022_04/blog.rb +162 -0
- data/lib/shopify_api/rest/resources/2022_04/cancellation_request.rb +83 -0
- data/lib/shopify_api/rest/resources/2022_04/carrier_service.rb +116 -0
- data/lib/shopify_api/rest/resources/2022_04/checkout.rb +209 -0
- data/lib/shopify_api/rest/resources/2022_04/collect.rb +142 -0
- data/lib/shopify_api/rest/resources/2022_04/collection.rb +110 -0
- data/lib/shopify_api/rest/resources/2022_04/collection_listing.rb +155 -0
- data/lib/shopify_api/rest/resources/2022_04/comment.rb +283 -0
- data/lib/shopify_api/rest/resources/2022_04/country.rb +137 -0
- data/lib/shopify_api/rest/resources/2022_04/currency.rb +57 -0
- data/lib/shopify_api/rest/resources/2022_04/custom_collection.rb +187 -0
- data/lib/shopify_api/rest/resources/2022_04/customer.rb +321 -0
- data/lib/shopify_api/rest/resources/2022_04/customer_address.rb +201 -0
- data/lib/shopify_api/rest/resources/2022_04/customer_saved_search.rb +169 -0
- data/lib/shopify_api/rest/resources/2022_04/deprecated_api_call.rb +57 -0
- data/lib/shopify_api/rest/resources/2022_04/discount_code.rb +219 -0
- data/lib/shopify_api/rest/resources/2022_04/dispute.rb +111 -0
- data/lib/shopify_api/rest/resources/2022_04/draft_order.rb +275 -0
- data/lib/shopify_api/rest/resources/2022_04/event.rb +148 -0
- data/lib/shopify_api/rest/resources/2022_04/fulfillment.rb +268 -0
- data/lib/shopify_api/rest/resources/2022_04/fulfillment_event.rb +166 -0
- data/lib/shopify_api/rest/resources/2022_04/fulfillment_order.rb +284 -0
- data/lib/shopify_api/rest/resources/2022_04/fulfillment_request.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_04/fulfillment_service.rb +130 -0
- data/lib/shopify_api/rest/resources/2022_04/gift_card.rb +215 -0
- data/lib/shopify_api/rest/resources/2022_04/gift_card_adjustment.rb +118 -0
- data/lib/shopify_api/rest/resources/2022_04/image.rb +157 -0
- data/lib/shopify_api/rest/resources/2022_04/inventory_item.rb +108 -0
- data/lib/shopify_api/rest/resources/2022_04/inventory_level.rb +179 -0
- data/lib/shopify_api/rest/resources/2022_04/location.rb +167 -0
- data/lib/shopify_api/rest/resources/2022_04/locations_for_move.rb +56 -0
- data/lib/shopify_api/rest/resources/2022_04/marketing_event.rb +209 -0
- data/lib/shopify_api/rest/resources/2022_04/metafield.rb +342 -0
- data/lib/shopify_api/rest/resources/2022_04/mobile_platform_application.rb +110 -0
- data/lib/shopify_api/rest/resources/2022_04/order.rb +473 -0
- data/lib/shopify_api/rest/resources/2022_04/order_risk.rb +135 -0
- data/lib/shopify_api/rest/resources/2022_04/page.rb +194 -0
- data/lib/shopify_api/rest/resources/2022_04/payment.rb +140 -0
- data/lib/shopify_api/rest/resources/2022_04/payment_gateway.rb +143 -0
- data/lib/shopify_api/rest/resources/2022_04/payment_transaction.rb +107 -0
- data/lib/shopify_api/rest/resources/2022_04/payout.rb +97 -0
- data/lib/shopify_api/rest/resources/2022_04/policy.rb +69 -0
- data/lib/shopify_api/rest/resources/2022_04/price_rule.rb +223 -0
- data/lib/shopify_api/rest/resources/2022_04/product.rb +223 -0
- data/lib/shopify_api/rest/resources/2022_04/product_listing.rb +196 -0
- data/lib/shopify_api/rest/resources/2022_04/product_resource_feedback.rb +88 -0
- data/lib/shopify_api/rest/resources/2022_04/province.rb +132 -0
- data/lib/shopify_api/rest/resources/2022_04/recurring_application_charge.rb +167 -0
- data/lib/shopify_api/rest/resources/2022_04/redirect.rb +139 -0
- data/lib/shopify_api/rest/resources/2022_04/refund.rb +151 -0
- data/lib/shopify_api/rest/resources/2022_04/report.rb +121 -0
- data/lib/shopify_api/rest/resources/2022_04/resource_feedback.rb +73 -0
- data/lib/shopify_api/rest/resources/2022_04/script_tag.rb +155 -0
- data/lib/shopify_api/rest/resources/2022_04/shipping_zone.rb +83 -0
- data/lib/shopify_api/rest/resources/2022_04/shop.rb +218 -0
- data/lib/shopify_api/rest/resources/2022_04/smart_collection.rb +216 -0
- data/lib/shopify_api/rest/resources/2022_04/storefront_access_token.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_04/tender_transaction.rb +93 -0
- data/lib/shopify_api/rest/resources/2022_04/theme.rb +120 -0
- data/lib/shopify_api/rest/resources/2022_04/transaction.rb +181 -0
- data/lib/shopify_api/rest/resources/2022_04/usage_charge.rb +97 -0
- data/lib/shopify_api/rest/resources/2022_04/user.rb +138 -0
- data/lib/shopify_api/rest/resources/2022_04/variant.rb +212 -0
- data/lib/shopify_api/rest/resources/2022_04/webhook.rb +168 -0
- data/lib/shopify_api/rest/resources/2022_07/abandoned_checkout.rb +190 -0
- data/lib/shopify_api/rest/resources/2022_07/access_scope.rb +58 -0
- data/lib/shopify_api/rest/resources/2022_07/android_pay_key.rb +77 -0
- data/lib/shopify_api/rest/resources/2022_07/apple_pay_certificate.rb +105 -0
- data/lib/shopify_api/rest/resources/2022_07/application_charge.rb +104 -0
- data/lib/shopify_api/rest/resources/2022_07/application_credit.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_07/article.rb +265 -0
- data/lib/shopify_api/rest/resources/2022_07/asset.rb +118 -0
- data/lib/shopify_api/rest/resources/2022_07/assigned_fulfillment_order.rb +79 -0
- data/lib/shopify_api/rest/resources/2022_07/balance.rb +50 -0
- data/lib/shopify_api/rest/resources/2022_07/blog.rb +162 -0
- data/lib/shopify_api/rest/resources/2022_07/cancellation_request.rb +83 -0
- data/lib/shopify_api/rest/resources/2022_07/carrier_service.rb +113 -0
- data/lib/shopify_api/rest/resources/2022_07/checkout.rb +209 -0
- data/lib/shopify_api/rest/resources/2022_07/collect.rb +142 -0
- data/lib/shopify_api/rest/resources/2022_07/collection.rb +110 -0
- data/lib/shopify_api/rest/resources/2022_07/collection_listing.rb +155 -0
- data/lib/shopify_api/rest/resources/2022_07/comment.rb +283 -0
- data/lib/shopify_api/rest/resources/2022_07/country.rb +137 -0
- data/lib/shopify_api/rest/resources/2022_07/currency.rb +57 -0
- data/lib/shopify_api/rest/resources/2022_07/custom_collection.rb +187 -0
- data/lib/shopify_api/rest/resources/2022_07/customer.rb +321 -0
- data/lib/shopify_api/rest/resources/2022_07/customer_address.rb +201 -0
- data/lib/shopify_api/rest/resources/2022_07/customer_saved_search.rb +169 -0
- data/lib/shopify_api/rest/resources/2022_07/deprecated_api_call.rb +57 -0
- data/lib/shopify_api/rest/resources/2022_07/discount_code.rb +219 -0
- data/lib/shopify_api/rest/resources/2022_07/dispute.rb +111 -0
- data/lib/shopify_api/rest/resources/2022_07/dispute_evidence.rb +117 -0
- data/lib/shopify_api/rest/resources/2022_07/dispute_file_upload.rb +81 -0
- data/lib/shopify_api/rest/resources/2022_07/draft_order.rb +275 -0
- data/lib/shopify_api/rest/resources/2022_07/event.rb +148 -0
- data/lib/shopify_api/rest/resources/2022_07/fulfillment.rb +221 -0
- data/lib/shopify_api/rest/resources/2022_07/fulfillment_event.rb +166 -0
- data/lib/shopify_api/rest/resources/2022_07/fulfillment_order.rb +310 -0
- data/lib/shopify_api/rest/resources/2022_07/fulfillment_request.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_07/fulfillment_service.rb +130 -0
- data/lib/shopify_api/rest/resources/2022_07/gift_card.rb +215 -0
- data/lib/shopify_api/rest/resources/2022_07/gift_card_adjustment.rb +118 -0
- data/lib/shopify_api/rest/resources/2022_07/image.rb +157 -0
- data/lib/shopify_api/rest/resources/2022_07/inventory_item.rb +108 -0
- data/lib/shopify_api/rest/resources/2022_07/inventory_level.rb +179 -0
- data/lib/shopify_api/rest/resources/2022_07/location.rb +167 -0
- data/lib/shopify_api/rest/resources/2022_07/locations_for_move.rb +56 -0
- data/lib/shopify_api/rest/resources/2022_07/marketing_event.rb +209 -0
- data/lib/shopify_api/rest/resources/2022_07/metafield.rb +342 -0
- data/lib/shopify_api/rest/resources/2022_07/mobile_platform_application.rb +110 -0
- data/lib/shopify_api/rest/resources/2022_07/order.rb +473 -0
- data/lib/shopify_api/rest/resources/2022_07/order_risk.rb +135 -0
- data/lib/shopify_api/rest/resources/2022_07/page.rb +194 -0
- data/lib/shopify_api/rest/resources/2022_07/payment.rb +140 -0
- data/lib/shopify_api/rest/resources/2022_07/payment_gateway.rb +143 -0
- data/lib/shopify_api/rest/resources/2022_07/payment_transaction.rb +107 -0
- data/lib/shopify_api/rest/resources/2022_07/payout.rb +97 -0
- data/lib/shopify_api/rest/resources/2022_07/policy.rb +69 -0
- data/lib/shopify_api/rest/resources/2022_07/price_rule.rb +223 -0
- data/lib/shopify_api/rest/resources/2022_07/product.rb +223 -0
- data/lib/shopify_api/rest/resources/2022_07/product_listing.rb +196 -0
- data/lib/shopify_api/rest/resources/2022_07/product_resource_feedback.rb +88 -0
- data/lib/shopify_api/rest/resources/2022_07/province.rb +132 -0
- data/lib/shopify_api/rest/resources/2022_07/recurring_application_charge.rb +167 -0
- data/lib/shopify_api/rest/resources/2022_07/redirect.rb +139 -0
- data/lib/shopify_api/rest/resources/2022_07/refund.rb +151 -0
- data/lib/shopify_api/rest/resources/2022_07/report.rb +121 -0
- data/lib/shopify_api/rest/resources/2022_07/resource_feedback.rb +73 -0
- data/lib/shopify_api/rest/resources/2022_07/script_tag.rb +155 -0
- data/lib/shopify_api/rest/resources/2022_07/shipping_zone.rb +83 -0
- data/lib/shopify_api/rest/resources/2022_07/shop.rb +218 -0
- data/lib/shopify_api/rest/resources/2022_07/smart_collection.rb +216 -0
- data/lib/shopify_api/rest/resources/2022_07/storefront_access_token.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_07/tender_transaction.rb +93 -0
- data/lib/shopify_api/rest/resources/2022_07/theme.rb +120 -0
- data/lib/shopify_api/rest/resources/2022_07/transaction.rb +181 -0
- data/lib/shopify_api/rest/resources/2022_07/usage_charge.rb +97 -0
- data/lib/shopify_api/rest/resources/2022_07/user.rb +138 -0
- data/lib/shopify_api/rest/resources/2022_07/variant.rb +212 -0
- data/lib/shopify_api/rest/resources/2022_07/webhook.rb +168 -0
- data/lib/shopify_api/rest/resources/2022_10/abandoned_checkout.rb +190 -0
- data/lib/shopify_api/rest/resources/2022_10/access_scope.rb +58 -0
- data/lib/shopify_api/rest/resources/2022_10/android_pay_key.rb +77 -0
- data/lib/shopify_api/rest/resources/2022_10/apple_pay_certificate.rb +105 -0
- data/lib/shopify_api/rest/resources/2022_10/application_charge.rb +104 -0
- data/lib/shopify_api/rest/resources/2022_10/application_credit.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_10/article.rb +265 -0
- data/lib/shopify_api/rest/resources/2022_10/asset.rb +118 -0
- data/lib/shopify_api/rest/resources/2022_10/assigned_fulfillment_order.rb +79 -0
- data/lib/shopify_api/rest/resources/2022_10/balance.rb +50 -0
- data/lib/shopify_api/rest/resources/2022_10/blog.rb +162 -0
- data/lib/shopify_api/rest/resources/2022_10/cancellation_request.rb +83 -0
- data/lib/shopify_api/rest/resources/2022_10/carrier_service.rb +113 -0
- data/lib/shopify_api/rest/resources/2022_10/checkout.rb +209 -0
- data/lib/shopify_api/rest/resources/2022_10/collect.rb +142 -0
- data/lib/shopify_api/rest/resources/2022_10/collection.rb +110 -0
- data/lib/shopify_api/rest/resources/2022_10/collection_listing.rb +155 -0
- data/lib/shopify_api/rest/resources/2022_10/comment.rb +283 -0
- data/lib/shopify_api/rest/resources/2022_10/country.rb +137 -0
- data/lib/shopify_api/rest/resources/2022_10/currency.rb +57 -0
- data/lib/shopify_api/rest/resources/2022_10/custom_collection.rb +187 -0
- data/lib/shopify_api/rest/resources/2022_10/customer.rb +321 -0
- data/lib/shopify_api/rest/resources/2022_10/customer_address.rb +201 -0
- data/lib/shopify_api/rest/resources/2022_10/customer_saved_search.rb +169 -0
- data/lib/shopify_api/rest/resources/2022_10/deprecated_api_call.rb +57 -0
- data/lib/shopify_api/rest/resources/2022_10/discount_code.rb +219 -0
- data/lib/shopify_api/rest/resources/2022_10/dispute.rb +111 -0
- data/lib/shopify_api/rest/resources/2022_10/dispute_evidence.rb +117 -0
- data/lib/shopify_api/rest/resources/2022_10/dispute_file_upload.rb +81 -0
- data/lib/shopify_api/rest/resources/2022_10/draft_order.rb +275 -0
- data/lib/shopify_api/rest/resources/2022_10/event.rb +148 -0
- data/lib/shopify_api/rest/resources/2022_10/fulfillment.rb +221 -0
- data/lib/shopify_api/rest/resources/2022_10/fulfillment_event.rb +166 -0
- data/lib/shopify_api/rest/resources/2022_10/fulfillment_order.rb +310 -0
- data/lib/shopify_api/rest/resources/2022_10/fulfillment_request.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_10/fulfillment_service.rb +130 -0
- data/lib/shopify_api/rest/resources/2022_10/gift_card.rb +215 -0
- data/lib/shopify_api/rest/resources/2022_10/gift_card_adjustment.rb +118 -0
- data/lib/shopify_api/rest/resources/2022_10/image.rb +157 -0
- data/lib/shopify_api/rest/resources/2022_10/inventory_item.rb +108 -0
- data/lib/shopify_api/rest/resources/2022_10/inventory_level.rb +179 -0
- data/lib/shopify_api/rest/resources/2022_10/location.rb +167 -0
- data/lib/shopify_api/rest/resources/2022_10/locations_for_move.rb +56 -0
- data/lib/shopify_api/rest/resources/2022_10/marketing_event.rb +209 -0
- data/lib/shopify_api/rest/resources/2022_10/metafield.rb +342 -0
- data/lib/shopify_api/rest/resources/2022_10/mobile_platform_application.rb +110 -0
- data/lib/shopify_api/rest/resources/2022_10/order.rb +476 -0
- data/lib/shopify_api/rest/resources/2022_10/order_risk.rb +135 -0
- data/lib/shopify_api/rest/resources/2022_10/page.rb +194 -0
- data/lib/shopify_api/rest/resources/2022_10/payment.rb +140 -0
- data/lib/shopify_api/rest/resources/2022_10/payment_gateway.rb +143 -0
- data/lib/shopify_api/rest/resources/2022_10/payment_transaction.rb +107 -0
- data/lib/shopify_api/rest/resources/2022_10/payout.rb +97 -0
- data/lib/shopify_api/rest/resources/2022_10/policy.rb +69 -0
- data/lib/shopify_api/rest/resources/2022_10/price_rule.rb +223 -0
- data/lib/shopify_api/rest/resources/2022_10/product.rb +223 -0
- data/lib/shopify_api/rest/resources/2022_10/product_listing.rb +196 -0
- data/lib/shopify_api/rest/resources/2022_10/product_resource_feedback.rb +88 -0
- data/lib/shopify_api/rest/resources/2022_10/province.rb +132 -0
- data/lib/shopify_api/rest/resources/2022_10/recurring_application_charge.rb +167 -0
- data/lib/shopify_api/rest/resources/2022_10/redirect.rb +139 -0
- data/lib/shopify_api/rest/resources/2022_10/refund.rb +151 -0
- data/lib/shopify_api/rest/resources/2022_10/report.rb +121 -0
- data/lib/shopify_api/rest/resources/2022_10/resource_feedback.rb +73 -0
- data/lib/shopify_api/rest/resources/2022_10/script_tag.rb +155 -0
- data/lib/shopify_api/rest/resources/2022_10/shipping_zone.rb +83 -0
- data/lib/shopify_api/rest/resources/2022_10/shop.rb +221 -0
- data/lib/shopify_api/rest/resources/2022_10/smart_collection.rb +216 -0
- data/lib/shopify_api/rest/resources/2022_10/storefront_access_token.rb +87 -0
- data/lib/shopify_api/rest/resources/2022_10/tender_transaction.rb +93 -0
- data/lib/shopify_api/rest/resources/2022_10/theme.rb +120 -0
- data/lib/shopify_api/rest/resources/2022_10/transaction.rb +181 -0
- data/lib/shopify_api/rest/resources/2022_10/usage_charge.rb +97 -0
- data/lib/shopify_api/rest/resources/2022_10/user.rb +138 -0
- data/lib/shopify_api/rest/resources/2022_10/variant.rb +212 -0
- data/lib/shopify_api/rest/resources/2022_10/webhook.rb +168 -0
- data/lib/shopify_api/utils/graphql_proxy.rb +52 -0
- data/lib/shopify_api/utils/hmac_validator.rb +44 -0
- data/lib/shopify_api/utils/http_utils.rb +17 -0
- data/lib/shopify_api/utils/session_utils.rb +152 -0
- data/lib/shopify_api/utils/verifiable_query.rb +18 -0
- data/lib/shopify_api/version.rb +6 -0
- data/lib/shopify_api/webhooks/handler.rb +15 -0
- data/lib/shopify_api/webhooks/register_result.rb +14 -0
- data/lib/shopify_api/webhooks/registration.rb +73 -0
- data/lib/shopify_api/webhooks/registrations/event_bridge.rb +61 -0
- data/lib/shopify_api/webhooks/registrations/http.rb +72 -0
- data/lib/shopify_api/webhooks/registrations/pub_sub.rb +65 -0
- data/lib/shopify_api/webhooks/registry.rb +215 -0
- data/lib/shopify_api/webhooks/request.rb +56 -0
- data/lib/shopify_api.rb +23 -472
- data/service.yml +1 -0
- data/shipit.rubygems.yml +1 -0
- data/shopify_api.gemspec +43 -102
- data/sorbet/config +3 -0
- data/sorbet/rbi/gems/activesupport@7.0.1.rbi +654 -0
- data/sorbet/rbi/gems/addressable@2.8.0.rbi +290 -0
- data/sorbet/rbi/gems/ast@2.4.2.rbi +54 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
- data/sorbet/rbi/gems/concurrent-ruby@1.1.9.rbi +2401 -0
- data/sorbet/rbi/gems/crack@0.4.5.rbi +57 -0
- data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +185 -0
- data/sorbet/rbi/gems/fakefs@1.4.1.rbi +571 -0
- data/sorbet/rbi/gems/hash_diff@1.0.0.rbi +47 -0
- data/sorbet/rbi/gems/hashdiff@1.0.1.rbi +82 -0
- data/sorbet/rbi/gems/httparty@0.20.0.rbi +573 -0
- data/sorbet/rbi/gems/i18n@1.8.11.rbi +25 -0
- data/sorbet/rbi/gems/jwt@2.3.0.rbi +437 -0
- data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
- data/sorbet/rbi/gems/mime-types-data@3.2022.0105.rbi +73 -0
- data/sorbet/rbi/gems/mime-types@3.4.1.rbi +295 -0
- data/sorbet/rbi/gems/minitest@5.15.0.rbi +541 -0
- data/sorbet/rbi/gems/mocha@1.13.0.rbi +986 -0
- data/sorbet/rbi/gems/multi_xml@0.6.0.rbi +36 -0
- data/sorbet/rbi/gems/oj@3.13.11.rbi +274 -0
- data/sorbet/rbi/gems/openssl@3.0.0.rbi +581 -0
- data/sorbet/rbi/gems/parallel@1.21.0.rbi +113 -0
- data/sorbet/rbi/gems/parser@3.1.0.0.rbi +1741 -0
- data/sorbet/rbi/gems/pry@0.14.1.rbi +8 -0
- data/sorbet/rbi/gems/public_suffix@4.0.6.rbi +145 -0
- data/sorbet/rbi/gems/rainbow@3.1.1.rbi +157 -0
- data/sorbet/rbi/gems/rake@13.0.6.rbi +814 -0
- data/sorbet/rbi/gems/rbi@0.0.11.rbi +1646 -0
- data/sorbet/rbi/gems/regexp_parser@2.2.0.rbi +1130 -0
- data/sorbet/rbi/gems/rexml@3.2.5.rbi +709 -0
- data/sorbet/rbi/gems/rubocop-ast@1.15.1.rbi +1921 -0
- data/sorbet/rbi/gems/rubocop-shopify@2.4.0.rbi +8 -0
- data/sorbet/rbi/gems/rubocop-sorbet@0.6.5.rbi +295 -0
- data/sorbet/rbi/gems/rubocop@1.25.1.rbi +13507 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +405 -0
- data/sorbet/rbi/gems/securerandom@0.1.1.rbi +10 -0
- data/sorbet/rbi/gems/spoom@1.1.8.rbi +1252 -0
- data/sorbet/rbi/gems/tapioca@0.6.3.rbi +1238 -0
- data/sorbet/rbi/gems/thor@1.2.1.rbi +844 -0
- data/sorbet/rbi/gems/tzinfo@2.0.4.rbi +858 -0
- data/sorbet/rbi/gems/unicode-display_width@2.1.0.rbi +26 -0
- data/sorbet/rbi/gems/unparser@0.6.3.rbi +1816 -0
- data/sorbet/rbi/gems/webmock@3.14.0.rbi +683 -0
- data/sorbet/rbi/gems/webrick@1.7.0.rbi +601 -0
- data/sorbet/rbi/gems/yard-sorbet@0.6.1.rbi +199 -0
- data/sorbet/rbi/gems/yard@0.9.27.rbi +4145 -0
- data/sorbet/rbi/gems/zeitwerk@2.5.4.rbi +200 -0
- data/sorbet/rbi/shims/fakefs.rbi +1 -0
- data/sorbet/rbi/shims/openssl.rb +3 -0
- data/sorbet/rbi/todo.rbi +8 -0
- data/sorbet/tapioca/config.yml +4 -0
- data/sorbet/tapioca/require.rb +20 -0
- metadata +736 -80
- data/.document +0 -5
- data/.gitignore +0 -5
- data/CHANGELOG +0 -5
- data/README.rdoc +0 -55
- data/VERSION +0 -1
- data/test/order_test.rb +0 -48
- data/test/shopify_api_test.rb +0 -21
- data/test/test_helper.rb +0 -28
@@ -0,0 +1,100 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module ShopifyAPI
|
5
|
+
module Clients
|
6
|
+
class HttpClient
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
RETRY_WAIT_TIME = 1
|
10
|
+
|
11
|
+
sig { params(base_path: String, session: T.nilable(Auth::Session)).void }
|
12
|
+
def initialize(base_path:, session: nil)
|
13
|
+
session ||= Context.active_session
|
14
|
+
raise Errors::NoActiveSessionError, "No passed or active session" unless session
|
15
|
+
|
16
|
+
@base_uri = T.let("https://#{session.shop}", String)
|
17
|
+
@base_uri_and_path = T.let("#{@base_uri}#{base_path}", String)
|
18
|
+
|
19
|
+
user_agent_prefix = Context.user_agent_prefix.nil? ? "" : "#{Context.user_agent_prefix} | "
|
20
|
+
|
21
|
+
@headers = T.let({
|
22
|
+
"User-Agent": "#{user_agent_prefix}Shopify API Library v#{VERSION} | Ruby #{RUBY_VERSION}",
|
23
|
+
"Accept": "application/json",
|
24
|
+
}, T::Hash[T.any(Symbol, String), T.untyped])
|
25
|
+
|
26
|
+
unless session.access_token.nil? || T.must(session.access_token).empty?
|
27
|
+
@headers["X-Shopify-Access-Token"] = T.cast(session.access_token, String)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
sig { params(request: HttpRequest).returns(HttpResponse) }
|
32
|
+
def request(request)
|
33
|
+
request.verify
|
34
|
+
|
35
|
+
headers = @headers
|
36
|
+
headers["Content-Type"] = T.must(request.body_type) if request.body_type
|
37
|
+
headers = headers.merge(T.must(request.extra_headers)) if request.extra_headers
|
38
|
+
|
39
|
+
tries = 0
|
40
|
+
response = HttpResponse.new(code: 0, headers: {}, body: "")
|
41
|
+
while tries < request.tries
|
42
|
+
tries += 1
|
43
|
+
res = T.cast(HTTParty.send(
|
44
|
+
request.http_method,
|
45
|
+
request_url(request),
|
46
|
+
headers: headers,
|
47
|
+
query: request.query,
|
48
|
+
body: request.body.class == Hash ? T.unsafe(request.body).to_json : request.body,
|
49
|
+
), HTTParty::Response)
|
50
|
+
|
51
|
+
body = res.body.empty? ? {} : JSON.parse(res.body)
|
52
|
+
response = HttpResponse.new(code: res.code.to_i, headers: res.headers.to_h, body: body)
|
53
|
+
|
54
|
+
if response.headers["x-shopify-api-deprecated-reason"]
|
55
|
+
reason = T.must(response.headers["x-shopify-api-deprecated-reason"])[0]
|
56
|
+
Context.logger.warn("Deprecated request to Shopify API at #{request.path}, received reason: #{reason}")
|
57
|
+
end
|
58
|
+
|
59
|
+
break if response.ok?
|
60
|
+
|
61
|
+
error_messages = []
|
62
|
+
error_messages << response.body["errors"] if response.body["errors"]
|
63
|
+
|
64
|
+
if response.headers["x-request-id"]
|
65
|
+
id = T.must(response.headers["x-request-id"])[0]
|
66
|
+
error_messages << "If you report this error, please include this id: #{id}."
|
67
|
+
end
|
68
|
+
|
69
|
+
error_message = error_messages.join("\n")
|
70
|
+
|
71
|
+
unless [429, 500].include?(response.code)
|
72
|
+
raise ShopifyAPI::Errors::HttpResponseError.new(response: response), error_message
|
73
|
+
end
|
74
|
+
|
75
|
+
if tries == request.tries
|
76
|
+
raise ShopifyAPI::Errors::HttpResponseError.new(response: response), error_message if request.tries == 1
|
77
|
+
|
78
|
+
raise ShopifyAPI::Errors::MaxHttpRetriesExceededError.new(response: response),
|
79
|
+
"Exceeded maximum retry count of #{request.tries}. Last message: #{error_message}"
|
80
|
+
end
|
81
|
+
|
82
|
+
if response.code == 500 || response.headers["retry-after"].nil?
|
83
|
+
sleep(RETRY_WAIT_TIME)
|
84
|
+
else
|
85
|
+
sleep(T.must(response.headers["retry-after"])[0].to_i)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
response
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
|
94
|
+
sig { params(request: HttpRequest).returns(String) }
|
95
|
+
def request_url(request)
|
96
|
+
"#{@base_uri_and_path}/#{request.path}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module ShopifyAPI
|
5
|
+
module Clients
|
6
|
+
class HttpRequest < T::Struct
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
prop :http_method, Symbol
|
10
|
+
prop :path, String
|
11
|
+
prop :body, T.nilable(T.any(T::Hash[T.any(Symbol, String), T.untyped], String))
|
12
|
+
prop :body_type, T.nilable(String)
|
13
|
+
prop :query, T.nilable(T::Hash[T.any(Symbol, String), T.untyped])
|
14
|
+
prop :extra_headers, T.nilable(T::Hash[T.any(Symbol, String), T.untyped])
|
15
|
+
prop :tries, Integer, default: 1
|
16
|
+
|
17
|
+
sig { void }
|
18
|
+
def verify
|
19
|
+
unless [:get, :delete, :put, :post].include?(http_method)
|
20
|
+
raise ShopifyAPI::Errors::InvalidHttpRequestError, "Invalid Http method #{http_method}."
|
21
|
+
end
|
22
|
+
|
23
|
+
if body && !body_type
|
24
|
+
raise ShopifyAPI::Errors::InvalidHttpRequestError, "Cannot set a body without also setting body_type."
|
25
|
+
end
|
26
|
+
|
27
|
+
return unless [:put, :post].include?(http_method)
|
28
|
+
|
29
|
+
unless body
|
30
|
+
raise ShopifyAPI::Errors::InvalidHttpRequestError, "Cannot use #{http_method} without specifying data."
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module ShopifyAPI
|
5
|
+
module Clients
|
6
|
+
class HttpResponse
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { returns(Integer) }
|
10
|
+
attr_reader :code
|
11
|
+
|
12
|
+
sig { returns(T::Hash[String, T::Array[String]]) }
|
13
|
+
attr_reader :headers
|
14
|
+
|
15
|
+
sig { returns(T.any(T::Hash[String, T.untyped], String)) }
|
16
|
+
attr_reader :body
|
17
|
+
|
18
|
+
sig { returns(T.nilable(String)) }
|
19
|
+
attr_reader :prev_page_info, :next_page_info
|
20
|
+
|
21
|
+
sig do
|
22
|
+
params(
|
23
|
+
code: Integer,
|
24
|
+
headers: T::Hash[String, T::Array[String]],
|
25
|
+
body: T.any(T::Hash[String, T.untyped], String),
|
26
|
+
).void
|
27
|
+
end
|
28
|
+
def initialize(code:, headers:, body:)
|
29
|
+
@code = code
|
30
|
+
@headers = headers
|
31
|
+
@body = body
|
32
|
+
|
33
|
+
@prev_page_info = T.let(nil, T.nilable(String))
|
34
|
+
@next_page_info = T.let(nil, T.nilable(String))
|
35
|
+
@prev_page_info, @next_page_info = parse_link_header
|
36
|
+
end
|
37
|
+
|
38
|
+
sig { returns(T::Boolean) }
|
39
|
+
def ok?
|
40
|
+
code >= 200 && code <= 299
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
sig { returns(T::Array[T.nilable(String)]) }
|
46
|
+
def parse_link_header
|
47
|
+
return [nil, nil] if @headers["link"].nil?
|
48
|
+
|
49
|
+
page_info = {}
|
50
|
+
T.must(T.must(@headers["link"])[0]).split(",").each do |link|
|
51
|
+
rel = T.must(link.match(/rel="(.*?)"/))[1]
|
52
|
+
url = T.must(T.must(link.match(/<(.*?)>/))[1])
|
53
|
+
|
54
|
+
T.must(URI.parse(url).query).split("&").each do |param|
|
55
|
+
if param.split("=")[0] == "page_info"
|
56
|
+
page_info[rel] = param.split("=")[1]
|
57
|
+
break
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
[page_info["previous"], page_info["next"]]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module ShopifyAPI
|
5
|
+
module Clients
|
6
|
+
module Rest
|
7
|
+
class Admin < HttpClient
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
sig { params(session: T.nilable(Auth::Session)).void }
|
11
|
+
def initialize(session: nil)
|
12
|
+
super(session: session, base_path: "/admin/api/#{Context.api_version}")
|
13
|
+
end
|
14
|
+
|
15
|
+
sig do
|
16
|
+
params(
|
17
|
+
path: String,
|
18
|
+
body: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
19
|
+
query: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
20
|
+
headers: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
21
|
+
tries: T.nilable(Integer),
|
22
|
+
).returns(HttpResponse)
|
23
|
+
end
|
24
|
+
def get(path:, body: nil, query: nil, headers: nil, tries: 1)
|
25
|
+
request(
|
26
|
+
make_request(http_method: :get, path: path, body: body, query: query, headers: headers,
|
27
|
+
tries: T.must(tries)),
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
sig do
|
32
|
+
params(
|
33
|
+
path: String,
|
34
|
+
body: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
35
|
+
query: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
36
|
+
headers: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
37
|
+
tries: T.nilable(Integer),
|
38
|
+
).returns(HttpResponse)
|
39
|
+
end
|
40
|
+
def delete(path:, body: nil, query: nil, headers: nil, tries: 1)
|
41
|
+
request(
|
42
|
+
make_request(http_method: :delete, path: path, body: body, query: query, headers: headers,
|
43
|
+
tries: T.must(tries)),
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
sig do
|
48
|
+
params(
|
49
|
+
path: String,
|
50
|
+
body: T::Hash[T.any(Symbol, String), T.untyped],
|
51
|
+
query: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
52
|
+
headers: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
53
|
+
tries: T.nilable(Integer),
|
54
|
+
).returns(HttpResponse)
|
55
|
+
end
|
56
|
+
def put(path:, body:, query: nil, headers: nil, tries: 1)
|
57
|
+
request(
|
58
|
+
make_request(http_method: :put, path: path, body: body, query: query, headers: headers,
|
59
|
+
tries: T.must(tries)),
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
sig do
|
64
|
+
params(
|
65
|
+
path: String,
|
66
|
+
body: T::Hash[T.any(Symbol, String), T.untyped],
|
67
|
+
query: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
68
|
+
headers: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
69
|
+
tries: T.nilable(Integer),
|
70
|
+
).returns(HttpResponse)
|
71
|
+
end
|
72
|
+
def post(path:, body:, query: nil, headers: nil, tries: 1)
|
73
|
+
request(
|
74
|
+
make_request(http_method: :post, path: path, body: body, query: query, headers: headers,
|
75
|
+
tries: T.must(tries)),
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
sig { params(request: HttpRequest).returns(String) }
|
82
|
+
def request_url(request)
|
83
|
+
request_path = request.path.sub(%r/\A\//, "").sub(/\.json\z/, "") + ".json"
|
84
|
+
|
85
|
+
if request_path.start_with?("admin/")
|
86
|
+
"#{@base_uri}/#{request_path}"
|
87
|
+
else
|
88
|
+
"#{@base_uri_and_path}/#{request_path}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
sig do
|
95
|
+
params(
|
96
|
+
http_method: Symbol,
|
97
|
+
path: String,
|
98
|
+
body: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
99
|
+
query: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
100
|
+
headers: T.nilable(T::Hash[T.any(Symbol, String), T.untyped]),
|
101
|
+
tries: Integer,
|
102
|
+
).returns(HttpRequest)
|
103
|
+
end
|
104
|
+
def make_request(http_method:, path:, body:, query:, headers:, tries:)
|
105
|
+
HttpRequest.new(
|
106
|
+
http_method: http_method,
|
107
|
+
path: path,
|
108
|
+
body: body,
|
109
|
+
query: query,
|
110
|
+
extra_headers: headers,
|
111
|
+
body_type: body.nil? ? nil : "application/json",
|
112
|
+
tries: tries,
|
113
|
+
)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module ShopifyAPI
|
5
|
+
class Context
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
@api_key = T.let("", String)
|
9
|
+
@api_secret_key = T.let("", String)
|
10
|
+
@api_version = T.let(LATEST_SUPPORTED_ADMIN_VERSION, String)
|
11
|
+
@scope = T.let(Auth::AuthScopes.new, Auth::AuthScopes)
|
12
|
+
@is_private = T.let(false, T::Boolean)
|
13
|
+
@private_shop = T.let(nil, T.nilable(String))
|
14
|
+
@is_embedded = T.let(true, T::Boolean)
|
15
|
+
@logger = T.let(::Logger.new($stdout), ::Logger)
|
16
|
+
@log_level = T.let(:info, Symbol)
|
17
|
+
@notified_missing_resources_folder = T.let({}, T::Hash[String, T::Boolean])
|
18
|
+
@active_session = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
|
19
|
+
@session_storage = T.let(nil, T.nilable(ShopifyAPI::Auth::SessionStorage))
|
20
|
+
@user_agent_prefix = T.let(nil, T.nilable(String))
|
21
|
+
@old_api_secret_key = T.let(nil, T.nilable(String))
|
22
|
+
|
23
|
+
@rest_resource_loader = T.let(nil, T.nilable(Zeitwerk::Loader))
|
24
|
+
|
25
|
+
class << self
|
26
|
+
extend T::Sig
|
27
|
+
|
28
|
+
sig do
|
29
|
+
params(
|
30
|
+
api_key: String,
|
31
|
+
api_secret_key: String,
|
32
|
+
api_version: String,
|
33
|
+
scope: T.any(T::Array[String], String),
|
34
|
+
is_private: T::Boolean,
|
35
|
+
is_embedded: T::Boolean,
|
36
|
+
log_level: T.any(String, Symbol),
|
37
|
+
logger: ::Logger,
|
38
|
+
session_storage: T.nilable(ShopifyAPI::Auth::SessionStorage),
|
39
|
+
host_name: T.nilable(String),
|
40
|
+
host: T.nilable(String),
|
41
|
+
private_shop: T.nilable(String),
|
42
|
+
user_agent_prefix: T.nilable(String),
|
43
|
+
old_api_secret_key: T.nilable(String),
|
44
|
+
).void
|
45
|
+
end
|
46
|
+
def setup(
|
47
|
+
api_key:,
|
48
|
+
api_secret_key:,
|
49
|
+
api_version:,
|
50
|
+
scope:,
|
51
|
+
is_private:,
|
52
|
+
is_embedded:,
|
53
|
+
log_level: :info,
|
54
|
+
logger: ::Logger.new($stdout),
|
55
|
+
session_storage: nil,
|
56
|
+
host_name: nil,
|
57
|
+
host: ENV["HOST"] || "https://#{host_name}",
|
58
|
+
private_shop: nil,
|
59
|
+
user_agent_prefix: nil,
|
60
|
+
old_api_secret_key: nil
|
61
|
+
)
|
62
|
+
unless ShopifyAPI::AdminVersions::SUPPORTED_ADMIN_VERSIONS.include?(api_version)
|
63
|
+
raise Errors::UnsupportedVersionError,
|
64
|
+
"Invalid version #{api_version}, supported versions: #{ShopifyAPI::AdminVersions::SUPPORTED_ADMIN_VERSIONS}"
|
65
|
+
end
|
66
|
+
|
67
|
+
@api_key = api_key
|
68
|
+
@api_secret_key = api_secret_key
|
69
|
+
@api_version = api_version
|
70
|
+
@host = T.let(host, T.nilable(String))
|
71
|
+
@is_private = is_private
|
72
|
+
@scope = Auth::AuthScopes.new(scope)
|
73
|
+
@is_embedded = is_embedded
|
74
|
+
@session_storage = session_storage
|
75
|
+
@logger = logger
|
76
|
+
@private_shop = private_shop
|
77
|
+
@user_agent_prefix = user_agent_prefix
|
78
|
+
@old_api_secret_key = old_api_secret_key
|
79
|
+
@log_level = if valid_log_level?(log_level)
|
80
|
+
log_level.to_sym
|
81
|
+
else
|
82
|
+
:info
|
83
|
+
end
|
84
|
+
|
85
|
+
if @session_storage
|
86
|
+
::ShopifyAPI::Logger.deprecated("The use of SessionStorage in the API library has been deprecated. " \
|
87
|
+
"The ShopifyAPI will no longer have responsibility for session persistence. " \
|
88
|
+
"Upgrading to `shopify_app` 21.3 will allow you to remove session_storage" \
|
89
|
+
" from the API library Context configuration.", "13.0.0")
|
90
|
+
end
|
91
|
+
|
92
|
+
load_rest_resources(api_version: api_version)
|
93
|
+
end
|
94
|
+
|
95
|
+
sig { params(api_version: String).void }
|
96
|
+
def load_rest_resources(api_version:)
|
97
|
+
# Unload any previous instances - mostly useful for tests where we need to reset the version
|
98
|
+
@rest_resource_loader&.unload
|
99
|
+
|
100
|
+
# No resources for the unstable version
|
101
|
+
return if api_version == "unstable"
|
102
|
+
|
103
|
+
version_folder_name = api_version.gsub("-", "_")
|
104
|
+
path = "#{__dir__}/rest/resources/#{version_folder_name}"
|
105
|
+
|
106
|
+
unless Dir.exist?(path)
|
107
|
+
unless @notified_missing_resources_folder.key?(api_version)
|
108
|
+
@logger.warn("Cannot autoload REST resources for API version '#{version_folder_name}', folder is missing")
|
109
|
+
@notified_missing_resources_folder[api_version] = true
|
110
|
+
end
|
111
|
+
|
112
|
+
return
|
113
|
+
end
|
114
|
+
|
115
|
+
@rest_resource_loader = T.let(Zeitwerk::Loader.new, T.nilable(Zeitwerk::Loader))
|
116
|
+
T.must(@rest_resource_loader).enable_reloading
|
117
|
+
T.must(@rest_resource_loader).ignore("#{__dir__}/rest/resources")
|
118
|
+
T.must(@rest_resource_loader).setup
|
119
|
+
T.must(@rest_resource_loader).push_dir(path, namespace: ShopifyAPI)
|
120
|
+
T.must(@rest_resource_loader).reload
|
121
|
+
end
|
122
|
+
|
123
|
+
sig { returns(String) }
|
124
|
+
attr_reader :api_key, :api_secret_key, :api_version
|
125
|
+
|
126
|
+
sig { returns(Auth::AuthScopes) }
|
127
|
+
attr_reader :scope
|
128
|
+
|
129
|
+
sig { returns(T.nilable(ShopifyAPI::Auth::SessionStorage)) }
|
130
|
+
attr_reader :session_storage
|
131
|
+
|
132
|
+
sig { returns(::Logger) }
|
133
|
+
attr_reader :logger
|
134
|
+
|
135
|
+
sig { returns(Symbol) }
|
136
|
+
attr_reader :log_level
|
137
|
+
|
138
|
+
sig { returns(T::Boolean) }
|
139
|
+
def private?
|
140
|
+
@is_private
|
141
|
+
end
|
142
|
+
|
143
|
+
sig { returns(T.nilable(String)) }
|
144
|
+
attr_reader :private_shop, :user_agent_prefix, :old_api_secret_key, :host
|
145
|
+
|
146
|
+
sig { returns(T::Boolean) }
|
147
|
+
def embedded?
|
148
|
+
@is_embedded
|
149
|
+
end
|
150
|
+
|
151
|
+
sig { returns(T::Boolean) }
|
152
|
+
def setup?
|
153
|
+
[api_key, api_secret_key, T.must(host)].none?(&:empty?)
|
154
|
+
end
|
155
|
+
|
156
|
+
sig { returns(T.nilable(Auth::Session)) }
|
157
|
+
def active_session
|
158
|
+
return @active_session.value unless @active_session.value.nil?
|
159
|
+
|
160
|
+
private? ? Utils::SessionUtils.load_current_session : nil
|
161
|
+
end
|
162
|
+
|
163
|
+
sig { params(session: T.nilable(Auth::Session)).void }
|
164
|
+
def activate_session(session)
|
165
|
+
@active_session.value = session
|
166
|
+
end
|
167
|
+
|
168
|
+
sig { void }
|
169
|
+
def deactivate_session
|
170
|
+
@active_session.value = nil
|
171
|
+
end
|
172
|
+
|
173
|
+
sig { returns(String) }
|
174
|
+
def host_scheme
|
175
|
+
T.must(URI.parse(T.must(host)).scheme)
|
176
|
+
end
|
177
|
+
|
178
|
+
sig { returns(String) }
|
179
|
+
def host_name
|
180
|
+
T.must(URI(T.must(host)).host)
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
sig { params(log_level: T.any(Symbol, String)).returns(T::Boolean) }
|
186
|
+
def valid_log_level?(log_level)
|
187
|
+
return true if ::ShopifyAPI::Logger.levels.include?(log_level.to_sym)
|
188
|
+
|
189
|
+
ShopifyAPI::Logger.warn("#{log_level} is not a valid log_level. "\
|
190
|
+
"Valid options are #{::ShopifyAPI::Logger.levels.join(", ")}")
|
191
|
+
|
192
|
+
false
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module ShopifyAPI
|
5
|
+
module Errors
|
6
|
+
class HttpResponseError < StandardError
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { returns(Integer) }
|
10
|
+
attr_reader :code
|
11
|
+
|
12
|
+
sig { returns(ShopifyAPI::Clients::HttpResponse) }
|
13
|
+
attr_reader :response
|
14
|
+
|
15
|
+
sig { params(response: ShopifyAPI::Clients::HttpResponse).void }
|
16
|
+
def initialize(response:)
|
17
|
+
super
|
18
|
+
@code = T.let(response.code, Integer)
|
19
|
+
@response = response
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|