shopify_api 13.2.0 → 13.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b83eabed3d0c78f619d6061eb4bb92c389e1d15afca55225c243c0200a73f1f9
4
- data.tar.gz: 2d6858dda679bb4a65f2eddbbc3d746f6177eda1808109a1ebcce943ae5cb9b9
3
+ metadata.gz: 3242835d9dedea2805ab36b498f6fc5b1e778584b6edf05d07c894cf87bf1dec
4
+ data.tar.gz: 6953d7096849c3ee5b685ec708ef3d0191252f6c48adaa97c163487c73c52687
5
5
  SHA512:
6
- metadata.gz: fb175ef43080cec7459eff1a7a40c3d0c48aabc8b69bd8fe10fba1bdcfb3c3ca9a9d4e5e5bd6184421a0639f06b18097efa151c912439198f28838a6f60b5b67
7
- data.tar.gz: 121a72ef9cc5b608b96d5be67a9404f739598708e9649fd720b21fa7614f2d53f162d2e12872441bf4419318d5cb7f13721606239ce21f9bbfa3868e1c4153f8
6
+ metadata.gz: c407661dca2a62ba8815cc42371471eccc5a6cf4a1633aac95b9506ade343e89b5d4831376ff8a994093a7a721b2f4ac1708f736b1c4f8df7c17a978407188c0
7
+ data.tar.gz: c7eb834293eb3c5101b6fe17fb2ee4bc7771e8e9cf9f747c77f2cdb5ba123346cad392eef52b1c4cf323270ee9e26bdc60e475a38512d4d7b097f54744d93caa
data/.github/CODEOWNERS CHANGED
@@ -1 +1 @@
1
- * @shopify/learn-libs-superteam
1
+ * @Shopify/client-libraries-app-templates
@@ -20,6 +20,10 @@ jobs:
20
20
  uses: ruby/setup-ruby@v1
21
21
  with:
22
22
  ruby-version: ${{ matrix.version }}
23
+ - name: Install OpenSSL
24
+ run: |
25
+ sudo apt-get update
26
+ sudo apt-get install -y libssl-dev
23
27
  - name: Run Bundle Commands
24
28
  run: |
25
29
  bundle config set --with docs
data/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ Note: For changes to the API, see https://shopify.dev/changelog?filter=api
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 13.3.0
8
+
9
+ - [#1241](https://github.com/Shopify/shopify-api-ruby/pull/1241) Add `api_host` to `ShopifyAPI::Context.setup`, allowing the API host to be overridden in `ShopifyAPI::Clients::HttpClient`. This context option is intended for internal Shopify use only.
10
+ - [#1237](https://github.com/Shopify/shopify-api-ruby/pull/1237) Skip mandatory webhook topic registration/unregistrations
11
+ - [#1239](https://github.com/Shopify/shopify-api-ruby/pull/1239) Update `OAuth.validate_auth_callback` to use `ShopifyApi::Clients::HttpClient`.
12
+
7
13
  ## 13.2.0
8
14
 
9
15
  - [#1183](https://github.com/Shopify/shopify-api-ruby/pull/1189) Added string array support for fields parameter in Webhook::Registry
data/CONTRIBUTING.md CHANGED
@@ -1,9 +1,34 @@
1
1
 
2
2
  Submitting Issues
3
3
  -----------------
4
+ Submitting Issues
4
5
 
5
6
  Please open an issue here if you encounter a specific bug with this API client library or if something is documented here https://shopify.dev/docs/apps but is missing from this package.
6
7
 
7
8
  General questions about the Shopify API and usage of this package (not necessarily a bug) should be posted on the [Shopify forums](https://community.shopify.com/c/partners-and-developers/ct-p/appdev).
8
9
 
9
10
  When in doubt, post on the forum first. You'll likely have your questions answered more quickly if you post there; more people monitor the forum than Github.
11
+
12
+ In order for us to best triage the issue, please include steps to reproduce the issue as well as the impacted feature.
13
+
14
+ ## Roadmap
15
+
16
+ The focus of development efforts by maintainers of this project a roadmap will be proposed via PR and accessible at any point in the ROADMAP.md file.
17
+
18
+ Working with a pull request modify the [ROADMAP.md](https://github.com/Shopify/shopify-api-ruby/blob/aa0b7f9a5a9095ca11f3f93f9aecc72e8daa6bce/ROADMAP.md) allows us to invite community feedback on the direction while not adding another communication avenue. While there are certainly better tools for the job than a markdown file for this, we are aiming to keep a minimal toolset to help us better manage the communication channels that we have open.
19
+
20
+ If there are concerns with the direction and priorities of the maintainers, this roadmap PR is the appropriate place to share your concerns.
21
+
22
+ ## Submitting Pull Requests
23
+
24
+ We welcome pull requests and help from the community! PRs fixing bugs will take priority to triaging proposed net new functionality. If you do want to add a feature, we recommend opening an issue first exploring the appetite of the community / maintainers to ensure there is alignment on direction before you spend time on the PR.
25
+
26
+ ## Gem Architecture
27
+ Understanding how all the components of the Shopify App development stack work together will help best understand what level of abstraction a feature is meant to be applied. Please consider this architecture before introducing new functionally to ensure it is in the right place:
28
+
29
+ | Gem Name | Job |
30
+ |---|---|
31
+ | Shopify API (this gem) | Obtain a session, clients for APIs (REST, GraphQL), error handling, webhook management |
32
+ | REST Resources | Interfaces to the APIs. Response casting into defined objects with attributes/methods |
33
+ | Shopify App | Build Shopify app using Rails conventions. Oauth, webhook processing, persistence, etc |
34
+ | App Template | Template demonstrating how to use all these components in one starting boilerplate application |
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shopify_api (13.2.0)
4
+ shopify_api (13.3.0)
5
5
  activesupport
6
6
  concurrent-ruby
7
7
  hash_diff
@@ -40,7 +40,6 @@ GEM
40
40
  concurrent-ruby (~> 1.0)
41
41
  json (2.6.2)
42
42
  jwt (2.7.1)
43
- language_server-protocol (3.17.0.1)
44
43
  method_source (1.0.0)
45
44
  mini_mime (1.1.5)
46
45
  minitest (5.15.0)
@@ -50,9 +49,9 @@ GEM
50
49
  oj (3.16.0)
51
50
  openssl (3.1.0)
52
51
  parallel (1.22.1)
53
- parser (3.1.2.1)
52
+ parser (3.2.2.4)
54
53
  ast (~> 2.4.1)
55
- prettier_print (0.1.0)
54
+ racc
56
55
  pry (0.14.1)
57
56
  coderay (~> 1.1)
58
57
  method_source (~> 1.0)
@@ -60,6 +59,7 @@ GEM
60
59
  byebug (~> 11.0)
61
60
  pry (>= 0.13, < 0.15)
62
61
  public_suffix (4.0.6)
62
+ racc (1.7.1)
63
63
  rainbow (3.1.1)
64
64
  rake (13.0.6)
65
65
  rbi (0.0.15)
@@ -85,10 +85,6 @@ GEM
85
85
  rubocop (~> 1.35)
86
86
  rubocop-sorbet (0.6.11)
87
87
  rubocop (>= 0.90.0)
88
- ruby-lsp (0.3.2)
89
- language_server-protocol (~> 3.17.0)
90
- sorbet-runtime
91
- syntax_tree (>= 3.4)
92
88
  ruby-progressbar (1.11.0)
93
89
  securerandom (0.2.2)
94
90
  sorbet (0.5.10438)
@@ -104,8 +100,6 @@ GEM
104
100
  sorbet (>= 0.5.9204)
105
101
  sorbet-runtime (>= 0.5.9204)
106
102
  thor (>= 0.19.2)
107
- syntax_tree (3.6.1)
108
- prettier_print
109
103
  tapioca (0.10.2)
110
104
  bundler (>= 1.17.3)
111
105
  netrc (>= 0.11.0)
@@ -149,7 +143,6 @@ DEPENDENCIES
149
143
  rubocop
150
144
  rubocop-shopify
151
145
  rubocop-sorbet
152
- ruby-lsp
153
146
  shopify_api!
154
147
  sorbet
155
148
  tapioca
data/ROADMAP.md ADDED
@@ -0,0 +1,10 @@
1
+ # Roadmap
2
+
3
+ |Priority|Description|Delivery Time frame|
4
+ |---|---|---|
5
+ |P0|Respond timely to open issues/Pull Requests|Ongoing|
6
+ |P1|Minor API release with support for 10-23 API version|Oct 6 - 13|
7
+ |P2|Restore dot notation access to GraphQL responses|Oct 26 - Dec 7|
8
+ |P2|Restrospection GQL queries to define types for GQL resources|October 26- Dec 7|
9
+ |P2|New token exchange authentication via optional feature flag|October 26- Dec 7|
10
+ |P3|[Extract REST resources into their own gem](https://github.com/Shopify/shopify-api-ruby/issues/1194)|Oct 26 - Dec 7|
@@ -75,8 +75,8 @@ module ShopifyAPI
75
75
  def decode_token(token, api_secret_key)
76
76
  JWT.decode(token, api_secret_key, true,
77
77
  { exp_leeway: JWT_EXPIRATION_LEEWAY, algorithm: "HS256" })[0]
78
- rescue
79
- raise ShopifyAPI::Errors::InvalidJwtTokenError, "Failed to parse session token '#{token}'"
78
+ rescue JWT::DecodeError => err
79
+ raise ShopifyAPI::Errors::InvalidJwtTokenError, "Error decoding session token: #{err.message}"
80
80
  end
81
81
  end
82
82
  end
@@ -70,15 +70,25 @@ module ShopifyAPI
70
70
  raise Errors::InvalidOauthError,
71
71
  "Invalid state in OAuth callback." unless state == auth_query.state
72
72
 
73
- # TODO: replace this call with the HTTP client once it is built
73
+ null_session = Auth::Session.new(shop: auth_query.shop)
74
74
  body = { client_id: Context.api_key, client_secret: Context.api_secret_key, code: auth_query.code }
75
- response = HTTParty.post("https://#{auth_query.shop}/admin/oauth/access_token", body: body)
76
- unless response.ok?
75
+
76
+ client = Clients::HttpClient.new(session: null_session, base_path: "/admin/oauth")
77
+ response = begin
78
+ client.request(
79
+ Clients::HttpRequest.new(
80
+ http_method: :post,
81
+ path: "access_token",
82
+ body: body,
83
+ body_type: "application/json",
84
+ ),
85
+ )
86
+ rescue ShopifyAPI::Errors::HttpResponseError => e
77
87
  raise Errors::RequestAccessTokenError,
78
- "Cannot complete OAuth process. Received a #{response.code} error while requesting access token."
88
+ "Cannot complete OAuth process. Received a #{e.code} error while requesting access token."
79
89
  end
80
- session_params = response.to_h
81
90
 
91
+ session_params = T.cast(response.body, T::Hash[String, T.untyped]).to_h
82
92
  session = create_new_session(session_params, auth_query.shop)
83
93
 
84
94
  cookie = if Context.embedded?
@@ -13,7 +13,9 @@ module ShopifyAPI
13
13
  session ||= Context.active_session
14
14
  raise Errors::NoActiveSessionError, "No passed or active session" unless session
15
15
 
16
- @base_uri = T.let("https://#{session.shop}", String)
16
+ api_host = Context.api_host
17
+
18
+ @base_uri = T.let("https://#{api_host || session.shop}", String)
17
19
  @base_uri_and_path = T.let("#{@base_uri}#{base_path}", String)
18
20
 
19
21
  user_agent_prefix = Context.user_agent_prefix.nil? ? "" : "#{Context.user_agent_prefix} | "
@@ -23,6 +25,8 @@ module ShopifyAPI
23
25
  "Accept": "application/json",
24
26
  }, T::Hash[T.any(Symbol, String), T.untyped])
25
27
 
28
+ @headers["Host"] = session.shop unless api_host.nil?
29
+
26
30
  unless session.access_token.nil? || T.must(session.access_token).empty?
27
31
  @headers["X-Shopify-Access-Token"] = T.cast(session.access_token, String)
28
32
  end
@@ -8,6 +8,7 @@ module ShopifyAPI
8
8
  @api_key = T.let("", String)
9
9
  @api_secret_key = T.let("", String)
10
10
  @api_version = T.let(LATEST_SUPPORTED_ADMIN_VERSION, String)
11
+ @api_host = T.let(nil, T.nilable(String))
11
12
  @scope = T.let(Auth::AuthScopes.new, Auth::AuthScopes)
12
13
  @is_private = T.let(false, T::Boolean)
13
14
  @private_shop = T.let(nil, T.nilable(String))
@@ -41,6 +42,7 @@ module ShopifyAPI
41
42
  private_shop: T.nilable(String),
42
43
  user_agent_prefix: T.nilable(String),
43
44
  old_api_secret_key: T.nilable(String),
45
+ api_host: T.nilable(String),
44
46
  ).void
45
47
  end
46
48
  def setup(
@@ -56,7 +58,8 @@ module ShopifyAPI
56
58
  host: ENV["HOST"] || "https://#{host_name}",
57
59
  private_shop: nil,
58
60
  user_agent_prefix: nil,
59
- old_api_secret_key: nil
61
+ old_api_secret_key: nil,
62
+ api_host: nil
60
63
  )
61
64
  unless ShopifyAPI::AdminVersions::SUPPORTED_ADMIN_VERSIONS.include?(api_version)
62
65
  raise Errors::UnsupportedVersionError,
@@ -66,6 +69,7 @@ module ShopifyAPI
66
69
  @api_key = api_key
67
70
  @api_secret_key = api_secret_key
68
71
  @api_version = api_version
72
+ @api_host = api_host
69
73
  @host = T.let(host, T.nilable(String))
70
74
  @is_private = is_private
71
75
  @scope = Auth::AuthScopes.new(scope)
@@ -130,7 +134,7 @@ module ShopifyAPI
130
134
  end
131
135
 
132
136
  sig { returns(T.nilable(String)) }
133
- attr_reader :private_shop, :user_agent_prefix, :old_api_secret_key, :host
137
+ attr_reader :private_shop, :user_agent_prefix, :old_api_secret_key, :host, :api_host
134
138
 
135
139
  sig { returns(T::Boolean) }
136
140
  def embedded?
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module ShopifyAPI
5
- VERSION = "13.2.0"
5
+ VERSION = "13.3.0"
6
6
  end
@@ -5,6 +5,11 @@ module ShopifyAPI
5
5
  module Webhooks
6
6
  class Registry
7
7
  @registry = T.let({}, T::Hash[String, Registration])
8
+ MANDATORY_TOPICS = T.let([
9
+ "shop/redact",
10
+ "customers/redact",
11
+ "customers/data_request",
12
+ ].freeze, T::Array[String])
8
13
 
9
14
  class << self
10
15
  extend T::Sig
@@ -17,6 +22,8 @@ module ShopifyAPI
17
22
  metafield_namespaces: T.nilable(T::Array[String])).void
18
23
  end
19
24
  def add_registration(topic:, delivery_method:, path:, handler: nil, fields: nil, metafield_namespaces: nil)
25
+ return if mandatory_webhook_topic?(topic)
26
+
20
27
  @registry[topic] = case delivery_method
21
28
  when :pub_sub
22
29
  Registrations::PubSub.new(topic: topic, path: path, fields: fields,
@@ -101,6 +108,8 @@ module ShopifyAPI
101
108
  ).returns(T::Hash[String, T.untyped])
102
109
  end
103
110
  def unregister(topic:, session:)
111
+ return { "response": nil } if mandatory_webhook_topic?(topic)
112
+
104
113
  client = Clients::Graphql::Admin.new(session: session)
105
114
 
106
115
  webhook_id = get_webhook_id(topic: topic, client: client)
@@ -213,6 +222,13 @@ module ShopifyAPI
213
222
  def registration_sucessful?(body, mutation_name)
214
223
  !body.dig("data", mutation_name, "webhookSubscription").nil?
215
224
  end
225
+
226
+ # Mandatory webhooks are subscribed to via the partner dashboard not the API
227
+ # https://shopify.dev/docs/apps/webhooks/configuration/mandatory-webhooks
228
+ sig { params(topic: String).returns(T::Boolean) }
229
+ def mandatory_webhook_topic?(topic)
230
+ MANDATORY_TOPICS.include?(topic)
231
+ end
216
232
  end
217
233
  end
218
234
  end
data/shopify_api.gemspec CHANGED
@@ -48,7 +48,6 @@ Gem::Specification.new do |s|
48
48
  s.add_development_dependency("rubocop")
49
49
  s.add_development_dependency("rubocop-shopify")
50
50
  s.add_development_dependency("rubocop-sorbet")
51
- s.add_development_dependency("ruby-lsp")
52
51
  s.add_development_dependency("sorbet")
53
52
  s.add_development_dependency("tapioca")
54
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 13.2.0
4
+ version: 13.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-10 00:00:00.000000000 Z
11
+ date: 2023-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -220,20 +220,6 @@ dependencies:
220
220
  - - ">="
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
- - !ruby/object:Gem::Dependency
224
- name: ruby-lsp
225
- requirement: !ruby/object:Gem::Requirement
226
- requirements:
227
- - - ">="
228
- - !ruby/object:Gem::Version
229
- version: '0'
230
- type: :development
231
- prerelease: false
232
- version_requirements: !ruby/object:Gem::Requirement
233
- requirements:
234
- - - ">="
235
- - !ruby/object:Gem::Version
236
- version: '0'
237
223
  - !ruby/object:Gem::Dependency
238
224
  name: sorbet
239
225
  requirement: !ruby/object:Gem::Requirement
@@ -296,6 +282,7 @@ files:
296
282
  - LICENSE
297
283
  - README.md
298
284
  - RELEASING.md
285
+ - ROADMAP.md
299
286
  - Rakefile
300
287
  - SECURITY.md
301
288
  - bin/tapioca
@@ -970,7 +957,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
970
957
  - !ruby/object:Gem::Version
971
958
  version: '0'
972
959
  requirements: []
973
- rubygems_version: 3.4.20
960
+ rubygems_version: 3.4.21
974
961
  signing_key:
975
962
  specification_version: 4
976
963
  summary: The gem for accessing the Shopify API