shopify_api 4.9.0 → 4.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/.travis.yml +0 -4
- data/CHANGELOG +18 -0
- data/README.md +28 -12
- data/lib/shopify_api/limits.rb +1 -2
- data/lib/shopify_api/resources/access_scope.rb +5 -0
- data/lib/shopify_api/resources/api_permission.rb +9 -0
- data/lib/shopify_api/resources/asset.rb +8 -8
- data/lib/shopify_api/resources/billing_address.rb +1 -1
- data/lib/shopify_api/resources/custom_collection.rb +3 -3
- data/lib/shopify_api/resources/{customer_invite_message.rb → customer_invite.rb} +0 -0
- data/lib/shopify_api/resources/graphql.rb +22 -0
- data/lib/shopify_api/resources/image.rb +2 -2
- data/lib/shopify_api/resources/inventory_item.rb +6 -0
- data/lib/shopify_api/resources/inventory_level.rb +55 -0
- data/lib/shopify_api/resources/line_item.rb +9 -1
- data/lib/shopify_api/resources/location.rb +4 -0
- data/lib/shopify_api/resources/o_auth.rb +8 -0
- data/lib/shopify_api/resources/order.rb +7 -2
- data/lib/shopify_api/resources/ping.rb +3 -0
- data/lib/shopify_api/resources/ping/conversation.rb +18 -0
- data/lib/shopify_api/resources/ping/message.rb +9 -0
- data/lib/shopify_api/resources/product.rb +4 -4
- data/lib/shopify_api/resources/shipping_line.rb +1 -1
- data/lib/shopify_api/resources/shop.rb +4 -4
- data/lib/shopify_api/version.rb +1 -1
- data/shopify_api.gemspec +2 -1
- data/test/api_permission_test.rb +9 -0
- data/test/fixtures/inventory_level.json +7 -0
- data/test/fixtures/inventory_levels.json +24 -0
- data/test/fixtures/order_with_properties.json +373 -0
- data/test/fixtures/ping/conversation.json +1 -0
- data/test/fixtures/ping/message.json +1 -0
- data/test/inventory_level_test.rb +59 -0
- data/test/location_test.rb +14 -0
- data/test/order_test.rb +13 -1
- data/test/ping/conversation_test.rb +39 -0
- data/test/test_helper.rb +7 -5
- data/test/variant_test.rb +4 -1
- metadata +37 -10
- data/lib/shopify_api/resources/discount.rb +0 -11
- data/test/discount_test.rb +0 -52
- data/test/fixtures/discount.json +0 -17
- data/test/fixtures/discount_disabled.json +0 -17
- data/test/fixtures/discounts.json +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef057d0e70073f7c63a076b7f878c1c3afd062d0
|
4
|
+
data.tar.gz: 477cf304d0a68dc7e68cfac7e39c9af5617611c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c24fa3742f763e0f798a4e2d0eccd37ff2db06ba21e08e09d5853584550398db112354f39b9fd6edc55af2cc8e438f5d04b8e3ade7e704c81e2eda2a8236338f
|
7
|
+
data.tar.gz: 9886ecfff88b5b9e7dac1e1e1948fbe3ea3a0c69cbc9f13f601c413dead928bdfc68678f81d06ad74f277631f8048628252f390a37717bf17d9c1b6c4c3e016b
|
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
@@ -2,7 +2,6 @@ language: ruby
|
|
2
2
|
sudo: false
|
3
3
|
|
4
4
|
rvm:
|
5
|
-
- '2.0'
|
6
5
|
- 2.3.1
|
7
6
|
- 2.4.0-preview1
|
8
7
|
|
@@ -15,9 +14,6 @@ gemfile:
|
|
15
14
|
- Gemfile_ar_master
|
16
15
|
|
17
16
|
matrix:
|
18
|
-
exclude:
|
19
|
-
- rvm: '2.0'
|
20
|
-
gemfile: Gemfile_ar_master
|
21
17
|
fast_finish: true
|
22
18
|
allow_failures:
|
23
19
|
- rvm: 2.4.0-preview1
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
== Version 4.12.0
|
2
|
+
|
3
|
+
* Added support for the GraphQL API
|
4
|
+
|
5
|
+
== Version 4.11.0
|
6
|
+
|
7
|
+
* Added `ShopifyAPI::InventoryItem`
|
8
|
+
* Added `ShopifyAPI::InventoryLevel`
|
9
|
+
* Added `#inventory_levels` method to `ShopifyAPI::Location`
|
10
|
+
|
11
|
+
== Version 4.10.0
|
12
|
+
|
13
|
+
* Added `ShopifyAPI::AccessScope`
|
14
|
+
|
15
|
+
== Version 4.9.1
|
16
|
+
|
17
|
+
* Fix a bug with custom properties for orders
|
18
|
+
|
1
19
|
== Version 4.9.0
|
2
20
|
|
3
21
|
* Added `ShopifyAPI::PriceRule`
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ All API usage happens through Shopify applications, created by either shop owner
|
|
19
19
|
* Shop owners can create applications for themselves through their own admin: https://docs.shopify.com/api/authentication/creating-a-private-app
|
20
20
|
* Shopify Partners create applications through their admin: http://app.shopify.com/services/partners
|
21
21
|
|
22
|
-
For more information and detailed documentation about the API visit
|
22
|
+
For more information and detailed documentation about the API visit https://developers.shopify.com/
|
23
23
|
|
24
24
|
#### Ruby version
|
25
25
|
|
@@ -39,15 +39,6 @@ Or install via [gem](http://rubygems.org/)
|
|
39
39
|
gem install shopify_api
|
40
40
|
```
|
41
41
|
|
42
|
-
#### Rails 5
|
43
|
-
|
44
|
-
shopify_api is compatible with Rails 5 but since the latest ActiveResource release (4.1) is locked on Rails 4.x, you'll need to use the unreleased master version:
|
45
|
-
|
46
|
-
```ruby
|
47
|
-
gem 'shopify_api'
|
48
|
-
gem 'activeresource', github: 'rails/activeresource'
|
49
|
-
```
|
50
|
-
|
51
42
|
### Getting Started
|
52
43
|
|
53
44
|
ShopifyAPI uses ActiveResource to communicate with the REST web service. ActiveResource has to be configured with a fully authorized URL of a particular store first. To obtain that URL you can follow these steps:
|
@@ -230,6 +221,30 @@ gem install shopify_cli
|
|
230
221
|
shopify-cli help
|
231
222
|
```
|
232
223
|
|
224
|
+
## GraphQL
|
225
|
+
|
226
|
+
This library also supports Shopify's new [GraphQL API](https://help.shopify.com/api/graphql-admin-api)
|
227
|
+
via a dependency on the [graphql-client](https://github.com/github/graphql-client) gem.
|
228
|
+
The authentication process (steps 1-5 under [Getting Started](#getting-started))
|
229
|
+
is identical. Once your session is activated, simply construct a new graphql
|
230
|
+
client and use `parse` and `query` as defined by
|
231
|
+
[graphql-client](https://github.com/github/graphql-client#defining-queries).
|
232
|
+
|
233
|
+
```ruby
|
234
|
+
client = ShopifyAPI::GraphQL.new
|
235
|
+
|
236
|
+
SHOP_NAME_QUERY = client.parse <<-'GRAPHQL'
|
237
|
+
{
|
238
|
+
shop {
|
239
|
+
name
|
240
|
+
}
|
241
|
+
}
|
242
|
+
GRAPHQL
|
243
|
+
|
244
|
+
result = client.query(SHOP_NAME_QUERY)
|
245
|
+
result.data.shop.name
|
246
|
+
```
|
247
|
+
|
233
248
|
## Threadsafety
|
234
249
|
|
235
250
|
ActiveResource is threadsafe as of version 4.1 (which works with Rails 4.x and above).
|
@@ -241,12 +256,13 @@ If you were previously using Shopify's [activeresource fork](https://github.com/
|
|
241
256
|
Download the source code and run:
|
242
257
|
|
243
258
|
```bash
|
244
|
-
|
259
|
+
bundle install
|
260
|
+
bundle exec rake test
|
245
261
|
```
|
246
262
|
|
247
263
|
## Additional Resources
|
248
264
|
|
249
|
-
API
|
265
|
+
API Reference: https://help.shopify.com/api/reference
|
250
266
|
|
251
267
|
Ask questions on the forums: http://ecommerce.shopify.com/c/shopify-apis-and-technology
|
252
268
|
|
data/lib/shopify_api/limits.rb
CHANGED
@@ -39,8 +39,7 @@ module ShopifyAPI
|
|
39
39
|
# @return {Integer}
|
40
40
|
#
|
41
41
|
def credit_limit(scope=:shop)
|
42
|
-
|
43
|
-
@api_credit_limit[scope] ||= api_credit_limit_param(scope).pop.to_i - 1
|
42
|
+
api_credit_limit_param(scope).pop.to_i - 1
|
44
43
|
end
|
45
44
|
alias_method :call_limit, :credit_limit
|
46
45
|
|
@@ -42,7 +42,7 @@ module ShopifyAPI
|
|
42
42
|
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
|
43
43
|
"#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
# find an asset by key:
|
47
47
|
# ShopifyAPI::Asset.find('layout/theme.liquid', :params => {:theme_id => 99})
|
48
48
|
def self.find(*args)
|
@@ -57,7 +57,7 @@ module ShopifyAPI
|
|
57
57
|
resource
|
58
58
|
end
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
# For text assets, Shopify returns the data in the 'value' attribute.
|
62
62
|
# For binary assets, the data is base-64-encoded and returned in the
|
63
63
|
# 'attachment' attribute. This accessor returns the data in both cases.
|
@@ -65,28 +65,28 @@ module ShopifyAPI
|
|
65
65
|
attributes['value'] ||
|
66
66
|
(attributes['attachment'] ? Base64.decode64(attributes['attachment']) : nil)
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
def attach(data)
|
70
70
|
self.attachment = Base64.encode64(data)
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
def destroy
|
74
74
|
connection.delete(element_path(prefix_options.merge(:asset => {:key => key})), self.class.headers)
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
def new?
|
78
78
|
false
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
def method_missing(method_symbol, *arguments) #:nodoc:
|
82
82
|
if %w{value= attachment= src= source_key=}.include?(method_symbol)
|
83
83
|
wipe_value_attributes
|
84
84
|
end
|
85
85
|
super
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
private
|
89
|
-
|
89
|
+
|
90
90
|
def wipe_value_attributes
|
91
91
|
%w{value attachment src source_key}.each do |attr|
|
92
92
|
attributes.delete(attr)
|
@@ -6,14 +6,14 @@ module ShopifyAPI
|
|
6
6
|
def products
|
7
7
|
Product.find(:all, :params => {:collection_id => self.id})
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def add_product(product)
|
11
11
|
Collect.create(:collection_id => self.id, :product_id => product.id)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def remove_product(product)
|
15
15
|
collect = Collect.find(:first, :params => {:collection_id => self.id, :product_id => product.id})
|
16
16
|
collect.destroy if collect
|
17
17
|
end
|
18
|
-
end
|
18
|
+
end
|
19
19
|
end
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'graphql/client'
|
3
|
+
require 'graphql/client/http'
|
4
|
+
|
5
|
+
module ShopifyAPI
|
6
|
+
# GraphQL API.
|
7
|
+
class GraphQL
|
8
|
+
def initialize
|
9
|
+
uri = Base.site.dup
|
10
|
+
uri.path = '/admin/api/graphql.json'
|
11
|
+
@http = ::GraphQL::Client::HTTP.new(uri.to_s) do
|
12
|
+
define_method(:headers) do |_context|
|
13
|
+
Base.headers
|
14
|
+
end
|
15
|
+
end
|
16
|
+
@schema = ::GraphQL::Client.load_schema(@http)
|
17
|
+
@client = ::GraphQL::Client.new(schema: @schema, execute: @http)
|
18
|
+
end
|
19
|
+
|
20
|
+
delegate :parse, :query, to: :@client
|
21
|
+
end
|
22
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module ShopifyAPI
|
2
2
|
class Image < Base
|
3
3
|
init_prefix :product
|
4
|
-
|
4
|
+
|
5
5
|
# generate a method for each possible image variant
|
6
6
|
[:pico, :icon, :thumb, :small, :compact, :medium, :large, :grande, :original].each do |m|
|
7
7
|
reg_exp_match = "/\\1_#{m}.\\2"
|
8
8
|
define_method(m) { src.gsub(/\/(.*)\.(\w{2,4})/, reg_exp_match) }
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def attach_image(data, filename = nil)
|
12
12
|
attributes['attachment'] = Base64.encode64(data)
|
13
13
|
attributes['filename'] = filename unless filename.nil?
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShopifyAPI
|
4
|
+
class InventoryLevel < Base
|
5
|
+
|
6
|
+
# The default path structure in ActiveResource for delete would result in:
|
7
|
+
# /admin/inventory_levels/#{ inventory_level.id }.json?#{ params }, but since
|
8
|
+
# InventroyLevels are a second class resource made up of a Where and a What
|
9
|
+
# (Location and InventoryItem), it does not have a resource ID. Here we
|
10
|
+
# redefine element_path to remove the id so HTTP DELETE requests go to
|
11
|
+
# /admin/inventory_levels.json?#{ params } instead.
|
12
|
+
#
|
13
|
+
def self.element_path(prefix_options = {}, query_options = nil)
|
14
|
+
prefix_options, query_options = split_options(prefix_options) if query_options.nil?
|
15
|
+
"#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def destroy
|
19
|
+
load_attributes_from_response(
|
20
|
+
self.class.delete('/', location_id: location_id, inventory_item_id: inventory_item_id)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def connect(relocate_if_necessary: nil)
|
25
|
+
body = { location_id: location_id, inventory_item_id: inventory_item_id }
|
26
|
+
body[:relocate_if_necessary] = relocate_if_necessary unless relocate_if_necessary.nil?
|
27
|
+
load_attributes_from_response(
|
28
|
+
self.class.post(:connect, {}, body.to_json)
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def set(new_available, disconnect_if_necessary: nil)
|
33
|
+
body = {
|
34
|
+
location_id: location_id,
|
35
|
+
inventory_item_id: inventory_item_id,
|
36
|
+
available: new_available
|
37
|
+
}
|
38
|
+
body[:disconnect_if_necessary] = disconnect_if_necessary unless disconnect_if_necessary.nil?
|
39
|
+
load_attributes_from_response(
|
40
|
+
self.class.post(:set, {}, body.to_json)
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def adjust(available_adjustment)
|
45
|
+
body = {
|
46
|
+
location_id: location_id,
|
47
|
+
inventory_item_id: inventory_item_id,
|
48
|
+
available_adjustment: available_adjustment
|
49
|
+
}
|
50
|
+
load_attributes_from_response(
|
51
|
+
self.class.post(:adjust, {}, body.to_json)
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -1,6 +1,14 @@
|
|
1
1
|
module ShopifyAPI
|
2
|
-
class LineItem < Base
|
2
|
+
class LineItem < Base
|
3
3
|
class Property < Base
|
4
|
+
def initialize(*args)
|
5
|
+
attributes = args[0] || {}
|
6
|
+
persisted = args[1] || false
|
7
|
+
super
|
8
|
+
rescue NameError
|
9
|
+
attributes = attributes.to_hash
|
10
|
+
self
|
11
|
+
end
|
4
12
|
end
|
5
13
|
end
|
6
14
|
end
|
@@ -1,8 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This resource is deprecated and will be removed in a future version of this gem.
|
4
|
+
# Use ShopifyAPI::ApiPermission.destroy instead
|
5
|
+
|
1
6
|
module ShopifyAPI
|
2
7
|
class OAuth < Base
|
3
8
|
self.collection_name = 'oauth'
|
4
9
|
|
5
10
|
def self.revoke
|
11
|
+
warn '[DEPRECATED] ShopifyAPI::OAuth#revoke is deprecated and will be removed in a future version. ' \
|
12
|
+
'Use ShopifyAPI::ApiPermission#destroy instead.'
|
13
|
+
|
6
14
|
delete(:revoke)
|
7
15
|
end
|
8
16
|
end
|
@@ -3,8 +3,13 @@ module ShopifyAPI
|
|
3
3
|
include Events
|
4
4
|
include Metafields
|
5
5
|
|
6
|
-
def close
|
7
|
-
|
6
|
+
def close
|
7
|
+
load_attributes_from_response(post(:close, {}, only_id))
|
8
|
+
end
|
9
|
+
|
10
|
+
def open
|
11
|
+
load_attributes_from_response(post(:open, {}, only_id))
|
12
|
+
end
|
8
13
|
|
9
14
|
def cancel(options = {})
|
10
15
|
load_attributes_from_response(post(:cancel, {}, options.to_json))
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ShopifyAPI
|
4
|
+
module Ping
|
5
|
+
class Conversation < Base
|
6
|
+
self.prefix = "/admin/api/ping-api/v1/"
|
7
|
+
|
8
|
+
def send_message(message_attrs)
|
9
|
+
message = ShopifyAPI::Ping::Message.new(
|
10
|
+
message_attrs.merge(conversation_id: id)
|
11
|
+
)
|
12
|
+
|
13
|
+
message.save
|
14
|
+
message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|