spree_api 4.2.5 → 4.3.0.rc1

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +14 -1
  3. data/app/controllers/concerns/spree/api/v2/product_list_includes.rb +23 -0
  4. data/app/controllers/spree/api/v1/classifications_controller.rb +4 -3
  5. data/app/controllers/spree/api/v1/orders_controller.rb +5 -1
  6. data/app/controllers/spree/api/v1/products_controller.rb +2 -2
  7. data/app/controllers/spree/api/v1/taxonomies_controller.rb +1 -1
  8. data/app/controllers/spree/api/v2/base_controller.rb +29 -6
  9. data/app/controllers/spree/api/v2/platform/addresses_controller.rb +19 -0
  10. data/app/controllers/spree/api/v2/platform/classifications_controller.rb +43 -0
  11. data/app/controllers/spree/api/v2/platform/cms_pages_controller.rb +15 -0
  12. data/app/controllers/spree/api/v2/platform/cms_sections_controller.rb +34 -0
  13. data/app/controllers/spree/api/v2/platform/countries_controller.rb +19 -0
  14. data/app/controllers/spree/api/v2/platform/menu_items_controller.rb +35 -0
  15. data/app/controllers/spree/api/v2/platform/menus_controller.rb +19 -0
  16. data/app/controllers/spree/api/v2/platform/option_types_controller.rb +15 -0
  17. data/app/controllers/spree/api/v2/platform/option_values_controller.rb +19 -0
  18. data/app/controllers/spree/api/v2/platform/products_controller.rb +21 -0
  19. data/app/controllers/spree/api/v2/platform/resource_controller.rb +112 -0
  20. data/app/controllers/spree/api/v2/platform/taxons_controller.rb +30 -0
  21. data/app/controllers/spree/api/v2/platform/users_controller.rb +28 -0
  22. data/app/controllers/spree/api/v2/resource_controller.rb +18 -6
  23. data/app/controllers/spree/api/v2/storefront/account/addresses_controller.rb +2 -14
  24. data/app/controllers/spree/api/v2/storefront/account/credit_cards_controller.rb +13 -11
  25. data/app/controllers/spree/api/v2/storefront/account/orders_controller.rb +2 -2
  26. data/app/controllers/spree/api/v2/storefront/account_controller.rb +32 -1
  27. data/app/controllers/spree/api/v2/storefront/cart_controller.rb +28 -6
  28. data/app/controllers/spree/api/v2/storefront/checkout_controller.rb +2 -1
  29. data/app/controllers/spree/api/v2/storefront/cms_pages_controller.rb +41 -0
  30. data/app/controllers/spree/api/v2/storefront/countries_controller.rb +9 -14
  31. data/app/controllers/spree/api/v2/storefront/menus_controller.rb +35 -0
  32. data/app/controllers/spree/api/v2/storefront/order_status_controller.rb +1 -1
  33. data/app/controllers/spree/api/v2/storefront/products_controller.rb +6 -12
  34. data/app/controllers/spree/api/v2/storefront/stores_controller.rb +1 -1
  35. data/app/controllers/spree/api/v2/storefront/taxons_controller.rb +7 -8
  36. data/app/helpers/spree/api/v2/display_money_helper.rb +2 -2
  37. data/app/models/spree/api_configuration.rb +1 -0
  38. data/app/models/spree/api_dependencies.rb +19 -5
  39. data/app/serializers/concerns/spree/api/v2/resource_serializer_concern.rb +16 -0
  40. data/app/serializers/spree/api/v2/base_serializer.rb +32 -0
  41. data/app/serializers/spree/api/v2/platform/address_serializer.rb +15 -0
  42. data/app/serializers/spree/api/v2/platform/base_serializer.rb +10 -0
  43. data/app/serializers/spree/api/v2/platform/classification_serializer.rb +14 -0
  44. data/app/serializers/spree/api/v2/platform/cms_page_serializer.rb +13 -0
  45. data/app/serializers/spree/api/v2/platform/cms_section_serializer.rb +11 -0
  46. data/app/serializers/spree/api/v2/platform/country_serializer.rb +13 -0
  47. data/app/serializers/spree/api/v2/platform/image_serializer.rb +15 -0
  48. data/app/serializers/spree/api/v2/platform/menu_item_serializer.rb +22 -0
  49. data/app/serializers/spree/api/v2/platform/menu_serializer.rb +13 -0
  50. data/app/serializers/spree/api/v2/platform/option_type_serializer.rb +13 -0
  51. data/app/serializers/spree/api/v2/platform/option_value_serializer.rb +13 -0
  52. data/app/serializers/spree/api/v2/platform/product_property_serializer.rb +11 -0
  53. data/app/serializers/spree/api/v2/platform/product_serializer.rb +78 -0
  54. data/app/serializers/spree/api/v2/platform/state_serializer.rb +13 -0
  55. data/app/serializers/spree/api/v2/platform/stock_item_serializer.rb +20 -0
  56. data/app/serializers/spree/api/v2/platform/stock_location_serializer.rb +16 -0
  57. data/app/serializers/spree/api/v2/platform/store_serializer.rb +14 -0
  58. data/app/serializers/spree/api/v2/platform/tax_category_serializer.rb +13 -0
  59. data/app/serializers/spree/api/v2/platform/taxon_image_serializer.rb +13 -0
  60. data/app/serializers/spree/api/v2/platform/taxon_serializer.rb +38 -0
  61. data/app/serializers/spree/api/v2/platform/taxonomy_serializer.rb +14 -0
  62. data/app/serializers/spree/api/v2/platform/user_serializer.rb +21 -0
  63. data/app/serializers/spree/api/v2/platform/variant_serializer.rb +57 -0
  64. data/app/serializers/spree/v2/storefront/base_serializer.rb +3 -2
  65. data/app/serializers/spree/v2/storefront/cms_page_serializer.rb +14 -0
  66. data/app/serializers/spree/v2/storefront/cms_section_serializer.rb +28 -0
  67. data/app/serializers/spree/v2/storefront/country_serializer.rb +4 -4
  68. data/app/serializers/spree/v2/storefront/estimated_shipping_rate_serializer.rb +2 -0
  69. data/app/serializers/spree/v2/storefront/menu_item_serializer.rb +37 -0
  70. data/app/serializers/spree/v2/storefront/menu_serializer.rb +13 -0
  71. data/app/serializers/spree/v2/storefront/product_property_serializer.rb +1 -1
  72. data/app/serializers/spree/v2/storefront/product_serializer.rb +4 -1
  73. data/app/serializers/spree/v2/storefront/store_serializer.rb +10 -0
  74. data/app/serializers/spree/v2/storefront/taxon_serializer.rb +6 -5
  75. data/config/initializers/doorkeeper.rb +8 -1
  76. data/config/initializers/rabl.rb +9 -0
  77. data/config/routes.rb +115 -3
  78. data/db/migrate/20210727102516_change_integer_id_columns_type.rb +9 -0
  79. data/docs/oauth/index.yml +2 -2
  80. data/docs/v2/platform/index.yaml +1501 -0
  81. data/docs/v2/storefront/index.yaml +48 -2
  82. data/lib/spree/api.rb +1 -0
  83. data/lib/spree/api/engine.rb +6 -17
  84. data/lib/spree/api/testing_support/v2/base.rb +1 -1
  85. data/lib/spree/api/testing_support/v2/platform_contexts.rb +214 -0
  86. data/lib/spree/api/testing_support/v2/serializers_params.rb +14 -0
  87. data/spree_api.gemspec +3 -0
  88. metadata +100 -10
  89. data/app/assets/javascripts/spree/api/main.js +0 -36
  90. data/app/assets/javascripts/spree/api/storefront/cart.js +0 -49
@@ -0,0 +1,112 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class ResourceController < ::Spree::Api::V2::ResourceController
6
+ READ_ACTIONS = %i[show index]
7
+ WRITE_ACTIONS = %i[create update destroy]
8
+
9
+ # doorkeeper scopes usage: https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
10
+ before_action -> { doorkeeper_authorize! :read, :admin }, only: READ_ACTIONS
11
+ before_action -> { doorkeeper_authorize! :write, :admin }, only: WRITE_ACTIONS
12
+
13
+ # optional authorization if using a user token instead of app token
14
+ before_action :authorize_spree_user, only: WRITE_ACTIONS
15
+
16
+ # index and show acrtions are defined in Spree::Api::V2::ResourceController
17
+
18
+ def create
19
+ resource = model_class.new(permitted_resource_params)
20
+
21
+ if resource.save
22
+ render_serialized_payload(201) { serialize_resource(resource) }
23
+ else
24
+ render_error_payload(resource.errors)
25
+ end
26
+ end
27
+
28
+ def update
29
+ if resource.update(permitted_resource_params)
30
+ render_serialized_payload { serialize_resource(resource) }
31
+ else
32
+ render_error_payload(resource.errors)
33
+ end
34
+ end
35
+
36
+ def destroy
37
+ if resource.destroy
38
+ head 204
39
+ else
40
+ render_error_payload(resource.errors)
41
+ end
42
+ end
43
+
44
+ protected
45
+
46
+ def resource_serializer
47
+ "Spree::Api::V2::Platform::#{model_class.to_s.demodulize}Serializer".constantize
48
+ end
49
+
50
+ def collection_serializer
51
+ resource_serializer
52
+ end
53
+
54
+ # overwiting to utilize ransack gem for filtering
55
+ # https://github.com/activerecord-hackery/ransack#search-matchers
56
+ def collection
57
+ @collection ||= scope.ransack(params[:filter]).result
58
+ end
59
+
60
+ # overwriting to skip cancancan check if API is consumed by an application
61
+ def scope
62
+ return super if spree_current_user.present?
63
+
64
+ super(skip_cancancan: true)
65
+ end
66
+
67
+ # We're overwriting this method because the original one calls `dookreeper_authorize`
68
+ # which breaks our application authorizations defined on top of this controller
69
+ def spree_current_user
70
+ return nil unless doorkeeper_token
71
+ return nil if doorkeeper_token.resource_owner_id.nil?
72
+ return @spree_current_user if @spree_current_user
73
+
74
+ @spree_current_user ||= Spree.user_class.find_by(id: doorkeeper_token.resource_owner_id)
75
+ end
76
+
77
+ def access_denied(exception)
78
+ access_denied_401(exception)
79
+ end
80
+
81
+ # if using a user oAuth token we need to check CanCanCan abilities
82
+ # defined in https://github.com/spree/spree/blob/master/core/app/models/spree/ability.rb
83
+ def authorize_spree_user
84
+ return if spree_current_user.nil?
85
+
86
+ if action_name == 'create'
87
+ spree_authorize! :create, model_class
88
+ else
89
+ spree_authorize! action_name, resource
90
+ end
91
+ end
92
+
93
+ def model_param_name
94
+ model_class.to_s.demodulize.underscore
95
+ end
96
+
97
+ def spree_permitted_attributes
98
+ Spree::PermittedAttributes.try("#{model_param_name}_attributes") || {}
99
+ end
100
+
101
+ def permitted_resource_params
102
+ params.require(model_param_name).permit(spree_permitted_attributes)
103
+ end
104
+
105
+ def allowed_sort_attributes
106
+ (super << spree_permitted_attributes).uniq.compact
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,30 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class TaxonsController < ResourceController
6
+ private
7
+
8
+ def model_class
9
+ Spree::Taxon
10
+ end
11
+
12
+ def scope_includes
13
+ node_includes = %i[icon parent taxonomy]
14
+
15
+ {
16
+ parent: node_includes,
17
+ children: node_includes,
18
+ taxonomy: [root: node_includes],
19
+ icon: [attachment_attachment: :blob]
20
+ }
21
+ end
22
+
23
+ def serializer_params
24
+ super.merge(include_products: action_name == 'show')
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Platform
5
+ class UsersController < ResourceController
6
+ private
7
+
8
+ def model_class
9
+ Spree.user_class
10
+ end
11
+
12
+ def resource_serializer
13
+ Spree::Api::V2::Platform::UserSerializer
14
+ end
15
+
16
+ def scope_includes
17
+ [:ship_address, :bill_address]
18
+ end
19
+
20
+ # we need to define this here as developers can configure their own `user_class`
21
+ def model_param_name
22
+ 'user'
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -15,7 +15,7 @@ module Spree
15
15
  protected
16
16
 
17
17
  def sorted_collection
18
- collection_sorter.new(collection, params, allowed_sort_attributes).call
18
+ @sorted_collection ||= collection_sorter.new(collection, params, allowed_sort_attributes).call
19
19
  end
20
20
 
21
21
  def allowed_sort_attributes
@@ -23,11 +23,14 @@ module Spree
23
23
  end
24
24
 
25
25
  def default_sort_atributes
26
- [:id, :updated_at, :created_at]
26
+ [:id, :name, :number, :position, :updated_at, :created_at]
27
27
  end
28
28
 
29
- def scope
30
- model_class.accessible_by(current_ability, :show).includes(scope_includes)
29
+ def scope(skip_cancancan: false)
30
+ base_scope = model_class.for_store(current_store)
31
+ base_scope = base_scope.accessible_by(current_ability, :show) unless skip_cancancan
32
+ base_scope = base_scope.includes(scope_includes) if scope_includes.any? && action_name == 'index'
33
+ base_scope
31
34
  end
32
35
 
33
36
  def scope_includes
@@ -36,7 +39,7 @@ module Spree
36
39
 
37
40
  def resource
38
41
  @resource ||= if defined?(resource_finder)
39
- resource_finder.new(scope: scope, params: params).execute
42
+ resource_finder.new(scope: scope, params: finder_params).execute
40
43
  else
41
44
  scope.find(params[:id])
42
45
  end
@@ -44,12 +47,21 @@ module Spree
44
47
 
45
48
  def collection
46
49
  @collection ||= if defined?(collection_finder)
47
- collection_finder.new(scope: scope, params: params).execute
50
+ collection_finder.new(scope: scope, params: finder_params).execute
48
51
  else
49
52
  scope
50
53
  end
51
54
  end
52
55
 
56
+ def finder_params
57
+ params.merge(
58
+ store: current_store,
59
+ locale: current_locale,
60
+ currency: current_currency,
61
+ user: spree_current_user
62
+ )
63
+ end
64
+
53
65
  def collection_sorter
54
66
  Spree::Api::Dependencies.storefront_collection_sorter.constantize
55
67
  end
@@ -33,11 +33,11 @@ module Spree
33
33
  private
34
34
 
35
35
  def collection
36
- collection_finder.new(scope: scope, params: params).execute
36
+ collection_finder.new(scope: scope, params: finder_params).execute
37
37
  end
38
38
 
39
39
  def scope
40
- super.not_deleted
40
+ super.where(user: spree_current_user).not_deleted
41
41
  end
42
42
 
43
43
  def model_class
@@ -56,10 +56,6 @@ module Spree
56
56
  Spree::Api::Dependencies.storefront_address_serializer.constantize
57
57
  end
58
58
 
59
- def serialize_collection(collection)
60
- collection_serializer.new(collection).serializable_hash
61
- end
62
-
63
59
  def create_service
64
60
  Spree::Api::Dependencies.storefront_account_create_address_service.constantize
65
61
  end
@@ -71,14 +67,6 @@ module Spree
71
67
  def address_params
72
68
  params.require(:address).permit(permitted_address_attributes)
73
69
  end
74
-
75
- def render_result(result)
76
- if result.success?
77
- render_serialized_payload { serialize_resource(result.value) }
78
- else
79
- render_error_payload(result.error)
80
- end
81
- end
82
70
  end
83
71
  end
84
72
  end
@@ -6,14 +6,24 @@ module Spree
6
6
  class CreditCardsController < ::Spree::Api::V2::ResourceController
7
7
  before_action :require_spree_current_user
8
8
 
9
+ def destroy
10
+ spree_authorize! :destroy, resource, resource
11
+
12
+ destroy_service.call(card: resource)
13
+ end
14
+
9
15
  private
10
16
 
17
+ def resource
18
+ params[:id].eql?('default') ? scope.default.first! : scope.find(params[:id])
19
+ end
20
+
11
21
  def model_class
12
22
  Spree::CreditCard
13
23
  end
14
24
 
15
25
  def scope
16
- super.where(user: spree_current_user)
26
+ super.where(user: spree_current_user, payment_method: current_store.payment_methods.available_on_front_end)
17
27
  end
18
28
 
19
29
  def collection_serializer
@@ -28,16 +38,8 @@ module Spree
28
38
  Spree::Api::Dependencies.storefront_credit_card_serializer.constantize
29
39
  end
30
40
 
31
- def resource_finder
32
- Spree::Api::Dependencies.storefront_credit_card_finder.constantize
33
- end
34
-
35
- def serialize_collection(collection)
36
- collection_serializer.new(
37
- collection,
38
- include: resource_includes,
39
- fields: sparse_fields
40
- ).serializable_hash
41
+ def destroy_service
42
+ Spree::Api::Dependencies.storefront_credit_cards_destroy_service.constantize
41
43
  end
42
44
  end
43
45
  end
@@ -9,11 +9,11 @@ module Spree
9
9
  private
10
10
 
11
11
  def collection
12
- collection_finder.new(user: spree_current_user).execute
12
+ collection_finder.new(user: spree_current_user, store: current_store).execute
13
13
  end
14
14
 
15
15
  def resource
16
- resource = resource_finder.new(user: spree_current_user, number: params[:id]).execute.take
16
+ resource = resource_finder.new(user: spree_current_user, number: params[:id], store: current_store).execute.take
17
17
  raise ActiveRecord::RecordNotFound if resource.nil?
18
18
 
19
19
  resource
@@ -3,7 +3,18 @@ module Spree
3
3
  module V2
4
4
  module Storefront
5
5
  class AccountController < ::Spree::Api::V2::ResourceController
6
- before_action :require_spree_current_user
6
+ before_action :require_spree_current_user, except: :create
7
+
8
+ def create
9
+ result = create_service.call(user_params: user_create_params)
10
+ render_result(result)
11
+ end
12
+
13
+ def update
14
+ spree_authorize! :update, spree_current_user
15
+ result = update_service.call(user: spree_current_user, user_params: user_update_params)
16
+ render_result(result)
17
+ end
7
18
 
8
19
  private
9
20
 
@@ -14,6 +25,26 @@ module Spree
14
25
  def resource_serializer
15
26
  Spree::Api::Dependencies.storefront_user_serializer.constantize
16
27
  end
28
+
29
+ def model_class
30
+ Spree.user_class
31
+ end
32
+
33
+ def create_service
34
+ Spree::Api::Dependencies.storefront_account_create_service.constantize
35
+ end
36
+
37
+ def update_service
38
+ Spree::Api::Dependencies.storefront_account_update_service.constantize
39
+ end
40
+
41
+ def user_create_params
42
+ user_update_params.except(:bill_address_id, :ship_address_id)
43
+ end
44
+
45
+ def user_update_params
46
+ params.require(:user).permit(permitted_user_attributes)
47
+ end
17
48
  end
18
49
  end
19
50
  end
@@ -50,11 +50,25 @@ module Spree
50
50
  def empty
51
51
  spree_authorize! :update, spree_current_order, order_token
52
52
 
53
- # TODO: we should extract this logic into service and let
54
- # developers overwrite it
55
- spree_current_order.empty!
53
+ result = empty_cart_service.call(order: spree_current_order)
56
54
 
57
- render_serialized_payload { serialized_current_order }
55
+ if result.success?
56
+ render_serialized_payload { serialized_current_order }
57
+ else
58
+ render_error_payload(result.error)
59
+ end
60
+ end
61
+
62
+ def destroy
63
+ spree_authorize! :update, spree_current_order, order_token
64
+
65
+ result = destroy_cart_service.call(order: spree_current_order)
66
+
67
+ if result.success?
68
+ head 204
69
+ else
70
+ render_error_payload(result.error)
71
+ end
58
72
  end
59
73
 
60
74
  def set_quantity
@@ -128,6 +142,14 @@ module Spree
128
142
  Spree::Api::Dependencies.storefront_cart_add_item_service.constantize
129
143
  end
130
144
 
145
+ def empty_cart_service
146
+ Spree::Api::Dependencies.storefront_cart_empty_service.constantize
147
+ end
148
+
149
+ def destroy_cart_service
150
+ Spree::Api::Dependencies.storefront_cart_destroy_service.constantize
151
+ end
152
+
131
153
  def set_item_quantity_service
132
154
  Spree::Api::Dependencies.storefront_cart_set_item_quantity_service.constantize
133
155
  end
@@ -149,7 +171,7 @@ module Spree
149
171
  end
150
172
 
151
173
  def load_variant
152
- @variant = Spree::Variant.find(params[:variant_id])
174
+ @variant = current_store.variants.find(params[:variant_id])
153
175
  end
154
176
 
155
177
  def render_error_item_quantity
@@ -163,7 +185,7 @@ module Spree
163
185
  def serialize_estimated_shipping_rates(shipping_rates)
164
186
  estimate_shipping_rates_serializer.new(
165
187
  shipping_rates,
166
- params: { currency: spree_current_order.currency }
188
+ params: serializer_params
167
189
  ).serializable_hash
168
190
  end
169
191
 
@@ -119,12 +119,13 @@ module Spree
119
119
  end
120
120
 
121
121
  def serialize_payment_methods(payment_methods)
122
- payment_methods_serializer.new(payment_methods).serializable_hash
122
+ payment_methods_serializer.new(payment_methods, params: serializer_params).serializable_hash
123
123
  end
124
124
 
125
125
  def serialize_shipping_rates(shipments)
126
126
  shipping_rates_serializer.new(
127
127
  shipments,
128
+ params: serializer_params,
128
129
  include: [:shipping_rates, :stock_location]
129
130
  ).serializable_hash
130
131
  end