shopify_graphql 0.2.0 → 0.4.0
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 +4 -4
- data/README.md +1 -1
- data/app/graphql/shopify_graphql/app_subscription_fields.rb +68 -0
- data/app/graphql/shopify_graphql/cancel_subscription.rb +34 -0
- data/app/graphql/shopify_graphql/create_recurring_subscription.rb +64 -0
- data/app/graphql/shopify_graphql/create_usage_subscription.rb +62 -0
- data/app/graphql/shopify_graphql/get_app_subscription.rb +33 -0
- data/lib/shopify_graphql/client.rb +12 -0
- data/lib/shopify_graphql/engine.rb +1 -1
- data/lib/shopify_graphql/version.rb +1 -1
- data/lib/shopify_graphql.rb +1 -0
- metadata +21 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '018b4cef704098a6424fda98cb9805a11e86c29fd3e5a391e5945687a7ddc621'
|
4
|
+
data.tar.gz: 1f4e1be2f4b3edbf319251023a6a9d596bf34fa1f877dc51269d0cd9bb5db6f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2d0fdd479419a47c2647dffdc6cf65c1c09dfd6b66b35e2e13df9827b0844f0ee2191471d3a53ac42ddb60ecfec2f180457e61082fb209a385628e49c0a62af
|
7
|
+
data.tar.gz: cb05b2a483d83066fc233625938da8243905086baa31b0b29b1b6ff1af82f1b0afd5eb8534b4f3539b9f79fcc6c866a56295db1587a0a168fef33dbfe1242e3a
|
data/README.md
CHANGED
@@ -10,8 +10,8 @@ Less painful way to work with [Shopify Graphql API](https://shopify.dev/api/admi
|
|
10
10
|
- Graphql webhooks integration
|
11
11
|
- Built-in error handling
|
12
12
|
- No schema and no memory issues
|
13
|
+
- Buil-in retry on error
|
13
14
|
- (Planned) Testing helpers
|
14
|
-
- (Planned) Buil-in retry on error
|
15
15
|
- (Planned) Pre-built calls for common Graphql operations
|
16
16
|
|
17
17
|
## Usage
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module ShopifyGraphql
|
2
|
+
class AppSubscriptionFields
|
3
|
+
FRAGMENT = <<~GRAPHQL
|
4
|
+
fragment AppSubscriptionFields on AppSubscription {
|
5
|
+
id
|
6
|
+
name
|
7
|
+
status
|
8
|
+
createdAt
|
9
|
+
trialDays
|
10
|
+
currentPeriodEnd
|
11
|
+
test
|
12
|
+
lineItems {
|
13
|
+
id
|
14
|
+
plan {
|
15
|
+
pricingDetails {
|
16
|
+
__typename
|
17
|
+
... on AppRecurringPricing {
|
18
|
+
price {
|
19
|
+
amount
|
20
|
+
}
|
21
|
+
interval
|
22
|
+
}
|
23
|
+
... on AppUsagePricing {
|
24
|
+
balanceUsed {
|
25
|
+
amount
|
26
|
+
}
|
27
|
+
cappedAmount {
|
28
|
+
amount
|
29
|
+
}
|
30
|
+
interval
|
31
|
+
terms
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
GRAPHQL
|
38
|
+
|
39
|
+
def self.parse(data)
|
40
|
+
recurring_line_item = data.lineItems.find do |line_item|
|
41
|
+
line_item.plan.pricingDetails.__typename == "AppRecurringPricing"
|
42
|
+
end
|
43
|
+
recurring_pricing = recurring_line_item&.plan&.pricingDetails
|
44
|
+
usage_line_item = data.lineItems.find do |line_item|
|
45
|
+
line_item.plan.pricingDetails.__typename == "AppUsagePricing"
|
46
|
+
end
|
47
|
+
usage_pricing = usage_line_item&.plan&.pricingDetails
|
48
|
+
|
49
|
+
OpenStruct.new(
|
50
|
+
id: data.id,
|
51
|
+
name: data.name,
|
52
|
+
status: data.status,
|
53
|
+
created_at: data.createdAt && Time.parse(data.createdAt),
|
54
|
+
trial_days: data.trialDays,
|
55
|
+
current_period_end: data.currentPeriodEnd && Time.parse(data.currentPeriodEnd),
|
56
|
+
test: data.test,
|
57
|
+
recurring_line_item_id: recurring_line_item&.id,
|
58
|
+
recurring_price: recurring_pricing&.price&.amount&.to_d,
|
59
|
+
recurring_interval: recurring_pricing&.interval,
|
60
|
+
usage_line_item_id: usage_line_item&.id,
|
61
|
+
usage_balance: usage_pricing&.balanceUsed&.amount&.to_d,
|
62
|
+
usage_capped_amount: usage_pricing&.cappedAmount&.amount&.to_d,
|
63
|
+
usage_interval: usage_pricing&.interval,
|
64
|
+
usage_terms: usage_pricing&.terms
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ShopifyGraphql
|
2
|
+
class CancelSubscription
|
3
|
+
include Mutation
|
4
|
+
|
5
|
+
MUTATION = <<~GRAPHQL
|
6
|
+
mutation appSubscriptionCancel($id: ID!) {
|
7
|
+
appSubscriptionCancel(id: $id) {
|
8
|
+
appSubscription {
|
9
|
+
id
|
10
|
+
}
|
11
|
+
userErrors {
|
12
|
+
field
|
13
|
+
message
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
GRAPHQL
|
18
|
+
|
19
|
+
def call(id:)
|
20
|
+
response = execute(MUTATION, id: id)
|
21
|
+
response.data = response.data.appSubscriptionCancel
|
22
|
+
handle_user_errors(response.data)
|
23
|
+
response.data = parse_data(response.data)
|
24
|
+
response
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def parse_data(data)
|
30
|
+
subscription = OpenStruct.new(id: data.appSubscription.id)
|
31
|
+
OpenStruct.new(subscription: subscription)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module ShopifyGraphql
|
2
|
+
class CreateRecurringSubscription
|
3
|
+
include Mutation
|
4
|
+
|
5
|
+
MUTATION = <<~GRAPHQL
|
6
|
+
#{AppSubscriptionFields::FRAGMENT}
|
7
|
+
|
8
|
+
mutation appSubscriptionCreate(
|
9
|
+
$name: String!,
|
10
|
+
$lineItems: [AppSubscriptionLineItemInput!]!,
|
11
|
+
$returnUrl: URL!,
|
12
|
+
$trialDays: Int,
|
13
|
+
$test: Boolean
|
14
|
+
) {
|
15
|
+
appSubscriptionCreate(
|
16
|
+
name: $name,
|
17
|
+
lineItems: $lineItems,
|
18
|
+
returnUrl: $returnUrl,
|
19
|
+
trialDays: $trialDays,
|
20
|
+
test: $test
|
21
|
+
) {
|
22
|
+
appSubscription {
|
23
|
+
... AppSubscriptionFields
|
24
|
+
}
|
25
|
+
confirmationUrl
|
26
|
+
userErrors {
|
27
|
+
field
|
28
|
+
message
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
GRAPHQL
|
33
|
+
|
34
|
+
def call(name:, price:, return_url:, trial_days: nil, test: nil, interval: :monthly)
|
35
|
+
payload = {name: name, returnUrl: return_url}
|
36
|
+
plan_interval = interval == :monthly ? "EVERY_30_DAYS" : "ANNUAL"
|
37
|
+
payload[:lineItems] = [{
|
38
|
+
plan: {
|
39
|
+
appRecurringPricingDetails: {
|
40
|
+
price: {amount: price, currencyCode: "USD"},
|
41
|
+
interval: plan_interval
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}]
|
45
|
+
payload[:trialDays] = trial_days if trial_days
|
46
|
+
payload[:test] = test if test
|
47
|
+
|
48
|
+
response = execute(MUTATION, **payload)
|
49
|
+
response.data = response.data.appSubscriptionCreate
|
50
|
+
handle_user_errors(response.data)
|
51
|
+
response.data = parse_data(response.data)
|
52
|
+
response
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def parse_data(data)
|
58
|
+
OpenStruct.new(
|
59
|
+
subscription: AppSubscriptionFields.parse(data.appSubscription),
|
60
|
+
confirmation_url: data.confirmationUrl
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module ShopifyGraphql
|
2
|
+
class CreateUsageSubscription
|
3
|
+
include Mutation
|
4
|
+
|
5
|
+
MUTATION = <<~GRAPHQL
|
6
|
+
#{AppSubscriptionFields::FRAGMENT}
|
7
|
+
|
8
|
+
mutation appSubscriptionCreate(
|
9
|
+
$name: String!,
|
10
|
+
$returnUrl: URL!,
|
11
|
+
$test: Boolean
|
12
|
+
$lineItems: [AppSubscriptionLineItemInput!]!,
|
13
|
+
) {
|
14
|
+
appSubscriptionCreate(
|
15
|
+
name: $name,
|
16
|
+
returnUrl: $returnUrl,
|
17
|
+
test: $test
|
18
|
+
lineItems: $lineItems,
|
19
|
+
) {
|
20
|
+
appSubscription {
|
21
|
+
... AppSubscriptionFields
|
22
|
+
}
|
23
|
+
confirmationUrl
|
24
|
+
userErrors {
|
25
|
+
field
|
26
|
+
message
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
GRAPHQL
|
31
|
+
|
32
|
+
def call(name:, return_url:, terms:, capped_amount:, test: false)
|
33
|
+
response = execute(
|
34
|
+
MUTATION,
|
35
|
+
name: name,
|
36
|
+
returnUrl: return_url,
|
37
|
+
test: test,
|
38
|
+
lineItems: [{
|
39
|
+
plan: {
|
40
|
+
appUsagePricingDetails: {
|
41
|
+
terms: terms,
|
42
|
+
cappedAmount: {amount: capped_amount, currencyCode: "USD"}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}]
|
46
|
+
)
|
47
|
+
response.data = response.data.appSubscriptionCreate
|
48
|
+
handle_user_errors(response.data)
|
49
|
+
response.data = parse_data(response.data)
|
50
|
+
response
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def parse_data(data)
|
56
|
+
OpenStruct.new(
|
57
|
+
subscription: AppSubscriptionFields.parse(data.appSubscription),
|
58
|
+
confirmation_url: data.confirmationUrl
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ShopifyGraphql
|
2
|
+
class GetAppSubscription
|
3
|
+
include Query
|
4
|
+
|
5
|
+
QUERY = <<~GRAPHQL
|
6
|
+
#{AppSubscriptionFields::FRAGMENT}
|
7
|
+
|
8
|
+
query($id: ID!) {
|
9
|
+
node(id: $id) {
|
10
|
+
... AppSubscriptionFields
|
11
|
+
}
|
12
|
+
}
|
13
|
+
GRAPHQL
|
14
|
+
|
15
|
+
def call(id:)
|
16
|
+
response = execute(QUERY, id: id)
|
17
|
+
response.data = parse_data(response.data)
|
18
|
+
response
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def parse_data(data)
|
24
|
+
unless data.node
|
25
|
+
raise ResourceNotFound.new(200, "Subscription not found")
|
26
|
+
end
|
27
|
+
|
28
|
+
OpenStruct.new(
|
29
|
+
subscription: AppSubscriptionFields.parse(data.node),
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,5 +1,16 @@
|
|
1
1
|
module ShopifyGraphql
|
2
2
|
class Client
|
3
|
+
RETRIABLE_EXCEPTIONS = [
|
4
|
+
Errno::ETIMEDOUT,
|
5
|
+
Errno::ECONNREFUSED,
|
6
|
+
Errno::EHOSTUNREACH,
|
7
|
+
'Timeout::Error',
|
8
|
+
Faraday::TimeoutError,
|
9
|
+
Faraday::RetriableResponse,
|
10
|
+
Faraday::ParsingError,
|
11
|
+
Faraday::ConnectionFailed,
|
12
|
+
].freeze
|
13
|
+
|
3
14
|
def initialize(api_version = ShopifyAPI::Base.api_version)
|
4
15
|
@api_version = api_version
|
5
16
|
end
|
@@ -29,6 +40,7 @@ module ShopifyGraphql
|
|
29
40
|
@connection ||= Faraday.new(url: api_url, headers: request_headers) do |conn|
|
30
41
|
conn.request :json
|
31
42
|
conn.response :json, parser_options: { object_class: OpenStruct }
|
43
|
+
conn.request :retry, max: 3, interval: 1, backoff_factor: 2, exceptions: RETRIABLE_EXCEPTIONS
|
32
44
|
end
|
33
45
|
end
|
34
46
|
|
@@ -17,7 +17,7 @@ module ShopifyGraphql
|
|
17
17
|
engine_name 'shopify_graphql'
|
18
18
|
isolate_namespace ShopifyGraphql
|
19
19
|
|
20
|
-
initializer "
|
20
|
+
initializer "shopify_graphql.redact_job_params" do
|
21
21
|
ActiveSupport.on_load(:active_job) do
|
22
22
|
if ActiveJob::Base.respond_to?(:log_arguments?)
|
23
23
|
CreateWebhooksJob.log_arguments = false
|
data/lib/shopify_graphql.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shopify_graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kirill Platonov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -17,9 +17,6 @@ dependencies:
|
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 5.2.0
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 8.0.0
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,9 +24,20 @@ dependencies:
|
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 5.2.0
|
30
|
-
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: shopify_api
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
31
32
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
33
41
|
- !ruby/object:Gem::Dependency
|
34
42
|
name: shopify_app
|
35
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,6 +90,11 @@ files:
|
|
82
90
|
- LICENSE.txt
|
83
91
|
- README.md
|
84
92
|
- app/controllers/shopify_graphql/graphql_webhooks_controller.rb
|
93
|
+
- app/graphql/shopify_graphql/app_subscription_fields.rb
|
94
|
+
- app/graphql/shopify_graphql/cancel_subscription.rb
|
95
|
+
- app/graphql/shopify_graphql/create_recurring_subscription.rb
|
96
|
+
- app/graphql/shopify_graphql/create_usage_subscription.rb
|
97
|
+
- app/graphql/shopify_graphql/get_app_subscription.rb
|
85
98
|
- config/routes.rb
|
86
99
|
- lib/shopify_graphql.rb
|
87
100
|
- lib/shopify_graphql/client.rb
|
@@ -122,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
135
|
- !ruby/object:Gem::Version
|
123
136
|
version: '0'
|
124
137
|
requirements: []
|
125
|
-
rubygems_version: 3.2.
|
138
|
+
rubygems_version: 3.2.33
|
126
139
|
signing_key:
|
127
140
|
specification_version: 4
|
128
141
|
summary: Less painful way to work with Shopify Graphql API in Ruby.
|