solidus_api 2.9.5 → 2.10.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +35 -2
- data/app/controllers/spree/api/addresses_controller.rb +1 -1
- data/app/controllers/spree/api/base_controller.rb +10 -10
- data/app/controllers/spree/api/checkouts_controller.rb +21 -8
- data/app/controllers/spree/api/credit_cards_controller.rb +1 -1
- data/app/controllers/spree/api/images_controller.rb +1 -1
- data/app/controllers/spree/api/inventory_units_controller.rb +1 -1
- data/app/controllers/spree/api/option_types_controller.rb +1 -1
- data/app/controllers/spree/api/option_values_controller.rb +1 -1
- data/app/controllers/spree/api/orders_controller.rb +17 -6
- data/app/controllers/spree/api/payments_controller.rb +1 -1
- data/app/controllers/spree/api/product_properties_controller.rb +1 -1
- data/app/controllers/spree/api/properties_controller.rb +1 -1
- data/app/controllers/spree/api/resource_controller.rb +1 -1
- data/app/controllers/spree/api/return_authorizations_controller.rb +1 -1
- data/app/controllers/spree/api/shipments_controller.rb +1 -1
- data/app/controllers/spree/api/stock_items_controller.rb +1 -1
- data/app/controllers/spree/api/stock_locations_controller.rb +1 -1
- data/app/controllers/spree/api/stores_controller.rb +1 -1
- data/app/controllers/spree/api/taxonomies_controller.rb +4 -2
- data/app/controllers/spree/api/taxons_controller.rb +1 -1
- data/app/controllers/spree/api/variants_controller.rb +1 -1
- data/app/controllers/spree/api/zones_controller.rb +1 -1
- data/app/helpers/spree/api/api_helpers.rb +2 -2
- data/app/views/spree/api/images/_image.json.jbuilder +2 -2
- data/app/views/spree/api/orders/_order.json.jbuilder +1 -1
- data/app/views/spree/api/shared/_pagination.json.jbuilder +1 -1
- data/lib/spree/api.rb +0 -7
- data/lib/spree/api/config.rb +9 -0
- data/lib/spree/api/engine.rb +4 -4
- data/lib/spree/api/responders.rb +3 -2
- data/lib/spree/api/responders/{rabl_template.rb → jbuilder_template.rb} +3 -1
- data/{app/models → lib}/spree/api_configuration.rb +0 -0
- data/openapi/.stoplight.yml +7 -0
- data/openapi/api.oas2.yml +6108 -0
- data/openapi/authentication.md +25 -0
- data/openapi/checkout-flow.md +50 -0
- data/openapi/errors.md +3 -0
- data/openapi/lint.yml +1 -0
- data/openapi/main.hub.yml +65 -0
- data/openapi/pagination.md +7 -0
- data/openapi/theme.css +0 -0
- data/solidus_api.gemspec +1 -1
- data/spec/controllers/spree/api/resource_controller_spec.rb +4 -4
- data/spec/lib/spree_api_responders_spec.rb +10 -0
- data/spec/requests/api/address_books_spec.rb +2 -2
- data/spec/requests/{rabl_cache_spec.rb → jbuilder_cache_spec.rb} +2 -2
- data/spec/requests/spree/api/checkouts_controller_spec.rb +35 -7
- data/spec/requests/spree/api/classifications_controller_spec.rb +1 -1
- data/spec/requests/spree/api/option_types_controller_spec.rb +2 -2
- data/spec/requests/spree/api/option_values_controller_spec.rb +2 -2
- data/spec/requests/spree/api/orders_controller_spec.rb +38 -15
- data/spec/requests/spree/api/payments_controller_spec.rb +3 -3
- data/spec/requests/spree/api/products_controller_spec.rb +6 -6
- data/spec/requests/spree/api/stock_items_controller_spec.rb +5 -5
- data/spec/requests/spree/api/stock_locations_controller_spec.rb +4 -4
- data/spec/requests/spree/api/taxons_controller_spec.rb +2 -2
- metadata +21 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7afcbef6dfdc19f02d26c7b3e410f072dc0d6be5a5b7d476b64b3725b1b24b7
|
4
|
+
data.tar.gz: ac898e6b9d5df7e526a5cd9af63a240aed5e2ab46c7ac75ca583b0fb7eb599b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce175516b04998e778b53e3d1ae47fc1a04c2ef4146a68000bc8745d5e267e423054d0e96fb1b02a03fa26ac186210012b84b54fa7592d15df7cf4fcf8e8d39a
|
7
|
+
data.tar.gz: 197562fcd0ea03c6593c21bfb8cb6f8d2424c6ddc3b12cbbc5b83a501976fe724c448a341de063a630daa3cb0f1309687503f5f35ee27536ad4d0a715392c3ea
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
#
|
1
|
+
# solidus_api
|
2
2
|
|
3
|
-
API contains the controllers and
|
3
|
+
API contains the controllers and Jbuilder views implementing the REST API of
|
4
|
+
Solidus.
|
4
5
|
|
5
6
|
## Testing
|
6
7
|
|
@@ -9,3 +10,35 @@ Run the API tests:
|
|
9
10
|
```bash
|
10
11
|
bundle exec rspec
|
11
12
|
```
|
13
|
+
|
14
|
+
## Documentation
|
15
|
+
|
16
|
+
The API documentation is in the [openapi][docs-dir] directory. It follows the
|
17
|
+
OpenAPI specification and it is hosted on [Stoplight Docs][live-docs].
|
18
|
+
|
19
|
+
If you want to contribute, you can use [Stoplight Studio][studio]. Simply
|
20
|
+
follow these steps:
|
21
|
+
|
22
|
+
1. Create a new Stoplight Studio project
|
23
|
+
2. Copy-paste the content of `openapi/api.oas2.yml` into your project
|
24
|
+
3. Edit the endpoints and models as needed
|
25
|
+
4. Copy-paste the result back into `openapi/api.oas2.yml`
|
26
|
+
5. Open a PR!
|
27
|
+
|
28
|
+
**Note: Only use embedded models in Stoplight Studio, as Stoplight Docs is
|
29
|
+
not compatible with externally-defined models!**
|
30
|
+
|
31
|
+
CircleCI automatically syncs our Git repo with Stoplight Docs when a PR is
|
32
|
+
merged, and automatically publishes a new version on Docs when a new Solidus
|
33
|
+
version is released.
|
34
|
+
|
35
|
+
## Related projects
|
36
|
+
|
37
|
+
- [solidus-sdk](https://gitlab.com/deseretbook/packages/solidus-sdk): created
|
38
|
+
by Joel Saupe at [Deseret Book](https://deseretbook.com/), this is a JS SDK
|
39
|
+
that allows you to use the Solidus API. It even supports plug-ins, so you can
|
40
|
+
easily extend it with the endpoints provided by your Solidus extensions!
|
41
|
+
|
42
|
+
[docs-dir]: https://github.com/solidusio/solidus/tree/master/api/openapi
|
43
|
+
[live-docs]: https://solidus.docs.stoplight.io
|
44
|
+
[studio]: https://stoplight.io/p/studio
|
@@ -15,7 +15,7 @@ module Spree
|
|
15
15
|
authorize! :update, @order, order_token
|
16
16
|
find_address
|
17
17
|
|
18
|
-
if @order.
|
18
|
+
if @order.update({ "#{@order_source}_attributes" => address_params })
|
19
19
|
@address = @order.send(@order_source)
|
20
20
|
respond_with(@address, default_template: :show)
|
21
21
|
else
|
@@ -49,9 +49,9 @@ module Spree
|
|
49
49
|
def authenticate_user
|
50
50
|
unless @current_api_user
|
51
51
|
if requires_authentication? && api_key.blank? && order_token.blank?
|
52
|
-
render "spree/api/errors/must_specify_api_key", status:
|
52
|
+
render "spree/api/errors/must_specify_api_key", status: :unauthorized
|
53
53
|
elsif order_token.blank? && (requires_authentication? || api_key.present?)
|
54
|
-
render "spree/api/errors/invalid_api_key", status:
|
54
|
+
render "spree/api/errors/invalid_api_key", status: :unauthorized
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
@@ -65,7 +65,7 @@ module Spree
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def unauthorized
|
68
|
-
render "spree/api/errors/unauthorized", status:
|
68
|
+
render "spree/api/errors/unauthorized", status: :unauthorized
|
69
69
|
end
|
70
70
|
|
71
71
|
def gateway_error(exception)
|
@@ -78,7 +78,7 @@ module Spree
|
|
78
78
|
exception: exception.message,
|
79
79
|
error: exception.message,
|
80
80
|
missing_param: exception.param
|
81
|
-
}, status:
|
81
|
+
}, status: :unprocessable_entity
|
82
82
|
end
|
83
83
|
|
84
84
|
def requires_authentication?
|
@@ -86,7 +86,7 @@ module Spree
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def not_found
|
89
|
-
render "spree/api/errors/not_found", status:
|
89
|
+
render "spree/api/errors/not_found", status: :not_found
|
90
90
|
end
|
91
91
|
|
92
92
|
def current_ability
|
@@ -96,7 +96,7 @@ module Spree
|
|
96
96
|
def invalid_resource!(resource)
|
97
97
|
Rails.logger.error "invalid_resouce_errors=#{resource.errors.full_messages}"
|
98
98
|
@resource = resource
|
99
|
-
render "spree/api/errors/invalid_resource", status:
|
99
|
+
render "spree/api/errors/invalid_resource", status: :unprocessable_entity
|
100
100
|
end
|
101
101
|
|
102
102
|
def api_key
|
@@ -112,7 +112,7 @@ module Spree
|
|
112
112
|
|
113
113
|
def spree_token
|
114
114
|
token = request.headers["X-Spree-Token"]
|
115
|
-
return
|
115
|
+
return if token.blank?
|
116
116
|
|
117
117
|
Spree::Deprecation.warn(
|
118
118
|
'The custom X-Spree-Token request header is deprecated and will be removed in the next release.' \
|
@@ -164,8 +164,8 @@ module Spree
|
|
164
164
|
|
165
165
|
def lock_order
|
166
166
|
OrderMutex.with_lock!(@order) { yield }
|
167
|
-
rescue Spree::OrderMutex::LockFailed =>
|
168
|
-
render plain:
|
167
|
+
rescue Spree::OrderMutex::LockFailed => error
|
168
|
+
render plain: error.message, status: :conflict
|
169
169
|
end
|
170
170
|
|
171
171
|
def insufficient_stock_error(exception)
|
@@ -175,7 +175,7 @@ module Spree
|
|
175
175
|
errors: [I18n.t(:quantity_is_not_available, scope: "spree.api.order")],
|
176
176
|
type: 'insufficient_stock'
|
177
177
|
},
|
178
|
-
status:
|
178
|
+
status: :unprocessable_entity
|
179
179
|
)
|
180
180
|
end
|
181
181
|
|
@@ -23,8 +23,8 @@ module Spree
|
|
23
23
|
authorize! :update, @order, order_token
|
24
24
|
@order.next!
|
25
25
|
respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
|
26
|
-
rescue StateMachines::InvalidTransition =>
|
27
|
-
logger.error("invalid_transition #{
|
26
|
+
rescue StateMachines::InvalidTransition => error
|
27
|
+
logger.error("invalid_transition #{error.event} from #{error.from} for #{error.object.class.name}. Error: #{error.inspect}")
|
28
28
|
respond_with(@order, default_template: 'spree/api/orders/could_not_transition', status: 422)
|
29
29
|
end
|
30
30
|
|
@@ -42,8 +42,8 @@ module Spree
|
|
42
42
|
@order.complete!
|
43
43
|
respond_with(@order, default_template: 'spree/api/orders/show', status: 200)
|
44
44
|
end
|
45
|
-
rescue StateMachines::InvalidTransition =>
|
46
|
-
logger.error("invalid_transition #{
|
45
|
+
rescue StateMachines::InvalidTransition => error
|
46
|
+
logger.error("invalid_transition #{error.event} from #{error.from} for #{error.object.class.name}. Error: #{error.inspect}")
|
47
47
|
respond_with(@order, default_template: 'spree/api/orders/could_not_transition', status: 422)
|
48
48
|
end
|
49
49
|
|
@@ -76,11 +76,24 @@ module Spree
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def update_params
|
79
|
-
|
80
|
-
|
79
|
+
state = @order.state
|
80
|
+
case state.to_sym
|
81
|
+
when :cart, :address
|
82
|
+
massaged_params.fetch(:order, {}).permit(
|
83
|
+
permitted_checkout_address_attributes
|
84
|
+
)
|
85
|
+
when :delivery
|
86
|
+
massaged_params.require(:order).permit(
|
87
|
+
permitted_checkout_delivery_attributes
|
88
|
+
)
|
89
|
+
when :payment
|
90
|
+
massaged_params.require(:order).permit(
|
91
|
+
permitted_checkout_payment_attributes
|
92
|
+
)
|
81
93
|
else
|
82
|
-
|
83
|
-
|
94
|
+
massaged_params.fetch(:order, {}).permit(
|
95
|
+
permitted_checkout_confirm_attributes
|
96
|
+
)
|
84
97
|
end
|
85
98
|
end
|
86
99
|
|
@@ -29,7 +29,7 @@ module Spree
|
|
29
29
|
|
30
30
|
def update
|
31
31
|
@option_type = Spree::OptionType.accessible_by(current_ability, :update).find(params[:id])
|
32
|
-
if @option_type.
|
32
|
+
if @option_type.update(option_type_params)
|
33
33
|
render :show
|
34
34
|
else
|
35
35
|
invalid_resource!(@option_type)
|
@@ -29,7 +29,7 @@ module Spree
|
|
29
29
|
|
30
30
|
def update
|
31
31
|
@option_value = scope.accessible_by(current_ability, :update).find(params[:id])
|
32
|
-
if @option_value.
|
32
|
+
if @option_value.update(option_value_params)
|
33
33
|
render :show
|
34
34
|
else
|
35
35
|
invalid_resource!(@option_value)
|
@@ -55,10 +55,9 @@ module Spree
|
|
55
55
|
def index
|
56
56
|
authorize! :index, Order
|
57
57
|
orders_includes = [
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:line_items
|
58
|
+
{ user: :store_credits },
|
59
|
+
:line_items,
|
60
|
+
:valid_store_credit_payments
|
62
61
|
]
|
63
62
|
@orders = paginate(
|
64
63
|
Spree::Order
|
@@ -131,7 +130,13 @@ module Spree
|
|
131
130
|
end
|
132
131
|
|
133
132
|
def normalize_params
|
134
|
-
|
133
|
+
if params[:order][:payments]
|
134
|
+
payments_params = params[:order].delete(:payments)
|
135
|
+
params[:order][:payments_attributes] = payments_params.map do |payment_params|
|
136
|
+
payment_params[:source_attributes] = payment_params.delete(:source) if payment_params[:source].present?
|
137
|
+
payment_params
|
138
|
+
end
|
139
|
+
end
|
135
140
|
params[:order][:shipments_attributes] = params[:order].delete(:shipments) if params[:order][:shipments]
|
136
141
|
params[:order][:line_items_attributes] = params[:order].delete(:line_items) if params[:order][:line_items]
|
137
142
|
params[:order][:ship_address_attributes] = params[:order].delete(:ship_address) if params[:order][:ship_address].present?
|
@@ -168,7 +173,13 @@ module Spree
|
|
168
173
|
end
|
169
174
|
|
170
175
|
def find_order(_lock = false)
|
171
|
-
@order = Spree::Order.
|
176
|
+
@order = Spree::Order.
|
177
|
+
includes(line_items: [:adjustments, { variant: :images }],
|
178
|
+
payments: :payment_method,
|
179
|
+
shipments: {
|
180
|
+
shipping_rates: { shipping_method: :zones, taxes: :tax_rate }
|
181
|
+
}).
|
182
|
+
find_by!(number: params[:id])
|
172
183
|
end
|
173
184
|
|
174
185
|
def order_id
|
@@ -31,7 +31,7 @@ module Spree
|
|
31
31
|
authorize! params[:action], @payment
|
32
32
|
if !@payment.pending?
|
33
33
|
render 'update_forbidden', status: 403
|
34
|
-
elsif @payment.
|
34
|
+
elsif @payment.update(payment_params)
|
35
35
|
respond_with(@payment, default_template: :show)
|
36
36
|
else
|
37
37
|
invalid_resource!(@payment)
|
@@ -38,7 +38,7 @@ module Spree
|
|
38
38
|
def update
|
39
39
|
if @product_property
|
40
40
|
authorize! :update, @product_property
|
41
|
-
@product_property.
|
41
|
+
@product_property.update(product_property_params)
|
42
42
|
respond_with(@product_property, status: 200, default_template: :show)
|
43
43
|
else
|
44
44
|
invalid_resource!(@product_property)
|
@@ -39,7 +39,7 @@ module Spree
|
|
39
39
|
def update
|
40
40
|
if @property
|
41
41
|
authorize! :update, @property
|
42
|
-
@property.
|
42
|
+
@property.update(property_params)
|
43
43
|
respond_with(@property, status: 200, default_template: :show)
|
44
44
|
else
|
45
45
|
invalid_resource!(@property)
|
@@ -43,7 +43,7 @@ class Spree::Api::ResourceController < Spree::Api::BaseController
|
|
43
43
|
def update
|
44
44
|
authorize! :update, @object
|
45
45
|
|
46
|
-
if @object.
|
46
|
+
if @object.update(permitted_resource_params)
|
47
47
|
respond_with(@object, status: 200, default_template: :show)
|
48
48
|
else
|
49
49
|
invalid_resource!(@object)
|
@@ -50,7 +50,7 @@ module Spree
|
|
50
50
|
|
51
51
|
def update
|
52
52
|
@return_authorization = @order.return_authorizations.accessible_by(current_ability, :update).find(params[:id])
|
53
|
-
if @return_authorization.
|
53
|
+
if @return_authorization.update(return_authorization_params)
|
54
54
|
respond_with(@return_authorization, default_template: :show)
|
55
55
|
else
|
56
56
|
invalid_resource!(@return_authorization)
|
@@ -40,7 +40,7 @@ module Spree
|
|
40
40
|
adjustment -= @stock_item.count_on_hand if params[:stock_item][:force]
|
41
41
|
|
42
42
|
Spree::StockItem.transaction do
|
43
|
-
if @stock_item.
|
43
|
+
if @stock_item.update(stock_item_params)
|
44
44
|
adjust_stock_item_count_on_hand(adjustment)
|
45
45
|
respond_with(@stock_item, status: 200, default_template: :show)
|
46
46
|
else
|
@@ -33,7 +33,7 @@ module Spree
|
|
33
33
|
|
34
34
|
def update
|
35
35
|
authorize! :update, stock_location
|
36
|
-
if stock_location.
|
36
|
+
if stock_location.update(stock_location_params)
|
37
37
|
respond_with(stock_location, status: 200, default_template: :show)
|
38
38
|
else
|
39
39
|
invalid_resource!(stock_location)
|
@@ -33,7 +33,7 @@ module Spree
|
|
33
33
|
|
34
34
|
def update
|
35
35
|
authorize! :update, taxonomy
|
36
|
-
if taxonomy.
|
36
|
+
if taxonomy.update(taxonomy_params)
|
37
37
|
respond_with(taxonomy, status: 200, default_template: :show)
|
38
38
|
else
|
39
39
|
invalid_resource!(taxonomy)
|
@@ -58,7 +58,9 @@ module Spree
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def taxonomy
|
61
|
-
@taxonomy ||= Spree::Taxonomy.accessible_by(current_ability, :read).
|
61
|
+
@taxonomy ||= Spree::Taxonomy.accessible_by(current_ability, :read).
|
62
|
+
includes(root: :children).
|
63
|
+
find(params[:id])
|
62
64
|
end
|
63
65
|
|
64
66
|
def taxonomy_params
|
@@ -43,7 +43,7 @@ module Spree
|
|
43
43
|
|
44
44
|
def update
|
45
45
|
@variant = scope.accessible_by(current_ability, :update).find(params[:id])
|
46
|
-
if @variant.
|
46
|
+
if @variant.update(variant_params)
|
47
47
|
respond_with(@variant, status: 200, default_template: :show)
|
48
48
|
else
|
49
49
|
invalid_resource!(@product)
|
@@ -40,7 +40,7 @@ module Spree
|
|
40
40
|
|
41
41
|
def required_fields_for(model)
|
42
42
|
required_fields = model._validators.select do |_field, validations|
|
43
|
-
validations.any? { |
|
43
|
+
validations.any? { |validation| validation.is_a?(ActiveModel::Validations::PresenceValidator) }
|
44
44
|
end.map(&:first) # get fields that are invalid
|
45
45
|
# Permalinks presence is validated, but are really automatically generated
|
46
46
|
# Therefore we shouldn't tell API clients that they MUST send one through
|
@@ -177,7 +177,7 @@ module Spree
|
|
177
177
|
]
|
178
178
|
|
179
179
|
def variant_attributes
|
180
|
-
if @current_user_roles
|
180
|
+
if @current_user_roles&.include?("admin")
|
181
181
|
@@variant_attributes + [:cost_price]
|
182
182
|
else
|
183
183
|
@@variant_attributes
|
@@ -2,6 +2,6 @@
|
|
2
2
|
|
3
3
|
json.(image, *image_attributes)
|
4
4
|
json.(image, :viewable_type, :viewable_id)
|
5
|
-
Spree::Image.attachment_definitions[:attachment][:styles].each do |
|
6
|
-
json.set! "#{
|
5
|
+
Spree::Image.attachment_definitions[:attachment][:styles].each do |key, _value|
|
6
|
+
json.set! "#{key}_url", image.attachment.url(key)
|
7
7
|
end
|