e_plat 1.0.0.pre.rc.3 → 1.0.0.pre.rc.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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +23 -1
  3. data/lib/e_plat/mapping/shopify/v_2025_01/metafield.rb +26 -0
  4. data/lib/e_plat/mapping/shopify/v_2025_01/order/billing_address.rb +14 -0
  5. data/lib/e_plat/mapping/shopify/v_2025_01/order/shipping_address.rb +30 -0
  6. data/lib/e_plat/mapping/shopify/v_2025_01/order.rb +26 -0
  7. data/lib/e_plat/mapping/shopify/v_2025_01/product/image.rb +52 -0
  8. data/lib/e_plat/mapping/shopify/v_2025_01/product/option.rb +45 -0
  9. data/lib/e_plat/mapping/shopify/v_2025_01/product/variant/option_value.rb +58 -0
  10. data/lib/e_plat/mapping/shopify/v_2025_01/product/variant.rb +186 -0
  11. data/lib/e_plat/mapping/shopify/v_2025_01/product.rb +100 -0
  12. data/lib/e_plat/mapping/shopify/v_2025_01/script_tag.rb +26 -0
  13. data/lib/e_plat/mapping/shopify/v_2025_01/shop.rb +26 -0
  14. data/lib/e_plat/mapping/shopify/v_2025_01/webhook.rb +29 -0
  15. data/lib/e_plat/resource/base.rb +8 -3
  16. data/lib/e_plat/resource/concerns/graph_q_lable.rb +17 -11
  17. data/lib/e_plat/resource/concerns/overwrite_request_methods.rb +7 -1
  18. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/input/product/variant.rb +90 -0
  19. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/input/product/variants_bulk.rb +60 -0
  20. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/input/product.rb +36 -0
  21. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/input.rb +133 -0
  22. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/mutation/product/variant.rb +86 -0
  23. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/mutation/product.rb +55 -0
  24. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/mutation.rb +5 -0
  25. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/query/product/variant.rb +44 -0
  26. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/query/product.rb +58 -0
  27. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2025_01/query.rb +5 -0
  28. data/lib/e_plat/resource/platform_specific/shopify/product/variant.rb +3 -3
  29. data/lib/e_plat/resource/platform_specific/shopify/product.rb +1 -5
  30. data/lib/e_plat/resource/product/variant.rb +1 -1
  31. data/lib/e_plat/version.rb +1 -1
  32. data/lib/e_plat.rb +3 -4
  33. metadata +24 -2
@@ -75,8 +75,11 @@ module EPlat
75
75
  def cached_shopify_webhook?
76
76
  self.to_s.include?("EPlat::ShopifyWebhook")
77
77
  end
78
+
79
+ def element_name_plural?(word)
80
+ word&.downcase&.include? element_name.pluralize
81
+ end
78
82
 
79
-
80
83
  private
81
84
 
82
85
  def mapping_instance
@@ -219,9 +222,11 @@ module EPlat
219
222
  def element_name
220
223
  self.class.element_name
221
224
  end
222
-
223
- end
224
225
 
226
+ def element_name_plural?(word)
227
+ self.class.element_name_plural?(word)
228
+ end
225
229
 
230
+ end
226
231
  end
227
232
 
@@ -136,6 +136,10 @@ module EPlat
136
136
 
137
137
  def remove_nodes_from(data)
138
138
  return data unless data.is_a?(Hash) or data.is_a?(Array)
139
+
140
+ if data.is_a?(Hash) && data.keys.one? && self.element_name_plural?(data.keys.first)
141
+ data = data.values.first if data.values.first.is_a?(Array)
142
+ end
139
143
 
140
144
  if data.is_a?(Array)
141
145
  return data.map { |item| remove_nodes_from(item) }
@@ -145,7 +149,7 @@ module EPlat
145
149
  if value.is_a?(Hash) && value.key?('nodes')
146
150
  remove_nodes_from(value['nodes'])
147
151
  elsif value.is_a?(Array)
148
- value.map { |item| remove_nodes_from(item) }
152
+ value.map { |item| remove_nodes_from(item) }
149
153
  else
150
154
  remove_nodes_from(value)
151
155
  end
@@ -222,7 +226,13 @@ module EPlat
222
226
  raise EPlat::GraphqlError.new(response["errors"].first["message"])
223
227
  else
224
228
  response = remove_mutation_root_from(response, graphql_proc_constant)
225
- load self.class.resources_parsed_from(response), true, true
229
+ parsed_response = self.class.resources_parsed_from(response)
230
+
231
+ if parsed_response.is_a?(Array)
232
+ load parsed_response.first, true, true
233
+ else
234
+ load parsed_response, true, true
235
+ end
226
236
 
227
237
  @persisted = true
228
238
  changed_attributes.clear
@@ -233,16 +243,12 @@ module EPlat
233
243
  end
234
244
 
235
245
  def graphql_mutation_string(graphql_proc_constant, action)
236
- mutation_proc = eval graphql_proc_constant
246
+ mutation_proc = eval graphql_proc_constant
247
+ input = graphql_input.mutation_input(self, action)
248
+
237
249
  additional_graphql = self.class.before_graphql_callbacks[action.to_sym]&.call(self)
238
- input =
239
- if action == :delete
240
- self.is_a?(EPlat::Product::Variant) ? graphql_input.new(id: formatted_id) : graphql_input.new({id: formatted_id})
241
- else
242
- graphql_input.new mapping.via_native_attributes_where_possible(self.class.remove_root_from as_json)
243
- end
244
-
245
- mutation_proc.call(input.to_graphql_args, additional_graphql:)
250
+
251
+ mutation_proc.call(input, additional_graphql:)
246
252
  end
247
253
 
248
254
  def remove_mutation_root_from(data, graphql_proc_constant)
@@ -33,7 +33,8 @@ module EPlat
33
33
 
34
34
  def instantiate_collection(collection, original_params = {}, prefix_options = {})
35
35
  collection = collection["data"] if collection.is_a?(Hash) && collection["data"]
36
- super
36
+
37
+ super(collection, original_params, prefix_options)
37
38
  end
38
39
 
39
40
  def new(attributes={}, persisted = false)
@@ -42,11 +43,16 @@ module EPlat
42
43
  else
43
44
  initialize_singleton!
44
45
 
46
+ if self.element_name == "product"
47
+ (attributes["variants"] || []).each{ _1["product_id"] ||= attributes["id"] }
48
+ end
49
+
45
50
  self.mapping = EPlat::Mapping.new_instance(specifc_mapping: specifc_mapping_name, resource: nil)
46
51
 
47
52
  if attributes[mapping.native_top_key]
48
53
  attributes = attributes.send(*top_key_method(mapping.native_top_key))
49
54
  end
55
+
50
56
  attributes = attributes.with_defaults(mapping.class::DEFAULT_VALUES)
51
57
 
52
58
  super
@@ -0,0 +1,90 @@
1
+ class EPlat::Shopify::GraphQL::V202501::Input::Product::Variant < EPlat::Shopify::GraphQL::V202501::Input
2
+ USES_ELEMENT_NAME_AS_INPUT_ROOT_KEY = false
3
+
4
+ SUPPORTED_FIELDS = %w[
5
+ barcode
6
+ compareAtPrice
7
+ id
8
+ inventoryItem
9
+ inventoryPolicy
10
+ inventoryQuantities
11
+ mediaSrc
12
+ metafields
13
+ optionValues
14
+ price
15
+ taxCode
16
+ taxable
17
+ ].freeze
18
+
19
+ SUPPORTED_NAMED_ARGUMENT_FIELDS = {
20
+ product_id: %w[
21
+ productId
22
+ ],
23
+ variant: %w[
24
+ barcode
25
+ compareAtPrice
26
+ id
27
+ inventoryItem
28
+ inventoryPolicy
29
+ inventoryQuantities
30
+ mediaSrc
31
+ metafields
32
+ optionValues
33
+ price
34
+ taxCode
35
+ taxable
36
+ ],
37
+ variants: %w[
38
+ barcode
39
+ compareAtPrice
40
+ id
41
+ inventoryItem
42
+ inventoryPolicy
43
+ inventoryQuantities
44
+ mediaSrc
45
+ metafields
46
+ optionValues
47
+ price
48
+ taxCode
49
+ taxable
50
+ ],
51
+ inventory_item: %w[
52
+ cost
53
+ countryCodeOfOrigin
54
+ countryHarmonizedSystemCodes
55
+ harmonizedSystemCode
56
+ measurement
57
+ provinceCodeOfOrigin
58
+ requiresShipping
59
+ sku
60
+ tracked
61
+ ],
62
+ option_values: %w[
63
+ optionId
64
+ name
65
+ linkedMetafieldValue
66
+ optionId
67
+ optionName
68
+ ]
69
+ }.with_indifferent_access.freeze
70
+
71
+
72
+ def self.mutation_input(resource, action)
73
+ case action.to_sym
74
+ when :delete
75
+ new(
76
+ variantsIds: [resource.formatted_id],
77
+ product_id: EPlat::Product.formatted_id(resource.product_id)
78
+ )
79
+ else
80
+ new(
81
+ variants: [
82
+ resource.class.mapping.via_native_attributes_where_possible(
83
+ resource.class.remove_root_from(resource.as_json)
84
+ )
85
+ ],
86
+ product_id: EPlat::Product.formatted_id(resource.product_id)
87
+ )
88
+ end.query_input
89
+ end
90
+ end
@@ -0,0 +1,60 @@
1
+ class EPlat::Shopify::GraphQL::V202501::Input::Product::VariantsBulk < EPlat::Shopify::GraphQL::V202501::Input
2
+ USES_ELEMENT_NAME_AS_INPUT_ROOT_KEY = false
3
+
4
+ SUPPORTED_FIELDS = %w[
5
+ barcode
6
+ compareAtPrice
7
+ id
8
+ inventoryItem
9
+ inventoryPolicy
10
+ inventoryQuantities
11
+ mediaSrc
12
+ metafields
13
+ optionValues
14
+ price
15
+ taxCode
16
+ taxable
17
+ ].freeze
18
+
19
+ SUPPORTED_NAMED_ARGUMENT_FIELDS = {
20
+ variants: %w[
21
+ barcode
22
+ compareAtPrice
23
+ id
24
+ inventoryItem
25
+ inventoryPolicy
26
+ inventoryQuantities
27
+ mediaSrc
28
+ metafields
29
+ optionValues
30
+ price
31
+ taxCode
32
+ taxable
33
+ ],
34
+ inventory_item: %w[
35
+ cost
36
+ countryCodeOfOrigin
37
+ countryHarmonizedSystemCodes
38
+ harmonizedSystemCode
39
+ measurement
40
+ provinceCodeOfOrigin
41
+ requiresShipping
42
+ sku
43
+ tracked
44
+ ],
45
+ option_values: %w[
46
+ name
47
+ optionId
48
+ linkedMetafieldValue
49
+ optionId
50
+ optionName
51
+ ]
52
+ }.with_indifferent_access.freeze
53
+
54
+ def self.mutation_input(product, action)
55
+ new(
56
+ product_id: EPlat::Product.formatted_id(product.id),
57
+ variants: product.as_json["product"]["variants"]
58
+ ).query_input
59
+ end
60
+ end
@@ -0,0 +1,36 @@
1
+ class EPlat::Shopify::GraphQL::V202501::Input::Product < EPlat::Shopify::GraphQL::V202501::Input
2
+
3
+ SUPPORTED_FIELDS = %w[
4
+ category
5
+ claimOwnership
6
+ title
7
+ descriptionHtml
8
+ productType
9
+ vendor
10
+ tags
11
+ collectionsToJoin
12
+ collectionsToLeave
13
+ combinedListingRole
14
+ metafields
15
+ productOptions
16
+ templateSuffix
17
+ requiresSellingPlan
18
+ giftCard
19
+ giftCardTemplateSuffix
20
+ seo
21
+ status
22
+ id
23
+ handle
24
+ redirectNewHandle
25
+ ].freeze
26
+
27
+ def self.mutation_input(resource, action)
28
+ case action.to_sym
29
+ when :delete
30
+ new(input: {id: resource.formatted_id})
31
+ else
32
+ rootless_json = resource.class.remove_root_from(resource.as_json)
33
+ new(resource.class.mapping.via_native_attributes_where_possible rootless_json)
34
+ end.query_input
35
+ end
36
+ end
@@ -0,0 +1,133 @@
1
+ class EPlat::Shopify::GraphQL::V202501::Input
2
+ attr_accessor :input, :named_arguments
3
+
4
+ SUPPORTED_FIELDS = []
5
+ SUPPORTED_NAMED_ARGUMENT_FIELDS = {}
6
+ USES_ELEMENT_NAME_AS_INPUT_ROOT_KEY = true
7
+
8
+ def initialize(input = {}, **named_arguments)
9
+ @input = input.deep_transform_keys { |key| key.to_s.camelize(:lower) }
10
+ @named_arguments = named_arguments.deep_transform_keys { |key| key.to_s.camelize(:lower) }
11
+ end
12
+
13
+ def query_input
14
+ args =
15
+ if named_arguments.present?
16
+ named_arguments_with_allowed_fields(named_arguments)
17
+ else
18
+ self.class::USES_ELEMENT_NAME_AS_INPUT_ROOT_KEY ? { element_name => allowed_fields } : allowed_fields
19
+ end
20
+
21
+ format_graphql_args(args)
22
+ end
23
+
24
+ def self.mutation_input(resource, action)
25
+ raise "mutation_input not implemented for #{self.class.name}"
26
+ # example:
27
+ # case action.to_sym
28
+ # when :delete
29
+ # new(input: { id: resource.formatted_id })
30
+ # else
31
+ # new(resource.class.mapping.via_native_attributes_where_possible(
32
+ # resource.class.remove_root_from(resource.as_json)
33
+ # ))
34
+ # end.query_input
35
+ end
36
+
37
+
38
+ protected
39
+
40
+ def allowed_fields
41
+ fields_hash = input.slice(*self.class::SUPPORTED_FIELDS)
42
+
43
+ fields_hash.map do |key, value|
44
+ if value.is_a?(Hash) && child_allowed_fields = self.class::SUPPORTED_NAMED_ARGUMENT_FIELDS[key] || self.class::SUPPORTED_NAMED_ARGUMENT_FIELDS[key&.underscore]
45
+ [key, value.slice(*child_allowed_fields)]
46
+ else
47
+ [key, value]
48
+ end
49
+ end.to_h
50
+ end
51
+
52
+ def named_arguments_with_allowed_fields(arguments, name=nil)
53
+ arguments.map do |key, value|
54
+ fields_hash = self.class::SUPPORTED_NAMED_ARGUMENT_FIELDS[name] || self.class::SUPPORTED_NAMED_ARGUMENT_FIELDS[key] || self.class::SUPPORTED_NAMED_ARGUMENT_FIELDS[key&.underscore] || []
55
+
56
+ case value
57
+ when Hash
58
+ [key, named_arguments_with_allowed_fields(value, key.underscore)]
59
+ when Array
60
+ [key, value.map {_1.is_a?(Hash) ? named_arguments_with_allowed_fields(_1, key.underscore) : _1}]
61
+ else
62
+ (fields_hash.empty? || fields_hash.include?(key)) ? [key, value] : [nil, nil]
63
+ end
64
+ end.to_h.compact_blank
65
+ end
66
+
67
+ def format_graphql_item(item, key: nil)
68
+ case item
69
+ when Hash
70
+ "{ #{item.map { |k, v| "#{k}: #{v.is_a?(String) ? enum_friendly(v, key: k) : format_graphql_item(v, key: k)}" }.join(', ')} }"
71
+ when Array
72
+ "[ #{item.map { |i| format_graphql_item(i, key: key) }.join(', ')} ]"
73
+ else
74
+ enum_friendly(item, key: key)
75
+ end
76
+ end
77
+
78
+ def enum_friendly(value, key: nil)
79
+ case
80
+ when key == "tags"
81
+ "\"#{single_quotes_only(value)}\""
82
+ when value.is_a?(String)
83
+ if value.match?(/\A[A-Z_]+\z/)
84
+ value
85
+ else
86
+ "\"#{single_quotes_only(value)}\""
87
+ end
88
+ else
89
+ value
90
+ end
91
+ end
92
+
93
+ def single_quotes_only(value)
94
+ value&.gsub("\"", "'")
95
+ end
96
+
97
+ def format_graphql_args(args, key: nil)
98
+ args.map do |key, value|
99
+ case value
100
+ when Hash
101
+ "#{key}: { #{format_graphql_args(value, key:)} }"
102
+ when Array
103
+ if (value.first.is_a? Hash)
104
+ "#{key}: [ #{value.map { |v| "{ #{format_graphql_args(v, key:)} }" }.join(', ')} ]"
105
+ else
106
+ "#{key}: [ #{value.map { |v| enum_friendly(v, key: key) }.join(', ')} ]"
107
+ end
108
+ when String
109
+ "#{key}: #{enum_friendly(value, key: key)}"
110
+ else
111
+ "#{key}: #{value}"
112
+ end
113
+ end.join(', ')
114
+ end
115
+
116
+ def element_name
117
+ self.class.name.split("::").last.downcase
118
+ end
119
+
120
+ end
121
+ #
122
+ # creates a graphql mutation input.
123
+ # if just input as arg, use:
124
+ # input.new(
125
+ # [{...}, {...}]
126
+ # ).to_graphql_args
127
+ #
128
+ # Otherwise, you can pass named arguments in for each graphql argument:
129
+ # input.new(
130
+ # product_id: "gid/123",
131
+ # variants: [{...}, {...}]
132
+ # ).to_graphql_args
133
+ #
@@ -0,0 +1,86 @@
1
+
2
+ module EPlat::Shopify::GraphQL::V202501::Mutation::Product::Variant
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+
7
+ # def self.product_variant_delete
8
+ # ->(args, additional_graphql: nil) do
9
+ # <<~GRAPHQL
10
+ # mutation {
11
+ # #{additional_graphql}
12
+ # productVariantDelete(#{args}) {
13
+ # deletedProductVariantId
14
+ # userErrors {
15
+ # field
16
+ # message
17
+ # }
18
+ # }
19
+ # }
20
+ # GRAPHQL
21
+ # end
22
+ # end
23
+
24
+ def self.product_variants_bulk_update
25
+ ->(args, additional_graphql: nil) do
26
+ <<~GRAPHQL
27
+ mutation {
28
+ #{product_variants_bulk_update_fragment.call(args, additional_graphql: additional_graphql)}
29
+ }
30
+ GRAPHQL
31
+ end
32
+ end
33
+
34
+ def self.product_variants_bulk_create
35
+ ->(args, additional_graphql: nil) do
36
+ <<~GRAPHQL
37
+ mutation {
38
+ #{product_variants_bulk_create_fragment.call(args, additional_graphql: additional_graphql)}
39
+ }
40
+ GRAPHQL
41
+ end
42
+ end
43
+
44
+ def self.product_variants_bulk_delete
45
+ ->(args, additional_graphql: nil) do
46
+ <<~GRAPHQL
47
+ mutation {
48
+ #{additional_graphql}
49
+ productVariantsBulkDelete(#{args}) {
50
+ product {
51
+ id
52
+ }
53
+ }
54
+ }
55
+ GRAPHQL
56
+ end
57
+ end
58
+
59
+ def self.product_variants_bulk_create_fragment
60
+ ->(args, additional_graphql: nil) do
61
+ <<~GRAPHQL
62
+ #{additional_graphql}
63
+ productVariantsBulkCreate(#{args}) {
64
+ productVariants {
65
+ #{EPlat::Shopify::Product::Variant.graphql_fields}
66
+ }
67
+ }
68
+ GRAPHQL
69
+ end
70
+ end
71
+
72
+ def self.product_variants_bulk_update_fragment
73
+ ->(args, additional_graphql: nil) do
74
+ <<~GRAPHQL
75
+ #{additional_graphql}
76
+ productVariantsBulkUpdate(#{args}) {
77
+ productVariants {
78
+ #{EPlat::Shopify::Product::Variant.graphql_fields}
79
+ }
80
+ }
81
+ GRAPHQL
82
+ end
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,55 @@
1
+
2
+ module EPlat::Shopify::GraphQL::V202501::Mutation::Product
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+
7
+ def self.product_create
8
+ ->(args, additional_graphql: nil) do
9
+ <<~GRAPHQL
10
+ mutation {
11
+ #{additional_graphql}
12
+ productCreate(#{args}) {
13
+ product {
14
+ #{EPlat::Shopify::Product.graphql_fields}
15
+ }
16
+ }
17
+ }
18
+ GRAPHQL
19
+ end
20
+ end
21
+
22
+ def self.product_update
23
+ ->(args, additional_graphql: nil) do
24
+ <<~GRAPHQL
25
+ mutation {
26
+ #{additional_graphql}
27
+ productUpdate(#{args}) {
28
+ product {
29
+ #{EPlat::Shopify::Product.graphql_fields}
30
+ }
31
+ }
32
+ }
33
+ GRAPHQL
34
+ end
35
+ end
36
+
37
+ def self.product_delete
38
+ ->(args, additional_graphql: nil) do
39
+ <<~GRAPHQL
40
+ mutation {
41
+ #{additional_graphql}
42
+ productDelete(#{args}) {
43
+ deletedProductId
44
+ userErrors {
45
+ field
46
+ message
47
+ }
48
+ }
49
+ }
50
+ GRAPHQL
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ class EPlat::Shopify::GraphQL::V202501::Mutation
2
+ include Product, Product::Variant
3
+ end
4
+
5
+
@@ -0,0 +1,44 @@
1
+
2
+ module EPlat::Shopify::GraphQL::V202501::Query::Product::Variant
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+
7
+ def self.variants
8
+ ->(args) do
9
+ formatted_args = args.present? ? "(#{args})" : ""
10
+
11
+ <<~GRAPHQL
12
+ query getProductVariants {
13
+ productVariants#{formatted_args} {
14
+ nodes {
15
+ #{EPlat::Shopify::Product::Variant.graphql_fields}
16
+ }
17
+ pageInfo {
18
+ endCursor
19
+ startCursor
20
+ hasNextPage
21
+ hasPreviousPage
22
+ }
23
+ }
24
+ }
25
+ GRAPHQL
26
+ end
27
+ end
28
+
29
+ def self.variant
30
+ ->(args) do
31
+ formatted_args = args.present? ? "(#{args})" : ""
32
+
33
+ <<~GRAPHQL
34
+ query getProductVariant {
35
+ productVariant#{formatted_args} {
36
+ #{EPlat::Shopify::Product::Variant.graphql_fields}
37
+ }
38
+ }
39
+ GRAPHQL
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,58 @@
1
+
2
+ module EPlat::Shopify::GraphQL::V202501::Query::Product
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+
7
+ def self.products
8
+ ->(args) do
9
+ formatted_args = args.present? ? "(#{args})" : ""
10
+
11
+ <<~GRAPHQL
12
+ query getProducts {
13
+ products#{formatted_args} {
14
+ nodes {
15
+ #{EPlat::Shopify::Product.graphql_fields}
16
+ }
17
+ pageInfo {
18
+ endCursor
19
+ startCursor
20
+ hasNextPage
21
+ hasPreviousPage
22
+ }
23
+ }
24
+ }
25
+ GRAPHQL
26
+ end
27
+ end
28
+
29
+ def self.product
30
+ ->(args) do
31
+ formatted_args = args.present? ? "(#{args})" : ""
32
+
33
+ <<~GRAPHQL
34
+ query getProduct {
35
+ product#{formatted_args} {
36
+ #{EPlat::Shopify::Product.graphql_fields}
37
+ }
38
+ }
39
+ GRAPHQL
40
+ end
41
+ end
42
+
43
+ def self.products_count
44
+ ->(args) do
45
+ formatted_args = args.present? ? "(#{args})" : ""
46
+
47
+ <<~GRAPHQL
48
+ query productsCount {
49
+ productsCount#{formatted_args} {
50
+ count
51
+ }
52
+ }
53
+ GRAPHQL
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ class EPlat::Shopify::GraphQL::V202501::Query
2
+ include Product, Product::Variant
3
+ end
4
+
5
+
@@ -4,9 +4,9 @@ class EPlat::Shopify::Product::Variant < EPlat::Product::Variant
4
4
  find_every: "EPlat::Shopify::GraphQL::{API_VERSION}::Query.variants",
5
5
  find_single: "EPlat::Shopify::GraphQL::{API_VERSION}::Query.variant",
6
6
  find_one: "EPlat::Shopify::GraphQL::{API_VERSION}::Query.variants",
7
- create: "EPlat::Shopify::GraphQL::{API_VERSION}::Mutation.product_variant_create",
8
- update: "EPlat::Shopify::GraphQL::{API_VERSION}::Mutation.product_variant_update",
9
- delete: "EPlat::Shopify::GraphQL::{API_VERSION}::Mutation.product_variant_delete"
7
+ create: "EPlat::Shopify::GraphQL::{API_VERSION}::Mutation.product_variants_bulk_create",
8
+ update: "EPlat::Shopify::GraphQL::{API_VERSION}::Mutation.product_variants_bulk_update",
9
+ delete: "EPlat::Shopify::GraphQL::{API_VERSION}::Mutation.product_variants_bulk_delete"
10
10
  }, unless: -> { EPlat.config.shopify_api_version == "2024_01" }
11
11
 
12
12
  def self.graphql_fields