e_plat 0.5.5 → 0.7.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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +109 -60
  3. data/lib/e_plat/client/default_request_args.rb +1 -1
  4. data/lib/e_plat/client.rb +55 -9
  5. data/lib/e_plat/initializer.rb +26 -0
  6. data/lib/e_plat/mapping/bigcommerce/v_3/product/option.rb +58 -0
  7. data/lib/e_plat/mapping/bigcommerce/v_3/product/variant/option_value.rb +42 -0
  8. data/lib/e_plat/mapping/shopify/v_2024_07/metafield.rb +26 -0
  9. data/lib/e_plat/mapping/shopify/v_2024_07/order/billing_address.rb +14 -0
  10. data/lib/e_plat/mapping/shopify/v_2024_07/order/shipping_address.rb +30 -0
  11. data/lib/e_plat/mapping/shopify/v_2024_07/order.rb +26 -0
  12. data/lib/e_plat/mapping/shopify/v_2024_07/product/image.rb +52 -0
  13. data/lib/e_plat/mapping/shopify/v_2024_07/product/option.rb +45 -0
  14. data/lib/e_plat/mapping/shopify/v_2024_07/product/variant/option_value.rb +58 -0
  15. data/lib/e_plat/mapping/shopify/v_2024_07/product/variant.rb +180 -0
  16. data/lib/e_plat/mapping/shopify/v_2024_07/product.rb +100 -0
  17. data/lib/e_plat/mapping/shopify/v_2024_07/script_tag.rb +26 -0
  18. data/lib/e_plat/mapping/shopify/v_2024_07/shop.rb +26 -0
  19. data/lib/e_plat/mapping/shopify/v_2024_07/webhook.rb +29 -0
  20. data/lib/e_plat/mapping/virtual_collection/shopify/product/variant/option_value.rb +272 -0
  21. data/lib/e_plat/mapping.rb +39 -15
  22. data/lib/e_plat/resource/base.rb +39 -5
  23. data/lib/e_plat/resource/collection.rb +45 -16
  24. data/lib/e_plat/resource/concerns/aliases.rb +39 -19
  25. data/lib/e_plat/resource/concerns/dirty.rb +12 -8
  26. data/lib/e_plat/resource/concerns/graph_q_lable.rb +253 -0
  27. data/lib/e_plat/resource/concerns/overwrite_instance_methods.rb +4 -4
  28. data/lib/e_plat/resource/concerns/overwrite_request_methods.rb +64 -21
  29. data/lib/e_plat/resource/countable.rb +37 -10
  30. data/lib/e_plat/resource/metafield.rb +2 -2
  31. data/lib/e_plat/resource/platform_specific/bigcommerce/metafield.rb +4 -0
  32. data/lib/e_plat/resource/platform_specific/bigcommerce/order/Consignment.rb +2 -0
  33. data/lib/e_plat/resource/platform_specific/bigcommerce/order/billing_address.rb +2 -0
  34. data/lib/e_plat/resource/platform_specific/bigcommerce/order/fulfillment.rb +2 -0
  35. data/lib/e_plat/resource/platform_specific/bigcommerce/order/line_item.rb +2 -0
  36. data/lib/e_plat/resource/platform_specific/bigcommerce/order/shipping_address.rb +2 -0
  37. data/lib/e_plat/resource/platform_specific/bigcommerce/order/shipping_line.rb +2 -0
  38. data/lib/e_plat/resource/platform_specific/bigcommerce/order.rb +4 -0
  39. data/lib/e_plat/resource/platform_specific/bigcommerce/product/image.rb +2 -0
  40. data/lib/e_plat/resource/platform_specific/bigcommerce/product/option.rb +2 -0
  41. data/lib/e_plat/resource/platform_specific/bigcommerce/product/variant/option_value.rb +2 -0
  42. data/lib/e_plat/resource/platform_specific/bigcommerce/product/variant.rb +2 -0
  43. data/lib/e_plat/resource/platform_specific/bigcommerce/product.rb +4 -0
  44. data/lib/e_plat/resource/platform_specific/bigcommerce/script_tag.rb +4 -0
  45. data/lib/e_plat/resource/platform_specific/bigcommerce/shop.rb +4 -0
  46. data/lib/e_plat/resource/platform_specific/bigcommerce/webhook.rb +4 -0
  47. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/input/product/variant.rb +47 -0
  48. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/input/product/variants_bulk.rb +47 -0
  49. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/input/product.rb +23 -0
  50. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/input.rb +98 -0
  51. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/mutation/product/variant.rb +78 -0
  52. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/mutation/product.rb +55 -0
  53. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/mutation.rb +5 -0
  54. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/query/product/variant.rb +44 -0
  55. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/query/product.rb +58 -0
  56. data/lib/e_plat/resource/platform_specific/shopify/graph_q_l/v_2024_07/query.rb +5 -0
  57. data/lib/e_plat/resource/platform_specific/shopify/metafield.rb +4 -0
  58. data/lib/e_plat/resource/platform_specific/shopify/order/Consignment.rb +2 -0
  59. data/lib/e_plat/resource/platform_specific/shopify/order/billing_address.rb +2 -0
  60. data/lib/e_plat/resource/platform_specific/shopify/order/fulfillment.rb +2 -0
  61. data/lib/e_plat/resource/platform_specific/shopify/order/line_item.rb +2 -0
  62. data/lib/e_plat/resource/platform_specific/shopify/order/shipping_address.rb +2 -0
  63. data/lib/e_plat/resource/platform_specific/shopify/order/shipping_line.rb +2 -0
  64. data/lib/e_plat/resource/platform_specific/shopify/order.rb +4 -0
  65. data/lib/e_plat/resource/platform_specific/shopify/product/image.rb +14 -0
  66. data/lib/e_plat/resource/platform_specific/shopify/product/option.rb +14 -0
  67. data/lib/e_plat/resource/platform_specific/shopify/product/variant/option_value.rb +14 -0
  68. data/lib/e_plat/resource/platform_specific/shopify/product/variant.rb +66 -0
  69. data/lib/e_plat/resource/platform_specific/shopify/product.rb +79 -0
  70. data/lib/e_plat/resource/platform_specific/shopify/recurring_application_charge/usage_charge.rb +2 -0
  71. data/lib/e_plat/resource/platform_specific/shopify/recurring_application_charge.rb +4 -0
  72. data/lib/e_plat/resource/platform_specific/shopify/script_tag.rb +4 -0
  73. data/lib/e_plat/resource/platform_specific/shopify/shop.rb +4 -0
  74. data/lib/e_plat/resource/platform_specific/shopify/webhook.rb +4 -0
  75. data/lib/e_plat/resource/product/image.rb +8 -5
  76. data/lib/e_plat/resource/product/option.rb +2 -3
  77. data/lib/e_plat/resource/product/variant/option_value.rb +17 -0
  78. data/lib/e_plat/resource/product/variant.rb +6 -14
  79. data/lib/e_plat/resource/product.rb +23 -11
  80. data/lib/e_plat/session.rb +3 -2
  81. data/lib/e_plat/type_coercer.rb +4 -2
  82. data/lib/e_plat/version.rb +1 -1
  83. data/lib/e_plat.rb +33 -4
  84. data/lib/hash.rb +39 -0
  85. metadata +163 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85b0fb58fb552bdd494649429de66feb12612b53ee0cf49bda4b1a87e14e81b7
4
- data.tar.gz: e5702192f1057e1f65736e20c88d7c35a4d6490db785d0dc4ef95381015cc6b2
3
+ metadata.gz: d10eb52dda105627cb32fb58161da4777a8a020f6ea70ba4111da4487441e743
4
+ data.tar.gz: 00ef52bdc6790981c6fcfb35615982c06b82152279d9a5f301ff3c84ad50747b
5
5
  SHA512:
6
- metadata.gz: ac493807a5ffc4e61a7eb7d5fa4b28777697a9aa5c50a8cb145e8d1327bef821f8efcdacc672e6652778fb3b3c5c5961d76d5844d4a874a2f2bdacdf3b7896e8
7
- data.tar.gz: c69b4fb8c31be9eecaaf6e587bbdd964a4a7ff046a844f0e3c81063d95a156fffe5667d9273a40e3e25fed5460e780bf02b2a5f29b7eb215d55c7806b15d718d
6
+ metadata.gz: f5951156f87b275af28cefeed42eff062aeb85155454a8b498c54d795843be40acd5245d1f20b5e724912abef7ef43b0dc47c4e09f2084ad1ad1fbab8418aafa
7
+ data.tar.gz: 0af92dd3962135ec69c738eab60bc320e8add2de57832cc793ed11ab5118e1515a7a048623f75537e3c126ae1e78e9c109cab49685335d7a9860da655d611bdc
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <strong>EPlat <small>(E-commerce Platform)</small> </br></strong>
4
4
  A single interface for interacting with E-commerce platform APIs.
5
5
 
6
- Goals are:
6
+ Goals:
7
7
  <ul>
8
8
  <li>
9
9
  Make it easy to use and request API resources from different platforms.
@@ -12,7 +12,7 @@ Goals are:
12
12
  Offer a universal alias interface for interacting with common natured attributes. e.g. Shopify's product.body_html and BigCommerce's product.description.
13
13
  </li>
14
14
  <li>
15
- Have a simple, easy-to-understand, lightweight project structure.
15
+ Have a simple, easy-to-understand project structure.
16
16
  </li>
17
17
  <li>
18
18
  The e_plat alias interface mimics Shopify's API schema names and types.
@@ -43,15 +43,37 @@ You can configure which platform APIs are used by updating the EPlat config: <br
43
43
  #initializers/e_plat.rb
44
44
  EPlat.config.shopify_api_version = "2024-01"
45
45
  EPlat.config.bigcommerce_api_version = "v3"
46
- EPlat.config.woocommerce_api_version = "v3"
47
46
 
48
47
  # EPlat.api_display_name.shopify #=> "2024-01" # presents as the platform would display in URL paths
49
48
  # EPlat.config.shopify_api_version #=> "2024_01" # coerced interally for creating constants
49
+ # EPlat.config.print_graphql_requests #=> false # prints out Shopify graphql queries/mutations to the console
50
50
  ```
51
51
  <br>
52
52
 
53
- ## Relasing new version
53
+ ## Testing
54
+
55
+ To run the test for the default versions of all supported platforms:
56
+ ```
57
+ bundle exec rails test
58
+ ```
59
+
60
+ To run with specific api versions, you can set globals inline
61
+ ```
62
+ EPLAT_SHOPIFY_API_VERSION=2024_07 EPLAT_BIGCOMMERCE_API_VERSION=v3 rails test
63
+ ```
64
+
65
+ To print out Shopify GraphQL queries/mutations
66
+ ```
67
+ EPLAT_PRINT_GRAPHQL_REQUESTS=true rails test
68
+ ```
69
+
70
+ <br>
71
+
72
+ ## Releasing a new version
54
73
  https://dev.to/doctolib/release-a-new-gem-version-je0
74
+
75
+ <br>
76
+
55
77
  <br>
56
78
 
57
79
  ## Usage
@@ -62,7 +84,7 @@ EPlat::Session.new(
62
84
  platform: :shopify,
63
85
  store_url: "test-store.myshopify.com",
64
86
  api_token: "123",
65
- # store_hash: optional BigCommerce store hash
87
+ # store_hash: "optional BigCommerce store hash"
66
88
  )
67
89
  ```
68
90
 
@@ -71,7 +93,7 @@ EPlat::Session.new(
71
93
  EPlat::Product.find(id: 123)
72
94
  ```
73
95
 
74
- 3. Which will return an instance of:
96
+ 3. Which will return a platform resource instance that inherits from:
75
97
  ```ruby
76
98
  EPlat::Product
77
99
  ```
@@ -212,10 +234,8 @@ EPlat is designed to let you mostly use it's universal interface, but then easil
212
234
  | options | array | * | * | nil |
213
235
  | product_type | string | * | type | nil |
214
236
  | published_at | datetime | * | nil | nil |
215
- | published_scope | string | * | nil | nil |
216
237
  | status | string | * | availability | nil |
217
238
  | tags | string | * | nil | nil |
218
- | admin_graphql_api_id | string | * | nil | nil |
219
239
  | template_suffix | string | * | nil | nil |
220
240
  | title | string | * | name | nil |
221
241
  | updated_at | datetime | * | date_modified| nil |
@@ -225,68 +245,62 @@ EPlat is designed to let you mostly use it's universal interface, but then easil
225
245
 
226
246
  ### EPlat::Product::Variant
227
247
 
228
-
229
- | Alias | Type | Shopify | BigCommerce | Etc |
230
- | --------------------- | -------- | ------- | ----------------------| ------------|
231
- | id | integer | * | id | nil |
232
- | product_id | integer | * | product_id | nil |
233
- | title | string | * | option_values&.map(&:label)&.join(' ') | nil |
234
- | price | string | * | price | nil |
235
- | sku | string | * | sku | nil |
236
- | position | integer | * | nil | nil |
237
- | inventory_policy | string | * | nil | nil |
238
- | compare_at_price | string | * | nil | nil |
239
- | fulfillment_service | string | * | nil | nil |
240
- | inventory_management | string | * | nil | nil |
241
- | option1 | string | * | option_values[0].label| nil |
242
- | option2 | string | * | nil | nil |
243
- | option3 | string | * | nil | nil |
244
- | created_at | datetime | * | nil | nil |
245
- | updated_at | datetime | * | nil | nil |
246
- | taxable | boolean | * | nil | nil |
247
- | barcode | string | * | nil | nil |
248
- | grams | integer | * | nil | nil |
249
- | image_id | integer | * | nil | nil |
250
- | weight | float | * | weight | nil |
251
- | weight_unit | string | * | nil | nil |
252
- | inventory_item_id | integer | * | nil | nil |
253
- | inventory_quantity | integer | * | inventory_level | nil |
254
- | old_inventory_quantity| integer | * | nil | nil |
255
- | presentment_prices | array | * | nil | nil |
256
- | tax_code | string | * | nil | nil |
257
- | requires_shipping | boolean | * | nil | nil |
258
- | admin_graphql_api_id | string | * | nil | nil |
259
-
248
+
249
+ | Alias | Type | Shopify | BigCommerce | Etc |
250
+ |-----------------------|----------|---------|--------------------------------------|-----|
251
+ | id | integer | * | id | nil |
252
+ | title | string | * | option_values&.map(&:label)&.join(' ') | nil |
253
+ | price | string | * | price | nil |
254
+ | sku | string | * | sku | nil |
255
+ | position | integer | * | nil | nil |
256
+ | inventory_policy | string | * | nil | nil |
257
+ | compare_at_price | string | * | nil | nil |
258
+ | inventory_management | boolean | inventoryItem[tracked] | nil | nil |
259
+ | created_at | datetime | * | nil | nil |
260
+ | updated_at | datetime | * | nil | nil |
261
+ | taxable | boolean | * | nil | nil |
262
+ | barcode | string | * | nil | nil |
263
+ | grams | integer | getter only: converted node.inventoryItem[measurement][weight][value] | nil | nil |
264
+ | weight | float | getter only: node.inventoryItem[measurement][weight][value] | weight |
265
+ | weight_unit | string | getter only: node.inventoryItem[measurement][weight][unit] | nil |
266
+ | inventory_item_id | integer | getter only: node.inventoryItem[id]| nil | nil |
267
+ | inventory_quantity | integer | getter only: node.inventoryQuantity | inventory_level | nil |
268
+ | tax_code | string | * | nil | nil |
269
+ | requires_shipping | boolean | InventoryItem[requiresShipping] | nil | nil |
260
270
  *Bigcommerce variant.title= setter is not supported
261
271
 
262
272
 
263
273
  ### EPlat::Product::Option
264
274
 
265
- | Alias | Type | Shopify | BigCommerce| Etc |
266
- | --------- | -------- | ------- | -----------| ------------|
267
- | id | integer | * | nil | nil |
268
- | product_id| integer | * | nil | nil |
269
- | name | string | * | nil | nil |
270
- | position | integer | * | nil | nil |
271
- | values | array | * | nil | nil |
272
-
275
+ | Alias | Type | Shopify | BigCommerce | Etc |
276
+ | ---------- | -------- | ------- | ---------------------------- | --- |
277
+ | id | integer | * | id | nil |
278
+ | name | string | * | display_name | nil |
279
+ | position | integer | * | sort_order | nil |
280
+ | values | array | * | option_values[i][label] | nil |
281
+
273
282
 
274
283
  ### EPlat::Product::Image
275
284
 
276
285
  | Alias | Type | Shopify | BigCommerce | Etc |
277
286
  | -------------------- | -------- | ------- | ----------- | ------------|
278
287
  | id | integer | * | id | nil |
279
- | product_id | integer | * | product_id | nil |
280
288
  | position | integer | * | nil | nil |
281
- | created_at | datetime | * | date_created | nil |
282
- | updated_at | datetime | * | date_modified| nil |
283
289
  | alt | string | * | nil | nil |
284
290
  | width | integer | * | nil | nil |
285
291
  | height | integer | * | nil | nil |
286
292
  | src | string | * | url_standard | nil |
287
293
  | variant_ids | array | * | nil | nil |
288
- | admin_graphql_api_id | string | * | nil | nil |
289
294
 
295
+
296
+ ### EPlat::Product::Variant::OptionValue
297
+ (not supported for Shopify API v2024_01)
298
+
299
+ | Alias | Type | Shopify | BigCommerce | Etc |
300
+ | -------------------- | -------- | ------------------------------------------ | ------------------ | --- |
301
+ | id | integer | [selected_options][option_value][id] | id | nil |
302
+ | name | string | [selected_options][name] | option_display_name| nil |
303
+ | value | string | [selected_options][value] | label | nil |
290
304
  </details>
291
305
 
292
306
  <details>
@@ -412,6 +426,26 @@ EPlat is designed to let you mostly use it's universal interface, but then easil
412
426
  | longitude | float | * | nil | nil |
413
427
 
414
428
 
429
+ ### EPlat::Order::BillingAddress
430
+
431
+ | Alias | Type | Shopify | BigCommerce | Etc |
432
+ |---------------|---------|---------|-------------|-------------|
433
+ | address1 | string | * | street_1 | nil |
434
+ | address2 | string | * | street_2 | nil |
435
+ | city | string | * | city | nil |
436
+ | company | string | * | company | nil |
437
+ | country | string | * | country | nil |
438
+ | first_name | string | * | first_name | nil |
439
+ | last_name | string | * | last_name | nil |
440
+ | phone | string | * | phone | nil |
441
+ | province | string | * | state | nil |
442
+ | zip | string | * | zip | nil |
443
+ | country_code | string | * | country_iso2| nil |
444
+ | province_code | string | * | nil | nil |
445
+ | latitude | float | * | nil | nil |
446
+ | longitude | float | * | nil | nil |
447
+
448
+
415
449
  ### EPlat::Order::LineItem
416
450
 
417
451
  | Attribute | Type | Shopify | BigCommerce | Etc |
@@ -565,11 +599,12 @@ Unfortunately it's in a Time Integer format. Haven't yet got dynamic conversion
565
599
  | ::Product.find_by(attr: '') | * | * | |
566
600
  | ::Product.create(attr:) | * | * | |
567
601
  | ::Product.save | * | * | |
568
- | .save saves nested resources | * | | |
602
+ | .save saves nested resources | only variants | | |
569
603
  | ::Product.delete(id) | * | * | |
570
604
  | ::Product.count | * | * | |
571
605
  | product.dup | * | * | |
572
606
  | product.variants | * | * | |
607
+ | product.load_all_variants | * | * | |
573
608
  | product.find_variant(id) | * | * | |
574
609
  | product.images | * | * | |
575
610
  | products.next_page? | * | * | |
@@ -580,11 +615,23 @@ Unfortunately it's in a Time Integer format. Haven't yet got dynamic conversion
580
615
  | products.next_page_info | * | * | |
581
616
 
582
617
  ```ruby
583
- # How you might safely handle pagination via user input
584
- # <%= link_to "previous products", "/", page_info: products.previous_page_info %>
585
- # <%= link_to "Next products", "/", page_info: products.next_page_info %>
586
-
587
- EPlat::Product.find(:all, params: {limit: 2, EPlat::Current.e_plat_session.pagination_param => params['page_info'] })
618
+ # The 2024 increased Shopify variants limit
619
+ @product.load_all_variants #returns all variants. In Shopify's case it will keep on requesting in batches until it has the full amount (capped at 10x requests of 200 currently i.e. 2,000 variants)
620
+
621
+ ### Pagination
622
+ # ...How you might handle pagination.
623
+
624
+ # Add pagination cursors to your link's params. This is available on any EPlat::Collection instance
625
+ <%= link_to "previous products", "/", forward_page_info: products.previous_page_info %>
626
+ <%= link_to "Next products", "/", backward_page_info: products.next_page_info %>
627
+
628
+ # Then on the server, let EPlat handle the correct platform specific arguments to request with.
629
+ EPlat::Product.find(:all, params: {
630
+ EPlat::Current.e_plat_session.pagination_param(:forward) => params['forward_page_info']
631
+ })
632
+ EPlat::Product.find(:all, params: {
633
+ EPlat::Current.e_plat_session.pagination_param(:backward) => params['backward_page_info']
634
+ })
588
635
  ```
589
636
 
590
637
 
@@ -749,7 +796,7 @@ Unfortunately it's in a Time Integer format. Haven't yet got dynamic conversion
749
796
  (although should be kept track of locally)
750
797
  </li>
751
798
  <li>
752
- <strong>GraphQL</strong>. EPlat just handles REST
799
+ <strong>GraphQL</strong>. EPlat just handles REST (for now, although we plan to change the internals for Shopify product to use Graphql under the hood)
753
800
  <ul>
754
801
  </details>
755
802
 
@@ -786,12 +833,14 @@ EPlat::Product.find(my_id).destroy
786
833
 
787
834
  ### save record
788
835
  product = EPlat::Product.new(title: 't-shirt')
789
- product.save
836
+ product.save # true or false
837
+ product.errors # active record like errors if .save returned false
790
838
 
791
839
  product.full_response # <Net::HTTPOK>
792
840
  product.headers # { "date"=>"Fri, 17 Nov 2023 14:25:53 GMT", ...}
793
841
  JSON.parse(product.full_response.body) # "{...}"
794
842
 
843
+
795
844
  ### get records
796
845
  EPlat::Product.find(101) # GET EPlat::Product.first(args)) (or EPlat::Product.last(args))
797
846
  EPlat::Product.all
@@ -10,7 +10,7 @@ module EPlat
10
10
  {}
11
11
  when :bigcommerce
12
12
  {
13
- "include" => "variants,images"
13
+ "include" => "variants,images,options"
14
14
  }
15
15
  when :woocommerce
16
16
  {}
data/lib/e_plat/client.rb CHANGED
@@ -4,18 +4,34 @@ module EPlat
4
4
  class Client
5
5
  include Client::PlatformConvenienceMethods, Client::DefaultRequestArgs
6
6
 
7
- SHOPIFY_PAGINATION_PARAM = "page_info"
8
- BIGCOMMERCE_PAGINATION_PARAM = "page"
7
+ SHOPIFY_REST_PAGINATION_PARAM = "page_info"
8
+ SHOPIFY_GRAPHQL_FORWARD_PAGINATION_PARAM = "after"
9
+ SHOPIFY_GRAPHQL_BACKWARD_PAGINATION_PARAM = "before"
10
+ BIGCOMMERCE_PAGINATION_PARAM = "page"
9
11
 
10
12
  attr_reader :platform, :store_url, :api_token, :api_version, :store_hash
11
13
 
12
- def initialize(platform: nil, store_url: nil, api_token: nil, store_hash: nil)
13
- @platform, @store_url, @api_token, @store_hash = platform&.to_sym, store_url, api_token, store_hash
14
+ def initialize(platform: nil, store_url: nil, api_token: nil, store_hash: nil, api_version: nil)
15
+ @platform, @store_url, @api_token, @store_hash, @api_version = platform&.to_sym, store_url, api_token, store_hash, api_version
14
16
  end
15
17
 
16
18
  def headers
17
19
  platform_headers
18
20
  end
21
+
22
+ # Dynamically determines the class based on the platform
23
+ # needs to return nil if there isn't a more specific class than the klass passed in
24
+ def platform_klass(klass)
25
+ return if klass.to_s.include? "EPlat::#{platform.capitalize}"
26
+ platform_specific_class_name = klass.to_s.gsub("EPlat::", "EPlat::#{platform.capitalize}::")
27
+
28
+ platform_specific_class = platform_specific_class_name.safe_constantize
29
+ if platform_specific_class_name != klass.to_s && platform_specific_class
30
+ platform_specific_class
31
+ else
32
+ nil
33
+ end
34
+ end
19
35
 
20
36
  def inspect
21
37
  "#<#{self.class} platform=#{platform.inspect} store_url=#{store_url.inspect} api_version=#{api_version.inspect}>"
@@ -42,8 +58,14 @@ module EPlat
42
58
 
43
59
  def url_prefix(klass: nil)
44
60
  # for nested resources like "/products/:product/variants/:id"
61
+ klass_without_platform_scoping = nil
62
+ EPlat::SUPPORTED_PLATFORMS.each do |platform|
63
+ klass_without_platform_scoping = klass.to_s.gsub!("#{ platform.capitalize }::", "") if klass.to_s.include?("#{ platform.capitalize }::")
64
+ end
65
+ klass = klass_without_platform_scoping&.safe_constantize || klass
66
+
45
67
  collection_path =
46
- if klass.to_s.scan("::").length == 2
68
+ if klass.to_s.scan("::").length > 1
47
69
  parent_klass = klass.to_s.split("::")[1].underscore
48
70
  "#{ parent_klass.pluralize }/:#{ parent_klass }/"
49
71
  else
@@ -63,6 +85,19 @@ module EPlat
63
85
  "/" # not yet supported
64
86
  end
65
87
  end
88
+
89
+ def graphql_request_url
90
+ case platform
91
+ when :shopify
92
+ "https://#{ store_url }/admin/api/#{ api_version.dasherize }/graphql.json"
93
+ else
94
+ raise EPlat::Error, "GraphQL is not supported for #{ platform }"
95
+ end
96
+ end
97
+
98
+ def uses_graphql_for_products?
99
+ platform == :shopify && api_version != "2024_01"
100
+ end
66
101
 
67
102
  def platform_headers
68
103
  case platform
@@ -87,6 +122,8 @@ module EPlat
87
122
  end
88
123
 
89
124
  def api_version
125
+ return @api_version if @api_version.present?
126
+
90
127
  case platform
91
128
  when :shopify
92
129
  EPlat.config.shopify_api_version
@@ -97,6 +134,10 @@ module EPlat
97
134
  end
98
135
  end
99
136
 
137
+ def shopify_graphql_version
138
+ "V202407"
139
+ end
140
+
100
141
  def can_update_nested_resources?
101
142
  case platform
102
143
  when :shopify then true
@@ -105,11 +146,16 @@ module EPlat
105
146
  end
106
147
  end
107
148
 
108
- def pagination_param
149
+ def pagination_param(direction=:forward)
109
150
  case platform
110
- when :shopify then SHOPIFY_PAGINATION_PARAM
111
- when :bigcommerce then BIGCOMMERCE_PAGINATION_PARAM
112
- when :woocommerce then nil
151
+ when :shopify
152
+ if uses_graphql_for_products?
153
+ direction == :backward ? SHOPIFY_GRAPHQL_BACKWARD_PAGINATION_PARAM : SHOPIFY_GRAPHQL_FORWARD_PAGINATION_PARAM
154
+ else
155
+ SHOPIFY_REST_PAGINATION_PARAM
156
+ end
157
+ when :bigcommerce
158
+ BIGCOMMERCE_PAGINATION_PARAM
113
159
  end
114
160
  end
115
161
 
@@ -0,0 +1,26 @@
1
+ module EPlat
2
+ class Initializer
3
+ class << self
4
+
5
+ REQUIRED_CLASSES = EPlat::SUPPORTED_RESOURCES.map do |resource|
6
+ [
7
+ "EPlat::#{ resource.classify }",
8
+ EPlat::SUPPORTED_PLATFORMS.map do |platform|
9
+ "EPlat::#{ platform.classify }::#{ resource.classify }"
10
+ end
11
+ ]
12
+ end.flatten.freeze
13
+
14
+ def check_required_classes!
15
+ REQUIRED_CLASSES.each do |klass|
16
+ unless Object.const_defined?(klass)
17
+ raise EPlat::Error, "Required class #{klass} not defined"
18
+ end
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+
26
+
@@ -0,0 +1,58 @@
1
+
2
+
3
+ module EPlat
4
+ class Mapping
5
+ module Bigcommerce
6
+ module V3
7
+ class Product
8
+ class Option < EPlat::Mapping::Base
9
+
10
+ def native_top_key
11
+ "data"
12
+ end
13
+
14
+ def native_attributes
15
+ super.concat([
16
+ "id",
17
+ "product_id",
18
+ "display_name",
19
+ "type",
20
+ "config",
21
+ "sort_order",
22
+ "option_values",
23
+ "modifiers",
24
+ "option_set_id",
25
+ "option_set_display",
26
+ "variants"
27
+ ])
28
+ end
29
+
30
+ def native_attribute_aliases
31
+ super.concat([
32
+ {
33
+ existing_entry: {native_key: "id", e_plat_key: "id"}
34
+ },
35
+ {
36
+ alias_attribute: {native_key: "display_name", e_plat_key: "name"}
37
+ },
38
+ {
39
+ alias_attribute: {native_key: "sort_order", e_plat_key: "position"}
40
+ },
41
+ {
42
+ alias_attribute: {native_key: "option_values", e_plat_key: "values",
43
+ custom_e_plat_getter: '-> (option_values) {
44
+ option_values.map{|val| val.label}
45
+ }',
46
+ custom_native_setter: '-> (option) { raise EPlat::Error.new "EPlat does not yet support native setting back to .option_values[i][:label]" }'
47
+ }
48
+ }
49
+
50
+ ])
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,42 @@
1
+
2
+
3
+ module EPlat
4
+ class Mapping
5
+ module Bigcommerce
6
+ module V3
7
+ class Product::Variant
8
+ class OptionValue < EPlat::Mapping::Base
9
+
10
+ def native_top_key
11
+ "data"
12
+ end
13
+
14
+ def native_attributes
15
+ super.concat([
16
+ "id",
17
+ "label",
18
+ "option_id",
19
+ "option_display_name"
20
+ ])
21
+ end
22
+
23
+ def native_attribute_aliases
24
+ super.concat([
25
+ {
26
+ existing_entry: {native_key: "id", e_plat_key: "id"}
27
+ },
28
+ {
29
+ alias_attribute: {native_key: "option_display_name", e_plat_key: "name"}
30
+ },
31
+ {
32
+ alias_attribute: {native_key: "label", e_plat_key: "value"}
33
+ }
34
+ ])
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,26 @@
1
+ module EPlat
2
+ class Mapping
3
+ module Shopify
4
+ module V202407 #< :module
5
+ class Metafield < EPlat::Mapping::Base
6
+
7
+ def native_top_key
8
+ "metafield"
9
+ end
10
+
11
+ def native_attributes
12
+ super.concat([
13
+ ])
14
+ end
15
+
16
+ def native_attribute_aliases
17
+ super.concat([
18
+ ])
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,14 @@
1
+
2
+
3
+ module EPlat
4
+ class Mapping
5
+ module Shopify
6
+ module V202407
7
+ class Order
8
+ class BillingAddress < ShippingAddress; end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,30 @@
1
+
2
+
3
+ module EPlat
4
+ class Mapping
5
+ module Shopify
6
+ module V202407
7
+ class Order
8
+ class ShippingAddress < EPlat::Mapping::Base
9
+
10
+ def native_top_key
11
+ :itself
12
+ end
13
+
14
+ def native_attributes
15
+ super.concat([
16
+ ])
17
+ end
18
+
19
+ def native_attribute_aliases
20
+ super.concat([
21
+ ])
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,26 @@
1
+ module EPlat
2
+ class Mapping
3
+ module Shopify
4
+ module V202407 #< :module
5
+ class Order < EPlat::Mapping::Base
6
+
7
+ def native_top_key
8
+ "order"
9
+ end
10
+
11
+ def native_attributes
12
+ super.concat([
13
+ ])
14
+ end
15
+
16
+ def native_attribute_aliases
17
+ super.concat([
18
+ ])
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+