shopify_api 6.0.0 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -19
  3. data/CHANGELOG +11 -0
  4. data/Gemfile +1 -2
  5. data/Gemfile_ar41 +5 -0
  6. data/Gemfile_ar50 +5 -0
  7. data/Gemfile_ar51 +5 -0
  8. data/Gemfile_ar_master +0 -1
  9. data/README.md +116 -9
  10. data/RELEASING +2 -5
  11. data/lib/shopify_api.rb +4 -4
  12. data/lib/shopify_api/api_version.rb +116 -0
  13. data/lib/shopify_api/disable_prefix_check.rb +31 -0
  14. data/lib/shopify_api/limits.rb +5 -5
  15. data/lib/shopify_api/resources/access_scope.rb +6 -1
  16. data/lib/shopify_api/resources/asset.rb +15 -11
  17. data/lib/shopify_api/resources/base.rb +63 -1
  18. data/lib/shopify_api/resources/fulfillment_event.rb +1 -1
  19. data/lib/shopify_api/resources/graphql.rb +1 -1
  20. data/lib/shopify_api/resources/inventory_level.rb +2 -2
  21. data/lib/shopify_api/resources/location.rb +1 -1
  22. data/lib/shopify_api/resources/marketing_event.rb +2 -0
  23. data/lib/shopify_api/resources/payment.rb +1 -1
  24. data/lib/shopify_api/resources/refund.rb +4 -3
  25. data/lib/shopify_api/resources/shipping_rate.rb +1 -1
  26. data/lib/shopify_api/resources/shop.rb +4 -2
  27. data/lib/shopify_api/resources/smart_collection.rb +1 -1
  28. data/lib/shopify_api/session.rb +45 -16
  29. data/lib/shopify_api/version.rb +1 -1
  30. data/shopify_api.gemspec +3 -2
  31. data/test/access_scope_test.rb +23 -0
  32. data/test/api_version_test.rb +144 -0
  33. data/test/base_test.rb +75 -32
  34. data/test/detailed_log_subscriber_test.rb +51 -12
  35. data/test/fixtures/access_scopes.json +10 -0
  36. data/test/limits_test.rb +2 -2
  37. data/test/marketing_event_test.rb +1 -1
  38. data/test/recurring_application_charge_test.rb +3 -9
  39. data/test/session_test.rb +158 -32
  40. data/test/test_helper.rb +27 -11
  41. metadata +33 -21
  42. data/Gemfile_ar30 +0 -6
  43. data/Gemfile_ar31 +0 -6
  44. data/Gemfile_ar32 +0 -6
  45. data/Gemfile_ar40 +0 -6
  46. data/lib/active_resource/base_ext.rb +0 -21
  47. data/lib/active_resource/disable_prefix_check.rb +0 -36
  48. data/lib/active_resource/to_query.rb +0 -10
  49. data/lib/shopify_api/json_format.rb +0 -18
  50. data/lib/shopify_api/resources/o_auth.rb +0 -17
  51. data/lib/shopify_api/resources/ping/conversation.rb +0 -42
  52. data/lib/shopify_api/resources/ping/delivery_confirmation_details.rb +0 -10
  53. data/lib/shopify_api/resources/ping/message.rb +0 -8
  54. data/test/fixtures/o_auth_revoke.json +0 -5
  55. data/test/o_auth_test.rb +0 -8
  56. data/test/ping/conversation_test.rb +0 -71
  57. data/test/ping/message_test.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b0ab297c1e32ac84d673b04ddf366cc5f9d43f2eb6f060d70e5d1fcc7c8736f
4
- data.tar.gz: 99a2583bf370e73c85f2b71c4b6e99f1ac2e37db2a628a30dcbed346c29bdf8a
3
+ metadata.gz: d45434390ab4152c9a33eafcd9757ef46c16372f3ad2dee6b918e0a6260ccc26
4
+ data.tar.gz: 552c1cb7a7d72c654e0f5c8fafa909a9a5cb9690e02ff689b1d4f29f9f31d530
5
5
  SHA512:
6
- metadata.gz: 94e653b2a765e962ba1f4c360308bab8a66bb32b8fe487def7ef9880c4b972f934f280fce5805a7f5dcdea60b2a591c0ff4ea87dff04ce6334d490506155aa5a
7
- data.tar.gz: 13701b452c87df0a9fb4054857f37d5821b63bb0ee8e467556bc8bb1d5beeae0712ec2457462567a45a715bc8b5a60d68aad8811385d9353e61779bec68bf060
6
+ metadata.gz: 59f9e5a631f1c9f13d6078636f11480ac711338fecab5caa1a47f5368f11a97514884eb9c42b007e13ad5f1ee8313e0f94c2a3eff7d17a5a3732cc9bea5edc54
7
+ data.tar.gz: e42b188914ca14ee80f0c3307ca1847ee2cfc0bac22c3cb7c6a4c8a1a0bfd3e41fc46d00deb21348ccef764cb3be97e656b8edc25734cd9a1bee28794842e371
@@ -2,31 +2,22 @@ language: ruby
2
2
  sudo: false
3
3
 
4
4
  rvm:
5
- - 2.3.1
6
- - 2.4.0-preview1
5
+ - 2.4.6
6
+ - 2.5.5
7
+ - 2.6.2
7
8
 
8
9
  gemfile:
9
- - Gemfile
10
- - Gemfile_ar30
11
- - Gemfile_ar31
12
- - Gemfile_ar32
13
- - Gemfile_ar40
10
+ - Gemfile_ar41
11
+ - Gemfile_ar50
12
+ - Gemfile_ar51
14
13
  - Gemfile_ar_master
15
14
 
16
15
  matrix:
17
16
  fast_finish: true
18
17
  allow_failures:
19
- - rvm: 2.4.0-preview1
20
- gemfile: Gemfile
21
- - rvm: 2.4.0-preview1
22
- gemfile: Gemfile_ar30
23
- - rvm: 2.4.0-preview1
24
- gemfile: Gemfile_ar31
25
- - rvm: 2.4.0-preview1
26
- gemfile: Gemfile_ar32
27
- - rvm: 2.4.0-preview1
28
- gemfile: Gemfile_ar40
29
- - rvm: 2.4.0-preview1
18
+ - rvm: 2.4.6
30
19
  gemfile: Gemfile_ar_master
31
- - rvm: 2.3.1
20
+ - rvm: 2.5.5
21
+ gemfile: Gemfile_ar_master
22
+ - rvm: 2.6.2
32
23
  gemfile: Gemfile_ar_master
data/CHANGELOG CHANGED
@@ -1,3 +1,14 @@
1
+ == Version 7.0.0
2
+
3
+ * Removed support for `ActiveResouce` < `4.1`.
4
+ * Removed `ShopifyAPI::Oauth`.
5
+ * Added api version support, See [migration
6
+ notes](README.md#-breaking-change-notice-for-version-700-)
7
+ * Changed `ShopifyAPI::Session` method signatures from positional to keyword
8
+ arguments, See [migration notes](README.md#-breaking-change-notice-for-version-700-)
9
+ * Add support for newer call limit header `X-Shopify-Shop-Api-Call-Limit`.
10
+ * Removed all Ping resources.
11
+
1
12
  == Version 6.0.0
2
13
 
3
14
  * Removed undocumented `protocol` and `port` options from `ShopifyAPI::Session`.
data/Gemfile CHANGED
@@ -2,5 +2,4 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
- gem "activeresource", "~> 4.1"
6
- gem "rack", "< 2" if RUBY_VERSION < "2.2"
5
+ gem "activeresource", "~> 5.1"
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "activeresource", "4.1.0"
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "activeresource", "5.0.0"
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "activeresource", "5.1.0"
@@ -3,4 +3,3 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  gem 'activeresource', git: 'git://github.com/rails/activeresource'
6
- gem "rack", "< 2" if RUBY_VERSION < "2.2"
data/README.md CHANGED
@@ -10,12 +10,87 @@ The Shopify API gem allows Ruby developers to programmatically access the admin
10
10
 
11
11
  The API is implemented as JSON over HTTP using all four verbs (GET/POST/PUT/DELETE). Each resource, like Order, Product, or Collection, has its own URL and is manipulated in isolation. In other words, we’ve tried to make the API follow the REST principles as much as possible.
12
12
 
13
- ## ⚠️ Breaking change notice for version 5.0.0 ⚠️
14
- The [Abandoned Checkout API](https://help.shopify.com/en/api/reference/orders/abandoned_checkouts) is now accessed through the `ShopifyAPI::AbandonedCheckout` resource. If you were previously accessing the Abandoned Checkout API through the `ShopifyAPI::Checkout` resource, you will need to update your code after upgrading from version 4.x.x or earlier.
13
+ ## !! Breaking change notice for version 7.0.0 !!
15
14
 
16
- Going forward, the `ShopifyAPI::Checkout` resource is used to access the [Checkout API](https://help.shopify.com/en/api/reference/sales_channels/checkout), which can be used to create new checkouts.
15
+ ### Changes to ShopifyAPI::Session
16
+ Session creation requires `api_version` to be set and now uses keyword arguments
17
17
 
18
- For more details, [please see this issue](https://github.com/Shopify/shopify_api/issues/471).
18
+ To upgrade your use of ShopifyAPI you will need to make the following changes.
19
+
20
+ ```ruby
21
+ ShopifyAPI::Session.new(domain, token, extras)
22
+ ```
23
+ is now
24
+ ```ruby
25
+ ShopifyAPI::Session.new(domain: domain, token: token, api_verison: api_verison, extras: extras)
26
+ ```
27
+ Note `extras` is still optional the other arguments are required.
28
+
29
+ ```ruby
30
+ ShopifyAPI::Session.temp(domain, token, extras) do
31
+ ...
32
+ end
33
+ ```
34
+ is now
35
+ ```ruby
36
+ ShopifyAPI::Session.temp(domain: domain, token: token, api_verison: api_verison) do
37
+ ...
38
+ end
39
+ ```
40
+
41
+ The `api_version` attribute can take the string or symbol name of any known version and correctly coerce it to a `ShopifyAPI::ApiVersion`. You can find the currently defined versions [here](https://github.com/Shopify/shopify_api/blob/master/lib/shopify_api/api_version.rb#L58), follow these [instructions](#adding-aditional-api-versions) to add additional version definitions if needed.
42
+
43
+ For example if you want to use the `2019-04` version you would create a session like this:
44
+ ```ruby
45
+ session = ShopifyAPI::Session.new(domain: domain, token: token, api_verison: '2019-04')
46
+ ```
47
+ if you want to use the `unstable` version you would create a session like this:
48
+ ```ruby
49
+ session = ShopifyAPI::Session.new(domain: domain, token: token, api_verison: :unstable)
50
+ ```
51
+
52
+ ### Changes to how to define resources
53
+
54
+ If you have defined or customized Resources, classes that extend `ShopifyAPI::Base`:
55
+ The use of `self.prefix =` has been deprecated you should now use `self.resource =` and not include `/admin`.
56
+ For example if you specified a prefix like this before:
57
+ ```ruby
58
+ class MyResource < ShopifyAPI::Base
59
+ self.prefix = '/admin/shop/'
60
+ end
61
+ ```
62
+ You will update this to:
63
+ ```ruby
64
+ class MyResource < ShopifyAPI::Base
65
+ self.resource_prefix = 'shop/'
66
+ end
67
+ ```
68
+
69
+ ### URL construction
70
+
71
+ If you have specifed any full paths for API calls in find
72
+ ```ruby
73
+ def self.current(options={})
74
+ find(:one, options.merge(from: "/admin/shop.#{format.extension}"))
75
+ end
76
+ ```
77
+ would be changed to
78
+
79
+ ```ruby
80
+ def self.current(options = {})
81
+ find(:one, options.merge(
82
+ from: api_version.construct_api_path("shop.#{format.extension}")
83
+ ))
84
+ end
85
+ ```
86
+
87
+ ### URLs that have not changed
88
+
89
+ - OAuth URLs for `authorize`, getting the `access_token` from a code, `access_scopes`, and using a `refresh_token` have _not_ changed.
90
+ - get: `/admin/oauth/authorize.json`
91
+ - post: `/admin/oauth/access_token.json`
92
+ - get: `/admin/oauth/access_scopes.json`
93
+ - URLs for the merchant’s web admin have _not_ changed. For example: to send the merchant to the product page the url is still `/admin/product/<id>`
19
94
 
20
95
  ## Usage
21
96
 
@@ -57,8 +132,9 @@ ShopifyAPI uses ActiveResource to communicate with the REST web service. ActiveR
57
132
  2. For a private App you just need to set the base site url as follows:
58
133
 
59
134
  ```ruby
60
- shop_url = "https://#{API_KEY}:#{PASSWORD}@#{SHOP_NAME}.myshopify.com/admin"
135
+ shop_url = "https://#{API_KEY}:#{PASSWORD}@#{SHOP_NAME}.myshopify.com"
61
136
  ShopifyAPI::Base.site = shop_url
137
+ ShopifyAPI::Base.api_verison = '<version_name>' # find the latest stable api_version [here](https://help.shopify.com/api/versioning)
62
138
  ```
63
139
 
64
140
  That's it, you're done, skip to step 6 and start using the API!
@@ -88,7 +164,7 @@ ShopifyAPI uses ActiveResource to communicate with the REST web service. ActiveR
88
164
  We've added the create_permission_url method to make this easier, first instantiate your session object:
89
165
 
90
166
  ```ruby
91
- shopify_session = ShopifyAPI::Session.new("SHOP_NAME.myshopify.com")
167
+ shopify_session = ShopifyAPI::Session.new(domain: "SHOP_NAME.myshopify.com", api_version: api_version, token: nil)
92
168
  ```
93
169
 
94
170
  Then call:
@@ -155,7 +231,7 @@ ShopifyAPI uses ActiveResource to communicate with the REST web service. ActiveR
155
231
  For future sessions simply pass in the `token` and `extra` hash (optional) when creating the session object:
156
232
 
157
233
  ```ruby
158
- shopify_session = ShopifyAPI::Session.new("SHOP_NAME.myshopify.com", token, extra)
234
+ shopify_session = ShopifyAPI::Session.new(domain: "SHOP_NAME.myshopify.com", token: token, api_version: api_version, extra: extra)
159
235
  ```
160
236
 
161
237
  5. The session must be activated before use:
@@ -187,10 +263,26 @@ ShopifyAPI uses ActiveResource to communicate with the REST web service. ActiveR
187
263
  Alternatively, you can use #temp to initialize a Session and execute a command which also handles temporarily setting ActiveResource::Base.site:
188
264
 
189
265
  ```ruby
190
- products = ShopifyAPI::Session.temp("SHOP_NAME.myshopify.com", token) { ShopifyAPI::Product.find(:all) }
266
+ products = ShopifyAPI::Session.temp(domain: "SHOP_NAME.myshopify.com", token: token, api_version: api_version) do
267
+ ShopifyAPI::Product.find(:all)
268
+ end
269
+ ```
270
+
271
+ 7. If you would like to run a small number of calls against a different API version you can use this block syntax:
272
+
273
+ ```ruby
274
+ ShopifyAPI::Session.temp(domain: "SHOP_NAME.myshopify.com", token: token, api_version: '2019-04') do
275
+ ShopifyAPI::Product.find(:all) # find call against version `2019-04`
276
+
277
+ ShopifyAPI::Session.with_version(:unstable) do
278
+ ShopifyAPI::Product.find(:all) # find call against version `unstable`
279
+ end
280
+
281
+ ShopifyAPI::Product.find(:all) # find call against version `2019-04`
282
+ end
191
283
  ```
192
284
 
193
- 7. If you want to work with another shop, you'll first need to clear the session:
285
+ 8. If you want to work with another shop, you'll first need to clear the session:
194
286
 
195
287
  ```ruby
196
288
  ShopifyAPI::Base.clear_session
@@ -252,6 +344,21 @@ result = client.query(SHOP_NAME_QUERY)
252
344
  result.data.shop.name
253
345
  ```
254
346
 
347
+ ## Adding aditional API versions
348
+ We will release a gem update every time we release a new version of the API. Most of the time upgrading the gem will be all you need to do.
349
+
350
+ If you want access to a newer version without upgrading you can define an api version.
351
+ For example if you wanted to add an `ApiVersion` '2022-03', you would add the following to the initialization of your application:
352
+ ```ruby
353
+ ShopifyAPI::ApiVersion.define_version(ShopifyAPI::ApiVersion::Release.new('2022-03')
354
+ ```
355
+ Once you have done that you can now set this version in a Sesssion like this:
356
+
357
+ ```ruby
358
+ ShopifyAPI::Session.new(domain: domain, token: token, api_version: '2022-03')
359
+ ```
360
+
361
+
255
362
  ## Threadsafety
256
363
 
257
364
  ActiveResource is threadsafe as of version 4.1 (which works with Rails 4.x and above).
data/RELEASING CHANGED
@@ -2,7 +2,7 @@ Releasing ShopifyAPI
2
2
 
3
3
  1. Check the Semantic Versioning page for info on how to version the new release: http://semver.org
4
4
  2. Update the version of ShopifyAPI in lib/shopify_api/version.rb
5
- 3. Add a CHANGELOG entry for the new release with the date
5
+ 3. Add a CHANGELOG entry for the new release
6
6
  4. Commit the changes with a commit message like "Packaging for release X.Y.Z"
7
7
  5. Tag the release with the version (Leave REV blank for HEAD or provide a SHA)
8
8
  $ git tag vX.Y.Z REV
@@ -10,7 +10,4 @@ Releasing ShopifyAPI
10
10
  $ git push
11
11
  7. Push out the tags
12
12
  $ git push --tags
13
- 8. Build the new .gem from the updated .gemspec
14
- $ gem build shopify_api.gemspec
15
- 9. Publish the Gem to gemcutter
16
- $ gem push shopify_api-X.Y.Z.gem
13
+ 8. Publish the gem using Shipit
@@ -6,11 +6,9 @@ require 'digest/md5'
6
6
  require 'base64'
7
7
  require 'active_resource/detailed_log_subscriber'
8
8
  require 'shopify_api/limits'
9
- require 'shopify_api/json_format'
9
+ require 'shopify_api/api_version'
10
10
  require 'active_resource/json_errors'
11
- require 'active_resource/disable_prefix_check'
12
- require 'active_resource/base_ext'
13
- require 'active_resource/to_query'
11
+ require 'shopify_api/disable_prefix_check'
14
12
 
15
13
  module ShopifyAPI
16
14
  include Limits
@@ -28,3 +26,5 @@ if ShopifyAPI::Base.respond_to?(:connection_class)
28
26
  else
29
27
  require 'active_resource/connection_ext'
30
28
  end
29
+
30
+ ShopifyAPI::ApiVersion.define_known_versions
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+ module ShopifyAPI
3
+ class ApiVersion
4
+ class UnknownVersion < StandardError; end
5
+ class InvalidVersion < StandardError; end
6
+
7
+ include Comparable
8
+
9
+ def self.coerce_to_version(version_or_name)
10
+ return version_or_name if version_or_name.is_a?(ApiVersion)
11
+
12
+ @versions ||= {}
13
+ @versions.fetch(version_or_name.to_s) do
14
+ raise UnknownVersion, "#{version_or_name} is not in the defined version set: #{@versions.keys.join(', ')}"
15
+ end
16
+ end
17
+
18
+ def self.define_version(version)
19
+ @versions ||= {}
20
+
21
+ @versions[version.name] = version
22
+ end
23
+
24
+ def self.clear_defined_versions
25
+ @versions = {}
26
+ end
27
+
28
+ def self.define_known_versions
29
+ define_version(Unstable.new)
30
+ define_version(Release.new('2019-04'))
31
+ end
32
+
33
+ def self.latest_stable_version
34
+ @versions.values.select(&:stable?).sort.last
35
+ end
36
+
37
+ def to_s
38
+ @version_name
39
+ end
40
+ alias_method :name, :to_s
41
+
42
+ def inspect
43
+ @version_name
44
+ end
45
+
46
+ def ==(other)
47
+ other.class == self.class && to_s == other.to_s
48
+ end
49
+
50
+ def hash
51
+ @version_name.hash
52
+ end
53
+
54
+ def <=>(other)
55
+ numeric_version <=> other.numeric_version
56
+ end
57
+
58
+ def stable?
59
+ false
60
+ end
61
+
62
+ def construct_api_path(_path)
63
+ raise NotImplementedError
64
+ end
65
+
66
+ def construct_graphql_path
67
+ raise NotImplementedError
68
+ end
69
+
70
+ protected
71
+
72
+ attr_reader :numeric_version
73
+
74
+ class Unstable < ApiVersion
75
+ API_PREFIX = '/admin/api/unstable/'
76
+
77
+ def initialize
78
+ @version_name = "unstable"
79
+ @url = API_PREFIX
80
+ @numeric_version = 9_000_00
81
+ end
82
+
83
+ def construct_api_path(path)
84
+ "#{@url}#{path}"
85
+ end
86
+
87
+ def construct_graphql_path
88
+ construct_api_path("graphql.json")
89
+ end
90
+ end
91
+
92
+ class Release < ApiVersion
93
+ FORMAT = /^\d{4}-\d{2}$/.freeze
94
+ API_PREFIX = '/admin/api/'
95
+
96
+ def initialize(version_number)
97
+ raise InvalidVersion, version_number unless version_number.match(FORMAT)
98
+ @version_name = version_number
99
+ @url = "#{API_PREFIX}#{version_number}/"
100
+ @numeric_version = version_number.tr('-', '').to_i
101
+ end
102
+
103
+ def stable?
104
+ true
105
+ end
106
+
107
+ def construct_api_path(path)
108
+ "#{@url}#{path}"
109
+ end
110
+
111
+ def construct_graphql_path
112
+ construct_api_path('graphql.json')
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module ShopifyAPI
3
+ module DisablePrefixCheck
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def check_prefix_options(options)
8
+ end
9
+
10
+ # `flexible = true` is hack to allow multiple things through the same AR class
11
+ def conditional_prefix(resource, flexible = false)
12
+ resource_id = "#{resource}_id".to_sym
13
+ resource_type = flexible ? ":#{resource}" : resource.to_s.pluralize
14
+
15
+ init_prefix_explicit(resource_type, resource_id)
16
+
17
+ define_singleton_method :resource_prefix do |options = {}|
18
+ resource_type = options[resource] if flexible
19
+
20
+ options[resource_id].nil? ? '' : "#{resource_type}/#{options[resource_id]}/"
21
+ end
22
+
23
+ define_singleton_method :instantiate_record do |record, prefix_options = {}|
24
+ new(record, true).tap do |resource_instance|
25
+ resource_instance.prefix_options = prefix_options unless prefix_options.blank?
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end