shopify_api 16.2.0 → 16.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/skills/investigating-github-issues/SKILL.md +171 -0
  3. data/.claude/skills/investigating-github-issues/references/investigation-report-template.md +90 -0
  4. data/.claude/skills/shared/references/version-maintenance-policy.md +20 -0
  5. data/.github/workflows/gardener-investigate-issue.yml +226 -0
  6. data/.github/workflows/gardener-notify-event.yml +35 -0
  7. data/.github/workflows/gardener-notify-slack.yml +75 -0
  8. data/CHANGELOG.md +12 -0
  9. data/Gemfile.lock +3 -1
  10. data/docs/usage/oauth.md +4 -5
  11. data/lib/shopify_api/admin_versions.rb +1 -0
  12. data/lib/shopify_api/auth/client_credentials.rb +3 -2
  13. data/lib/shopify_api/auth/oauth.rb +2 -0
  14. data/lib/shopify_api/auth/refresh_token.rb +3 -2
  15. data/lib/shopify_api/auth/token_exchange.rb +18 -8
  16. data/lib/shopify_api/auth.rb +30 -0
  17. data/lib/shopify_api/clients/graphql/storefront.rb +3 -2
  18. data/lib/shopify_api/context.rb +5 -1
  19. data/lib/shopify_api/errors/invalid_shop_error.rb +9 -0
  20. data/lib/shopify_api/errors/rest_resource_not_loaded_error.rb +14 -0
  21. data/lib/shopify_api/rest/resources/2026_07/abandoned_checkout.rb +194 -0
  22. data/lib/shopify_api/rest/resources/2026_07/access_scope.rb +62 -0
  23. data/lib/shopify_api/rest/resources/2026_07/apple_pay_certificate.rb +109 -0
  24. data/lib/shopify_api/rest/resources/2026_07/application_charge.rb +113 -0
  25. data/lib/shopify_api/rest/resources/2026_07/application_credit.rb +95 -0
  26. data/lib/shopify_api/rest/resources/2026_07/article.rb +269 -0
  27. data/lib/shopify_api/rest/resources/2026_07/asset.rb +122 -0
  28. data/lib/shopify_api/rest/resources/2026_07/assigned_fulfillment_order.rb +92 -0
  29. data/lib/shopify_api/rest/resources/2026_07/balance.rb +58 -0
  30. data/lib/shopify_api/rest/resources/2026_07/blog.rb +166 -0
  31. data/lib/shopify_api/rest/resources/2026_07/cancellation_request.rb +87 -0
  32. data/lib/shopify_api/rest/resources/2026_07/carrier_service.rb +120 -0
  33. data/lib/shopify_api/rest/resources/2026_07/checkout.rb +213 -0
  34. data/lib/shopify_api/rest/resources/2026_07/collect.rb +146 -0
  35. data/lib/shopify_api/rest/resources/2026_07/collection.rb +114 -0
  36. data/lib/shopify_api/rest/resources/2026_07/collection_listing.rb +159 -0
  37. data/lib/shopify_api/rest/resources/2026_07/comment.rb +287 -0
  38. data/lib/shopify_api/rest/resources/2026_07/country.rb +141 -0
  39. data/lib/shopify_api/rest/resources/2026_07/currency.rb +61 -0
  40. data/lib/shopify_api/rest/resources/2026_07/custom_collection.rb +191 -0
  41. data/lib/shopify_api/rest/resources/2026_07/customer.rb +328 -0
  42. data/lib/shopify_api/rest/resources/2026_07/deprecated_api_call.rb +61 -0
  43. data/lib/shopify_api/rest/resources/2026_07/discount_code.rb +226 -0
  44. data/lib/shopify_api/rest/resources/2026_07/dispute.rb +115 -0
  45. data/lib/shopify_api/rest/resources/2026_07/dispute_evidence.rb +121 -0
  46. data/lib/shopify_api/rest/resources/2026_07/dispute_file_upload.rb +85 -0
  47. data/lib/shopify_api/rest/resources/2026_07/draft_order.rb +279 -0
  48. data/lib/shopify_api/rest/resources/2026_07/event.rb +152 -0
  49. data/lib/shopify_api/rest/resources/2026_07/fulfillment.rb +235 -0
  50. data/lib/shopify_api/rest/resources/2026_07/fulfillment_event.rb +167 -0
  51. data/lib/shopify_api/rest/resources/2026_07/fulfillment_order.rb +326 -0
  52. data/lib/shopify_api/rest/resources/2026_07/fulfillment_request.rb +116 -0
  53. data/lib/shopify_api/rest/resources/2026_07/fulfillment_service.rb +131 -0
  54. data/lib/shopify_api/rest/resources/2026_07/gift_card.rb +222 -0
  55. data/lib/shopify_api/rest/resources/2026_07/gift_card_adjustment.rb +122 -0
  56. data/lib/shopify_api/rest/resources/2026_07/image.rb +161 -0
  57. data/lib/shopify_api/rest/resources/2026_07/inventory_item.rb +112 -0
  58. data/lib/shopify_api/rest/resources/2026_07/inventory_level.rb +183 -0
  59. data/lib/shopify_api/rest/resources/2026_07/location.rb +171 -0
  60. data/lib/shopify_api/rest/resources/2026_07/locations_for_move.rb +60 -0
  61. data/lib/shopify_api/rest/resources/2026_07/marketing_event.rb +213 -0
  62. data/lib/shopify_api/rest/resources/2026_07/metafield.rb +348 -0
  63. data/lib/shopify_api/rest/resources/2026_07/mobile_platform_application.rb +120 -0
  64. data/lib/shopify_api/rest/resources/2026_07/order.rb +503 -0
  65. data/lib/shopify_api/rest/resources/2026_07/order_risk.rb +148 -0
  66. data/lib/shopify_api/rest/resources/2026_07/page.rb +198 -0
  67. data/lib/shopify_api/rest/resources/2026_07/payment.rb +98 -0
  68. data/lib/shopify_api/rest/resources/2026_07/payment_gateway.rb +147 -0
  69. data/lib/shopify_api/rest/resources/2026_07/payment_transaction.rb +117 -0
  70. data/lib/shopify_api/rest/resources/2026_07/payout.rb +101 -0
  71. data/lib/shopify_api/rest/resources/2026_07/policy.rb +73 -0
  72. data/lib/shopify_api/rest/resources/2026_07/price_rule.rb +227 -0
  73. data/lib/shopify_api/rest/resources/2026_07/product.rb +227 -0
  74. data/lib/shopify_api/rest/resources/2026_07/product_listing.rb +200 -0
  75. data/lib/shopify_api/rest/resources/2026_07/product_resource_feedback.rb +92 -0
  76. data/lib/shopify_api/rest/resources/2026_07/province.rb +136 -0
  77. data/lib/shopify_api/rest/resources/2026_07/recurring_application_charge.rb +184 -0
  78. data/lib/shopify_api/rest/resources/2026_07/redirect.rb +143 -0
  79. data/lib/shopify_api/rest/resources/2026_07/refund.rb +158 -0
  80. data/lib/shopify_api/rest/resources/2026_07/resource_feedback.rb +77 -0
  81. data/lib/shopify_api/rest/resources/2026_07/script_tag.rb +159 -0
  82. data/lib/shopify_api/rest/resources/2026_07/shipping_zone.rb +87 -0
  83. data/lib/shopify_api/rest/resources/2026_07/shop.rb +231 -0
  84. data/lib/shopify_api/rest/resources/2026_07/smart_collection.rb +220 -0
  85. data/lib/shopify_api/rest/resources/2026_07/storefront_access_token.rb +91 -0
  86. data/lib/shopify_api/rest/resources/2026_07/tender_transaction.rb +97 -0
  87. data/lib/shopify_api/rest/resources/2026_07/theme.rb +127 -0
  88. data/lib/shopify_api/rest/resources/2026_07/transaction.rb +194 -0
  89. data/lib/shopify_api/rest/resources/2026_07/usage_charge.rb +106 -0
  90. data/lib/shopify_api/rest/resources/2026_07/user.rb +142 -0
  91. data/lib/shopify_api/rest/resources/2026_07/variant.rb +212 -0
  92. data/lib/shopify_api/rest/resources/2026_07/webhook.rb +173 -0
  93. data/lib/shopify_api/utils/shop_validator.rb +127 -0
  94. data/lib/shopify_api/version.rb +1 -1
  95. data/lib/shopify_api.rb +69 -0
  96. data/shopify_api.gemspec +2 -0
  97. metadata +111 -2
data/docs/usage/oauth.md CHANGED
@@ -72,9 +72,9 @@ exchange a [session token](https://shopify.dev/docs/apps/auth/session-tokens) (S
72
72
  #### Input
73
73
  | Parameter | Type | Required? | Default Value | Notes |
74
74
  | -------------- | ---------------------- | :-------: | :-----------: | ----------------------------------------------------------------------------------------------------------- |
75
- | `shop` | `String` | Yes | - | A Shopify domain name in the form `{exampleshop}.myshopify.com`. |
76
- | `session_token` | `String` | Yes| - | The session token (Shopify Id Token) provided by App Bridge in either the request 'Authorization' header or URL param when the app is loaded in Admin. |
75
+ | `session_token` | `String` | Yes| - | The session token (Shopify Id Token) provided by App Bridge in either the request 'Authorization' header or URL param when the app is loaded in Admin. Its `dest` claim determines which shop receives the token exchange request. |
77
76
  | `requested_token_type` | `TokenExchange::RequestedTokenType` | Yes | - | The type of token requested. Online: `TokenExchange::RequestedTokenType::ONLINE_ACCESS_TOKEN` or offline: `TokenExchange::RequestedTokenType::OFFLINE_ACCESS_TOKEN`. |
77
+ | `shop` | `String` | No | `nil` | **Deprecated**, will be removed in v17.0.0. Ignored for the request host; the shop always comes from the session token `dest` claim. If passed, logs a deprecation warning. |
78
78
 
79
79
  #### Output
80
80
  This method returns the new `ShopifyAPI::Auth::Session` object from the token exchange,
@@ -83,14 +83,13 @@ your app should store this `Session` object to be used later [when making authen
83
83
  #### Example
84
84
  ```ruby
85
85
 
86
- # `shop` is the shop domain name - "this-is-my-example-shop.myshopify.com"
87
86
  # `session_token` is the session token provided by App Bridge either in:
88
87
  # - the request 'Authorization' header as `Bearer this-is-the-session_token`
89
88
  # - or as a URL param `id_token=this-is-the-session_token`
89
+ # The shop is taken from the token's `dest` claim (see session token documentation).
90
90
 
91
- def authenticate(shop, session_token)
91
+ def authenticate(session_token)
92
92
  session = ShopifyAPI::Auth::TokenExchange.exchange_token(
93
- shop: shop,
94
93
  session_token: session_token,
95
94
  requested_token_type: ShopifyAPI::Auth::TokenExchange::RequestedTokenType::OFFLINE_ACCESS_TOKEN,
96
95
  # or if you're requesting an online access token:
@@ -5,6 +5,7 @@ module ShopifyAPI
5
5
  module AdminVersions
6
6
  SUPPORTED_ADMIN_VERSIONS = T.let([
7
7
  "unstable",
8
+ "2026-10",
8
9
  "2026-07",
9
10
  "2026-04",
10
11
  "2026-01",
@@ -22,7 +22,8 @@ module ShopifyAPI
22
22
  "ShopifyAPI::Context not setup, please call ShopifyAPI::Context.setup"
23
23
  end
24
24
 
25
- shop_session = ShopifyAPI::Auth::Session.new(shop: shop)
25
+ validated_shop = Utils::ShopValidator.sanitize!(shop)
26
+ shop_session = ShopifyAPI::Auth::Session.new(shop: validated_shop)
26
27
  body = {
27
28
  client_id: ShopifyAPI::Context.api_key,
28
29
  client_secret: ShopifyAPI::Context.api_secret_key,
@@ -42,7 +43,7 @@ module ShopifyAPI
42
43
  response_hash = T.cast(response.body, T::Hash[String, T.untyped]).to_h
43
44
 
44
45
  Session.from(
45
- shop: shop,
46
+ shop: validated_shop,
46
47
  access_token_response: Oauth::AccessTokenResponse.from_hash(response_hash),
47
48
  )
48
49
  end
@@ -33,6 +33,8 @@ module ShopifyAPI
33
33
  end
34
34
  raise Errors::UnsupportedOauthError, "Cannot perform OAuth for private apps." if Context.private?
35
35
 
36
+ shop = Utils::ShopValidator.sanitize!(shop)
37
+
36
38
  state = SecureRandom.alphanumeric(NONCE_LENGTH)
37
39
 
38
40
  cookie = SessionCookie.new(value: state, expires: Time.now + 60)
@@ -21,7 +21,8 @@ module ShopifyAPI
21
21
  "ShopifyAPI::Context not setup, please call ShopifyAPI::Context.setup"
22
22
  end
23
23
 
24
- shop_session = ShopifyAPI::Auth::Session.new(shop:)
24
+ validated_shop = Utils::ShopValidator.sanitize!(shop)
25
+ shop_session = ShopifyAPI::Auth::Session.new(shop: validated_shop)
25
26
  body = {
26
27
  client_id: ShopifyAPI::Context.api_key,
27
28
  client_secret: ShopifyAPI::Context.api_secret_key,
@@ -47,7 +48,7 @@ module ShopifyAPI
47
48
  session_params = T.cast(response.body, T::Hash[String, T.untyped]).to_h
48
49
 
49
50
  Session.from(
50
- shop:,
51
+ shop: validated_shop,
51
52
  access_token_response: Oauth::AccessTokenResponse.from_hash(session_params),
52
53
  )
53
54
  end
@@ -21,12 +21,12 @@ module ShopifyAPI
21
21
 
22
22
  sig do
23
23
  params(
24
- shop: String,
25
24
  session_token: String,
26
25
  requested_token_type: RequestedTokenType,
26
+ shop: T.nilable(String),
27
27
  ).returns(ShopifyAPI::Auth::Session)
28
28
  end
29
- def exchange_token(shop:, session_token:, requested_token_type:)
29
+ def exchange_token(session_token:, requested_token_type:, shop: nil)
30
30
  unless ShopifyAPI::Context.setup?
31
31
  raise ShopifyAPI::Errors::ContextNotSetupError,
32
32
  "ShopifyAPI::Context not setup, please call ShopifyAPI::Context.setup"
@@ -36,10 +36,19 @@ module ShopifyAPI
36
36
  raise ShopifyAPI::Errors::UnsupportedOauthError,
37
37
  "Cannot perform OAuth Token Exchange for non embedded apps." unless ShopifyAPI::Context.embedded?
38
38
 
39
- # Validate the session token content
40
- ShopifyAPI::Auth::JwtPayload.new(session_token)
39
+ # Validate the session token and use the shop from the token's `dest` claim
40
+ jwt_payload = ShopifyAPI::Auth::JwtPayload.new(session_token)
41
+ dest_shop = jwt_payload.shop
42
+
43
+ if shop
44
+ ShopifyAPI::Logger.deprecated(
45
+ "The `shop` parameter for `exchange_token` is deprecated and will be removed in v17. " \
46
+ "The shop is now always taken from the session token's `dest` claim.",
47
+ "17.0.0",
48
+ )
49
+ end
41
50
 
42
- shop_session = ShopifyAPI::Auth::Session.new(shop: shop)
51
+ shop_session = ShopifyAPI::Auth::Session.new(shop: dest_shop)
43
52
  body = {
44
53
  client_id: ShopifyAPI::Context.api_key,
45
54
  client_secret: ShopifyAPI::Context.api_secret_key,
@@ -74,7 +83,7 @@ module ShopifyAPI
74
83
  session_params = T.cast(response.body, T::Hash[String, T.untyped]).to_h
75
84
 
76
85
  Session.from(
77
- shop: shop,
86
+ shop: dest_shop,
78
87
  access_token_response: Oauth::AccessTokenResponse.from_hash(session_params),
79
88
  )
80
89
  end
@@ -91,7 +100,8 @@ module ShopifyAPI
91
100
  "ShopifyAPI::Context not setup, please call ShopifyAPI::Context.setup"
92
101
  end
93
102
 
94
- shop_session = ShopifyAPI::Auth::Session.new(shop: shop)
103
+ validated_shop = Utils::ShopValidator.sanitize!(shop)
104
+ shop_session = ShopifyAPI::Auth::Session.new(shop: validated_shop)
95
105
  body = {
96
106
  client_id: ShopifyAPI::Context.api_key,
97
107
  client_secret: ShopifyAPI::Context.api_secret_key,
@@ -120,7 +130,7 @@ module ShopifyAPI
120
130
  session_params = T.cast(response.body, T::Hash[String, T.untyped]).to_h
121
131
 
122
132
  Session.from(
123
- shop: shop,
133
+ shop: validated_shop,
124
134
  access_token_response: Oauth::AccessTokenResponse.from_hash(session_params),
125
135
  )
126
136
  end
@@ -1,10 +1,19 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
+ require "addressable/uri"
5
+
4
6
  module ShopifyAPI
5
7
  module Auth
6
8
  extend T::Sig
7
9
 
10
+ # Hostname characters, plus an optional port. Anything else before the first "/" is rejected.
11
+ EMBEDDED_HOST_AUTHORITY_REGEX = T.let(/\A[a-zA-Z0-9._-]+(:\d{1,5})?\z/, Regexp)
12
+
13
+ # Printable ASCII only: no whitespace, control bytes or non-ASCII bytes.
14
+ EMBEDDED_HOST_ALLOWED_BYTES_REGEX = T.let(/\A[\x21-\x7e]+\z/n, Regexp)
15
+ private_constant :EMBEDDED_HOST_AUTHORITY_REGEX, :EMBEDDED_HOST_ALLOWED_BYTES_REGEX
16
+
8
17
  class << self
9
18
  extend T::Sig
10
19
 
@@ -19,8 +28,29 @@ module ShopifyAPI
19
28
  end
20
29
 
21
30
  decoded_host = Base64.decode64(host)
31
+ unless trusted_embedded_host?(decoded_host)
32
+ raise Errors::InvalidShopError, "host must decode to a trusted Shopify Admin host"
33
+ end
34
+
22
35
  "https://#{decoded_host}/apps/#{Context.api_key}"
23
36
  end
37
+
38
+ private
39
+
40
+ sig { params(decoded_host: String).returns(T::Boolean) }
41
+ def trusted_embedded_host?(decoded_host)
42
+ return false unless decoded_host.b.match?(EMBEDDED_HOST_ALLOWED_BYTES_REGEX)
43
+
44
+ authority = T.must(decoded_host.split("/", 2).first)
45
+ return false unless authority.match?(EMBEDDED_HOST_AUTHORITY_REGEX)
46
+
47
+ uri = Addressable::URI.parse("https://#{decoded_host}")
48
+ return false unless uri.userinfo.nil? && uri.authority == authority
49
+
50
+ !Utils::ShopValidator.sanitize_shop_domain(uri.to_s).nil?
51
+ rescue Addressable::URI::InvalidURIError
52
+ false
53
+ end
24
54
  end
25
55
  end
26
56
  end
@@ -19,9 +19,10 @@ module ShopifyAPI
19
19
  raise ArgumentError, "Storefront client requires either private_token or public_token to be provided"
20
20
  end
21
21
 
22
+ validated_shop = Utils::ShopValidator.sanitize!(shop)
22
23
  session = Auth::Session.new(
23
- id: shop,
24
- shop: shop,
24
+ id: validated_shop,
25
+ shop: validated_shop,
25
26
  access_token: "",
26
27
  is_online: false,
27
28
  )
@@ -114,7 +114,11 @@ module ShopifyAPI
114
114
 
115
115
  unless Dir.exist?(path)
116
116
  unless @notified_missing_resources_folder.key?(api_version)
117
- @logger.warn("Cannot autoload REST resources for API version '#{version_folder_name}', folder is missing")
117
+ @logger.warn(
118
+ "shopify_api #{ShopifyAPI::VERSION} does not bundle REST resources for API version " \
119
+ "'#{api_version}', so REST resource classes are unavailable. The GraphQL Admin API and " \
120
+ "the REST client are unaffected.",
121
+ )
118
122
  @notified_missing_resources_folder[api_version] = true
119
123
  end
120
124
 
@@ -0,0 +1,9 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ class InvalidShopError < StandardError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module ShopifyAPI
5
+ module Errors
6
+ # Raised when a REST resource class is referenced but this gem version does
7
+ # not bundle REST resources for the active API version.
8
+ #
9
+ # Subclasses NameError so existing `rescue NameError` handling keeps working.
10
+ # Construct it with the missing constant name - `new(message, name)` - so
11
+ # NameError#name keeps returning it, matching the NameError Ruby would raise.
12
+ class RestResourceNotLoadedError < NameError; end
13
+ end
14
+ end
@@ -0,0 +1,194 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ ########################################################################################################################
5
+ # This file is auto-generated. If you have an issue, please create a GitHub issue. #
6
+ ########################################################################################################################
7
+
8
+ module ShopifyAPI
9
+ class AbandonedCheckout < ShopifyAPI::Rest::Base
10
+ extend T::Sig
11
+
12
+ @prev_page_info = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
13
+ @next_page_info = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
14
+
15
+ @api_call_limit = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
16
+ @retry_request_after = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
17
+
18
+ sig { params(session: T.nilable(ShopifyAPI::Auth::Session), from_hash: T.nilable(T::Hash[T.untyped, T.untyped])).void }
19
+ def initialize(session: ShopifyAPI::Context.active_session, from_hash: nil)
20
+
21
+ @abandoned_checkout_url = T.let(nil, T.nilable(String))
22
+ @billing_address = T.let(nil, T.nilable(T::Hash[T.untyped, T.untyped]))
23
+ @buyer_accepts_marketing = T.let(nil, T.nilable(T::Boolean))
24
+ @buyer_accepts_sms_marketing = T.let(nil, T.nilable(T::Boolean))
25
+ @cart_token = T.let(nil, T.nilable(String))
26
+ @closed_at = T.let(nil, T.nilable(String))
27
+ @completed_at = T.let(nil, T.nilable(String))
28
+ @created_at = T.let(nil, T.nilable(String))
29
+ @currency = T.let(nil, T.nilable(Currency))
30
+ @customer = T.let(nil, T.nilable(Customer))
31
+ @customer_locale = T.let(nil, T.nilable(String))
32
+ @device_id = T.let(nil, T.nilable(Integer))
33
+ @discount_codes = T.let(nil, T.nilable(T::Array[T.untyped]))
34
+ @email = T.let(nil, T.nilable(String))
35
+ @gateway = T.let(nil, T.nilable(String))
36
+ @id = T.let(nil, T.nilable(Integer))
37
+ @landing_site = T.let(nil, T.nilable(String))
38
+ @line_items = T.let(nil, T.nilable(T::Hash[T.untyped, T.untyped]))
39
+ @location_id = T.let(nil, T.nilable(Integer))
40
+ @note = T.let(nil, T.nilable(String))
41
+ @phone = T.let(nil, T.nilable(String))
42
+ @presentment_currency = T.let(nil, T.nilable(String))
43
+ @referring_site = T.let(nil, T.nilable(String))
44
+ @shipping_address = T.let(nil, T.nilable(T::Hash[T.untyped, T.untyped]))
45
+ @shipping_lines = T.let(nil, T.nilable(T::Hash[T.untyped, T.untyped]))
46
+ @sms_marketing_phone = T.let(nil, T.nilable(String))
47
+ @source_name = T.let(nil, T.nilable(String))
48
+ @subtotal_price = T.let(nil, T.nilable(String))
49
+ @tax_lines = T.let(nil, T.nilable(T::Hash[T.untyped, T.untyped]))
50
+ @taxes_included = T.let(nil, T.nilable(T::Boolean))
51
+ @token = T.let(nil, T.nilable(String))
52
+ @total_discounts = T.let(nil, T.nilable(String))
53
+ @total_duties = T.let(nil, T.nilable(String))
54
+ @total_line_items_price = T.let(nil, T.nilable(String))
55
+ @total_price = T.let(nil, T.nilable(String))
56
+ @total_tax = T.let(nil, T.nilable(String))
57
+ @total_weight = T.let(nil, T.nilable(Integer))
58
+ @updated_at = T.let(nil, T.nilable(String))
59
+ @user_id = T.let(nil, T.nilable(Integer))
60
+
61
+ super(session: session, from_hash: from_hash)
62
+ end
63
+
64
+ @has_one = T.let({
65
+ currency: Currency,
66
+ customer: Customer
67
+ }, T::Hash[Symbol, Class])
68
+ @has_many = T.let({
69
+ discount_codes: DiscountCode
70
+ }, T::Hash[Symbol, Class])
71
+ @paths = T.let([
72
+ {http_method: :get, operation: :checkouts, ids: [], path: "checkouts.json"},
73
+ {http_method: :get, operation: :checkouts, ids: [], path: "checkouts.json"}
74
+ ], T::Array[T::Hash[String, T.any(T::Array[Symbol], String, Symbol)]])
75
+
76
+ sig { returns(T.nilable(String)) }
77
+ attr_reader :abandoned_checkout_url
78
+ sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
79
+ attr_reader :billing_address
80
+ sig { returns(T.nilable(T::Boolean)) }
81
+ attr_reader :buyer_accepts_marketing
82
+ sig { returns(T.nilable(T::Boolean)) }
83
+ attr_reader :buyer_accepts_sms_marketing
84
+ sig { returns(T.nilable(String)) }
85
+ attr_reader :cart_token
86
+ sig { returns(T.nilable(String)) }
87
+ attr_reader :closed_at
88
+ sig { returns(T.nilable(String)) }
89
+ attr_reader :completed_at
90
+ sig { returns(T.nilable(String)) }
91
+ attr_reader :created_at
92
+ sig { returns(T.nilable(Currency)) }
93
+ attr_reader :currency
94
+ sig { returns(T.nilable(Customer)) }
95
+ attr_reader :customer
96
+ sig { returns(T.nilable(String)) }
97
+ attr_reader :customer_locale
98
+ sig { returns(T.nilable(Integer)) }
99
+ attr_reader :device_id
100
+ sig { returns(T.nilable(T::Array[DiscountCode])) }
101
+ attr_reader :discount_codes
102
+ sig { returns(T.nilable(String)) }
103
+ attr_reader :email
104
+ sig { returns(T.nilable(String)) }
105
+ attr_reader :gateway
106
+ sig { returns(T.nilable(Integer)) }
107
+ attr_reader :id
108
+ sig { returns(T.nilable(String)) }
109
+ attr_reader :landing_site
110
+ sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
111
+ attr_reader :line_items
112
+ sig { returns(T.nilable(Integer)) }
113
+ attr_reader :location_id
114
+ sig { returns(T.nilable(String)) }
115
+ attr_reader :note
116
+ sig { returns(T.nilable(String)) }
117
+ attr_reader :phone
118
+ sig { returns(T.nilable(String)) }
119
+ attr_reader :presentment_currency
120
+ sig { returns(T.nilable(String)) }
121
+ attr_reader :referring_site
122
+ sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
123
+ attr_reader :shipping_address
124
+ sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
125
+ attr_reader :shipping_lines
126
+ sig { returns(T.nilable(String)) }
127
+ attr_reader :sms_marketing_phone
128
+ sig { returns(T.nilable(String)) }
129
+ attr_reader :source_name
130
+ sig { returns(T.nilable(String)) }
131
+ attr_reader :subtotal_price
132
+ sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
133
+ attr_reader :tax_lines
134
+ sig { returns(T.nilable(T::Boolean)) }
135
+ attr_reader :taxes_included
136
+ sig { returns(T.nilable(String)) }
137
+ attr_reader :token
138
+ sig { returns(T.nilable(String)) }
139
+ attr_reader :total_discounts
140
+ sig { returns(T.nilable(String)) }
141
+ attr_reader :total_duties
142
+ sig { returns(T.nilable(String)) }
143
+ attr_reader :total_line_items_price
144
+ sig { returns(T.nilable(String)) }
145
+ attr_reader :total_price
146
+ sig { returns(T.nilable(String)) }
147
+ attr_reader :total_tax
148
+ sig { returns(T.nilable(Integer)) }
149
+ attr_reader :total_weight
150
+ sig { returns(T.nilable(String)) }
151
+ attr_reader :updated_at
152
+ sig { returns(T.nilable(Integer)) }
153
+ attr_reader :user_id
154
+
155
+ class << self
156
+ sig do
157
+ params(
158
+ since_id: T.untyped,
159
+ created_at_min: T.untyped,
160
+ created_at_max: T.untyped,
161
+ updated_at_min: T.untyped,
162
+ updated_at_max: T.untyped,
163
+ status: T.untyped,
164
+ limit: T.untyped,
165
+ session: Auth::Session,
166
+ kwargs: T.untyped
167
+ ).returns(T.untyped)
168
+ end
169
+ def checkouts(
170
+ since_id: nil,
171
+ created_at_min: nil,
172
+ created_at_max: nil,
173
+ updated_at_min: nil,
174
+ updated_at_max: nil,
175
+ status: nil,
176
+ limit: nil,
177
+ session: ShopifyAPI::Context.active_session,
178
+ **kwargs
179
+ )
180
+ request(
181
+ http_method: :get,
182
+ operation: :checkouts,
183
+ session: session,
184
+ ids: {},
185
+ params: {since_id: since_id, created_at_min: created_at_min, created_at_max: created_at_max, updated_at_min: updated_at_min, updated_at_max: updated_at_max, status: status, limit: limit}.merge(kwargs).compact,
186
+ body: {},
187
+ entity: nil,
188
+ )
189
+ end
190
+
191
+ end
192
+
193
+ end
194
+ end
@@ -0,0 +1,62 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ ########################################################################################################################
5
+ # This file is auto-generated. If you have an issue, please create a GitHub issue. #
6
+ ########################################################################################################################
7
+
8
+ module ShopifyAPI
9
+ class AccessScope < ShopifyAPI::Rest::Base
10
+ extend T::Sig
11
+
12
+ @prev_page_info = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
13
+ @next_page_info = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
14
+
15
+ @api_call_limit = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
16
+ @retry_request_after = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
17
+
18
+ sig { params(session: T.nilable(ShopifyAPI::Auth::Session), from_hash: T.nilable(T::Hash[T.untyped, T.untyped])).void }
19
+ def initialize(session: ShopifyAPI::Context.active_session, from_hash: nil)
20
+
21
+ @handle = T.let(nil, T.nilable(String))
22
+ @access_scopes = T.let(nil, T.nilable(T::Array[T.untyped]))
23
+
24
+ super(session: session, from_hash: from_hash)
25
+ end
26
+
27
+ @has_one = T.let({}, T::Hash[Symbol, Class])
28
+ @has_many = T.let({}, T::Hash[Symbol, Class])
29
+ @custom_prefix = T.let("/admin/oauth", T.nilable(String))
30
+ @paths = T.let([
31
+ {http_method: :get, operation: :get, ids: [], path: "access_scopes.json"}
32
+ ], T::Array[T::Hash[String, T.any(T::Array[Symbol], String, Symbol)]])
33
+
34
+ sig { returns(T.nilable(String)) }
35
+ attr_reader :handle
36
+ sig { returns(T.nilable(T::Array[T::Hash[T.untyped, T.untyped]])) }
37
+ attr_reader :access_scopes
38
+
39
+ class << self
40
+ sig do
41
+ params(
42
+ session: Auth::Session,
43
+ kwargs: T.untyped
44
+ ).returns(T::Array[AccessScope])
45
+ end
46
+ def all(
47
+ session: ShopifyAPI::Context.active_session,
48
+ **kwargs
49
+ )
50
+ response = base_find(
51
+ session: session,
52
+ ids: {},
53
+ params: {}.merge(kwargs).compact,
54
+ )
55
+
56
+ T.cast(response, T::Array[AccessScope])
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,109 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ ########################################################################################################################
5
+ # This file is auto-generated. If you have an issue, please create a GitHub issue. #
6
+ ########################################################################################################################
7
+
8
+ module ShopifyAPI
9
+ class ApplePayCertificate < ShopifyAPI::Rest::Base
10
+ extend T::Sig
11
+
12
+ @prev_page_info = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
13
+ @next_page_info = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
14
+
15
+ @api_call_limit = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
16
+ @retry_request_after = T.let(Concurrent::ThreadLocalVar.new { nil }, Concurrent::ThreadLocalVar)
17
+
18
+ sig { params(session: T.nilable(ShopifyAPI::Auth::Session), from_hash: T.nilable(T::Hash[T.untyped, T.untyped])).void }
19
+ def initialize(session: ShopifyAPI::Context.active_session, from_hash: nil)
20
+
21
+ @id = T.let(nil, T.nilable(Integer))
22
+ @merchant_id = T.let(nil, T.nilable(String))
23
+ @status = T.let(nil, T.nilable(String))
24
+
25
+ super(session: session, from_hash: from_hash)
26
+ end
27
+
28
+ @has_one = T.let({}, T::Hash[Symbol, Class])
29
+ @has_many = T.let({}, T::Hash[Symbol, Class])
30
+ @paths = T.let([
31
+ {http_method: :delete, operation: :delete, ids: [:id], path: "apple_pay_certificates/<id>.json"},
32
+ {http_method: :get, operation: :csr, ids: [:id], path: "apple_pay_certificates/<id>/csr.json"},
33
+ {http_method: :get, operation: :get, ids: [:id], path: "apple_pay_certificates/<id>.json"},
34
+ {http_method: :post, operation: :post, ids: [], path: "apple_pay_certificates.json"},
35
+ {http_method: :put, operation: :put, ids: [:id], path: "apple_pay_certificates/<id>.json"}
36
+ ], T::Array[T::Hash[String, T.any(T::Array[Symbol], String, Symbol)]])
37
+
38
+ sig { returns(T.nilable(Integer)) }
39
+ attr_reader :id
40
+ sig { returns(T.nilable(String)) }
41
+ attr_reader :merchant_id
42
+ sig { returns(T.nilable(String)) }
43
+ attr_reader :status
44
+
45
+ class << self
46
+ sig do
47
+ params(
48
+ id: T.any(Integer, String),
49
+ session: Auth::Session
50
+ ).returns(T.nilable(ApplePayCertificate))
51
+ end
52
+ def find(
53
+ id:,
54
+ session: ShopifyAPI::Context.active_session
55
+ )
56
+ result = base_find(
57
+ session: session,
58
+ ids: {id: id},
59
+ params: {},
60
+ )
61
+ T.cast(result[0], T.nilable(ApplePayCertificate))
62
+ end
63
+
64
+ sig do
65
+ params(
66
+ id: T.any(Integer, String),
67
+ session: Auth::Session
68
+ ).returns(T.untyped)
69
+ end
70
+ def delete(
71
+ id:,
72
+ session: ShopifyAPI::Context.active_session
73
+ )
74
+ request(
75
+ http_method: :delete,
76
+ operation: :delete,
77
+ session: session,
78
+ ids: {id: id},
79
+ params: {},
80
+ )
81
+ end
82
+
83
+ sig do
84
+ params(
85
+ id: T.any(Integer, String),
86
+ session: Auth::Session,
87
+ kwargs: T.untyped
88
+ ).returns(T.untyped)
89
+ end
90
+ def csr(
91
+ id:,
92
+ session: ShopifyAPI::Context.active_session,
93
+ **kwargs
94
+ )
95
+ request(
96
+ http_method: :get,
97
+ operation: :csr,
98
+ session: session,
99
+ ids: {id: id},
100
+ params: {}.merge(kwargs).compact,
101
+ body: {},
102
+ entity: nil,
103
+ )
104
+ end
105
+
106
+ end
107
+
108
+ end
109
+ end