solidus_graphql_api 0.1.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 (253) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +93 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +20 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +62 -0
  8. data/CHANGELOG.md +0 -0
  9. data/CONTRIBUTING.md +57 -0
  10. data/Gemfile +33 -0
  11. data/LICENSE +26 -0
  12. data/LICENSE.md +26 -0
  13. data/README.md +245 -0
  14. data/Rakefile +43 -0
  15. data/app/controllers/spree/graphql_controller.rb +49 -0
  16. data/bin/console +17 -0
  17. data/bin/rails +9 -0
  18. data/bin/rails-engine +16 -0
  19. data/bin/rails-sandbox +18 -0
  20. data/bin/rake +8 -0
  21. data/bin/sandbox +84 -0
  22. data/bin/setup +8 -0
  23. data/config/locales/en.yml +6 -0
  24. data/config/routes.rb +5 -0
  25. data/lib/generators/solidus_graphql_api/install/install_generator.rb +8 -0
  26. data/lib/solidus_graphql_api.rb +11 -0
  27. data/lib/solidus_graphql_api/batch_loader.rb +114 -0
  28. data/lib/solidus_graphql_api/batch_loader/belongs_to.rb +30 -0
  29. data/lib/solidus_graphql_api/batch_loader/has_many.rb +24 -0
  30. data/lib/solidus_graphql_api/batch_loader/has_many_through.rb +42 -0
  31. data/lib/solidus_graphql_api/batch_loader/has_one.rb +22 -0
  32. data/lib/solidus_graphql_api/configuration.rb +19 -0
  33. data/lib/solidus_graphql_api/context.rb +76 -0
  34. data/lib/solidus_graphql_api/engine.rb +25 -0
  35. data/lib/solidus_graphql_api/factories.rb +11 -0
  36. data/lib/solidus_graphql_api/factories/address_factory.rb +8 -0
  37. data/lib/solidus_graphql_api/factories/country_factory.rb +12 -0
  38. data/lib/solidus_graphql_api/factories/store_factory.rb +16 -0
  39. data/lib/solidus_graphql_api/factories/taxonomy_factory.rb +26 -0
  40. data/lib/solidus_graphql_api/mutations/.keep +0 -0
  41. data/lib/solidus_graphql_api/mutations/base_mutation.rb +45 -0
  42. data/lib/solidus_graphql_api/mutations/checkout/add_addresses_to_checkout.rb +41 -0
  43. data/lib/solidus_graphql_api/mutations/checkout/add_payment_to_checkout.rb +45 -0
  44. data/lib/solidus_graphql_api/mutations/checkout/add_to_cart.rb +30 -0
  45. data/lib/solidus_graphql_api/mutations/checkout/advance_checkout.rb +27 -0
  46. data/lib/solidus_graphql_api/mutations/checkout/apply_coupon_code.rb +32 -0
  47. data/lib/solidus_graphql_api/mutations/checkout/complete_checkout.rb +31 -0
  48. data/lib/solidus_graphql_api/mutations/checkout/create_order.rb +27 -0
  49. data/lib/solidus_graphql_api/mutations/checkout/empty_cart.rb +29 -0
  50. data/lib/solidus_graphql_api/mutations/checkout/next_checkout_state.rb +27 -0
  51. data/lib/solidus_graphql_api/mutations/checkout/remove_from_cart.rb +33 -0
  52. data/lib/solidus_graphql_api/mutations/checkout/select_shipping_rate.rb +40 -0
  53. data/lib/solidus_graphql_api/mutations/checkout/set_order_email.rb +29 -0
  54. data/lib/solidus_graphql_api/mutations/checkout/update_cart_quantity.rb +41 -0
  55. data/lib/solidus_graphql_api/mutations/user/mark_default_address.rb +31 -0
  56. data/lib/solidus_graphql_api/mutations/user/remove_from_address_book.rb +25 -0
  57. data/lib/solidus_graphql_api/mutations/user/save_in_address_book.rb +30 -0
  58. data/lib/solidus_graphql_api/queries/address/country_query.rb +19 -0
  59. data/lib/solidus_graphql_api/queries/address/state_query.rb +19 -0
  60. data/lib/solidus_graphql_api/queries/completed_orders_query.rb +19 -0
  61. data/lib/solidus_graphql_api/queries/countries_query.rb +11 -0
  62. data/lib/solidus_graphql_api/queries/country/states_query.rb +19 -0
  63. data/lib/solidus_graphql_api/queries/line_item/variant_query.rb +19 -0
  64. data/lib/solidus_graphql_api/queries/option_type/option_values_query.rb +19 -0
  65. data/lib/solidus_graphql_api/queries/order/adjustments_query.rb +19 -0
  66. data/lib/solidus_graphql_api/queries/order/billing_address_query.rb +19 -0
  67. data/lib/solidus_graphql_api/queries/order/line_items_query.rb +19 -0
  68. data/lib/solidus_graphql_api/queries/order/payments_query.rb +19 -0
  69. data/lib/solidus_graphql_api/queries/order/shipments_query.rb +19 -0
  70. data/lib/solidus_graphql_api/queries/order/shipping_address_query.rb +19 -0
  71. data/lib/solidus_graphql_api/queries/product/master_variant_query.rb +19 -0
  72. data/lib/solidus_graphql_api/queries/product/option_types_query.rb +19 -0
  73. data/lib/solidus_graphql_api/queries/product/product_properties_query.rb +19 -0
  74. data/lib/solidus_graphql_api/queries/product/variants_query.rb +19 -0
  75. data/lib/solidus_graphql_api/queries/product_by_slug_query.rb +11 -0
  76. data/lib/solidus_graphql_api/queries/product_property/property_query.rb +19 -0
  77. data/lib/solidus_graphql_api/queries/products_query.rb +29 -0
  78. data/lib/solidus_graphql_api/queries/shipment/shipping_rates_query.rb +19 -0
  79. data/lib/solidus_graphql_api/queries/taxon/children_query.rb +19 -0
  80. data/lib/solidus_graphql_api/queries/taxon/parent_taxon_query.rb +19 -0
  81. data/lib/solidus_graphql_api/queries/taxonomies_query.rb +11 -0
  82. data/lib/solidus_graphql_api/queries/taxonomy/root_taxon_query.rb +19 -0
  83. data/lib/solidus_graphql_api/queries/taxonomy/taxons_query.rb +19 -0
  84. data/lib/solidus_graphql_api/queries/variant/default_price_query.rb +19 -0
  85. data/lib/solidus_graphql_api/queries/variant/images_query.rb +19 -0
  86. data/lib/solidus_graphql_api/queries/variant/option_values_query.rb +19 -0
  87. data/lib/solidus_graphql_api/queries/variant/prices_query.rb +19 -0
  88. data/lib/solidus_graphql_api/schema.rb +40 -0
  89. data/lib/solidus_graphql_api/types/.keep +0 -0
  90. data/lib/solidus_graphql_api/types/address.rb +32 -0
  91. data/lib/solidus_graphql_api/types/base/argument.rb +10 -0
  92. data/lib/solidus_graphql_api/types/base/enum.rb +10 -0
  93. data/lib/solidus_graphql_api/types/base/field.rb +13 -0
  94. data/lib/solidus_graphql_api/types/base/input_object.rb +10 -0
  95. data/lib/solidus_graphql_api/types/base/interface.rb +11 -0
  96. data/lib/solidus_graphql_api/types/base/object.rb +25 -0
  97. data/lib/solidus_graphql_api/types/base/relay_node.rb +13 -0
  98. data/lib/solidus_graphql_api/types/base/scalar.rb +10 -0
  99. data/lib/solidus_graphql_api/types/base/union.rb +10 -0
  100. data/lib/solidus_graphql_api/types/country.rb +23 -0
  101. data/lib/solidus_graphql_api/types/credit_card.rb +18 -0
  102. data/lib/solidus_graphql_api/types/currency.rb +14 -0
  103. data/lib/solidus_graphql_api/types/image.rb +27 -0
  104. data/lib/solidus_graphql_api/types/input_objects/address_input.rb +24 -0
  105. data/lib/solidus_graphql_api/types/input_objects/products_query_input.rb +15 -0
  106. data/lib/solidus_graphql_api/types/interfaces/adjustment.rb +32 -0
  107. data/lib/solidus_graphql_api/types/interfaces/payment_source.rb +19 -0
  108. data/lib/solidus_graphql_api/types/json.rb +63 -0
  109. data/lib/solidus_graphql_api/types/line_item.rb +26 -0
  110. data/lib/solidus_graphql_api/types/manifest_item.rb +12 -0
  111. data/lib/solidus_graphql_api/types/mutation.rb +24 -0
  112. data/lib/solidus_graphql_api/types/option_type.rb +22 -0
  113. data/lib/solidus_graphql_api/types/option_value.rb +15 -0
  114. data/lib/solidus_graphql_api/types/order.rb +63 -0
  115. data/lib/solidus_graphql_api/types/payment.rb +15 -0
  116. data/lib/solidus_graphql_api/types/payment_method.rb +15 -0
  117. data/lib/solidus_graphql_api/types/price.rb +21 -0
  118. data/lib/solidus_graphql_api/types/product.rb +38 -0
  119. data/lib/solidus_graphql_api/types/product_property.rb +19 -0
  120. data/lib/solidus_graphql_api/types/promotion_adjustment.rb +17 -0
  121. data/lib/solidus_graphql_api/types/property.rb +14 -0
  122. data/lib/solidus_graphql_api/types/query.rb +84 -0
  123. data/lib/solidus_graphql_api/types/shipment.rb +23 -0
  124. data/lib/solidus_graphql_api/types/shipping_rate.rb +15 -0
  125. data/lib/solidus_graphql_api/types/state.rb +14 -0
  126. data/lib/solidus_graphql_api/types/store.rb +27 -0
  127. data/lib/solidus_graphql_api/types/tax_adjustment.rb +11 -0
  128. data/lib/solidus_graphql_api/types/taxon.rb +33 -0
  129. data/lib/solidus_graphql_api/types/taxonomy.rb +23 -0
  130. data/lib/solidus_graphql_api/types/user.rb +23 -0
  131. data/lib/solidus_graphql_api/types/user_error.rb +12 -0
  132. data/lib/solidus_graphql_api/types/variant.rb +39 -0
  133. data/lib/solidus_graphql_api/types/wallet_payment_source.rb +14 -0
  134. data/lib/solidus_graphql_api/version.rb +5 -0
  135. data/schema.graphql +2070 -0
  136. data/solidus_graphql_api.gemspec +43 -0
  137. data/spec/integration/mutations/add_to_cart_spec.rb +67 -0
  138. data/spec/integration/mutations/checkout/add_addresses_to_checkout_spec.rb +115 -0
  139. data/spec/integration/mutations/checkout/add_payment_to_checkout_spec.rb +87 -0
  140. data/spec/integration/mutations/checkout/advance_checkout_spec.rb +71 -0
  141. data/spec/integration/mutations/checkout/apply_coupon_code_spec.rb +76 -0
  142. data/spec/integration/mutations/checkout/complete_checkout_spec.rb +56 -0
  143. data/spec/integration/mutations/checkout/next_checkout_state_spec.rb +69 -0
  144. data/spec/integration/mutations/checkout/select_shipping_rate_spec.rb +89 -0
  145. data/spec/integration/mutations/create_order_spec.rb +55 -0
  146. data/spec/integration/mutations/empty_cart_spec.rb +58 -0
  147. data/spec/integration/mutations/mark_default_address_spec.rb +33 -0
  148. data/spec/integration/mutations/remove_from_address_book_spec.rb +48 -0
  149. data/spec/integration/mutations/remove_from_cart_spec.rb +65 -0
  150. data/spec/integration/mutations/save_in_address_book_spec.rb +90 -0
  151. data/spec/integration/mutations/set_order_email_spec.rb +61 -0
  152. data/spec/integration/mutations/update_cart_quantity_spec.rb +68 -0
  153. data/spec/integration/queries/completed_orders_spec.rb +158 -0
  154. data/spec/integration/queries/countries_spec.rb +18 -0
  155. data/spec/integration/queries/current_order_spec.rb +15 -0
  156. data/spec/integration/queries/current_store_spec.rb +15 -0
  157. data/spec/integration/queries/current_user_spec.rb +43 -0
  158. data/spec/integration/queries/product_by_slug_spec.rb +42 -0
  159. data/spec/integration/queries/products_spec.rb +40 -0
  160. data/spec/integration/queries/taxonomies_spec.rb +22 -0
  161. data/spec/lib/solidus_graphql_api/batch_loader/belongs_to_spec.rb +67 -0
  162. data/spec/lib/solidus_graphql_api/batch_loader/has_many_spec.rb +38 -0
  163. data/spec/lib/solidus_graphql_api/batch_loader/has_many_through_spec.rb +47 -0
  164. data/spec/lib/solidus_graphql_api/batch_loader/has_one_spec.rb +38 -0
  165. data/spec/lib/solidus_graphql_api/context_spec.rb +236 -0
  166. data/spec/lib/solidus_graphql_api/queries/address/country_query_spec.rb +13 -0
  167. data/spec/lib/solidus_graphql_api/queries/address/state_query_spec.rb +13 -0
  168. data/spec/lib/solidus_graphql_api/queries/completed_orders_query_spec.rb +12 -0
  169. data/spec/lib/solidus_graphql_api/queries/countries_query_spec.rb +11 -0
  170. data/spec/lib/solidus_graphql_api/queries/country/states_query_spec.rb +11 -0
  171. data/spec/lib/solidus_graphql_api/queries/line_item/variant_query_spec.rb +9 -0
  172. data/spec/lib/solidus_graphql_api/queries/option_type/option_values_query_spec.rb +11 -0
  173. data/spec/lib/solidus_graphql_api/queries/order/adjustments_query_spec.rb +10 -0
  174. data/spec/lib/solidus_graphql_api/queries/order/billing_address_query_spec.rb +11 -0
  175. data/spec/lib/solidus_graphql_api/queries/order/line_items_query_spec.rb +9 -0
  176. data/spec/lib/solidus_graphql_api/queries/order/payments_query_spec.rb +9 -0
  177. data/spec/lib/solidus_graphql_api/queries/order/shipments_query_spec.rb +18 -0
  178. data/spec/lib/solidus_graphql_api/queries/order/shipping_address_query_spec.rb +11 -0
  179. data/spec/lib/solidus_graphql_api/queries/product/master_variant_query_spec.rb +11 -0
  180. data/spec/lib/solidus_graphql_api/queries/product/option_types_query_spec.rb +11 -0
  181. data/spec/lib/solidus_graphql_api/queries/product/product_properties_query_spec.rb +11 -0
  182. data/spec/lib/solidus_graphql_api/queries/product/variants_query_spec.rb +11 -0
  183. data/spec/lib/solidus_graphql_api/queries/product_by_slug_query_spec.rb +13 -0
  184. data/spec/lib/solidus_graphql_api/queries/product_property/property_query_spec.rb +11 -0
  185. data/spec/lib/solidus_graphql_api/queries/products_query_spec.rb +49 -0
  186. data/spec/lib/solidus_graphql_api/queries/shipment/shipping_rates_query_spec.rb +18 -0
  187. data/spec/lib/solidus_graphql_api/queries/taxon/children_query_spec.rb +11 -0
  188. data/spec/lib/solidus_graphql_api/queries/taxon/parent_taxon_query_spec.rb +10 -0
  189. data/spec/lib/solidus_graphql_api/queries/taxonomies_query_spec.rb +11 -0
  190. data/spec/lib/solidus_graphql_api/queries/taxonomy/root_taxon_query_spec.rb +10 -0
  191. data/spec/lib/solidus_graphql_api/queries/taxonomy/taxons_query_spec.rb +11 -0
  192. data/spec/lib/solidus_graphql_api/queries/variant/default_price_query_spec.rb +9 -0
  193. data/spec/lib/solidus_graphql_api/queries/variant/images_query_spec.rb +11 -0
  194. data/spec/lib/solidus_graphql_api/queries/variant/option_values_query_spec.rb +11 -0
  195. data/spec/lib/solidus_graphql_api/queries/variant/prices_query_spec.rb +13 -0
  196. data/spec/lib/solidus_graphql_api/schema_spec.rb +80 -0
  197. data/spec/lib/solidus_graphql_api/types/base/object_spec.rb +29 -0
  198. data/spec/lib/solidus_graphql_api/types/json_spec.rb +115 -0
  199. data/spec/lib/solidus_graphql_api/types/option_type_spec.rb +7 -0
  200. data/spec/lib/solidus_graphql_api/types/product_property_spec.rb +22 -0
  201. data/spec/lib/solidus_graphql_api/types/product_spec.rb +56 -0
  202. data/spec/lib/solidus_graphql_api/types/query_spec.rb +33 -0
  203. data/spec/lib/solidus_graphql_api/types/variant_spec.rb +58 -0
  204. data/spec/requests/spree/graphql_controller_spec.rb +17 -0
  205. data/spec/spec_helper.rb +62 -0
  206. data/spec/support/expected_schema.graphql +2070 -0
  207. data/spec/support/graphql/mutations/add_addresses_to_checkout.gql +19 -0
  208. data/spec/support/graphql/mutations/add_payment_to_checkout.gql +13 -0
  209. data/spec/support/graphql/mutations/add_to_cart.gql +21 -0
  210. data/spec/support/graphql/mutations/advance_checkout.gql +13 -0
  211. data/spec/support/graphql/mutations/apply_coupon_code.gql +13 -0
  212. data/spec/support/graphql/mutations/complete_checkout.gql +13 -0
  213. data/spec/support/graphql/mutations/create_order.gql +11 -0
  214. data/spec/support/graphql/mutations/empty_cart.gql +17 -0
  215. data/spec/support/graphql/mutations/mark_default_address.gql +9 -0
  216. data/spec/support/graphql/mutations/next_checkout_state.gql +13 -0
  217. data/spec/support/graphql/mutations/remove_from_address_book.gql +14 -0
  218. data/spec/support/graphql/mutations/remove_from_cart.gql +17 -0
  219. data/spec/support/graphql/mutations/save_in_address_book.gql +57 -0
  220. data/spec/support/graphql/mutations/select_shipping_rate.gql +23 -0
  221. data/spec/support/graphql/mutations/set_order_email.gql +13 -0
  222. data/spec/support/graphql/mutations/update_cart_quantity.gql +18 -0
  223. data/spec/support/graphql/queries/completed_orders.gql +29 -0
  224. data/spec/support/graphql/queries/completed_orders/adjustments.gql +24 -0
  225. data/spec/support/graphql/queries/completed_orders/available_payment_methods.gql +15 -0
  226. data/spec/support/graphql/queries/completed_orders/billing_address.gql +40 -0
  227. data/spec/support/graphql/queries/completed_orders/line_items.gql +23 -0
  228. data/spec/support/graphql/queries/completed_orders/payments.gql +23 -0
  229. data/spec/support/graphql/queries/completed_orders/shipping_address.gql +40 -0
  230. data/spec/support/graphql/queries/countries.gql +24 -0
  231. data/spec/support/graphql/queries/current_order.gql +32 -0
  232. data/spec/support/graphql/queries/current_store.gql +24 -0
  233. data/spec/support/graphql/queries/current_user.gql +197 -0
  234. data/spec/support/graphql/queries/product_by_slug.gql +106 -0
  235. data/spec/support/graphql/queries/products.gql +7 -0
  236. data/spec/support/graphql/queries/taxonomies.gql +81 -0
  237. data/spec/support/graphql/responses/completed_orders.json.erb +58 -0
  238. data/spec/support/graphql/responses/completed_orders/adjustments.json.erb +34 -0
  239. data/spec/support/graphql/responses/completed_orders/available_payment_methods.json.erb +29 -0
  240. data/spec/support/graphql/responses/completed_orders/billing_address.json.erb +78 -0
  241. data/spec/support/graphql/responses/completed_orders/line_items.json.erb +43 -0
  242. data/spec/support/graphql/responses/completed_orders/payments.json.erb +27 -0
  243. data/spec/support/graphql/responses/completed_orders/shipping_address.json.erb +78 -0
  244. data/spec/support/graphql/responses/countries.json.erb +51 -0
  245. data/spec/support/graphql/responses/current_order.json.erb +36 -0
  246. data/spec/support/graphql/responses/current_store.json.erb +34 -0
  247. data/spec/support/graphql/responses/current_user.json.erb +232 -0
  248. data/spec/support/graphql/responses/product_by_slug.json.erb +123 -0
  249. data/spec/support/graphql/responses/taxonomies.json.erb +145 -0
  250. data/spec/support/helpers/graphql.rb +43 -0
  251. data/spec/support/matchers/graphql.rb +35 -0
  252. data/spec/support/shared_contexts/graphql_query_subject.rb +21 -0
  253. metadata +572 -0
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'solidus_dev_support/rake_tasks'
4
+ SolidusDevSupport::RakeTasks.install
5
+
6
+ require 'rubocop/rake_task'
7
+ RuboCop::RakeTask.new
8
+
9
+ task default: %w[rubocop extension:specs]
10
+
11
+ namespace :schema do
12
+ desc 'Dump the schema to JSON and IDL'
13
+ task :dump do
14
+ setup_graphql_rake_tasks
15
+
16
+ Rake::Task['graphql:schema:dump'].invoke
17
+ end
18
+
19
+ desc 'Dump the schema to IDL in schema.graphql'
20
+ task :idl do
21
+ setup_graphql_rake_tasks
22
+
23
+ Rake::Task['graphql:schema:idl'].invoke
24
+ end
25
+
26
+ desc 'Dump the schema to JSON in schema.json'
27
+ task :json do
28
+ setup_graphql_rake_tasks
29
+
30
+ Rake::Task['graphql:schema:json'].invoke
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def setup_graphql_rake_tasks
37
+ require 'graphql/rake_task'
38
+ GraphQL::RakeTask.new(schema_name: 'SolidusGraphqlApi::Schema')
39
+
40
+ Rake::Task['extension:test_app'].invoke if Dir['spec/dummy'].empty?
41
+
42
+ require File.expand_path('spec/dummy/config/environment.rb', __dir__)
43
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ class GraphqlController < ApplicationController
5
+ skip_before_action :verify_authenticity_token
6
+
7
+ def execute
8
+ render json: SolidusGraphqlApi::Schema.execute(
9
+ params[:query],
10
+ variables: ensure_hash(params[:variables]),
11
+ context: SolidusGraphqlApi::Context.new(request: request).to_h,
12
+ operation_name: params[:operationName]
13
+ )
14
+ rescue StandardError => e
15
+ raise e unless Rails.env.development?
16
+
17
+ handle_error_in_development e
18
+ end
19
+
20
+ private
21
+
22
+ # Handle form data, JSON body, or a blank value
23
+ def ensure_hash(ambiguous_param)
24
+ case ambiguous_param
25
+ when String
26
+ if ambiguous_param.present?
27
+ ensure_hash(JSON.parse(ambiguous_param))
28
+ else
29
+ {}
30
+ end
31
+ when Hash
32
+ ambiguous_param
33
+ when ActionController::Parameters
34
+ ambiguous_param.permit!
35
+ when nil
36
+ {}
37
+ else
38
+ raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
39
+ end
40
+ end
41
+
42
+ def handle_error_in_development(error)
43
+ logger.error error.message
44
+ logger.error error.backtrace.join("\n")
45
+
46
+ render json: { error: { message: error.message, backtrace: error.backtrace }, data: {} }, status: 500
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require "bundler/setup"
6
+ require "solidus_graphql_api"
7
+
8
+ # You can add fixtures and/or initialization code here to make experimenting
9
+ # with your gem easier. You can also use a different console, if you like.
10
+ $LOAD_PATH.unshift(*Dir["#{__dir__}/../app/*"])
11
+
12
+ # (If you use this, don't forget to add pry to your Gemfile!)
13
+ require "pry"
14
+ Pry.start
15
+
16
+ require "irb"
17
+ IRB.start(__FILE__)
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ if %w[g generate].include? ARGV.first
6
+ exec "#{__dir__}/rails-engine", *ARGV
7
+ else
8
+ exec "#{__dir__}/rails-sandbox", *ARGV
9
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ # This command will automatically be run when you run "rails" with Rails gems
6
+ # installed from the root of your application.
7
+
8
+ ENGINE_ROOT = File.expand_path('..', __dir__)
9
+ ENGINE_PATH = File.expand_path('../lib/solidus_graphql_api/engine', __dir__)
10
+
11
+ # Set up gems listed in the Gemfile.
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
13
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
14
+
15
+ require 'rails/all'
16
+ require 'rails/engine/commands'
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ app_root = 'sandbox'
6
+
7
+ unless File.exist? "#{app_root}/bin/rails"
8
+ warn 'Creating the sandbox app...'
9
+ Dir.chdir "#{__dir__}/.." do
10
+ system "#{__dir__}/sandbox" or begin # rubocop:disable Style/AndOr
11
+ warn 'Automatic creation of the sandbox app failed'
12
+ exit 1
13
+ end
14
+ end
15
+ end
16
+
17
+ Dir.chdir app_root
18
+ exec 'bin/rails', *ARGV
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require "rubygems"
6
+ require "bundler/setup"
7
+
8
+ load Gem.bin_path("rake", "rake")
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ case "$DB" in
6
+ postgres|postgresql)
7
+ RAILSDB="postgresql"
8
+ ;;
9
+ mysql)
10
+ RAILSDB="mysql"
11
+ ;;
12
+ sqlite|'')
13
+ RAILSDB="sqlite3"
14
+ ;;
15
+ *)
16
+ echo "Invalid DB specified: $DB"
17
+ exit 1
18
+ ;;
19
+ esac
20
+
21
+ if [ ! -z $SOLIDUS_BRANCH ]
22
+ then
23
+ BRANCH=$SOLIDUS_BRANCH
24
+ else
25
+ BRANCH="master"
26
+ fi
27
+
28
+ extension_name="solidus_graphql_api"
29
+
30
+ # Stay away from the bundler env of the containing extension.
31
+ function unbundled {
32
+ ruby -rbundler -e'b = proc {system *ARGV}; Bundler.respond_to?(:with_unbundled_env) ? Bundler.with_unbundled_env(&b) : Bundler.with_clean_env(&b)' -- $@
33
+ }
34
+
35
+ rm -rf ./sandbox
36
+ unbundled bundle exec rails new sandbox --database="$RAILSDB" \
37
+ --skip-bundle \
38
+ --skip-git \
39
+ --skip-keeps \
40
+ --skip-rc \
41
+ --skip-spring \
42
+ --skip-test \
43
+ --skip-javascript
44
+
45
+ if [ ! -d "sandbox" ]; then
46
+ echo 'sandbox rails application failed'
47
+ exit 1
48
+ fi
49
+
50
+ cd ./sandbox
51
+ cat <<RUBY >> Gemfile
52
+ gem 'solidus', github: 'solidusio/solidus', branch: '$BRANCH'
53
+ gem 'solidus_auth_devise', '>= 2.1.0'
54
+ gem 'rails-i18n'
55
+ gem 'solidus_i18n'
56
+
57
+ gem '$extension_name', path: '..'
58
+
59
+ group :test, :development do
60
+ platforms :mri do
61
+ gem 'pry-byebug'
62
+ end
63
+ end
64
+ RUBY
65
+
66
+ unbundled bundle install --gemfile Gemfile
67
+
68
+ unbundled bundle exec rake db:drop db:create
69
+
70
+ unbundled bundle exec rails generate spree:install \
71
+ --auto-accept \
72
+ --user_class=Spree::User \
73
+ --enforce_available_locales=true \
74
+ --with-authentication=false \
75
+ $@
76
+
77
+ unbundled bundle exec rails generate solidus:auth:install
78
+
79
+ echo
80
+ echo "🚀 Sandbox app successfully created for $extension_name!"
81
+ echo "🚀 Using $RAILSDB and Solidus $BRANCH"
82
+ echo "🚀 Use 'export DB=[postgres|mysql|sqlite]' to control the DB adapter"
83
+ echo "🚀 Use 'export SOLIDUS_BRANCH=<BRANCH-NAME>' to control the Solidus version"
84
+ echo "🚀 This app is intended for test purposes."
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ gem install bundler --conservative
7
+ bundle update
8
+ bin/rake clobber
@@ -0,0 +1,6 @@
1
+ en:
2
+ activerecord:
3
+ exceptions:
4
+ not_found: Record not found
5
+ unauthorized:
6
+ default: You are not authorized to access this resource.
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ Spree::Core::Engine.routes.draw do
4
+ post '/graphql', to: 'graphql#execute'
5
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusGraphqlApi
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+ require 'batch-loader'
5
+
6
+ require 'solidus_core'
7
+ require 'solidus_support'
8
+
9
+ require 'solidus_graphql_api/version'
10
+ require 'solidus_graphql_api/engine'
11
+ require 'solidus_graphql_api/configuration'
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusGraphqlApi
4
+ # Provides an abstraction layer on top of +BatchLoader::GraphQL+ that removes all the
5
+ # boilerplate normally needed to batch-load ActiveRecord associations.
6
+ #
7
+ # @example Batch-loading a user's posts
8
+ # BatchLoader.for(user, :posts)
9
+ class BatchLoader
10
+ LOADER_CLASSES = {
11
+ has_one: BatchLoader::HasOne,
12
+ has_many: BatchLoader::HasMany,
13
+ has_many_through: BatchLoader::HasManyThrough,
14
+ belongs_to: BatchLoader::BelongsTo,
15
+ }.freeze
16
+
17
+ class << self
18
+ # Generates the batch loader for an ActiveRecord instance-association pair.
19
+ #
20
+ # @param object [ActiveRecord::Base] the record whose association you want to batch-load
21
+ # @param association [Symbol] the association to batch-load
22
+ # @param options [Hash] an options hash
23
+ #
24
+ # @option scope [ActiveRecord::Relation] a relation to use for scoping the association
25
+ #
26
+ # @return [BatchLoader::GraphQL]
27
+ #
28
+ # @see #new
29
+ def for(object, association, options = {})
30
+ reflection = object.class.reflect_on_association(association)
31
+ loader_class_for(reflection).new(object, reflection, options).load
32
+ end
33
+
34
+ private
35
+
36
+ def loader_class_for(reflection)
37
+ association_type = association_type(reflection)
38
+ LOADER_CLASSES[association_type] ||
39
+ raise(ArgumentError, "#{association_type} associations do not support batch loading")
40
+ end
41
+
42
+ def association_type(reflection)
43
+ macro = reflection.macro.to_sym
44
+
45
+ case macro
46
+ when :has_many
47
+ if reflection.through_reflection
48
+ :has_many_through
49
+ else
50
+ :has_many
51
+ end
52
+ else
53
+ macro
54
+ end
55
+ end
56
+ end
57
+
58
+ attr_reader :object, :reflection, :options
59
+
60
+ # Generates a new instance of this batch loader for an ActiveRecord instance-association pair.
61
+ #
62
+ # @param object [ActiveRecord::Base] the record whose association you want to batch-load
63
+ # @param reflection [ActiveRecord::Reflection] the association to batch-load
64
+ # @param options [Hash] an options hash
65
+ #
66
+ # @option scope [ActiveRecord::Relation] a relation to use for scoping the association
67
+ # @option klass [Class] the model class to load (only for polymorphic associations)
68
+ def initialize(object, reflection, options = {})
69
+ @object = object
70
+ @reflection = reflection
71
+ @options = options
72
+ end
73
+
74
+ # Returns the batch loading logic.
75
+ #
76
+ # @return [BatchLoader::GraphQL]
77
+ def load
78
+ raise NotImplementedError
79
+ end
80
+
81
+ private
82
+
83
+ def association_klass
84
+ if reflection.polymorphic?
85
+ options[:klass] || raise(
86
+ ArgumentError,
87
+ 'You need to provide :klass when batch-loading a polymorphic association!',
88
+ )
89
+ else
90
+ reflection.klass
91
+ end
92
+ end
93
+
94
+ def base_relation
95
+ relation = association_klass
96
+ relation = relation.instance_eval(&reflection.scope) if reflection.scope
97
+ relation = relation.merge(options[:scope]) if options[:scope]
98
+ relation
99
+ end
100
+
101
+ def default_options
102
+ return @default_options if @default_options
103
+
104
+ key_components = [object.class, reflection.name, options.inspect]
105
+ key = Digest::MD5.hexdigest(key_components.join)
106
+
107
+ @default_options ||= { key: key }.freeze
108
+ end
109
+
110
+ def graphql_loader_for(object_id, options = {}, &block)
111
+ ::BatchLoader::GraphQL.for(object_id).batch(default_options.merge(options), &block)
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusGraphqlApi
4
+ class BatchLoader
5
+ # A batch loader for +belongs_to+ associations.
6
+ class BelongsTo < BatchLoader
7
+ def load
8
+ graphql_loader_for(object.send(reflection.foreign_key)) do |object_ids, loader|
9
+ retrieve_records_for(object_ids).each do |record|
10
+ loader.call(record.send(association_primary_key), record)
11
+ end
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def retrieve_records_for(object_ids)
18
+ base_relation.where(association_primary_key => object_ids)
19
+ end
20
+
21
+ def association_primary_key
22
+ if reflection.polymorphic?
23
+ association_klass.primary_key
24
+ else
25
+ reflection.association_primary_key
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end