shopify_api 4.9.0 → 9.4.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 (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