lucid-shopify 0.60.0 → 0.63.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2000b0881f8f32a1ae28c1e81f75c4e10c99fb386e090087c930835453a7c20
4
- data.tar.gz: 871ddf85d10f96e5f03c253436d4fb49f76da54ed0e1bca68428fa2ae4cd095e
3
+ metadata.gz: ffe59e48e1d046fa4eb07460911384691bda6c07981b056cb3c89dd48d95514f
4
+ data.tar.gz: 778d7a488544cb0452290010eff0ff59db765afd55abd8bbdefd674b38984a79
5
5
  SHA512:
6
- metadata.gz: 17cbb58d6af88ebe841ff7ad8d2217512a7a11c78f40763a9061ef85e4e132d0334cce964235eed844d7d231a2657107ac3a493a091b6b2aba360d8f4042f925
7
- data.tar.gz: bfebbb6f59bb8592827a6b3264c00bef9d3839e9236628d4e8eb91da30af9cc032e15500d389f366d4c8c7b967b8bbe75612d28d3de8658e3124fc13d1495661
6
+ metadata.gz: 9ed2477757ec40d6464699bc8a930604f21b5aee5ccabaef0eebd1113fa4a73a1edbb76db8bfc50cb35a53f11440fda704535e0e982daa490f9e6e03deab66d8
7
+ data.tar.gz: 03d6ea262fc118da219fb18f11478da1d4a384c0d50b7a67e6b4941abd6112d82c854a4dd57f5de7b5510d28b781d0e647f28cd8ed1f14dffa6cca71753dc126
data/README.md CHANGED
@@ -35,7 +35,7 @@ Setup
35
35
 
36
36
  Lucid::Shopify.configure do |config|
37
37
  config.api_key = '...'
38
- config.api_version = '...' # e.g. '2020-01'
38
+ config.api_version = '...' # e.g. '2020-04'
39
39
  config.billing_callback_uri = '...'
40
40
  config.callback_uri = '...' # (for OAuth; unused by this gem)
41
41
  config.logger = Logger.new(STDOUT)
@@ -45,7 +45,7 @@ module Lucid
45
45
  extend Dry::Configurable
46
46
 
47
47
  setting :api_key
48
- setting :api_version, '2020-01'
48
+ setting :api_version, '2020-04'
49
49
  setting :billing_callback_uri
50
50
  setting :callback_uri
51
51
  setting :logger, Logger.new(File::NULL).freeze
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'json'
4
4
  require 'lucid/shopify'
5
+ require 'timeout'
5
6
 
6
7
  module Lucid
7
8
  module Shopify
@@ -13,6 +14,8 @@ module Lucid
13
14
  FailedOperationError = Class.new(OperationError)
14
15
  ObsoleteOperationError = Class.new(OperationError)
15
16
 
17
+ TimeoutError = Class.new(Error)
18
+
16
19
  class Operation
17
20
  include Dry::Initializer.define -> do
18
21
  # @return [Client]
@@ -31,6 +34,11 @@ module Lucid
31
34
  # @param http [HTTP::Client]
32
35
  #
33
36
  # @yield [Enumerator<Hash>] yields each parsed line of JSONL
37
+ #
38
+ # @raise CanceledOperationError
39
+ # @raise ExpiredOperationError
40
+ # @raise FailedOperationError
41
+ # @raise ObsoleteOperationError
34
42
  def call(delay: 1, http: Container[:http], &block)
35
43
  url = loop do
36
44
  status, url = poll
@@ -70,23 +78,52 @@ module Lucid
70
78
  end
71
79
 
72
80
  # Cancel the bulk operation.
81
+ #
82
+ # @raise ObsoleteOperationError
83
+ # @raise TimeoutError
73
84
  def cancel
74
- client.post_graphql(credentials, <<~QUERY)
75
- mutation {
76
- bulkOperationCancel(id: "#{id}") {
77
- userErrors {
78
- field
79
- message
85
+ begin
86
+ client.post_graphql(credentials, <<~QUERY)
87
+ mutation {
88
+ bulkOperationCancel(id: "#{id}") {
89
+ userErrors {
90
+ field
91
+ message
92
+ }
80
93
  }
81
94
  }
82
- }
83
- QUERY
95
+ QUERY
96
+ rescue Response::GraphQLClientError => e
97
+ return if e.response.error_message?([
98
+ /cannot be canceled when it is completed/,
99
+ ])
100
+
101
+ raise e
102
+ end
84
103
 
85
- loop do
86
- status, _ = poll
104
+ poll_until(['CANCELED', 'COMPLETED'])
105
+ end
87
106
 
88
- break unless status == 'CANCELING'
107
+ # Poll until operation status is met.
108
+ #
109
+ # @param statuses [Array<String>] to terminate polling on
110
+ # @param timeout [Integer] in seconds
111
+ #
112
+ # @raise ObsoleteOperationError
113
+ # @raise TimeoutError
114
+ def poll_until(statuses, timeout: 60)
115
+ Timeout.timeout(timeout) do
116
+ loop do
117
+ status, _ = poll
118
+
119
+ break if statuses.any? { |expected_status| status == expected_status }
120
+ end
89
121
  end
122
+ rescue Timeout::Error
123
+ raise TimeoutError, 'exceeded %s seconds polling for status %s' % [
124
+ timeout,
125
+ statuses.join(', '),
126
+ ]
90
127
  end
91
128
 
92
129
  # @return [Array(String, String | nil)] the operation status and the
@@ -111,7 +148,8 @@ module Lucid
111
148
  end
112
149
  end
113
150
 
114
- # Create and start a new bulk operation via the GraphQL API.
151
+ # Create and start a new bulk operation via the GraphQL API. Any currently
152
+ # running bulk operations are cancelled.
115
153
  #
116
154
  # @param client [Client]
117
155
  # @param credentials [Credentials]
@@ -154,7 +192,12 @@ module Lucid
154
192
  }
155
193
  QUERY
156
194
 
157
- Operation.new(client, credentials, op['id']).cancel if op && op['status'] == 'RUNNING'
195
+ case op&.fetch('status')
196
+ when 'CANCELING'
197
+ Operation.new(client, credentials, op['id']).poll_until(['CANCELED'])
198
+ when 'CREATED', 'RUNNING'
199
+ Operation.new(client, credentials, op['id']).cancel
200
+ end
158
201
 
159
202
  id = client.post_graphql(credentials, <<~QUERY)['data']['bulkOperationRunQuery']['bulkOperation']['id']
160
203
  mutation {
@@ -111,11 +111,18 @@ module Lucid
111
111
  # @raise [ClientError] for status 4xx
112
112
  # @raise [ServerError] for status 5xx
113
113
  #
114
- # @note https://help.shopify.com/en/api/getting-started/response-status-codes
114
+ # @note https://shopify.dev/concepts/about-apis/response-codes
115
115
  def assert!
116
116
  case status_code
117
117
  when 402
118
118
  raise ShopError.new(request, self), 'Shop is frozen, awaiting payment'
119
+ when 403
120
+ # NOTE: Not sure what this one means (undocumented).
121
+ if error_message?([/unavailable shop/i])
122
+ raise ShopError.new(request, self), 'Shop is unavailable'
123
+ else
124
+ raise ClientError.new(request, self)
125
+ end
119
126
  when 423
120
127
  raise ShopError.new(request, self), 'Shop is locked'
121
128
  when 400..499
@@ -207,7 +214,7 @@ module Lucid
207
214
  # @return [Array<String>]
208
215
  def error_messages
209
216
  errors.map do |field, message|
210
- "#{field} #{message}"
217
+ "#{message} [#{field}]"
211
218
  end
212
219
  end
213
220
 
@@ -222,12 +229,14 @@ module Lucid
222
229
  #
223
230
  # @return [Boolean]
224
231
  def error_message?(messages)
232
+ all_messages = error_messages + user_error_messages
233
+
225
234
  messages.any? do |message|
226
235
  case message
227
236
  when Regexp
228
- error_messages.any? { |other_message| other_message.match?(message) }
237
+ all_messages.any? { |other_message| other_message.match?(message) }
229
238
  when String
230
- error_messages.include?(message)
239
+ all_messages.include?(message)
231
240
  end
232
241
  end
233
242
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Lucid
4
4
  module Shopify
5
- VERSION = '0.60.0'
5
+ VERSION = '0.63.1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lucid-shopify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.60.0
4
+ version: 0.63.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kelsey Judson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-16 00:00:00.000000000 Z
11
+ date: 2020-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
@@ -136,7 +136,7 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '4.1'
139
- description:
139
+ description:
140
140
  email: kelsey@lucid.nz
141
141
  executables: []
142
142
  extensions: []
@@ -179,7 +179,7 @@ homepage: https://github.com/lucidnz/gem-lucid-shopify
179
179
  licenses:
180
180
  - ISC
181
181
  metadata: {}
182
- post_install_message:
182
+ post_install_message:
183
183
  rdoc_options: []
184
184
  require_paths:
185
185
  - lib
@@ -195,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
195
  version: '0'
196
196
  requirements: []
197
197
  rubygems_version: 3.1.2
198
- signing_key:
198
+ signing_key:
199
199
  specification_version: 4
200
200
  summary: Shopify client library
201
201
  test_files: []