shopify_api 4.13.0 → 12.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- 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 +56 -5
- data/BREAKING_CHANGES_FOR_OLDER_VERSIONS.md +110 -0
- data/CHANGELOG.md +568 -0
- data/CONTRIBUTING.md +4 -3
- data/Gemfile +9 -2
- data/Gemfile.lock +159 -0
- data/LICENSE +2 -2
- data/README.md +86 -218
- data/RELEASING.md +19 -0
- data/Rakefile +16 -32
- 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 +105 -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 +138 -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 +166 -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/http_response_error.rb +19 -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/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/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 +135 -0
- data/lib/shopify_api/utils/verifiable_query.rb +18 -0
- data/lib/shopify_api/version.rb +4 -1
- 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 +19 -26
- data/service.yml +1 -0
- data/shipit.rubygems.yml +1 -1
- data/shopify_api.gemspec +36 -19
- 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 +603 -280
- data/.document +0 -5
- data/.gitignore +0 -10
- data/.travis.yml +0 -32
- data/CHANGELOG +0 -310
- data/CONTRIBUTORS +0 -3
- data/Gemfile_ar30 +0 -6
- data/Gemfile_ar31 +0 -6
- data/Gemfile_ar32 +0 -6
- data/Gemfile_ar40 +0 -6
- data/Gemfile_ar_master +0 -6
- data/RELEASING +0 -16
- data/bin/shopify +0 -3
- data/lib/active_resource/base_ext.rb +0 -21
- data/lib/active_resource/connection_ext.rb +0 -10
- data/lib/active_resource/detailed_log_subscriber.rb +0 -19
- data/lib/active_resource/disable_prefix_check.rb +0 -36
- data/lib/active_resource/json_errors.rb +0 -31
- data/lib/active_resource/to_query.rb +0 -10
- data/lib/shopify_api/connection.rb +0 -33
- data/lib/shopify_api/countable.rb +0 -14
- data/lib/shopify_api/events.rb +0 -7
- data/lib/shopify_api/json_format.rb +0 -18
- data/lib/shopify_api/limits.rb +0 -76
- data/lib/shopify_api/metafields.rb +0 -20
- data/lib/shopify_api/resources/access_scope.rb +0 -5
- data/lib/shopify_api/resources/access_token.rb +0 -8
- data/lib/shopify_api/resources/address.rb +0 -4
- data/lib/shopify_api/resources/announcement.rb +0 -4
- data/lib/shopify_api/resources/api_permission.rb +0 -9
- data/lib/shopify_api/resources/application_charge.rb +0 -15
- data/lib/shopify_api/resources/application_credit.rb +0 -4
- data/lib/shopify_api/resources/article.rb +0 -21
- data/lib/shopify_api/resources/asset.rb +0 -96
- data/lib/shopify_api/resources/base.rb +0 -89
- data/lib/shopify_api/resources/billing_address.rb +0 -4
- data/lib/shopify_api/resources/blog.rb +0 -10
- data/lib/shopify_api/resources/carrier_service.rb +0 -4
- data/lib/shopify_api/resources/cart.rb +0 -4
- data/lib/shopify_api/resources/checkout.rb +0 -4
- data/lib/shopify_api/resources/collect.rb +0 -5
- data/lib/shopify_api/resources/collection_listing.rb +0 -9
- data/lib/shopify_api/resources/comment.rb +0 -9
- data/lib/shopify_api/resources/country.rb +0 -4
- data/lib/shopify_api/resources/custom_collection.rb +0 -19
- data/lib/shopify_api/resources/customer.rb +0 -29
- data/lib/shopify_api/resources/customer_group.rb +0 -5
- data/lib/shopify_api/resources/customer_invite.rb +0 -4
- data/lib/shopify_api/resources/customer_saved_search.rb +0 -9
- data/lib/shopify_api/resources/discount_code.rb +0 -9
- data/lib/shopify_api/resources/draft_order.rb +0 -14
- data/lib/shopify_api/resources/draft_order_invoice.rb +0 -4
- data/lib/shopify_api/resources/event.rb +0 -7
- data/lib/shopify_api/resources/fulfillment.rb +0 -13
- data/lib/shopify_api/resources/fulfillment_event.rb +0 -15
- data/lib/shopify_api/resources/fulfillment_request.rb +0 -15
- data/lib/shopify_api/resources/fulfillment_service.rb +0 -4
- data/lib/shopify_api/resources/gift_card.rb +0 -7
- data/lib/shopify_api/resources/graphql.rb +0 -22
- data/lib/shopify_api/resources/image.rb +0 -16
- data/lib/shopify_api/resources/inventory_item.rb +0 -6
- data/lib/shopify_api/resources/inventory_level.rb +0 -55
- data/lib/shopify_api/resources/line_item.rb +0 -14
- data/lib/shopify_api/resources/location.rb +0 -8
- data/lib/shopify_api/resources/marketing_event.rb +0 -8
- data/lib/shopify_api/resources/metafield.rb +0 -12
- data/lib/shopify_api/resources/note_attribute.rb +0 -4
- data/lib/shopify_api/resources/o_auth.rb +0 -17
- data/lib/shopify_api/resources/option.rb +0 -4
- data/lib/shopify_api/resources/order.rb +0 -29
- data/lib/shopify_api/resources/order_risk.rb +0 -8
- data/lib/shopify_api/resources/page.rb +0 -6
- data/lib/shopify_api/resources/payment_details.rb +0 -4
- data/lib/shopify_api/resources/ping/conversation.rb +0 -18
- data/lib/shopify_api/resources/ping/message.rb +0 -9
- data/lib/shopify_api/resources/ping.rb +0 -3
- data/lib/shopify_api/resources/policy.rb +0 -7
- data/lib/shopify_api/resources/price_rule.rb +0 -8
- data/lib/shopify_api/resources/product.rb +0 -33
- data/lib/shopify_api/resources/product_listing.rb +0 -9
- data/lib/shopify_api/resources/province.rb +0 -5
- data/lib/shopify_api/resources/receipt.rb +0 -4
- data/lib/shopify_api/resources/recurring_application_charge.rb +0 -31
- data/lib/shopify_api/resources/redirect.rb +0 -4
- data/lib/shopify_api/resources/refund.rb +0 -13
- data/lib/shopify_api/resources/report.rb +0 -4
- data/lib/shopify_api/resources/resource_feedback.rb +0 -19
- data/lib/shopify_api/resources/rule.rb +0 -4
- data/lib/shopify_api/resources/script_tag.rb +0 -4
- data/lib/shopify_api/resources/shipping_address.rb +0 -4
- data/lib/shopify_api/resources/shipping_line.rb +0 -4
- data/lib/shopify_api/resources/shipping_zone.rb +0 -4
- data/lib/shopify_api/resources/shop.rb +0 -23
- data/lib/shopify_api/resources/smart_collection.rb +0 -15
- data/lib/shopify_api/resources/storefront_access_token.rb +0 -4
- data/lib/shopify_api/resources/tax_line.rb +0 -4
- data/lib/shopify_api/resources/tax_service.rb +0 -4
- data/lib/shopify_api/resources/theme.rb +0 -4
- data/lib/shopify_api/resources/transaction.rb +0 -5
- data/lib/shopify_api/resources/usage_charge.rb +0 -5
- data/lib/shopify_api/resources/user.rb +0 -4
- data/lib/shopify_api/resources/variant.rb +0 -8
- data/lib/shopify_api/resources/webhook.rb +0 -4
- data/lib/shopify_api/resources.rb +0 -2
- data/lib/shopify_api/session.rb +0 -144
- data/test/access_token_test.rb +0 -19
- data/test/active_resource/json_errors_test.rb +0 -19
- data/test/api_permission_test.rb +0 -9
- data/test/application_charge_test.rb +0 -79
- data/test/application_credit_test.rb +0 -35
- data/test/article_test.rb +0 -73
- data/test/asset_test.rb +0 -18
- data/test/base_test.rb +0 -125
- data/test/blog_test.rb +0 -8
- data/test/carrier_service_test.rb +0 -17
- data/test/cart_test.rb +0 -13
- data/test/checkouts_test.rb +0 -9
- data/test/collect_test.rb +0 -9
- data/test/collection_listing_test.rb +0 -41
- data/test/countable_test.rb +0 -13
- data/test/custom_collection_test.rb +0 -9
- data/test/customer_saved_search_test.rb +0 -27
- data/test/customer_test.rb +0 -50
- data/test/detailed_log_subscriber_test.rb +0 -49
- data/test/discount_code_test.rb +0 -53
- data/test/draft_order_test.rb +0 -151
- data/test/fixtures/access_token_delegate.json +0 -4
- data/test/fixtures/application_charge.json +0 -16
- data/test/fixtures/application_charges.json +0 -57
- data/test/fixtures/application_credit.json +0 -12
- data/test/fixtures/application_credits.json +0 -24
- data/test/fixtures/article.json +0 -15
- data/test/fixtures/articles.json +0 -39
- data/test/fixtures/asset.json +0 -9
- data/test/fixtures/assets.json +0 -136
- data/test/fixtures/authors.json +0 -1
- data/test/fixtures/blog.json +0 -13
- data/test/fixtures/blogs.json +0 -13
- data/test/fixtures/carrier_service.json +0 -9
- data/test/fixtures/carts.json +0 -43
- data/test/fixtures/checkouts.json +0 -186
- data/test/fixtures/collect.json +0 -12
- data/test/fixtures/collection_listing.json +0 -11
- data/test/fixtures/collection_listing_product_ids.json +0 -1
- data/test/fixtures/collection_listings.json +0 -13
- data/test/fixtures/custom_collection.json +0 -17
- data/test/fixtures/customer_invite.json +0 -9
- data/test/fixtures/customer_saved_search.json +0 -9
- data/test/fixtures/customer_saved_search_customers.json +0 -60
- data/test/fixtures/customers.json +0 -59
- data/test/fixtures/customers_account_activation_url.json +0 -3
- data/test/fixtures/customers_search.json +0 -60
- data/test/fixtures/discount_code.json +0 -10
- data/test/fixtures/discount_codes.json +0 -12
- data/test/fixtures/draft_order.json +0 -159
- data/test/fixtures/draft_order_completed.json +0 -159
- data/test/fixtures/draft_order_invoice.json +0 -9
- data/test/fixtures/draft_orders.json +0 -161
- data/test/fixtures/engagement.json +0 -15
- data/test/fixtures/events.json +0 -31
- data/test/fixtures/fulfillment.json +0 -49
- data/test/fixtures/fulfillment_event.json +0 -12
- data/test/fixtures/fulfillment_request.json +0 -28
- data/test/fixtures/fulfillment_service.json +0 -10
- data/test/fixtures/gift_card.json +0 -20
- data/test/fixtures/gift_card_disabled.json +0 -20
- data/test/fixtures/image.json +0 -10
- data/test/fixtures/images.json +0 -20
- data/test/fixtures/inventory_level.json +0 -7
- data/test/fixtures/inventory_levels.json +0 -24
- data/test/fixtures/marketing_event.json +0 -28
- data/test/fixtures/marketing_events.json +0 -54
- data/test/fixtures/metafield.json +0 -12
- data/test/fixtures/metafields.json +0 -34
- data/test/fixtures/o_auth_revoke.json +0 -5
- data/test/fixtures/order.json +0 -297
- data/test/fixtures/order_risk.json +0 -14
- data/test/fixtures/order_risks.json +0 -28
- data/test/fixtures/order_with_properties.json +0 -373
- data/test/fixtures/orders.json +0 -299
- data/test/fixtures/ping/conversation.json +0 -1
- data/test/fixtures/ping/message.json +0 -1
- data/test/fixtures/policies.json +0 -8
- data/test/fixtures/price_rule.json +0 -27
- data/test/fixtures/price_rules.json +0 -28
- data/test/fixtures/product.json +0 -116
- data/test/fixtures/product_listing.json +0 -86
- data/test/fixtures/product_listing_product_ids.json +0 -1
- data/test/fixtures/product_listings.json +0 -174
- data/test/fixtures/recurring_application_charge.json +0 -22
- data/test/fixtures/recurring_application_charge_adjustment.json +0 -5
- data/test/fixtures/recurring_application_charges.json +0 -106
- data/test/fixtures/redirect.json +0 -7
- data/test/fixtures/refund.json +0 -112
- data/test/fixtures/report.json +0 -9
- data/test/fixtures/reports.json +0 -11
- data/test/fixtures/script_tag.json +0 -10
- data/test/fixtures/script_tags.json +0 -18
- data/test/fixtures/shipping_zones.json +0 -315
- data/test/fixtures/shop.json +0 -26
- data/test/fixtures/smart_collection.json +0 -21
- data/test/fixtures/storefront_access_token.json +0 -9
- data/test/fixtures/storefront_access_tokens.json +0 -18
- data/test/fixtures/tags.json +0 -1
- data/test/fixtures/tax_service.json +0 -9
- data/test/fixtures/transaction.json +0 -29
- data/test/fixtures/usage_charge.json +0 -11
- data/test/fixtures/usage_charges.json +0 -23
- data/test/fixtures/user.json +0 -21
- data/test/fixtures/users.json +0 -42
- data/test/fixtures/variant.json +0 -23
- data/test/fixtures/variants.json +0 -88
- data/test/fixtures/webhook.json +0 -10
- data/test/fixtures/webhooks.json +0 -18
- data/test/fulfillment_event_test.rb +0 -69
- data/test/fulfillment_request_test.rb +0 -33
- data/test/fulfillment_service_test.rb +0 -17
- data/test/fulfillment_test.rb +0 -61
- data/test/gift_card_test.rb +0 -22
- data/test/image_test.rb +0 -39
- data/test/inventory_level_test.rb +0 -59
- data/test/limits_test.rb +0 -38
- data/test/location_test.rb +0 -14
- data/test/marketing_event_test.rb +0 -68
- data/test/metafield_test.rb +0 -46
- data/test/o_auth_test.rb +0 -8
- data/test/order_risk_test.rb +0 -46
- data/test/order_test.rb +0 -59
- data/test/ping/conversation_test.rb +0 -39
- data/test/policy_test.rb +0 -19
- data/test/price_rule_test.rb +0 -65
- data/test/product_listing_test.rb +0 -40
- data/test/product_test.rb +0 -50
- data/test/recurring_application_charge_test.rb +0 -149
- data/test/redirect_test.rb +0 -9
- data/test/refund_test.rb +0 -32
- data/test/report_test.rb +0 -35
- data/test/resource_feedback_test.rb +0 -42
- data/test/script_tag_test.rb +0 -30
- data/test/session_test.rb +0 -250
- data/test/shipping_zone_test.rb +0 -10
- data/test/shop_test.rb +0 -68
- data/test/smart_collection_test.rb +0 -10
- data/test/storefront_access_token_test.rb +0 -32
- data/test/tax_service_test.rb +0 -8
- data/test/test_helper.rb +0 -97
- data/test/transaction_test.rb +0 -17
- data/test/usage_charge_test.rb +0 -21
- data/test/user_test.rb +0 -17
- data/test/variant_test.rb +0 -46
- data/test/webhook_test.rb +0 -21
data/SECURITY.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Security Policy
|
2
|
+
|
3
|
+
## Supported versions
|
4
|
+
|
5
|
+
### New features
|
6
|
+
|
7
|
+
New features will only be added to the main branch and will not be made available in point releases.
|
8
|
+
|
9
|
+
### Bug fixes
|
10
|
+
|
11
|
+
Only the latest release series will receive bug fixes. When enough bugs are fixed and its deemed worthy to release a new gem, this is the branch it happens from.
|
12
|
+
|
13
|
+
### Security issues
|
14
|
+
|
15
|
+
Only the latest release series will receive patches and new versions in case of a security issue.
|
16
|
+
|
17
|
+
### Severe security issues
|
18
|
+
|
19
|
+
For severe security issues we will provide new versions as above, and also the last major release series will receive patches and new versions. The classification of the security issue is judged by the core team.
|
20
|
+
|
21
|
+
### Unsupported Release Series
|
22
|
+
|
23
|
+
When a release series is no longer supported, it's your own responsibility to deal with bugs and security issues. If you are not comfortable maintaining your own versions, you should upgrade to a supported version.
|
24
|
+
|
25
|
+
## Reporting a bug
|
26
|
+
|
27
|
+
All security bugs in shopify repositories should be reported to [our hackerone program](https://hackerone.com/shopify)
|
28
|
+
Shopify's whitehat program is our way to reward security researchers for finding serious security vulnerabilities in the In Scope properties listed at the bottom of this page, including our core application (all functionality associated with a Shopify store, particularly your-store.myshopify.com/admin) and certain ancillary applications.
|
29
|
+
|
30
|
+
## Disclosure Policy
|
31
|
+
|
32
|
+
We look forward to working with all security researchers and strive to be respectful, always assume the best and treat others as peers. We expect the same in return from all participants. To achieve this, our team strives to:
|
33
|
+
|
34
|
+
- Reply to all reports within one business day and triage within two business days (if applicable)
|
35
|
+
- Be as transparent as possible, answering all inquires about our report decisions and adding hackers to duplicate HackerOne reports
|
36
|
+
- Award bounties within a week of resolution (excluding extenuating circumstances)
|
37
|
+
- Only close reports as N/A when the issue reported is included in Known Issues, Ineligible Vulnerabilities Types or lacks evidence of a vulnerability
|
38
|
+
|
39
|
+
**The following rules must be followed in order for any rewards to be paid:**
|
40
|
+
|
41
|
+
- You may only test against shops you have created which include your HackerOne YOURHANDLE @ wearehackerone.com registered email address.
|
42
|
+
- You must not attempt to gain access to, or interact with, any shops other than those created by you.
|
43
|
+
- The use of commercial scanners is prohibited (e.g., Nessus).
|
44
|
+
- Rules for reporting must be followed.
|
45
|
+
- Do not disclose any issues publicly before they have been resolved.
|
46
|
+
- Shopify reserves the right to modify the rules for this program or deem any submissions invalid at any time. Shopify may cancel the whitehat program without notice at any time.
|
47
|
+
- Contacting Shopify Support over chat, email or phone about your HackerOne report is not allowed. We may disqualify you from receiving a reward, or from participating in the program altogether.
|
48
|
+
- You are not an employee of Shopify; employees should report bugs to the internal bug bounty program.
|
49
|
+
- You hereby represent, warrant and covenant that any content you submit to Shopify is an original work of authorship and that you are legally entitled to grant the rights and privileges conveyed by these terms. You further represent, warrant and covenant that the consent of no other person or entity is or will be necessary for Shopify to use the submitted content.
|
50
|
+
- By submitting content to Shopify, you irrevocably waive all moral rights which you may have in the content.
|
51
|
+
- All content submitted by you to Shopify under this program is licensed under the MIT License.
|
52
|
+
- You must report any discovered vulnerability to Shopify as soon as you have validated the vulnerability.
|
53
|
+
- Failure to follow any of the foregoing rules will disqualify you from participating in this program.
|
54
|
+
|
55
|
+
** Please see our [Hackerone Profile](https://hackerone.com/shopify) for full details
|
56
|
+
|
57
|
+
## Receiving Security Updates
|
58
|
+
|
59
|
+
To recieve all general updates to vulnerabilities, please subscribe to our hackerone [Hacktivity](https://hackerone.com/shopify/hacktivity)
|
data/bin/tapioca
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'tapioca' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("tapioca", "tapioca")
|
data/dev.yml
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
name: shopify-api
|
2
|
+
|
3
|
+
type: ruby
|
4
|
+
|
5
|
+
up:
|
6
|
+
- ruby: 3.0.3
|
7
|
+
- bundler
|
8
|
+
|
9
|
+
commands:
|
10
|
+
console:
|
11
|
+
desc: 'start a ruby shell with ShopifyAPI already loaded'
|
12
|
+
aliases: ['c']
|
13
|
+
run: bundle exec irb -Ilib -rshopify_api
|
14
|
+
style:
|
15
|
+
desc: 'run rubocop'
|
16
|
+
run: bundle exec rubocop
|
17
|
+
typecheck:
|
18
|
+
desc: 'run Sorbet typechecking'
|
19
|
+
aliases: ['tc']
|
20
|
+
run: bundle exec srb tc
|
21
|
+
test:
|
22
|
+
run: bundle exec rake test
|
23
|
+
sanity:
|
24
|
+
desc: 'run all static checks against the codebase'
|
25
|
+
run: bundle exec rubocop && bundle exec srb tc && bundle exec rake test
|
26
|
+
subcommands:
|
27
|
+
all:
|
28
|
+
desc: 'run all checks regardless of the success states of previous checks'
|
29
|
+
run: bundle exec rubocop; bundle exec srb tc; bundle exec rake test
|
30
|
+
rbi:
|
31
|
+
desc: 'generate .rbi files for specified gem to the project'
|
32
|
+
run: bin/tapioca gem
|
data/docs/README.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
<!-- Make sure this file is in sync with the Getting started section in README -->
|
2
|
+
|
3
|
+
# Getting started
|
4
|
+
|
5
|
+
You can follow our getting started guide to learn how to use this library.
|
6
|
+
|
7
|
+
- [Getting started](getting_started.md)
|
8
|
+
- [Performing OAuth](usage/oauth.md)
|
9
|
+
- [REST Admin API](usage/rest.md)
|
10
|
+
- [Make a GraphQL API call](usage/graphql.md)
|
11
|
+
- [Make a Storefront API call](usage/graphql_storefront.md)
|
12
|
+
- [Webhooks](usage/webhooks.md)
|
13
|
+
- [Known issues and caveats](issues.md)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Getting started
|
2
|
+
|
3
|
+
This page will outline everything you need to know and the steps you need to follow in order to start using the Shopify Ruby API gem in your app.
|
4
|
+
|
5
|
+
## Requirements
|
6
|
+
|
7
|
+
- A working knowledge of ruby and a web framework such as Rails or Sinatra
|
8
|
+
- A private or custom app already set up in your test store or partner account
|
9
|
+
- We recommend `ngrok` to tunnel traffic to your localhost for testing
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add the following to your Gemfile:
|
14
|
+
|
15
|
+
`gem "shopify_api"`
|
16
|
+
|
17
|
+
## Steps to use the Gem
|
18
|
+
|
19
|
+
### Setup Shopify Context
|
20
|
+
|
21
|
+
Start by initializing the `ShopifyAPI::Context` with the parameters of your app by calling `ShopifyAPI::Context.setup` (example below) when your app starts (e.g `application.rb` in a Rails app).
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
ShopifyAPI::Context.setup(
|
25
|
+
api_key: "<api-key>",
|
26
|
+
api_secret_key: "<api-secret-key>",
|
27
|
+
host_name: "<application-host-name>",
|
28
|
+
scope: "read_orders,read_products,etc",
|
29
|
+
session_storage: ShopifyAPI::Auth::FileSessionStorage.new, # This is only to be used for testing, more information in session docs
|
30
|
+
is_embedded: true, # Set to true if you are building an embedded app
|
31
|
+
is_private: false, # Set to true if you are building a private app
|
32
|
+
api_version: "2021-01" # The vesion of the API you would like to use
|
33
|
+
)
|
34
|
+
```
|
35
|
+
|
36
|
+
### Setup a Session Store
|
37
|
+
|
38
|
+
In order for the Shopify API gem to properly store sessions it needs an implementation of `ShopifyAPI::Auth::SessionStorage`. There is one provided in the gem, `ShopifyAPI::Auth::FileSessionStorage`, this is suitable for testing, however it is not intended for production apps. See the [Session Storage doc](usage/session_storage.md) for instructions on how to create a custom session store for a production application.
|
39
|
+
|
40
|
+
Normally session information would be stored in cookies on the browser. However, due to restrictions with modern browsers we highly discourage using cookies for embedded apps. For this reason, an app needs to define a storage implementation that can be used to store and retrieve a session given an ID. In a non embedded app this ID will come from a cookie however, in an embedded app this ID will come from [App Bridge](https://shopify.dev/apps/tools/app-bridge)
|
41
|
+
|
42
|
+
### Performing OAuth
|
43
|
+
|
44
|
+
Next, unless you are making a private app, you need to go through OAuth as described [here](https://shopify.dev/apps/auth/oauth) to create sessions for shops using your app.
|
45
|
+
The Shopify API gem tries to make this easy by providing functions to begin and complete the OAuth process. See the [Oauth doc](usage/oauth.md) for instructions on how to use these.
|
46
|
+
|
47
|
+
### Register Webhooks and a Webhook Handler
|
48
|
+
|
49
|
+
If you intend to use webhooks in your application follow the steps in the [Webhooks doc](usage/webhooks.md) for instructions on registering and handling webhooks.
|
50
|
+
|
51
|
+
### Start Making Authenticated Shopify Requests
|
52
|
+
|
53
|
+
You can now start making authenticated Shopify API calls using the Admin [REST](usage/rest.md) or [GraphQL](usage/graphql.md) Clients or the [Storefront GraphQL Client](usage/graphql_storefront.md).
|
data/docs/issues.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Known issues and caveats
|
2
|
+
|
3
|
+
By following this guide, you will have a fully functional Shopify app. However, there are some things you should be aware of before using your new app in a production environment.
|
4
|
+
|
5
|
+
## Notes on session handling
|
6
|
+
|
7
|
+
Before you start writing your application, please note that the Shopify library needs to store some information for OAuth in sessions. Since each application may choose a different strategy to store information, the library cannot dictate any specific storage strategy. When calling `ShopifyAPI::Context.setup`, you'll need to provide an instance of a class that implements the `ShopifyAPI::Auth::SessionStorage` interface.
|
8
|
+
|
9
|
+
This library provides a very simple implementation of that interface which stores sessions in files, `ShopifyAPI::Auth::FileSessionStorage` ([source code](../lib/shopify_api/auth/file_session_storage.rb)). This class is meant to speed up development with this library, but it is not suitable for production use, because it will lead to disk build-up as old sessions are not cleaned up.
|
10
|
+
|
11
|
+
Before you deploy your app to production, it should use your selected storage method for sessions. You can do that by creating a class that implements the `SessionStorage` interface and pass that in your `Context.setup` call. Your class will need to implement the methods below.
|
12
|
+
|
13
|
+
**Note**: After you create your implementation of `SessionStorage`, you should make sure to clean up old sessions periodically in your data storage. The library will delete some sessions when they are no longer useful, but it cannot guarantee that expired sessions are deleted automatically.
|
14
|
+
|
15
|
+
#### `SessionStorage.storeSession`
|
16
|
+
|
17
|
+
Creates **or updates** a `Session` object in your storage. This function should return a `bool` indicating whether the operation was successful.
|
18
|
+
|
19
|
+
| Param | Type | Notes |
|
20
|
+
| --------- | --------- | --------------------------- |
|
21
|
+
| `session` | `Session` | The session object to store |
|
22
|
+
|
23
|
+
#### `SessionStorage.loadSession`
|
24
|
+
|
25
|
+
Fetches a `Session` object from your storage. This function should return a `Session` object, or `null` if it was not found.
|
26
|
+
|
27
|
+
| Param | Type | Notes |
|
28
|
+
| ----------- | -------- | ----------------------------- |
|
29
|
+
| `sessionId` | `string` | The id of the session to load |
|
30
|
+
|
31
|
+
#### `SessionStorage.deleteSession`
|
32
|
+
|
33
|
+
Deletes a session from your storage. This function should return a `bool` indicating whether the operation was successful.
|
34
|
+
|
35
|
+
| Param | Type | Notes |
|
36
|
+
| ----------- | -------- | ------------------------------- |
|
37
|
+
| `sessionId` | `string` | The id of the session to delete |
|
38
|
+
|
39
|
+
[Back to guide index](README.md)
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Make a GraphQL API call
|
2
|
+
|
3
|
+
Once you have a [session](oauth.md#fetching-sessions) after completing oauth, you can make GraphQL queries to the Admin API with `ShopifyAPI::Clients::Graphql::Admin`
|
4
|
+
|
5
|
+
Below is an example
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
# load the current session with SessionUtils.load_current_session
|
9
|
+
session = ShopifyAPI::Utils::SessionUtils.load_current_session(auth_header: <auth-header>, cookies: <cookies>, is_online: <true|false>)
|
10
|
+
|
11
|
+
# initalize the client
|
12
|
+
client = ShopifyAPI::Clients::Graphql::Admin.new(session: session)
|
13
|
+
|
14
|
+
# make the GraphQL query string
|
15
|
+
query =<<~QUERY
|
16
|
+
{
|
17
|
+
products(first: 10) {
|
18
|
+
edges {
|
19
|
+
cursor
|
20
|
+
node {
|
21
|
+
id
|
22
|
+
title
|
23
|
+
onlineStoreUrl
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
QUERY
|
29
|
+
|
30
|
+
response = client.query(query: query)
|
31
|
+
# do something with the response data
|
32
|
+
```
|
33
|
+
|
34
|
+
You can also make GraphQL calls that take in variables
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
client = ShopifyAPI::Clients::Graphql::Admin.new(session: session)
|
38
|
+
|
39
|
+
query = <<~QUERY
|
40
|
+
query testQueryWithVariables($first: Int!){
|
41
|
+
products(first: $first) {
|
42
|
+
edges {
|
43
|
+
cursor
|
44
|
+
node {
|
45
|
+
id
|
46
|
+
title
|
47
|
+
onlineStoreUrl
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
QUERY
|
53
|
+
variables = {
|
54
|
+
first: 3
|
55
|
+
}
|
56
|
+
|
57
|
+
response = client.query(query: query, variables: variables)
|
58
|
+
|
59
|
+
```
|
60
|
+
|
61
|
+
Here is an example of how you might use fragments as part of the client
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
client = ShopifyAPI::Clients::Graphql::Admin.new(session: session)
|
65
|
+
# define the fragment as part of the query
|
66
|
+
query = <<~QUERY
|
67
|
+
fragment ProductStuff on Product {
|
68
|
+
id
|
69
|
+
title
|
70
|
+
description
|
71
|
+
onlineStoreUrl
|
72
|
+
}
|
73
|
+
query testQueryWithVariables($first: Int){
|
74
|
+
products(first: $first) {
|
75
|
+
edges {
|
76
|
+
cursor
|
77
|
+
node {
|
78
|
+
...ProductStuff
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
QUERY
|
84
|
+
variables = {
|
85
|
+
first: 3
|
86
|
+
}
|
87
|
+
response = client.query(query: query, variables: variables)
|
88
|
+
# do something with the reponse
|
89
|
+
```
|
90
|
+
|
91
|
+
Want to make calls to the Storefront API? Click [here](graphql_storefront.md)
|
92
|
+
|
93
|
+
# Proxy a GraphQL Query
|
94
|
+
|
95
|
+
If you would like to give your front end the ability to make authenticated graphql queries to the Shopify Admin API, the `shopify_api` gem makes proxying a graphql request easy! The gem provides a utility function which will accept the raw request body (a GraphQL query), the headers, and the cookies (optional). It will add authentication to the request, proxy it to the Shopify Admin API, and return a `ShopifyAPI::Clients::HttpResponse`. An example utilization of this in Rails is shown below:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
def proxy
|
99
|
+
begin
|
100
|
+
response = ShopifyAPI::Utils::GraphqlProxy.proxy_query(
|
101
|
+
headers: request.headers.to_h,
|
102
|
+
body: request.raw_post,
|
103
|
+
cookies: request.cookies.to_h
|
104
|
+
)
|
105
|
+
|
106
|
+
render json: response.body, status: response.code
|
107
|
+
rescue ShopifyAPI::Errors::InvalidGraphqlRequestError
|
108
|
+
# Handle bad request
|
109
|
+
rescue ShopifyAPI::Errors::SessionNotFoundError
|
110
|
+
# Handle no session found
|
111
|
+
end
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
**Note:** GraphQL proxying is only supported for online sessions for non-private apps, the utility will raise a `ShopifyAPI::Errors::SessionNotFoundError` if there are no existing online tokens for the provided credentials, and a `ShopifyAPI::Errors::PrivateAppError` if called from a private app.
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Make a Storefront API call
|
2
|
+
|
3
|
+
The library also allows you to send GraphQL requests to the [Shopify Storefront API](https://shopify.dev/docs/storefront-api). To do that, you can use `ShopifyAPI::Clients::Graphql::Storefront` with the current session and a `storefrontAccessToken`.
|
4
|
+
|
5
|
+
You can obtain Storefront API access tokens for both private apps and sales channels. Please read [our documentation](https://shopify.dev/docs/storefront-api/getting-started) to learn more about Storefront Access Tokens.
|
6
|
+
|
7
|
+
Below is an example of how you may query the Storefront API:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
# Load the access token as per instructions above
|
11
|
+
storefront_access_token = ''
|
12
|
+
# your shop domain
|
13
|
+
shop_url = 'shop.myshopify.com'
|
14
|
+
|
15
|
+
# initialize the client with session and storefront access token
|
16
|
+
client = ShopifyAPI::Clients::Graphql::Storefront.new(shop_url, storefront_access_token)
|
17
|
+
|
18
|
+
query = <<~QUERY
|
19
|
+
{
|
20
|
+
collections(first: 2) {
|
21
|
+
edges {
|
22
|
+
node {
|
23
|
+
id
|
24
|
+
products(first: 5) {
|
25
|
+
edges {
|
26
|
+
node {
|
27
|
+
id
|
28
|
+
title
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
QUERY
|
37
|
+
|
38
|
+
response = client.query(query: query)
|
39
|
+
# do something with the returned data
|
40
|
+
```
|
41
|
+
|
42
|
+
Want to make calls to the Admin API? Click [here](graphql.md)
|
data/docs/usage/oauth.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# Performing OAuth
|
2
|
+
|
3
|
+
Once the library is set up for your project, you'll be able to use it to start adding functionality to your app. The first thing your app will need to do is to obtain an access token to the Admin API by performing the OAuth process.
|
4
|
+
|
5
|
+
To do this, you can follow the steps below.
|
6
|
+
|
7
|
+
**Note:** You do not need to go through the OAuth process if you are creating a private app. In this case you can simply set your `<key+password>` as the `api_secret_key` in `ShopifyAPI::Context.setup`. For more information on authenticating a Shopify app please see the [Types of Authentication](https://shopify.dev/apps/auth#types-of-authentication) page.
|
8
|
+
|
9
|
+
## Add a route to start OAuth
|
10
|
+
|
11
|
+
The route for starting the OAuth process (in this case `/login`) will use the library's `begin_auth` method. The method will return an `auth_route` URI that will be used for redirecting the user to the Shopify Authentication screen and a session cookie to store on the user's browser. These return values will be a hash in the form of {`auth_route`: `String`, `cookie`: `ShopifyAPI::Auth::Oauth::SessionCookie`}
|
12
|
+
|
13
|
+
| Parameter | Type | Required? | Default Value | Notes |
|
14
|
+
| -------------- | ---------------------- | :-------: | :-----------: | ----------------------------------------------------------------------------------------------------------- |
|
15
|
+
| `shop` | `String` | Yes | - | A Shopify domain name in the form `{exampleshop}.myshopify.com`. |
|
16
|
+
| `redirect_path` | `String` | Yes | - | The redirect path used for callback with a leading `/`. The route should be allowed under the app settings. |
|
17
|
+
| `is_online` | `Boolean` | No | `true` | `true` if the session is online and `false` otherwise. |
|
18
|
+
|
19
|
+
Your app should take the returned values from the `begin_auth` function and redirect the user to url defined by `auth_route` and set the cookie in the user's browser. We strongly recommend that you use secure, httpOnly cookies for this to help prevent session hijacking.
|
20
|
+
|
21
|
+
An example is shown below in a Rails app but these steps could be applied in any framework:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class ShopifyAuthController < ApplicationController
|
25
|
+
def login
|
26
|
+
shop = request.headers["Shop"]
|
27
|
+
|
28
|
+
auth_response = ShopifyAPI::Auth::Oauth.begin_auth(shop: domain, redirect_path: "/auth/callback")
|
29
|
+
|
30
|
+
cookies[auth_response[:cookie].name] = {
|
31
|
+
expires: auth_response[:cookie].expires,
|
32
|
+
secure: true,
|
33
|
+
http_only: true,
|
34
|
+
value: auth_response[:cookie].value
|
35
|
+
}
|
36
|
+
|
37
|
+
head 307
|
38
|
+
response.set_header("Location", auth_response[:auth_route])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
## Add your OAuth callback route
|
44
|
+
|
45
|
+
After the app is authenticated with Shopify, the Shopify platform will send a request back to your app using this route (which you provided as a parameter to `begin_auth`, above). Your app will now use the provided `validate_auth_callback` method to finalize the OAuth process. This method returns a hash containing the new session and a cookie to be set in the browser in form of {`session`: `ShopifyAPI::Auth::Session`, `cookie`: `ShopifyAPI::Auth::Oauth::SessionCookie`}.
|
46
|
+
|
47
|
+
An example is shown below in a Rails app but these steps could be applied in any framework:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
def callback
|
51
|
+
begin
|
52
|
+
auth_result = ShopifyAPI::Auth::Oauth.validate_auth_callback(
|
53
|
+
cookies: cookies.to_h,
|
54
|
+
auth_query: ShopifyAPI::Auth::Oauth::AuthQuery.new(request.parameters.symbolize_keys.except(:controller, :action))
|
55
|
+
)
|
56
|
+
|
57
|
+
cookies[auth_result[:cookie].name] = {
|
58
|
+
expires: auth_result[:cookie].expires,
|
59
|
+
secure: true,
|
60
|
+
http_only: true,
|
61
|
+
value: auth_result[:cookie].value
|
62
|
+
}
|
63
|
+
|
64
|
+
puts("OAuth complete! New access token: #{auth_result[:session].access_token}")
|
65
|
+
|
66
|
+
head 307
|
67
|
+
response.set_header("Location", "<some-redirect-url>")
|
68
|
+
rescue => e
|
69
|
+
puts(e.message)
|
70
|
+
head 500
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
## Fetching sessions
|
75
|
+
|
76
|
+
You can use the OAuth methods to create both offline and online sessions. Once the process is completed, the session will be stored as per your `Context.session_storage`, and can be retrieved with `SessionUtils` class methods.
|
77
|
+
|
78
|
+
- To load current session, you can use the following method:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
ShopifyAPI::Utils::SessionUtils.load_current_session(auth_header: <auth-header>, cookies: <cookies>, is_online: <true|false>)
|
82
|
+
```
|
83
|
+
|
84
|
+
Accepted arguments:
|
85
|
+
| Parameter | Type | Notes |
|
86
|
+
| ----------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
87
|
+
| `auth_header` | `String` | JWT token will be extracted from `auth_header` to load session for embedded apps. If JWT token is not provided this methods will try with `cookies`. Only required if trying to load, an embedded session. |
|
88
|
+
| `cookies` | `Hash(String, String)` | The cookies from the HTTP request. A session cookie named `shopify_app_session` is used to load session for non-embedded apps. Can be omitted if loading and embedded session without falling back on cookies |
|
89
|
+
| `is_online` | `Boolean` | Whether to load online or offline sessions. Defaults to `false` |
|
90
|
+
|
91
|
+
This method will return a `ShopifyAPI::Auth::Session` if a session exists. Either a proper token or a proper cookie must be present.
|
92
|
+
|
93
|
+
- To load offline session, you can use the following method:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
ShopifyAPI::Utils::SessionUtils.load_offline_session(shop)
|
97
|
+
```
|
98
|
+
|
99
|
+
Accepted arguments:
|
100
|
+
| Parameter | Type | Notes |
|
101
|
+
| ------------------- | --------- | --------------------------------------------- |
|
102
|
+
| `shop` | `String` | The shop url to find the offline session for. |
|
103
|
+
| `include_expired` | `Boolean` | Include expired sessions or not. |
|
104
|
+
|
105
|
+
This method will return a `ShopifyAPI::Auth::Session` if a session exists and `nil` otherwise. This method **does not** perform any validation on the shop domain, so it **must not** rely on user input for the domain. This method is typically meant to be used in background tasks like webhooks, where the data is expected to have been validated when the task was enqueued.
|
data/docs/usage/rest.md
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
# Make a REST API call
|
2
|
+
|
3
|
+
Once OAuth is complete, we can use the `ShopifyAPI::Clients::Rest::Admin` client to make an API call to the Shopify Admin API. To do this, you can create an instance of `ShopifyAPI::Clients::Rest::Admin` using the current session to make requests to the Admin API.
|
4
|
+
|
5
|
+
## Methods
|
6
|
+
|
7
|
+
The Rest Admin client offers the 4 core request methods: `get`, `delete`, `post`, and `put`. These methods each take the parameters outlined in the table below. If the request is successful these methods will all return a `ShopifyAPI::Clients::HttpResponse` object, which has properties `code`, `headers`, and `body` otherwise an error will be raised describing what went wrong.
|
8
|
+
|
9
|
+
| Parameter | Type | Required in Methods | Default Value | Notes |
|
10
|
+
| -------------- | -------------------------------------------------------- | :-----------------: | :-----------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
11
|
+
| `path` | `String` | all | none | The requested API endpoint path. This can be one of two formats:<ul><li>The path starting after the `/admin/api/{version}/` prefix, such as `products`, which executes `/admin/api/{version}/products.json`</li><li>The full path, such as `/admin/oauth/access_scopes.json`</li></ul> |
|
12
|
+
| `body` | `Hash(any(Symbol, String), untyped)` | `put`, `post` | none | The body of the request |
|
13
|
+
| `query` | `Hash(any(Symbol, String), any(String, Integer, Float))` | none | none | An optional query object to be appended to the request url as a query string |
|
14
|
+
| `extraHeaders` | `Hash(any(Symbol, String), any(String, Integer, Float))` | none | none | Any additional headers you want to send with your request |
|
15
|
+
| `tries` | `Integer` | None | `1` | The maximum number of times to try the request _(must be >= 0)_ |
|
16
|
+
|
17
|
+
**Note:** _These paramaters can still be used in all methods regardless of if they are required._
|
18
|
+
|
19
|
+
## Usage Examples:
|
20
|
+
|
21
|
+
### Perform a `GET` request:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
# Load the current session to get the `accessToken`.
|
25
|
+
session = ShopifyAPI::Utils::SessionUtils.load_current_session(headers, cookies, is_online)
|
26
|
+
|
27
|
+
# Create a new client.
|
28
|
+
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
|
29
|
+
|
30
|
+
# Use `client.get` to request the specified Shopify REST API endpoint, in this case `products`.
|
31
|
+
response = client.get(path: "products")
|
32
|
+
|
33
|
+
# Do something with the returned data
|
34
|
+
some_function(response.body)
|
35
|
+
```
|
36
|
+
|
37
|
+
### Perform a `POST` request:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# Load the current session to get the `accessToken`.
|
41
|
+
session = ShopifyAPI::Utils::SessionUtils.load_current_session(headers, cookies, is_online)
|
42
|
+
|
43
|
+
# Create a new client.
|
44
|
+
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
|
45
|
+
|
46
|
+
# Build your post request body.
|
47
|
+
body = {
|
48
|
+
product: {
|
49
|
+
title: "Burton Custom Freestyle 151",
|
50
|
+
body_html: "\u003cstrong\u003eGood snowboard!\u003c\/strong\u003e",
|
51
|
+
vendor: "Burton",
|
52
|
+
product_type: "Snowboard",
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
# Use `client.post` to send your request to the specified Shopify Admin REST API endpoint.
|
57
|
+
client.post({
|
58
|
+
path: "products",
|
59
|
+
body: body,
|
60
|
+
});
|
61
|
+
```
|
62
|
+
|
63
|
+
_for more information on the `products` endpoint, [check out our API reference guide](https://shopify.dev/api/admin-rest/unstable/resources/product)._
|
64
|
+
|
65
|
+
## Pagination
|
66
|
+
|
67
|
+
This library also supports cursor-based pagination for REST Admin API requests. [Learn more about REST request pagination](https://shopify.dev/api/usage/pagination-rest).
|
68
|
+
|
69
|
+
After making a request, the `next_page_info` and `prev_page_info` can be found on the response object and passed as the page_info query param in other requests.
|
70
|
+
|
71
|
+
An example of this is shown below:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
session = ShopifyAPI::Utils::SessionUtils.load_current_session(headers, cookies, is_online)
|
75
|
+
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
|
76
|
+
|
77
|
+
response = client.get(path: "products", query: { limit: 10 })
|
78
|
+
|
79
|
+
loop do
|
80
|
+
some_function(response.body)
|
81
|
+
break unless response.next_page_info
|
82
|
+
response = client.get(path: "products", query: { limit: 10, page_info: response.next_page_info })
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
Similarly, when using REST resources the `next_page_info` and `prev_page_info` can be found on the Resource class and passed as the page_info query param in other requests.
|
87
|
+
|
88
|
+
An example of this is shown below:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
session = ShopifyAPI::Utils::SessionUtils.load_current_session(headers, cookies, is_online)
|
92
|
+
|
93
|
+
products = ShopifyAPI::Product.all(session: session, limit: 10)
|
94
|
+
|
95
|
+
loop do
|
96
|
+
some_function(products)
|
97
|
+
break unless ShopifyAPI::Product.next_page?
|
98
|
+
products = ShopifyAPI::Product.all(session: session, limit: 10, page_info: ShopifyAPI::Product.next_page_info)
|
99
|
+
end
|
100
|
+
```
|
101
|
+
|
102
|
+
The next/previous page_info strings can also be retrieved from the response object and added to a request query to retrieve the next/previous pages.
|
103
|
+
|
104
|
+
An example of this is shown below:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
session = ShopifyAPI::Utils::SessionUtils.load_current_session(headers, cookies, is_online)
|
108
|
+
client = ShopifyAPI::Clients::Rest::Admin.new(session: session)
|
109
|
+
|
110
|
+
response = client.get(path: "products", query: { limit: 10 })
|
111
|
+
next_page_info = response.next_page_info
|
112
|
+
|
113
|
+
if next_page_info
|
114
|
+
next_page_response =client.get(path: "products", query: { limit: 10, page_info: next_page_info })
|
115
|
+
some_function(next_page_response)
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
### Error Messages
|
120
|
+
|
121
|
+
You can rescue `ShopifyAPI::Errors::HttpResponseError` and output error messages with `errors.full_messages`
|
122
|
+
|
123
|
+
See example:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
fulfillment = ShopifyAPI::Fulfillment.new(session: @session)
|
127
|
+
fulfillment.order_id = 2776493818000
|
128
|
+
...
|
129
|
+
fulfillment.tracking_company = "Jack Black's Pack, Stack and Track"
|
130
|
+
fulfillment.save()
|
131
|
+
rescue ShopifyAPI::Errors::HttpResponseError => e
|
132
|
+
puts fulfillment.errors.full_messages
|
133
|
+
# {"base"=>["Line items are already fulfilled"]}
|
134
|
+
# If you report this error, please include this id: e712dde0-1270-4258-8cdb-d198792c917e.
|
135
|
+
```
|
136
|
+
|
137
|
+
[Back to guide index](../README.md)
|