shopify_api 9.0.4 → 9.5

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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/ISSUE_TEMPLATE.md +36 -0
  4. data/.github/workflows/build.yml +44 -0
  5. data/.gitignore +2 -1
  6. data/.rubocop.yml +23 -3
  7. data/.rubocop_todo.yml +75 -0
  8. data/CHANGELOG.md +41 -0
  9. data/CONTRIBUTING.md +1 -1
  10. data/Gemfile +5 -0
  11. data/Gemfile.lock +153 -0
  12. data/Gemfile_ar51 +1 -1
  13. data/README.md +42 -32
  14. data/RELEASING +10 -6
  15. data/Rakefile +16 -5
  16. data/SECURITY.md +59 -0
  17. data/dev.yml +11 -0
  18. data/docs/_config.yml +1 -0
  19. data/docs/_includes/footer.html +28 -0
  20. data/docs/_includes/head.html +28 -0
  21. data/docs/_layouts/index.html +57 -0
  22. data/docs/graphql.md +47 -2
  23. data/docs/index.md +639 -0
  24. data/lib/active_resource/connection_ext.rb +1 -0
  25. data/lib/active_resource/detailed_log_subscriber.rb +10 -7
  26. data/lib/active_resource/json_errors.rb +8 -2
  27. data/lib/shopify_api/api_access.rb +57 -0
  28. data/lib/shopify_api/api_version.rb +6 -5
  29. data/lib/shopify_api/connection.rb +1 -0
  30. data/lib/shopify_api/countable.rb +3 -2
  31. data/lib/shopify_api/disable_prefix_check.rb +2 -2
  32. data/lib/shopify_api/events.rb +2 -1
  33. data/lib/shopify_api/graphql.rb +28 -8
  34. data/lib/shopify_api/hmac_params.rb +23 -0
  35. data/lib/shopify_api/limits.rb +3 -2
  36. data/lib/shopify_api/message_enricher.rb +11 -9
  37. data/lib/shopify_api/meta.rb +0 -1
  38. data/lib/shopify_api/metafields.rb +5 -4
  39. data/lib/shopify_api/pagination_link_headers.rb +5 -4
  40. data/lib/shopify_api/resources/access_scope.rb +1 -1
  41. data/lib/shopify_api/resources/access_token.rb +1 -0
  42. data/lib/shopify_api/resources/address.rb +1 -0
  43. data/lib/shopify_api/resources/announcement.rb +2 -1
  44. data/lib/shopify_api/resources/application_charge.rb +1 -0
  45. data/lib/shopify_api/resources/application_credit.rb +1 -0
  46. data/lib/shopify_api/resources/article.rb +3 -2
  47. data/lib/shopify_api/resources/asset.rb +6 -5
  48. data/lib/shopify_api/resources/assigned_fulfillment_order.rb +1 -1
  49. data/lib/shopify_api/resources/base.rb +12 -8
  50. data/lib/shopify_api/resources/billing_address.rb +1 -0
  51. data/lib/shopify_api/resources/blog.rb +2 -1
  52. data/lib/shopify_api/resources/carrier_service.rb +1 -0
  53. data/lib/shopify_api/resources/cart.rb +2 -1
  54. data/lib/shopify_api/resources/collect.rb +1 -0
  55. data/lib/shopify_api/resources/collection_listing.rb +1 -0
  56. data/lib/shopify_api/resources/comment.rb +20 -5
  57. data/lib/shopify_api/resources/country.rb +1 -0
  58. data/lib/shopify_api/resources/custom_collection.rb +4 -3
  59. data/lib/shopify_api/resources/customer.rb +2 -1
  60. data/lib/shopify_api/resources/customer_group.rb +1 -0
  61. data/lib/shopify_api/resources/customer_invite.rb +1 -0
  62. data/lib/shopify_api/resources/customer_saved_search.rb +2 -1
  63. data/lib/shopify_api/resources/discount_code.rb +1 -0
  64. data/lib/shopify_api/resources/discount_code_batch.rb +4 -2
  65. data/lib/shopify_api/resources/draft_order.rb +1 -0
  66. data/lib/shopify_api/resources/draft_order_invoice.rb +1 -0
  67. data/lib/shopify_api/resources/event.rb +1 -0
  68. data/lib/shopify_api/resources/fulfillment.rb +12 -3
  69. data/lib/shopify_api/resources/fulfillment_event.rb +1 -0
  70. data/lib/shopify_api/resources/fulfillment_order.rb +30 -16
  71. data/lib/shopify_api/resources/fulfillment_order_locations_for_move.rb +1 -0
  72. data/lib/shopify_api/resources/fulfillment_request.rb +1 -0
  73. data/lib/shopify_api/resources/fulfillment_service.rb +1 -0
  74. data/lib/shopify_api/resources/fulfillment_v2.rb +3 -2
  75. data/lib/shopify_api/resources/gift_card.rb +1 -0
  76. data/lib/shopify_api/resources/image.rb +2 -1
  77. data/lib/shopify_api/resources/inventory_level.rb +3 -4
  78. data/lib/shopify_api/resources/line_item.rb +4 -3
  79. data/lib/shopify_api/resources/location.rb +1 -1
  80. data/lib/shopify_api/resources/marketing_event.rb +1 -0
  81. data/lib/shopify_api/resources/metafield.rb +1 -0
  82. data/lib/shopify_api/resources/note_attribute.rb +1 -0
  83. data/lib/shopify_api/resources/option.rb +1 -0
  84. data/lib/shopify_api/resources/order.rb +2 -1
  85. data/lib/shopify_api/resources/order_risk.rb +1 -0
  86. data/lib/shopify_api/resources/page.rb +1 -0
  87. data/lib/shopify_api/resources/payment_details.rb +1 -0
  88. data/lib/shopify_api/resources/policy.rb +1 -0
  89. data/lib/shopify_api/resources/price_rule.rb +1 -1
  90. data/lib/shopify_api/resources/product.rb +27 -3
  91. data/lib/shopify_api/resources/product_listing.rb +1 -0
  92. data/lib/shopify_api/resources/province.rb +1 -0
  93. data/lib/shopify_api/resources/receipt.rb +1 -0
  94. data/lib/shopify_api/resources/recurring_application_charge.rb +4 -1
  95. data/lib/shopify_api/resources/redirect.rb +1 -0
  96. data/lib/shopify_api/resources/refund.rb +2 -1
  97. data/lib/shopify_api/resources/report.rb +1 -0
  98. data/lib/shopify_api/resources/resource_feedback.rb +1 -1
  99. data/lib/shopify_api/resources/rule.rb +1 -0
  100. data/lib/shopify_api/resources/script_tag.rb +1 -0
  101. data/lib/shopify_api/resources/shipping_address.rb +1 -0
  102. data/lib/shopify_api/resources/shipping_line.rb +1 -0
  103. data/lib/shopify_api/resources/shipping_zone.rb +1 -0
  104. data/lib/shopify_api/resources/shop.rb +2 -1
  105. data/lib/shopify_api/resources/smart_collection.rb +4 -8
  106. data/lib/shopify_api/resources/storefront_access_token.rb +1 -0
  107. data/lib/shopify_api/resources/tax_line.rb +1 -0
  108. data/lib/shopify_api/resources/tax_service.rb +1 -0
  109. data/lib/shopify_api/resources/theme.rb +1 -0
  110. data/lib/shopify_api/resources/transaction.rb +1 -0
  111. data/lib/shopify_api/resources/usage_charge.rb +1 -0
  112. data/lib/shopify_api/resources/user.rb +1 -0
  113. data/lib/shopify_api/resources/variant.rb +35 -0
  114. data/lib/shopify_api/resources/webhook.rb +1 -0
  115. data/lib/shopify_api/resources.rb +1 -0
  116. data/lib/shopify_api/session.rb +51 -20
  117. data/lib/shopify_api/version.rb +2 -1
  118. data/lib/shopify_api.rb +9 -1
  119. data/lib/verify_docs.rb +8 -0
  120. data/service.yml +2 -5
  121. data/shopify_api.gemspec +13 -7
  122. data/test/access_token_test.rb +6 -5
  123. data/test/active_resource/json_errors_test.rb +6 -6
  124. data/test/api_access_test.rb +153 -0
  125. data/test/api_version_test.rb +3 -3
  126. data/test/application_charge_test.rb +30 -27
  127. data/test/application_credit_test.rb +10 -9
  128. data/test/article_test.rb +34 -35
  129. data/test/asset_test.rb +14 -6
  130. data/test/assigned_fulfillment_order_test.rb +5 -4
  131. data/test/base_test.rb +64 -49
  132. data/test/blog_test.rb +4 -3
  133. data/test/carrier_service_test.rb +7 -6
  134. data/test/cart_test.rb +2 -1
  135. data/test/collect_test.rb +4 -3
  136. data/test/collection_listing_test.rb +21 -16
  137. data/test/collection_publication_test.rb +8 -8
  138. data/test/collection_test.rb +20 -19
  139. data/test/countable_test.rb +3 -2
  140. data/test/currency_test.rb +5 -5
  141. data/test/custom_collection_test.rb +4 -3
  142. data/test/customer_saved_search_test.rb +18 -8
  143. data/test/customer_test.rb +22 -14
  144. data/test/detailed_log_subscriber_test.rb +16 -12
  145. data/test/discount_code_batch_test.rb +11 -10
  146. data/test/discount_code_test.rb +21 -15
  147. data/test/draft_order_test.rb +68 -52
  148. data/test/fixtures/assigned_fulfillment_orders.json +2 -0
  149. data/test/fixtures/fulfillment_order.json +1 -0
  150. data/test/fixtures/fulfillment_orders.json +2 -0
  151. data/test/fulfillment_event_test.rb +31 -26
  152. data/test/fulfillment_order_test.rb +217 -149
  153. data/test/fulfillment_order_test_helper.rb +1 -0
  154. data/test/fulfillment_request_test.rb +10 -8
  155. data/test/fulfillment_service_test.rb +13 -12
  156. data/test/fulfillment_test.rb +81 -66
  157. data/test/fulfillment_v2_test.rb +16 -12
  158. data/test/gift_card_test.rb +6 -4
  159. data/test/graphql_test.rb +55 -23
  160. data/test/hmac_params_test.rb +25 -0
  161. data/test/image_test.rb +19 -17
  162. data/test/inventory_level_test.rb +24 -15
  163. data/test/lib/webmock_extensions/last_request.rb +1 -1
  164. data/test/limits_test.rb +2 -1
  165. data/test/location_test.rb +2 -1
  166. data/test/marketing_event_test.rb +20 -20
  167. data/test/message_enricher_test.rb +6 -6
  168. data/test/meta_test.rb +9 -11
  169. data/test/metafield_test.rb +30 -20
  170. data/test/order_risk_test.rb +17 -16
  171. data/test/order_test.rb +43 -28
  172. data/test/pagination_test.rb +89 -56
  173. data/test/policy_test.rb +6 -5
  174. data/test/price_rule_test.rb +20 -15
  175. data/test/product_listing_test.rb +20 -20
  176. data/test/product_publication_test.rb +8 -8
  177. data/test/product_test.rb +71 -20
  178. data/test/publication_test.rb +3 -3
  179. data/test/recurring_application_charge_test.rb +104 -42
  180. data/test/redirect_test.rb +4 -3
  181. data/test/refund_test.rb +22 -17
  182. data/test/report_test.rb +12 -10
  183. data/test/resource_feedback_test.rb +14 -13
  184. data/test/script_tag_test.rb +10 -9
  185. data/test/session_test.rb +319 -45
  186. data/test/shipping_zone_test.rb +4 -3
  187. data/test/shop_test.rb +47 -33
  188. data/test/smart_collection_test.rb +5 -29
  189. data/test/storefront_access_token_test.rb +13 -15
  190. data/test/tax_service_test.rb +7 -4
  191. data/test/tender_transaction_test.rb +3 -3
  192. data/test/test_helper.rb +14 -12
  193. data/test/transaction_test.rb +4 -3
  194. data/test/usage_charge_test.rb +12 -8
  195. data/test/user_test.rb +4 -3
  196. data/test/variant_test.rb +50 -23
  197. data/test/webhook_test.rb +10 -7
  198. metadata +44 -17
  199. data/.rubocop-https---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1027
  200. data/.travis.yml +0 -23
  201. data/bin/shopify +0 -3
@@ -1,9 +1,15 @@
1
+ # frozen_string_literal: true
1
2
  require 'active_resource/base'
2
3
 
3
4
  module ActiveResource
4
5
  class Errors < ActiveModel::Errors
5
6
  def from_json(json, save_cache = false)
6
- data = ActiveSupport::JSON.decode(json)['errors'] || {} rescue {}
7
+ data =
8
+ begin
9
+ ActiveSupport::JSON.decode(json)['errors'] || {}
10
+ rescue
11
+ {}
12
+ end
7
13
  case data
8
14
  when String
9
15
  from_string(data, save_cache)
@@ -15,7 +21,7 @@ module ActiveResource
15
21
  def from_hash(messages, save_cache = false)
16
22
  clear unless save_cache
17
23
 
18
- messages.each do |key,errors|
24
+ messages.each do |key, errors|
19
25
  errors.each do |error|
20
26
  add(key, error)
21
27
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShopifyAPI
4
+ class ApiAccess
5
+ SCOPE_DELIMITER = ','
6
+
7
+ def initialize(scope_names)
8
+ if scope_names.is_a?(String)
9
+ scope_names = scope_names.to_s.split(SCOPE_DELIMITER)
10
+ end
11
+
12
+ store_scopes(scope_names)
13
+ end
14
+
15
+ def covers?(scopes)
16
+ scopes.compressed_scopes <= expanded_scopes
17
+ end
18
+
19
+ def to_s
20
+ to_a.join(SCOPE_DELIMITER)
21
+ end
22
+
23
+ def to_a
24
+ compressed_scopes.to_a
25
+ end
26
+
27
+ def ==(other)
28
+ other.class == self.class &&
29
+ compressed_scopes == other.compressed_scopes
30
+ end
31
+
32
+ alias :eql? :==
33
+
34
+ def hash
35
+ compressed_scopes.hash
36
+ end
37
+
38
+ protected
39
+
40
+ attr_reader :compressed_scopes, :expanded_scopes
41
+
42
+ private
43
+
44
+ def store_scopes(scope_names)
45
+ scopes = scope_names.map(&:strip).reject(&:empty?).to_set
46
+ implied_scopes = scopes.map { |scope| implied_scope(scope) }.compact
47
+
48
+ @compressed_scopes = scopes - implied_scopes
49
+ @expanded_scopes = scopes + implied_scopes
50
+ end
51
+
52
+ def implied_scope(scope)
53
+ is_write_scope = scope =~ /\A(unauthenticated_)?write_(.*)\z/
54
+ "#{$1}read_#{$2}" if is_write_scope
55
+ end
56
+ end
57
+ end
@@ -54,8 +54,8 @@ module ShopifyAPI
54
54
 
55
55
  def define_known_versions
56
56
  warn(
57
- '[DEPRECATED] ShopifyAPI::ApiVersion.define_known_versions is deprecated and will be removed in a future version. ' \
58
- 'Use `fetch_known_versions` instead.'
57
+ '[DEPRECATED] ShopifyAPI::ApiVersion.define_known_versions is deprecated and will be ' \
58
+ 'removed in a future version. Use `fetch_known_versions` instead.'
59
59
  )
60
60
  fetch_known_versions
61
61
  end
@@ -70,15 +70,16 @@ module ShopifyAPI
70
70
 
71
71
  def clear_defined_versions
72
72
  warn(
73
- '[DEPRECATED] ShopifyAPI::ApiVersion.clear_defined_versions is deprecated and will be removed in a future version. ' \
74
- 'Use `clear_known_versions` instead.'
73
+ '[DEPRECATED] ShopifyAPI::ApiVersion.clear_defined_versions is deprecated and will be ' \
74
+ 'removed in a future version. Use `clear_known_versions` instead.'
75
75
  )
76
76
  clear_known_versions
77
77
  end
78
78
 
79
79
  def latest_stable_version
80
80
  warn(
81
- '[DEPRECATED] ShopifyAPI::ApiVersion.latest_stable_version is deprecated and will be removed in a future version.'
81
+ '[DEPRECATED] ShopifyAPI::ApiVersion.latest_stable_version is deprecated and will be ' \
82
+ 'removed in a future version.'
82
83
  )
83
84
  versions.values.find(&:latest_supported?)
84
85
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class Connection < ActiveResource::Connection
3
4
  attr_reader :response
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  module Countable
3
4
  def count(options = {})
4
5
  data = get(:count, options)
5
6
 
6
7
  count = case data
7
- when Hash then data["count"]
8
- else data
8
+ when Hash then data["count"]
9
+ else data
9
10
  end
10
11
 
11
12
  Integer(count)
@@ -14,13 +14,13 @@ module ShopifyAPI
14
14
 
15
15
  init_prefix_explicit(resource_type, resource_id)
16
16
 
17
- define_singleton_method :resource_prefix do |options = {}|
17
+ define_singleton_method(:resource_prefix) do |options = {}|
18
18
  resource_type = options[resource] if flexible
19
19
 
20
20
  options[resource_id].nil? ? '' : "#{resource_type}/#{options[resource_id]}/"
21
21
  end
22
22
 
23
- define_singleton_method :instantiate_record do |record, prefix_options = {}|
23
+ define_singleton_method(:instantiate_record) do |record, prefix_options = {}|
24
24
  new(record, true).tap do |resource_instance|
25
25
  resource_instance.prefix_options = prefix_options unless prefix_options.blank?
26
26
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  module Events
3
4
  def events
4
- Event.find(:all, :params => {:resource => self.class.collection_name, :resource_id => id})
5
+ Event.find(:all, params: { resource: self.class.collection_name, resource_id: id })
5
6
  end
6
7
  end
7
8
  end
@@ -5,6 +5,8 @@ require 'shopify_api/graphql/http_client'
5
5
  module ShopifyAPI
6
6
  module GraphQL
7
7
  DEFAULT_SCHEMA_LOCATION_PATH = Pathname('shopify_graphql_schemas')
8
+ DEFAULT_EXECUTION_ADAPTER = HTTPClient
9
+ DEFAULT_GRAPHQL_CLIENT = ::GraphQL::Client
8
10
 
9
11
  InvalidSchema = Class.new(StandardError)
10
12
  InvalidClient = Class.new(StandardError)
@@ -28,7 +30,10 @@ module ShopifyAPI
28
30
  To dump the schema file, use the `rake shopify_api:graphql:dump` task.
29
31
  MSG
30
32
  else
31
- puts '[WARNING] Client was not pre-initialized. Ensure `ShopifyAPI::GraphQL.initialize_clients` is called during app initialization.'
33
+ puts(
34
+ '[WARNING] Client was not pre-initialized. Ensure `ShopifyAPI::GraphQL.initialize_clients` ' \
35
+ 'is called during app initialization.'
36
+ )
32
37
  initialize_clients
33
38
  @_client_cache[api_version]
34
39
  end
@@ -48,16 +53,15 @@ module ShopifyAPI
48
53
 
49
54
  if matches
50
55
  api_version = ShopifyAPI::ApiVersion.new(handle: matches[1])
56
+ elsif raise_on_invalid_schema
57
+ raise InvalidSchema,
58
+ "Invalid schema file name `#{schema_file}`. Does not match format of: `<version>.json`."
51
59
  else
52
- if raise_on_invalid_schema
53
- raise InvalidSchema, "Invalid schema file name `#{schema_file}`. Does not match format of: `<version>.json`."
54
- else
55
- next
56
- end
60
+ next
57
61
  end
58
62
 
59
- schema = ::GraphQL::Client.load_schema(schema_file.to_s)
60
- client = ::GraphQL::Client.new(schema: schema, execute: HTTPClient.new(api_version)).tap do |c|
63
+ schema = graphql_client.load_schema(schema_file.to_s)
64
+ client = graphql_client.new(schema: schema, execute: execution_adapter.new(api_version)).tap do |c|
61
65
  c.allow_dynamic_queries = true
62
66
  end
63
67
 
@@ -73,6 +77,22 @@ module ShopifyAPI
73
77
  @schema_location = Pathname(path)
74
78
  end
75
79
 
80
+ def execution_adapter
81
+ @execution_adapter || DEFAULT_EXECUTION_ADAPTER
82
+ end
83
+
84
+ def execution_adapter=(executor)
85
+ @execution_adapter = executor
86
+ end
87
+
88
+ def graphql_client
89
+ @graphql_client || DEFAULT_GRAPHQL_CLIENT
90
+ end
91
+
92
+ def graphql_client=(client)
93
+ @graphql_client = client
94
+ end
95
+
76
96
  private
77
97
 
78
98
  def initialize_client_cache
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+ require 'webrick/httputils'
3
+
4
+ module ShopifyAPI
5
+ module HmacParams
6
+ extend WEBrick::HTTPUtils
7
+
8
+ def self.encode(params)
9
+ params
10
+ .except(:signature, :hmac, :action, :controller)
11
+ .map { |k,v| sprintf("%s=%s", encode_key(k), encode_value(v)) }
12
+ .sort.join("&")
13
+ end
14
+
15
+ def self.encode_key(key)
16
+ _escape(key.to_s, _make_regex('&=%'))
17
+ end
18
+
19
+ def self.encode_value(value)
20
+ _escape(value.to_s, _make_regex('&%'))
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  module Limits
3
4
  class LimitUnavailable < StandardError; end
@@ -38,7 +39,7 @@ module ShopifyAPI
38
39
  # @param {Symbol} scope [:shop]
39
40
  # @return {Integer}
40
41
  #
41
- def credit_limit(scope=:shop)
42
+ def credit_limit(scope = :shop)
42
43
  api_credit_limit_param(scope).pop.to_i - 1
43
44
  end
44
45
  alias_method :call_limit, :credit_limit
@@ -48,7 +49,7 @@ module ShopifyAPI
48
49
  # @param {Symbol} scope [:shop]
49
50
  # @return {Integer}
50
51
  #
51
- def credit_used(scope=:shop)
52
+ def credit_used(scope = :shop)
52
53
  api_credit_limit_param(scope).shift.to_i
53
54
  end
54
55
  alias_method :call_count, :credit_used
@@ -1,20 +1,22 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class MessageEnricher < SimpleDelegator
3
4
  def message
4
5
  return super unless (400...500).include?(code.to_i)
5
6
 
6
7
  @_cached_message ||= begin
7
- detailed_error = begin
8
- parsed_body = JSON.parse(body)
8
+ detailed_error =
9
+ begin
10
+ parsed_body = JSON.parse(body)
9
11
 
10
- if parsed_body['error']
11
- parsed_body['error'].to_s
12
- elsif parsed_body['errors']
13
- Array(parsed_body['errors']).join('; ')
12
+ if parsed_body['error']
13
+ parsed_body['error'].to_s
14
+ elsif parsed_body['errors']
15
+ Array(parsed_body['errors']).join('; ')
16
+ end
17
+ rescue JSON::ParserError
18
+ nil
14
19
  end
15
- rescue JSON::ParserError
16
- nil
17
- end
18
20
 
19
21
  detailed_error.present? ? "#{super} (#{detailed_error})" : super
20
22
  end
@@ -12,4 +12,3 @@ module ShopifyAPI
12
12
  end
13
13
  end
14
14
  end
15
-
@@ -1,17 +1,18 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  module Metafields
3
4
  def metafields(**options)
4
- options.merge! resource: self.class.collection_name, resource_id: id
5
+ options.merge!(resource: self.class.collection_name, resource_id: id)
5
6
 
6
- Metafield.find :all, params: options
7
+ Metafield.find(:all, params: options)
7
8
  end
8
9
 
9
10
  def add_metafield(metafield)
10
11
  raise ArgumentError, "You can only add metafields to resource that has been saved" if new?
11
12
 
12
13
  metafield.prefix_options = {
13
- :resource => self.class.collection_name,
14
- :resource_id => id
14
+ resource: self.class.collection_name,
15
+ resource_id: id,
15
16
  }
16
17
  metafield.save
17
18
  metafield
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class InvalidPaginationLinksError < StandardError; end
3
4
 
@@ -9,8 +10,6 @@ module ShopifyAPI
9
10
  links = parse_link_header(link_header)
10
11
  @previous_link = links.find { |link| link.rel == :previous }
11
12
  @next_link = links.find { |link| link.rel == :next }
12
-
13
- self
14
13
  end
15
14
 
16
15
  private
@@ -20,12 +19,14 @@ module ShopifyAPI
20
19
  links = link_header.split(',')
21
20
  links.map do |link|
22
21
  parts = link.split('; ')
23
- raise ShopifyAPI::InvalidPaginationLinksError.new("Invalid link header: url and rel expected") unless parts.length == 2
22
+ unless parts.length == 2
23
+ raise ShopifyAPI::InvalidPaginationLinksError, "Invalid link header: url and rel expected"
24
+ end
24
25
 
25
26
  url = parts[0][/<(.*)>/, 1]
26
27
  rel = parts[1][/rel="(.*)"/, 1]&.to_sym
27
28
 
28
- url = URI.parse(url)
29
+ url = URI.parse(url).request_uri
29
30
  LinkHeader.new(url, rel)
30
31
  end
31
32
  end
@@ -2,7 +2,7 @@
2
2
  module ShopifyAPI
3
3
  class AccessScope < Base
4
4
  class << self
5
- def prefix(_options={})
5
+ def prefix(_options = {})
6
6
  '/admin/oauth/'
7
7
  end
8
8
  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
@@ -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
@@ -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,10 +10,10 @@ 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
+ # asset = ShopifyAPI::Asset.new(key: 'assets/special.css', theme_id: 12345)
13
14
  #
14
15
  # Find by key:
15
- # asset = ShopifyAPI::Asset.find('assets/image.png', :params => {:theme_id => 12345})
16
+ # asset = ShopifyAPI::Asset.find('assets/image.png', params: {theme_id: 12345})
16
17
  #
17
18
  # Get the text or binary value:
18
19
  # asset.value # decodes from attachment attribute if necessary
@@ -38,13 +39,13 @@ 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
@@ -75,7 +76,7 @@ module ShopifyAPI
75
76
  end
76
77
 
77
78
  def destroy
78
- 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)
79
80
  end
80
81
 
81
82
  def new?
@@ -1,6 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class AssignedFulfillmentOrder < Base
3
-
4
4
  def initialize(attributes = {}, persisted = false)
5
5
  ShopifyAPI::Base.version_validation!(FulfillmentOrder::MINIMUM_VERSION)
6
6
  super(attributes, persisted)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'shopify_api/version'
2
3
 
3
4
  module ShopifyAPI
@@ -15,7 +16,7 @@ module ShopifyAPI
15
16
 
16
17
  def encode(options = {})
17
18
  same = dup
18
- 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'
19
20
 
20
21
  same.send("to_#{self.class.format.extension}", options)
21
22
  end
@@ -43,7 +44,7 @@ module ShopifyAPI
43
44
  end
44
45
 
45
46
  def activate_session(session)
46
- raise InvalidSessionError.new("Session cannot be nil") if session.nil?
47
+ raise InvalidSessionError, "Session cannot be nil" if session.nil?
47
48
  self.site = session.site
48
49
  self.headers.merge!('X-Shopify-Access-Token' => session.token)
49
50
  self.api_version = session.api_version
@@ -53,7 +54,6 @@ module ShopifyAPI
53
54
  self.site = nil
54
55
  self.password = nil
55
56
  self.user = nil
56
- self.api_version = nil
57
57
  self.headers.delete('X-Shopify-Access-Token')
58
58
  end
59
59
 
@@ -68,7 +68,11 @@ module ShopifyAPI
68
68
  end
69
69
 
70
70
  def api_version=(version)
71
- self._api_version = ApiVersion::NullVersion.matches?(version) ? ApiVersion::NullVersion : ApiVersion.find_version(version)
71
+ self._api_version = if ApiVersion::NullVersion.matches?(version)
72
+ ApiVersion::NullVersion
73
+ else
74
+ ApiVersion.find_version(version)
75
+ end
72
76
  end
73
77
 
74
78
  def prefix(options = {})
@@ -88,11 +92,11 @@ module ShopifyAPI
88
92
  def resource_prefix=(value)
89
93
  @prefix_parameters = nil
90
94
 
91
- resource_prefix_call = value.gsub(/:\w+/) { |key| "\#{URI.parser.escape options[#{key}].to_s}" }
95
+ resource_prefix_call = value.gsub(/:\w+/) { |key| "\#{URI::DEFAULT_PARSER.escape options[#{key}].to_s}" }
92
96
 
93
97
  silence_warnings do
94
98
  # Redefine the new methods.
95
- instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
99
+ instance_eval(<<-RUBY_EVAL, __FILE__, __LINE__ + 1)
96
100
  def prefix_source() "#{value}" end
97
101
  def resource_prefix(options={}) "#{resource_prefix_call}" end
98
102
  RUBY_EVAL
@@ -123,7 +127,7 @@ module ShopifyAPI
123
127
  def init_prefix_explicit(resource_type, resource_id)
124
128
  self.resource_prefix = "#{resource_type}/:#{resource_id}/"
125
129
 
126
- define_method resource_id.to_sym do
130
+ define_method(resource_id.to_sym) do
127
131
  @prefix_options[resource_id]
128
132
  end
129
133
  end
@@ -156,7 +160,7 @@ module ShopifyAPI
156
160
  private
157
161
 
158
162
  def only_id
159
- encode(:only => :id, :include => [], :methods => [])
163
+ encode(only: :id, include: [], methods: [])
160
164
  end
161
165
  end
162
166
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class BillingAddress < Base
3
4
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class Blog < Base
3
4
  include Events
4
5
  include Metafields
5
6
 
6
7
  def articles
7
- Article.find(:all, :params => { :blog_id => id })
8
+ Article.find(:all, params: { blog_id: id })
8
9
  end
9
10
  end
10
11
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class CarrierService < Base
3
4
  end
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class Cart < Base
3
4
  end
4
- end
5
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  # For adding/removing products from custom collections
3
4
  class Collect < Base
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class CollectionListing < Base
3
4
  self.primary_key = :collection_id
@@ -1,9 +1,24 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class Comment < Base
3
- def remove; load_attributes_from_response(post(:remove, {}, only_id)); end
4
- def spam; load_attributes_from_response(post(:spam, {}, only_id)); end
5
- def approve; load_attributes_from_response(post(:approve, {}, only_id)); end
6
- def restore; load_attributes_from_response(post(:restore, {}, only_id)); end
7
- def not_spam; load_attributes_from_response(post(:not_spam, {}, only_id)); end
4
+ def remove
5
+ load_attributes_from_response(post(:remove, {}, only_id))
6
+ end
7
+
8
+ def spam
9
+ load_attributes_from_response(post(:spam, {}, only_id))
10
+ end
11
+
12
+ def approve
13
+ load_attributes_from_response(post(:approve, {}, only_id))
14
+ end
15
+
16
+ def restore
17
+ load_attributes_from_response(post(:restore, {}, only_id))
18
+ end
19
+
20
+ def not_spam
21
+ load_attributes_from_response(post(:not_spam, {}, only_id))
22
+ end
8
23
  end
9
24
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ShopifyAPI
2
3
  class Country < Base
3
4
  end