shopify_api 4.9.0 → 9.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (281) hide show
  1. checksums.yaml +5 -5
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE.md +36 -0
  4. data/.github/probots.yml +2 -0
  5. data/.github/workflows/build.yml +41 -0
  6. data/.gitignore +5 -1
  7. data/.rubocop.yml +28 -0
  8. data/.rubocop_todo.yml +75 -0
  9. data/CHANGELOG.md +491 -0
  10. data/CONTRIBUTING.md +1 -1
  11. data/Gemfile +6 -2
  12. data/Gemfile.lock +151 -0
  13. data/Gemfile_ar41 +5 -0
  14. data/Gemfile_ar50 +5 -0
  15. data/Gemfile_ar51 +5 -0
  16. data/Gemfile_ar_master +0 -1
  17. data/README.md +492 -100
  18. data/RELEASING +10 -9
  19. data/Rakefile +21 -5
  20. data/SECURITY.md +59 -0
  21. data/docker-compose.yml +13 -0
  22. data/docs/_config.yml +1 -0
  23. data/docs/_includes/footer.html +28 -0
  24. data/docs/_includes/head.html +28 -0
  25. data/docs/_layouts/index.html +57 -0
  26. data/docs/graphql.md +241 -0
  27. data/docs/index.md +639 -0
  28. data/lib/active_resource/connection_ext.rb +1 -0
  29. data/lib/active_resource/detailed_log_subscriber.rb +43 -7
  30. data/lib/active_resource/json_errors.rb +8 -2
  31. data/lib/shopify_api.rb +16 -6
  32. data/lib/shopify_api/api_access.rb +57 -0
  33. data/lib/shopify_api/api_version.rb +206 -0
  34. data/lib/shopify_api/connection.rb +7 -4
  35. data/lib/shopify_api/countable.rb +3 -2
  36. data/lib/shopify_api/disable_prefix_check.rb +31 -0
  37. data/lib/shopify_api/events.rb +2 -1
  38. data/lib/shopify_api/graphql.rb +103 -0
  39. data/lib/shopify_api/graphql/http_client.rb +22 -0
  40. data/lib/shopify_api/graphql/railtie.rb +17 -0
  41. data/lib/shopify_api/graphql/task.rake +100 -0
  42. data/lib/shopify_api/limits.rb +9 -9
  43. data/lib/shopify_api/message_enricher.rb +25 -0
  44. data/lib/shopify_api/meta.rb +14 -0
  45. data/lib/shopify_api/metafields.rb +5 -4
  46. data/lib/shopify_api/paginated_collection.rb +69 -0
  47. data/lib/shopify_api/pagination_link_headers.rb +34 -0
  48. data/lib/shopify_api/resources.rb +3 -1
  49. data/lib/shopify_api/resources/abandoned_checkout.rb +7 -0
  50. data/lib/shopify_api/resources/access_scope.rb +10 -0
  51. data/lib/shopify_api/resources/access_token.rb +1 -0
  52. data/lib/shopify_api/resources/address.rb +1 -0
  53. data/lib/shopify_api/resources/announcement.rb +2 -1
  54. data/lib/shopify_api/resources/api_permission.rb +9 -0
  55. data/lib/shopify_api/resources/application_charge.rb +1 -0
  56. data/lib/shopify_api/resources/application_credit.rb +1 -0
  57. data/lib/shopify_api/resources/array_base.rb +13 -0
  58. data/lib/shopify_api/resources/article.rb +3 -2
  59. data/lib/shopify_api/resources/asset.rb +28 -23
  60. data/lib/shopify_api/resources/assigned_fulfillment_order.rb +16 -0
  61. data/lib/shopify_api/resources/base.rb +101 -24
  62. data/lib/shopify_api/resources/billing_address.rb +2 -1
  63. data/lib/shopify_api/resources/blog.rb +2 -1
  64. data/lib/shopify_api/resources/carrier_service.rb +1 -0
  65. data/lib/shopify_api/resources/cart.rb +2 -1
  66. data/lib/shopify_api/resources/checkout.rb +27 -1
  67. data/lib/shopify_api/resources/collect.rb +2 -0
  68. data/lib/shopify_api/resources/collection.rb +14 -0
  69. data/lib/shopify_api/resources/collection_listing.rb +11 -1
  70. data/lib/shopify_api/resources/collection_publication.rb +10 -0
  71. data/lib/shopify_api/resources/comment.rb +20 -5
  72. data/lib/shopify_api/resources/country.rb +1 -0
  73. data/lib/shopify_api/resources/currency.rb +6 -0
  74. data/lib/shopify_api/resources/custom_collection.rb +7 -6
  75. data/lib/shopify_api/resources/customer.rb +2 -1
  76. data/lib/shopify_api/resources/customer_group.rb +1 -0
  77. data/lib/shopify_api/resources/{customer_invite_message.rb → customer_invite.rb} +1 -0
  78. data/lib/shopify_api/resources/customer_saved_search.rb +4 -1
  79. data/lib/shopify_api/resources/discount_code.rb +1 -0
  80. data/lib/shopify_api/resources/discount_code_batch.rb +34 -0
  81. data/lib/shopify_api/resources/draft_order.rb +1 -0
  82. data/lib/shopify_api/resources/draft_order_invoice.rb +1 -0
  83. data/lib/shopify_api/resources/event.rb +2 -0
  84. data/lib/shopify_api/resources/fulfillment.rb +46 -3
  85. data/lib/shopify_api/resources/fulfillment_event.rb +2 -1
  86. data/lib/shopify_api/resources/fulfillment_order.rb +151 -0
  87. data/lib/shopify_api/resources/fulfillment_order_locations_for_move.rb +5 -0
  88. data/lib/shopify_api/resources/fulfillment_request.rb +1 -0
  89. data/lib/shopify_api/resources/fulfillment_service.rb +1 -0
  90. data/lib/shopify_api/resources/fulfillment_v2.rb +21 -0
  91. data/lib/shopify_api/resources/gift_card.rb +1 -0
  92. data/lib/shopify_api/resources/image.rb +4 -3
  93. data/lib/shopify_api/resources/inventory_item.rb +6 -0
  94. data/lib/shopify_api/resources/inventory_level.rb +54 -0
  95. data/lib/shopify_api/resources/line_item.rb +10 -1
  96. data/lib/shopify_api/resources/location.rb +4 -0
  97. data/lib/shopify_api/resources/marketing_event.rb +3 -0
  98. data/lib/shopify_api/resources/metafield.rb +2 -0
  99. data/lib/shopify_api/resources/note_attribute.rb +1 -0
  100. data/lib/shopify_api/resources/option.rb +1 -0
  101. data/lib/shopify_api/resources/order.rb +25 -5
  102. data/lib/shopify_api/resources/order_risk.rb +1 -0
  103. data/lib/shopify_api/resources/page.rb +1 -0
  104. data/lib/shopify_api/resources/payment.rb +7 -0
  105. data/lib/shopify_api/resources/payment_details.rb +1 -0
  106. data/lib/shopify_api/resources/ping.rb +3 -0
  107. data/lib/shopify_api/resources/policy.rb +1 -0
  108. data/lib/shopify_api/resources/price_rule.rb +1 -1
  109. data/lib/shopify_api/resources/product.rb +33 -7
  110. data/lib/shopify_api/resources/product_listing.rb +9 -1
  111. data/lib/shopify_api/resources/product_publication.rb +10 -0
  112. data/lib/shopify_api/resources/province.rb +1 -0
  113. data/lib/shopify_api/resources/publication.rb +5 -0
  114. data/lib/shopify_api/resources/receipt.rb +1 -0
  115. data/lib/shopify_api/resources/recurring_application_charge.rb +4 -1
  116. data/lib/shopify_api/resources/redirect.rb +1 -0
  117. data/lib/shopify_api/resources/refund.rb +6 -4
  118. data/lib/shopify_api/resources/report.rb +1 -0
  119. data/lib/shopify_api/resources/resource_feedback.rb +1 -1
  120. data/lib/shopify_api/resources/rule.rb +1 -0
  121. data/lib/shopify_api/resources/script_tag.rb +1 -0
  122. data/lib/shopify_api/resources/shipping_address.rb +1 -0
  123. data/lib/shopify_api/resources/shipping_line.rb +2 -1
  124. data/lib/shopify_api/resources/shipping_rate.rb +7 -0
  125. data/lib/shopify_api/resources/shipping_zone.rb +1 -0
  126. data/lib/shopify_api/resources/shop.rb +10 -7
  127. data/lib/shopify_api/resources/smart_collection.rb +3 -3
  128. data/lib/shopify_api/resources/storefront_access_token.rb +1 -0
  129. data/lib/shopify_api/resources/tax_line.rb +1 -0
  130. data/lib/shopify_api/resources/tax_service.rb +1 -0
  131. data/lib/shopify_api/resources/tender_transaction.rb +6 -0
  132. data/lib/shopify_api/resources/theme.rb +1 -0
  133. data/lib/shopify_api/resources/transaction.rb +1 -0
  134. data/lib/shopify_api/resources/usage_charge.rb +1 -0
  135. data/lib/shopify_api/resources/user.rb +1 -0
  136. data/lib/shopify_api/resources/variant.rb +35 -0
  137. data/lib/shopify_api/resources/webhook.rb +1 -0
  138. data/lib/shopify_api/session.rb +109 -45
  139. data/lib/shopify_api/version.rb +2 -1
  140. data/lib/verify_docs.rb +8 -0
  141. data/service.yml +8 -0
  142. data/shopify_api.gemspec +19 -8
  143. data/test/abandoned_checkouts_test.rb +29 -0
  144. data/test/access_scope_test.rb +23 -0
  145. data/test/access_token_test.rb +6 -5
  146. data/test/active_resource/json_errors_test.rb +6 -6
  147. data/test/api_access_test.rb +153 -0
  148. data/test/api_permission_test.rb +9 -0
  149. data/test/api_version_test.rb +157 -0
  150. data/test/application_charge_test.rb +30 -27
  151. data/test/application_credit_test.rb +10 -9
  152. data/test/article_test.rb +34 -35
  153. data/test/asset_test.rb +14 -6
  154. data/test/assigned_fulfillment_order_test.rb +78 -0
  155. data/test/base_test.rb +147 -59
  156. data/test/blog_test.rb +4 -3
  157. data/test/carrier_service_test.rb +7 -6
  158. data/test/cart_test.rb +2 -1
  159. data/test/checkouts_test.rb +72 -4
  160. data/test/collect_test.rb +4 -3
  161. data/test/collection_listing_test.rb +56 -13
  162. data/test/collection_publication_test.rb +40 -0
  163. data/test/collection_test.rb +50 -0
  164. data/test/countable_test.rb +3 -2
  165. data/test/currency_test.rb +21 -0
  166. data/test/custom_collection_test.rb +4 -3
  167. data/test/customer_saved_search_test.rb +18 -8
  168. data/test/customer_test.rb +22 -14
  169. data/test/detailed_log_subscriber_test.rb +113 -19
  170. data/test/discount_code_batch_test.rb +41 -0
  171. data/test/discount_code_test.rb +22 -16
  172. data/test/draft_order_test.rb +68 -52
  173. data/test/fixtures/abandoned_checkout.json +184 -0
  174. data/test/fixtures/abandoned_checkouts.json +186 -0
  175. data/test/fixtures/access_scopes.json +10 -0
  176. data/test/fixtures/api_versions.json +38 -0
  177. data/test/fixtures/apis.json +42 -0
  178. data/test/fixtures/assigned_fulfillment_orders.json +80 -0
  179. data/test/fixtures/checkout.json +160 -0
  180. data/test/fixtures/checkouts.json +25 -49
  181. data/test/fixtures/collection.json +17 -0
  182. data/test/fixtures/collection_listing_product_ids2.json +1 -0
  183. data/test/fixtures/collection_products.json +47 -0
  184. data/test/fixtures/collection_publication.json +11 -0
  185. data/test/fixtures/collection_publications.json +13 -0
  186. data/test/fixtures/currencies.json +25 -0
  187. data/test/fixtures/discount_code_batch.json +14 -0
  188. data/test/fixtures/discount_code_batch_discount_codes.json +21 -0
  189. data/test/fixtures/fulfillment_order.json +39 -0
  190. data/test/fixtures/fulfillment_order_locations_for_move.json +18 -0
  191. data/test/fixtures/fulfillment_orders.json +80 -0
  192. data/test/fixtures/fulfillments.json +53 -0
  193. data/test/fixtures/graphql/2019-10.json +1083 -0
  194. data/test/fixtures/graphql/dummy_schema.rb +16 -0
  195. data/test/fixtures/graphql/unstable.json +1083 -0
  196. data/test/fixtures/inventory_level.json +7 -0
  197. data/test/fixtures/inventory_levels.json +24 -0
  198. data/test/fixtures/order_with_properties.json +373 -0
  199. data/test/fixtures/payment.json +7 -0
  200. data/test/fixtures/payments.json +9 -0
  201. data/test/fixtures/ping/conversation.json +1 -0
  202. data/test/fixtures/ping/failed_delivery_confirmation.json +1 -0
  203. data/test/fixtures/ping/message.json +1 -0
  204. data/test/fixtures/ping/successful_delivery_confirmation.json +1 -0
  205. data/test/fixtures/product_listing_product_ids.json +1 -1
  206. data/test/fixtures/product_listing_product_ids2.json +1 -0
  207. data/test/fixtures/product_publication.json +11 -0
  208. data/test/fixtures/product_publications.json +13 -0
  209. data/test/fixtures/publications.json +9 -0
  210. data/test/fixtures/shipping_rates.json +12 -0
  211. data/test/fixtures/smart_collection_products.json +155 -0
  212. data/test/fixtures/tender_transactions.json +52 -0
  213. data/test/fulfillment_event_test.rb +31 -26
  214. data/test/fulfillment_order_test.rb +530 -0
  215. data/test/fulfillment_order_test_helper.rb +8 -0
  216. data/test/fulfillment_request_test.rb +10 -8
  217. data/test/fulfillment_service_test.rb +13 -12
  218. data/test/fulfillment_test.rb +198 -20
  219. data/test/fulfillment_v2_test.rb +66 -0
  220. data/test/gift_card_test.rb +6 -4
  221. data/test/graphql/http_client_test.rb +26 -0
  222. data/test/graphql_test.rb +190 -0
  223. data/test/image_test.rb +19 -17
  224. data/test/inventory_level_test.rb +68 -0
  225. data/test/lib/webmock_extensions/last_request.rb +16 -0
  226. data/test/limits_test.rb +4 -3
  227. data/test/location_test.rb +15 -0
  228. data/test/marketing_event_test.rb +21 -21
  229. data/test/message_enricher_test.rb +45 -0
  230. data/test/meta_test.rb +47 -0
  231. data/test/metafield_test.rb +30 -20
  232. data/test/order_risk_test.rb +17 -16
  233. data/test/order_test.rb +110 -17
  234. data/test/pagination_test.rb +290 -0
  235. data/test/payment_test.rb +19 -0
  236. data/test/policy_test.rb +6 -5
  237. data/test/price_rule_test.rb +20 -15
  238. data/test/product_listing_test.rb +72 -15
  239. data/test/product_publication_test.rb +40 -0
  240. data/test/product_test.rb +80 -19
  241. data/test/publication_test.rb +12 -0
  242. data/test/recurring_application_charge_test.rb +105 -50
  243. data/test/redirect_test.rb +4 -3
  244. data/test/refund_test.rb +22 -17
  245. data/test/report_test.rb +12 -10
  246. data/test/resource_feedback_test.rb +14 -13
  247. data/test/script_tag_test.rb +10 -9
  248. data/test/session_test.rb +497 -111
  249. data/test/shipping_rate_test.rb +17 -0
  250. data/test/shipping_zone_test.rb +4 -3
  251. data/test/shop_test.rb +47 -33
  252. data/test/smart_collection_test.rb +5 -4
  253. data/test/storefront_access_token_test.rb +13 -15
  254. data/test/tax_service_test.rb +7 -3
  255. data/test/tender_transaction_test.rb +18 -0
  256. data/test/test_helper.rb +98 -67
  257. data/test/transaction_test.rb +4 -3
  258. data/test/usage_charge_test.rb +12 -8
  259. data/test/user_test.rb +4 -3
  260. data/test/variant_test.rb +50 -20
  261. data/test/webhook_test.rb +10 -7
  262. metadata +196 -37
  263. data/.travis.yml +0 -36
  264. data/CHANGELOG +0 -292
  265. data/Gemfile_ar30 +0 -6
  266. data/Gemfile_ar31 +0 -6
  267. data/Gemfile_ar32 +0 -6
  268. data/Gemfile_ar40 +0 -6
  269. data/bin/shopify +0 -3
  270. data/lib/active_resource/base_ext.rb +0 -21
  271. data/lib/active_resource/disable_prefix_check.rb +0 -36
  272. data/lib/active_resource/to_query.rb +0 -10
  273. data/lib/shopify_api/json_format.rb +0 -18
  274. data/lib/shopify_api/resources/discount.rb +0 -11
  275. data/lib/shopify_api/resources/o_auth.rb +0 -9
  276. data/test/discount_test.rb +0 -52
  277. data/test/fixtures/discount.json +0 -17
  278. data/test/fixtures/discount_disabled.json +0 -17
  279. data/test/fixtures/discounts.json +0 -34
  280. data/test/fixtures/o_auth_revoke.json +0 -5
  281. data/test/o_auth_test.rb +0 -8
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ module ShopifyAPI
3
+ class InvalidPaginationLinksError < StandardError; end
4
+
5
+ class PaginationLinkHeaders
6
+ LinkHeader = Struct.new(:url, :rel)
7
+ attr_reader :previous_link, :next_link
8
+
9
+ def initialize(link_header)
10
+ links = parse_link_header(link_header)
11
+ @previous_link = links.find { |link| link.rel == :previous }
12
+ @next_link = links.find { |link| link.rel == :next }
13
+ end
14
+
15
+ private
16
+
17
+ def parse_link_header(link_header)
18
+ return [] unless link_header.present?
19
+ links = link_header.split(',')
20
+ links.map do |link|
21
+ parts = link.split('; ')
22
+ unless parts.length == 2
23
+ raise ShopifyAPI::InvalidPaginationLinksError, "Invalid link header: url and rel expected"
24
+ end
25
+
26
+ url = parts[0][/<(.*)>/, 1]
27
+ rel = parts[1][/rel="(.*)"/, 1]&.to_sym
28
+
29
+ url = URI.parse(url).request_uri
30
+ LinkHeader.new(url, rel)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'shopify_api/resources/base'
2
- Dir.glob("#{File.dirname(__FILE__)}/resources/*").each { |file| require(file) }
3
+ require 'shopify_api/resources/array_base'
4
+ Dir.glob("#{File.dirname(__FILE__)}/resources/*").each { |file| require(file) }
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyAPI
4
+ class AbandonedCheckout < Base
5
+ self.element_name = "checkout"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ module ShopifyAPI
3
+ class AccessScope < Base
4
+ class << self
5
+ def prefix(_options = {})
6
+ '/admin/oauth/'
7
+ end
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class AccessToken < Base
3
4
  def self.delegate(access_scope, expires_in = nil)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class Address < Base
3
4
  end
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class Announcement < Base
3
4
  end
4
- end
5
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyAPI
4
+ class ApiPermission < Base
5
+ def self.destroy
6
+ delete(:current)
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class ApplicationCharge < Base
3
4
  undef_method :test
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class ApplicationCredit < Base
3
4
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyAPI
4
+ class ArrayBase < Base
5
+ class << self
6
+ private
7
+
8
+ def instantiate_record(record, *)
9
+ record
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class Article < Base
3
4
  include Events
@@ -7,14 +8,14 @@ module ShopifyAPI
7
8
  conditional_prefix :blog
8
9
 
9
10
  def comments
10
- Comment.find(:all, :params => { :article_id => id })
11
+ Comment.find(:all, params: { article_id: id })
11
12
  end
12
13
 
13
14
  def self.authors(options = {})
14
15
  get(:authors, options)
15
16
  end
16
17
 
17
- def self.tags(options={})
18
+ def self.tags(options = {})
18
19
  get(:tags, options)
19
20
  end
20
21
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  # Assets represent the files that comprise your theme.
3
4
  # There are different buckets which hold different kinds
@@ -9,25 +10,25 @@ module ShopifyAPI
9
10
  # or assets/bg-body.gif.
10
11
  #
11
12
  # Initialize with a key:
12
- # asset = ShopifyAPI::Asset.new(:key => 'assets/special.css', :theme_id => 12345)
13
- #
13
+ # asset = ShopifyAPI::Asset.new(key: 'assets/special.css', theme_id: 12345)
14
+ #
14
15
  # Find by key:
15
- # asset = ShopifyAPI::Asset.find('assets/image.png', :params => {:theme_id => 12345})
16
- #
16
+ # asset = ShopifyAPI::Asset.find('assets/image.png', params: {theme_id: 12345})
17
+ #
17
18
  # Get the text or binary value:
18
19
  # asset.value # decodes from attachment attribute if necessary
19
- #
20
+ #
20
21
  # You can provide new data for assets in a few different ways:
21
- #
22
+ #
22
23
  # * assign text data for the value directly:
23
24
  # asset.value = "div.special {color:red;}"
24
- #
25
+ #
25
26
  # * provide binary data for the value:
26
27
  # asset.attach(File.read('image.png'))
27
- #
28
+ #
28
29
  # * set a URL from which Shopify will fetch the value:
29
30
  # asset.src = "http://mysite.com/image.png"
30
- #
31
+ #
31
32
  # * set a source key of another of your assets from which
32
33
  # the value will be copied:
33
34
  # asset.source_key = "assets/another_image.png"
@@ -38,26 +39,30 @@ module ShopifyAPI
38
39
 
39
40
  conditional_prefix :theme
40
41
 
41
- def self.element_path(id, prefix_options = {}, query_options = nil) #:nodoc:
42
+ def self.element_path(_id, prefix_options = {}, query_options = nil) #:nodoc:
42
43
  prefix_options, query_options = split_options(prefix_options) if query_options.nil?
43
44
  "#{prefix(prefix_options)}#{collection_name}.#{format.extension}#{query_string(query_options)}"
44
45
  end
45
-
46
+
46
47
  # find an asset by key:
47
- # ShopifyAPI::Asset.find('layout/theme.liquid', :params => {:theme_id => 99})
48
+ # ShopifyAPI::Asset.find('layout/theme.liquid', params: { theme_id: 99 })
48
49
  def self.find(*args)
49
50
  if args[0].is_a?(Symbol)
50
51
  super
51
52
  else
52
- params = {:asset => {:key => args[0]}}
53
+ params = { asset: { key: args[0] } }
53
54
  params = params.merge(args[1][:params]) if args[1] && args[1][:params]
54
- path_prefix = params[:theme_id] ? "/admin/themes/#{params[:theme_id]}" : "/admin"
55
- resource = find(:one, :from => "#{path_prefix}/assets.#{format.extension}", :params => params)
55
+ path_prefix = params[:theme_id] ? "themes/#{params[:theme_id]}/" : ""
56
+ resource = find(
57
+ :one,
58
+ from: api_version.construct_api_path("#{path_prefix}assets.#{format.extension}"),
59
+ params: params
60
+ )
56
61
  resource.prefix_options[:theme_id] = params[:theme_id] if resource && params[:theme_id]
57
62
  resource
58
63
  end
59
64
  end
60
-
65
+
61
66
  # For text assets, Shopify returns the data in the 'value' attribute.
62
67
  # For binary assets, the data is base-64-encoded and returned in the
63
68
  # 'attachment' attribute. This accessor returns the data in both cases.
@@ -65,28 +70,28 @@ module ShopifyAPI
65
70
  attributes['value'] ||
66
71
  (attributes['attachment'] ? Base64.decode64(attributes['attachment']) : nil)
67
72
  end
68
-
73
+
69
74
  def attach(data)
70
75
  self.attachment = Base64.encode64(data)
71
76
  end
72
-
77
+
73
78
  def destroy
74
- connection.delete(element_path(prefix_options.merge(:asset => {:key => key})), self.class.headers)
79
+ connection.delete(element_path(prefix_options.merge(asset: { key: key })), self.class.headers)
75
80
  end
76
-
81
+
77
82
  def new?
78
83
  false
79
84
  end
80
-
85
+
81
86
  def method_missing(method_symbol, *arguments) #:nodoc:
82
87
  if %w{value= attachment= src= source_key=}.include?(method_symbol)
83
88
  wipe_value_attributes
84
89
  end
85
90
  super
86
91
  end
87
-
92
+
88
93
  private
89
-
94
+
90
95
  def wipe_value_attributes
91
96
  %w{value attachment src source_key}.each do |attr|
92
97
  attributes.delete(attr)
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module ShopifyAPI
3
+ class AssignedFulfillmentOrder < Base
4
+ def initialize(attributes = {}, persisted = false)
5
+ ShopifyAPI::Base.version_validation!(FulfillmentOrder::MINIMUM_VERSION)
6
+ super(attributes, persisted)
7
+ end
8
+
9
+ def self.find(scope, *args)
10
+ ShopifyAPI::Base.version_validation!(FulfillmentOrder::MINIMUM_VERSION)
11
+
12
+ assigned_fulfillment_orders = super(scope, *args)
13
+ assigned_fulfillment_orders.map { |afo| FulfillmentOrder.new(afo.attributes) }
14
+ end
15
+ end
16
+ end
@@ -1,18 +1,22 @@
1
+ # frozen_string_literal: true
1
2
  require 'shopify_api/version'
2
3
 
3
4
  module ShopifyAPI
4
5
  class Base < ActiveResource::Base
5
6
  class InvalidSessionError < StandardError; end
6
7
  extend Countable
8
+
7
9
  self.timeout = 90
8
10
  self.include_root_in_json = false
9
11
  self.headers['User-Agent'] = ["ShopifyAPI/#{ShopifyAPI::VERSION}",
10
12
  "ActiveResource/#{ActiveResource::VERSION::STRING}",
11
13
  "Ruby/#{RUBY_VERSION}"].join(' ')
12
14
 
15
+ self.collection_parser = ShopifyAPI::PaginatedCollection
16
+
13
17
  def encode(options = {})
14
18
  same = dup
15
- same.attributes = {self.class.element_name => same.attributes} if self.class.format.extension == 'json'
19
+ same.attributes = { self.class.element_name => same.attributes } if self.class.format.extension == 'json'
16
20
 
17
21
  same.send("to_#{self.class.format.extension}", options)
18
22
  end
@@ -28,32 +32,22 @@ module ShopifyAPI
28
32
  end
29
33
 
30
34
  class << self
31
- if ActiveResource::Base.respond_to?(:_headers) && ActiveResource::Base.respond_to?(:_headers_defined?)
32
- def headers
33
- if _headers_defined?
34
- _headers
35
- elsif superclass != Object && superclass.headers
36
- superclass.headers
37
- else
38
- _headers ||= {}
39
- end
40
- end
41
- else
42
- def headers
43
- if defined?(@headers)
44
- @headers
45
- elsif superclass != Object && superclass.headers
46
- superclass.headers
47
- else
48
- @headers ||= {}
49
- end
35
+ threadsafe_attribute(:_api_version)
36
+ def headers
37
+ if _headers_defined?
38
+ _headers
39
+ elsif superclass != Object && superclass.headers
40
+ superclass.headers
41
+ else
42
+ _headers ||= {}
50
43
  end
51
44
  end
52
45
 
53
46
  def activate_session(session)
54
- raise InvalidSessionError.new("Session cannot be nil") if session.nil?
47
+ raise InvalidSessionError, "Session cannot be nil" if session.nil?
55
48
  self.site = session.site
56
49
  self.headers.merge!('X-Shopify-Access-Token' => session.token)
50
+ self.api_version = session.api_version
57
51
  end
58
52
 
59
53
  def clear_session
@@ -63,17 +57,100 @@ module ShopifyAPI
63
57
  self.headers.delete('X-Shopify-Access-Token')
64
58
  end
65
59
 
60
+ def api_version
61
+ if _api_version_defined?
62
+ _api_version
63
+ elsif superclass != Object && superclass.site
64
+ superclass.api_version.dup.freeze
65
+ else
66
+ ApiVersion::NullVersion
67
+ end
68
+ end
69
+
70
+ def api_version=(version)
71
+ self._api_version = if ApiVersion::NullVersion.matches?(version)
72
+ ApiVersion::NullVersion
73
+ else
74
+ ApiVersion.find_version(version)
75
+ end
76
+ end
77
+
78
+ def prefix(options = {})
79
+ api_version.construct_api_path(resource_prefix(options))
80
+ end
81
+
82
+ def prefix_source
83
+ ''
84
+ end
85
+
86
+ def resource_prefix(_options = {})
87
+ ''
88
+ end
89
+
90
+ # Sets the \prefix for a resource's nested URL (e.g., <tt>prefix/collectionname/1.json</tt>).
91
+ # Default value is <tt>site.path</tt>.
92
+ def resource_prefix=(value)
93
+ @prefix_parameters = nil
94
+
95
+ resource_prefix_call = value.gsub(/:\w+/) { |key| "\#{URI::DEFAULT_PARSER.escape options[#{key}].to_s}" }
96
+
97
+ silence_warnings do
98
+ # Redefine the new methods.
99
+ instance_eval(<<-RUBY_EVAL, __FILE__, __LINE__ + 1)
100
+ def prefix_source() "#{value}" end
101
+ def resource_prefix(options={}) "#{resource_prefix_call}" end
102
+ RUBY_EVAL
103
+ end
104
+ rescue => e
105
+ logger&.error("Couldn't set prefix: #{e}\n #{code}")
106
+ raise
107
+ end
108
+
109
+ def prefix=(value)
110
+ if value.start_with?('/admin')
111
+ raise ArgumentError, "'#{value}' can no longer start /admin/. Change to using resource_prefix="
112
+ end
113
+
114
+ warn(
115
+ '[DEPRECATED] ShopifyAPI::Base#prefix= is deprecated and will be removed in a future version. ' \
116
+ 'Use `self.resource_prefix=` instead.'
117
+ )
118
+ self.resource_prefix = value
119
+ end
120
+
121
+ alias_method :set_prefix, :prefix=
122
+
66
123
  def init_prefix(resource)
67
124
  init_prefix_explicit(resource.to_s.pluralize, "#{resource}_id")
68
125
  end
69
126
 
70
127
  def init_prefix_explicit(resource_type, resource_id)
71
- self.prefix = "/admin/#{resource_type}/:#{resource_id}/"
128
+ self.resource_prefix = "#{resource_type}/:#{resource_id}/"
72
129
 
73
- define_method resource_id.to_sym do
130
+ define_method(resource_id.to_sym) do
74
131
  @prefix_options[resource_id]
75
132
  end
76
133
  end
134
+
135
+ def early_july_pagination?
136
+ !!early_july_pagination
137
+ end
138
+
139
+ def version_validation!(minimum_version)
140
+ available_in_version = ShopifyAPI::ApiVersion.find_version(minimum_version)
141
+
142
+ unless ShopifyAPI::Base.api_version >= available_in_version
143
+ raise NotImplementedError, "The minimum supported version is #{minimum_version}."
144
+ end
145
+ end
146
+
147
+ private
148
+
149
+ attr_accessor :early_july_pagination
150
+
151
+ def early_july_pagination_release!
152
+ self.early_july_pagination = true
153
+ end
77
154
  end
78
155
 
79
156
  def persisted?
@@ -83,7 +160,7 @@ module ShopifyAPI
83
160
  private
84
161
 
85
162
  def only_id
86
- encode(:only => :id, :include => [], :methods => [])
163
+ encode(only: :id, include: [], methods: [])
87
164
  end
88
165
  end
89
166
  end