shopify_graphql 0.2.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7081c7f634ac890bc428d5eb2e67d260cebf1dae0cb56ee514d375a39de76c2f
4
- data.tar.gz: 48e7c7b931e462502a93359e175ec13858988e5435be1f3e8dc114b75680103c
3
+ metadata.gz: '018b4cef704098a6424fda98cb9805a11e86c29fd3e5a391e5945687a7ddc621'
4
+ data.tar.gz: 1f4e1be2f4b3edbf319251023a6a9d596bf34fa1f877dc51269d0cd9bb5db6f7
5
5
  SHA512:
6
- metadata.gz: a9db31af58e597e5d0b91e66e388ae8d1a2b75afcc08fc0c75e9a3a84ac3ffd4f2b94466c3747ed5131750b19d88283ec274ae6c366ea377368f6d98303a72d4
7
- data.tar.gz: 4b8ad458b06267f51d35b9b1e56d85ec3f7ed4582928cba184567f047c8cd628e6d80d1d70199a004c9a0fbfeacd14bf624e80af4ed7f9b1f10e04ed1664fb12
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 "shopify_app.redact_job_params" do
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
@@ -1,3 +1,3 @@
1
1
  module ShopifyGraphql
2
- VERSION = "0.2.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,3 +1,4 @@
1
+ require 'shopify_api'
1
2
  require 'faraday'
2
3
  require 'faraday_middleware'
3
4
 
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.2.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: 2021-12-29 00:00:00.000000000 Z
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: 8.0.0
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.22
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.