spree_api 5.4.0.beta7 → 5.4.0.beta9
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.
- checksums.yaml +4 -4
- data/app/controllers/concerns/spree/api/v3/error_handler.rb +3 -0
- data/app/controllers/spree/api/v3/store/auth_controller.rb +62 -19
- data/app/controllers/spree/api/v3/store/carts/{shipments_controller.rb → fulfillments_controller.rb} +13 -13
- data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +91 -0
- data/app/controllers/spree/api/v3/store/customers_controller.rb +6 -2
- data/app/controllers/spree/api/v3/store/products_controller.rb +1 -1
- data/app/serializers/spree/api/v3/admin/address_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/allowed_origin_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/{shipping_method_serializer.rb → delivery_method_serializer.rb} +1 -1
- data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/{shipment_serializer.rb → fulfillment_serializer.rb} +3 -3
- data/app/serializers/spree/api/v3/admin/media_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/admin/order_serializer.rb +5 -4
- data/app/serializers/spree/api/v3/admin/product_serializer.rb +8 -9
- data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/variant_serializer.rb +8 -3
- data/app/serializers/spree/api/v3/base_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/cart_serializer.rb +11 -3
- data/app/serializers/spree/api/v3/{shipping_method_serializer.rb → delivery_method_serializer.rb} +1 -1
- data/app/serializers/spree/api/v3/{shipping_rate_serializer.rb → delivery_rate_serializer.rb} +4 -4
- data/app/serializers/spree/api/v3/fulfillment_serializer.rb +45 -0
- data/app/serializers/spree/api/v3/gift_card_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/media_serializer.rb +60 -0
- data/app/serializers/spree/api/v3/newsletter_subscriber_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/order_serializer.rb +21 -5
- data/app/serializers/spree/api/v3/payment_serializer.rb +6 -2
- data/app/serializers/spree/api/v3/product_serializer.rb +10 -11
- data/app/serializers/spree/api/v3/variant_serializer.rb +14 -9
- data/config/locales/en.yml +3 -0
- data/config/routes.rb +4 -1
- data/lib/spree/api/configuration.rb +2 -0
- data/lib/spree/api/dependencies.rb +14 -8
- data/lib/spree/api/openapi/schema_helper.rb +31 -1
- metadata +17 -15
- data/app/serializers/spree/api/v3/admin/image_serializer.rb +0 -10
- data/app/serializers/spree/api/v3/admin/shipping_rate_serializer.rb +0 -11
- data/app/serializers/spree/api/v3/image_serializer.rb +0 -43
- data/app/serializers/spree/api/v3/shipment_serializer.rb +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7630000b76a8d6596d6a94e2e5ef3b928ad55035995a777d79a855da0b83e707
|
|
4
|
+
data.tar.gz: 5621ebbdb257e9c69518e3ad71a9368954c0fbf7db6ad7a3b4adb237b00cb83b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ecdbc7f8b2e6792a1e8641ebaabfcc69423705f032435bb960ff3f2ae36eb19c89dc224b8af79278b3e74536ca95112442139278e847cca9710f437300d9395e
|
|
7
|
+
data.tar.gz: 8264257bdf243e8bc504880ceed1f99233baaf09bf6e7264714ab9395b59429e0c9c553269012015d9e870dd3dc797b19224d204b7a33518681878533200e71e
|
|
@@ -12,7 +12,10 @@ module Spree
|
|
|
12
12
|
access_denied: 'access_denied',
|
|
13
13
|
invalid_token: 'invalid_token',
|
|
14
14
|
invalid_provider: 'invalid_provider',
|
|
15
|
+
invalid_refresh_token: 'invalid_refresh_token',
|
|
15
16
|
current_password_invalid: 'current_password_invalid',
|
|
17
|
+
password_reset_token_invalid: 'password_reset_token_invalid',
|
|
18
|
+
redirect_url_not_allowed: 'redirect_url_not_allowed',
|
|
16
19
|
|
|
17
20
|
# Resource errors
|
|
18
21
|
record_not_found: 'record_not_found',
|
|
@@ -7,9 +7,9 @@ module Spree
|
|
|
7
7
|
rate_limit to: Spree::Api::Config[:rate_limit_login], within: Spree::Api::Config[:rate_limit_window].seconds, store: Rails.cache, only: :create, with: RATE_LIMIT_RESPONSE
|
|
8
8
|
rate_limit to: Spree::Api::Config[:rate_limit_refresh], within: Spree::Api::Config[:rate_limit_window].seconds, store: Rails.cache, only: :refresh, with: RATE_LIMIT_RESPONSE
|
|
9
9
|
rate_limit to: Spree::Api::Config[:rate_limit_oauth], within: Spree::Api::Config[:rate_limit_window].seconds, store: Rails.cache, only: :oauth_callback, with: RATE_LIMIT_RESPONSE
|
|
10
|
+
rate_limit to: Spree::Api::Config[:rate_limit_refresh], within: Spree::Api::Config[:rate_limit_window].seconds, store: Rails.cache, only: :logout, with: RATE_LIMIT_RESPONSE
|
|
10
11
|
|
|
11
|
-
skip_before_action :authenticate_user, only: [:create, :oauth_callback]
|
|
12
|
-
prepend_before_action :require_authentication!, only: [:refresh]
|
|
12
|
+
skip_before_action :authenticate_user, only: [:create, :refresh, :oauth_callback]
|
|
13
13
|
|
|
14
14
|
# POST /api/v3/store/auth/login
|
|
15
15
|
# Supports multiple authentication providers via :provider param
|
|
@@ -23,11 +23,7 @@ module Spree
|
|
|
23
23
|
|
|
24
24
|
if result.success?
|
|
25
25
|
user = result.value
|
|
26
|
-
|
|
27
|
-
render json: {
|
|
28
|
-
token: token,
|
|
29
|
-
user: user_serializer.new(user, params: serializer_params).to_h
|
|
30
|
-
}
|
|
26
|
+
render json: auth_response(user)
|
|
31
27
|
else
|
|
32
28
|
render_error(
|
|
33
29
|
code: ERROR_CODES[:authentication_failed],
|
|
@@ -38,21 +34,55 @@ module Spree
|
|
|
38
34
|
end
|
|
39
35
|
|
|
40
36
|
# POST /api/v3/store/auth/refresh
|
|
37
|
+
# Accepts: { "refresh_token": "rt_xxx" }
|
|
38
|
+
# Returns new access JWT + rotated refresh token
|
|
41
39
|
def refresh
|
|
42
|
-
|
|
40
|
+
refresh_token_value = params[:refresh_token]
|
|
41
|
+
|
|
42
|
+
if refresh_token_value.blank?
|
|
43
|
+
return render_error(
|
|
44
|
+
code: ERROR_CODES[:invalid_refresh_token],
|
|
45
|
+
message: 'refresh_token is required',
|
|
46
|
+
status: :unauthorized
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
refresh_token = Spree::RefreshToken.active.find_by(token: refresh_token_value)
|
|
51
|
+
|
|
52
|
+
if refresh_token.nil?
|
|
53
|
+
return render_error(
|
|
54
|
+
code: ERROR_CODES[:invalid_refresh_token],
|
|
55
|
+
message: 'Invalid or expired refresh token',
|
|
56
|
+
status: :unauthorized
|
|
57
|
+
)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
user = refresh_token.user
|
|
61
|
+
new_refresh_token = refresh_token.rotate!(request_env: request_env_for_token)
|
|
62
|
+
|
|
43
63
|
render json: {
|
|
44
|
-
token:
|
|
45
|
-
|
|
64
|
+
token: generate_jwt(user),
|
|
65
|
+
refresh_token: new_refresh_token.token,
|
|
66
|
+
user: user_serializer.new(user, params: serializer_params).to_h
|
|
46
67
|
}
|
|
47
68
|
end
|
|
48
69
|
|
|
70
|
+
# POST /api/v3/store/auth/logout
|
|
71
|
+
# Accepts: { "refresh_token": "rt_xxx" }
|
|
72
|
+
# Revokes the refresh token
|
|
73
|
+
def logout
|
|
74
|
+
refresh_token_value = params[:refresh_token]
|
|
75
|
+
|
|
76
|
+
if refresh_token_value.present?
|
|
77
|
+
Spree::RefreshToken.find_by(token: refresh_token_value)&.destroy
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
head :no_content
|
|
81
|
+
end
|
|
82
|
+
|
|
49
83
|
# POST /api/v3/store/auth/oauth/callback
|
|
50
84
|
# OAuth callback endpoint for server-side OAuth flows
|
|
51
85
|
def oauth_callback
|
|
52
|
-
# This endpoint is designed for OAuth flows where the server
|
|
53
|
-
# exchanges the authorization code for an access token
|
|
54
|
-
# For client-side flows, use the regular /login endpoint with id_token
|
|
55
|
-
|
|
56
86
|
strategy = authentication_strategy
|
|
57
87
|
return unless strategy # Error already rendered by determine_strategy
|
|
58
88
|
|
|
@@ -60,11 +90,7 @@ module Spree
|
|
|
60
90
|
|
|
61
91
|
if result.success?
|
|
62
92
|
user = result.value
|
|
63
|
-
|
|
64
|
-
render json: {
|
|
65
|
-
token: token,
|
|
66
|
-
user: user_serializer.new(user, params: serializer_params).to_h
|
|
67
|
-
}
|
|
93
|
+
render json: auth_response(user)
|
|
68
94
|
else
|
|
69
95
|
render_error(
|
|
70
96
|
code: ERROR_CODES[:authentication_failed],
|
|
@@ -88,6 +114,23 @@ module Spree
|
|
|
88
114
|
|
|
89
115
|
private
|
|
90
116
|
|
|
117
|
+
def auth_response(user)
|
|
118
|
+
refresh_token = Spree::RefreshToken.create_for(user, request_env: request_env_for_token)
|
|
119
|
+
|
|
120
|
+
{
|
|
121
|
+
token: generate_jwt(user),
|
|
122
|
+
refresh_token: refresh_token.token,
|
|
123
|
+
user: user_serializer.new(user, params: serializer_params).to_h
|
|
124
|
+
}
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def request_env_for_token
|
|
128
|
+
{
|
|
129
|
+
ip_address: request.remote_ip,
|
|
130
|
+
user_agent: request.user_agent&.truncate(255)
|
|
131
|
+
}
|
|
132
|
+
end
|
|
133
|
+
|
|
91
134
|
def authentication_strategy
|
|
92
135
|
strategy_class = determine_strategy
|
|
93
136
|
strategy_class.new(
|
data/app/controllers/spree/api/v3/store/carts/{shipments_controller.rb → fulfillments_controller.rb}
RENAMED
|
@@ -3,31 +3,31 @@ module Spree
|
|
|
3
3
|
module V3
|
|
4
4
|
module Store
|
|
5
5
|
module Carts
|
|
6
|
-
class
|
|
6
|
+
class FulfillmentsController < Store::BaseController
|
|
7
7
|
include Spree::Api::V3::CartResolvable
|
|
8
8
|
include Spree::Api::V3::OrderLock
|
|
9
9
|
|
|
10
10
|
before_action :find_cart!
|
|
11
11
|
|
|
12
|
-
# GET /api/v3/store/carts/:cart_id/
|
|
12
|
+
# GET /api/v3/store/carts/:cart_id/fulfillments
|
|
13
13
|
def index
|
|
14
|
-
|
|
14
|
+
fulfillments = @cart.shipments.includes(shipping_rates: :shipping_method)
|
|
15
15
|
render json: {
|
|
16
|
-
data:
|
|
17
|
-
meta: { count:
|
|
16
|
+
data: fulfillments.map { |s| Spree.api.fulfillment_serializer.new(s, params: serializer_params).to_h },
|
|
17
|
+
meta: { count: fulfillments.size }
|
|
18
18
|
}
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
# PATCH /api/v3/store/carts/:cart_id/
|
|
22
|
-
# Select a
|
|
21
|
+
# PATCH /api/v3/store/carts/:cart_id/fulfillments/:id
|
|
22
|
+
# Select a delivery rate for a specific fulfillment
|
|
23
23
|
def update
|
|
24
24
|
with_order_lock do
|
|
25
|
-
|
|
25
|
+
fulfillment = @cart.shipments.find_by_prefix_id!(params[:id])
|
|
26
26
|
|
|
27
|
-
if permitted_params[:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
if permitted_params[:selected_delivery_rate_id].present?
|
|
28
|
+
delivery_rate = fulfillment.shipping_rates.find_by_prefix_id!(permitted_params[:selected_delivery_rate_id])
|
|
29
|
+
fulfillment.selected_shipping_rate_id = delivery_rate.id
|
|
30
|
+
fulfillment.save!
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# Auto-advance (e.g. delivery → payment) after rate selection.
|
|
@@ -41,7 +41,7 @@ module Spree
|
|
|
41
41
|
private
|
|
42
42
|
|
|
43
43
|
def permitted_params
|
|
44
|
-
params.permit(:
|
|
44
|
+
params.permit(:selected_delivery_rate_id)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
# Temporary — Spree 6 removes the checkout state machine.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module Api
|
|
5
|
+
module V3
|
|
6
|
+
module Store
|
|
7
|
+
module Customer
|
|
8
|
+
class PasswordResetsController < Store::BaseController
|
|
9
|
+
rate_limit to: Spree::Api::Config[:rate_limit_password_reset],
|
|
10
|
+
within: Spree::Api::Config[:rate_limit_window].seconds,
|
|
11
|
+
store: Rails.cache,
|
|
12
|
+
with: RATE_LIMIT_RESPONSE
|
|
13
|
+
|
|
14
|
+
skip_before_action :authenticate_user
|
|
15
|
+
|
|
16
|
+
# POST /api/v3/store/customer/password_resets
|
|
17
|
+
def create
|
|
18
|
+
redirect_url = params[:redirect_url]
|
|
19
|
+
|
|
20
|
+
# Validate redirect_url against allowed origins (secure by default).
|
|
21
|
+
# If no allowed origins are configured, redirect_url is silently ignored
|
|
22
|
+
# to prevent open redirect / token exfiltration attacks.
|
|
23
|
+
if redirect_url.present?
|
|
24
|
+
if current_store.allowed_origins.exists? && current_store.allowed_origin?(redirect_url)
|
|
25
|
+
# redirect_url is valid — keep it
|
|
26
|
+
else
|
|
27
|
+
redirect_url = nil
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
user = Spree.user_class.find_by(email: params[:email])
|
|
32
|
+
|
|
33
|
+
if user
|
|
34
|
+
token = user.generate_token_for(:password_reset)
|
|
35
|
+
event_payload = { reset_token: token, email: user.email }
|
|
36
|
+
event_payload[:redirect_url] = redirect_url if redirect_url.present?
|
|
37
|
+
user.publish_event('customer.password_reset_requested', event_payload)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Always return 202 to prevent email enumeration
|
|
41
|
+
render json: { message: Spree.t(:password_reset_requested, scope: :api) }, status: :accepted
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# PATCH /api/v3/store/customer/password_resets/:id
|
|
45
|
+
def update
|
|
46
|
+
user = Spree.user_class.find_by_password_reset_token(params[:id])
|
|
47
|
+
|
|
48
|
+
unless user
|
|
49
|
+
return render_error(
|
|
50
|
+
code: ERROR_CODES[:password_reset_token_invalid],
|
|
51
|
+
message: Spree.t(:password_reset_token_invalid, scope: :api),
|
|
52
|
+
status: :unprocessable_content
|
|
53
|
+
)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if user.update(password: params[:password], password_confirmation: params[:password_confirmation])
|
|
57
|
+
jwt = generate_jwt(user)
|
|
58
|
+
refresh_token = Spree::RefreshToken.create_for(user, request_env: { ip_address: request.remote_ip, user_agent: request.user_agent&.truncate(255) })
|
|
59
|
+
user.publish_event('customer.password_reset')
|
|
60
|
+
|
|
61
|
+
render json: {
|
|
62
|
+
token: jwt,
|
|
63
|
+
refresh_token: refresh_token.token,
|
|
64
|
+
user: serializer_class.new(user, params: serializer_params).to_h
|
|
65
|
+
}
|
|
66
|
+
else
|
|
67
|
+
render_errors(user.errors)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
protected
|
|
72
|
+
|
|
73
|
+
def serializer_class
|
|
74
|
+
Spree.api.customer_serializer
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def serializer_params
|
|
78
|
+
{
|
|
79
|
+
store: current_store,
|
|
80
|
+
locale: current_locale,
|
|
81
|
+
currency: current_currency,
|
|
82
|
+
user: nil,
|
|
83
|
+
includes: []
|
|
84
|
+
}
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -13,9 +13,13 @@ module Spree
|
|
|
13
13
|
user = Spree.user_class.new(create_params)
|
|
14
14
|
|
|
15
15
|
if user.save
|
|
16
|
-
|
|
16
|
+
refresh_token = Spree::RefreshToken.create_for(user, request_env: {
|
|
17
|
+
ip_address: request.remote_ip,
|
|
18
|
+
user_agent: request.user_agent&.truncate(255)
|
|
19
|
+
})
|
|
17
20
|
render json: {
|
|
18
|
-
token:
|
|
21
|
+
token: generate_jwt(user),
|
|
22
|
+
refresh_token: refresh_token.token,
|
|
19
23
|
user: user_serializer.new(user, params: serializer_params).to_h
|
|
20
24
|
}, status: :created
|
|
21
25
|
else
|
|
@@ -41,7 +41,7 @@ module Spree
|
|
|
41
41
|
# these scopes are not automatically picked by ar_lazy_preload gem and we need to explicitly include them
|
|
42
42
|
def scope_includes
|
|
43
43
|
[
|
|
44
|
-
|
|
44
|
+
primary_media: [attachment_attachment: :blob],
|
|
45
45
|
master: [:prices, stock_items: :stock_location],
|
|
46
46
|
variants: [:prices, stock_items: :stock_location]
|
|
47
47
|
]
|
|
@@ -4,13 +4,13 @@ module Spree
|
|
|
4
4
|
module Admin
|
|
5
5
|
class AddressSerializer < V3::AddressSerializer
|
|
6
6
|
typelize label: [:string, nullable: true],
|
|
7
|
-
|
|
7
|
+
customer_id: [:string, nullable: true],
|
|
8
8
|
metadata: 'Record<string, unknown> | null'
|
|
9
9
|
|
|
10
10
|
attributes :label,
|
|
11
11
|
created_at: :iso8601, updated_at: :iso8601
|
|
12
12
|
|
|
13
|
-
attribute :
|
|
13
|
+
attribute :customer_id do |address|
|
|
14
14
|
address.user&.prefixed_id
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
module Api
|
|
5
|
+
module V3
|
|
6
|
+
module Admin
|
|
7
|
+
class AllowedOriginSerializer < V3::BaseSerializer
|
|
8
|
+
typelize store_id: :string
|
|
9
|
+
|
|
10
|
+
attributes :id, :origin
|
|
11
|
+
|
|
12
|
+
attribute :store_id do |allowed_origin|
|
|
13
|
+
allowed_origin.store&.prefixed_id
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attributes created_at: :iso8601, updated_at: :iso8601
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -3,10 +3,10 @@ module Spree
|
|
|
3
3
|
module V3
|
|
4
4
|
module Admin
|
|
5
5
|
class CreditCardSerializer < V3::CreditCardSerializer
|
|
6
|
-
typelize
|
|
6
|
+
typelize customer_id: [:string, nullable: true],
|
|
7
7
|
payment_method_id: [:string, nullable: true]
|
|
8
8
|
|
|
9
|
-
attribute :
|
|
9
|
+
attribute :customer_id do |credit_card|
|
|
10
10
|
credit_card.user&.prefixed_id
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class DeliveryRateSerializer < V3::DeliveryRateSerializer
|
|
6
|
+
one :shipping_method, key: :delivery_method, resource: Spree.api.admin_delivery_method_serializer, if: proc { expand?('delivery_method') }
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
data/app/serializers/spree/api/v3/admin/{shipment_serializer.rb → fulfillment_serializer.rb}
RENAMED
|
@@ -2,7 +2,7 @@ module Spree
|
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
4
|
module Admin
|
|
5
|
-
class
|
|
5
|
+
class FulfillmentSerializer < V3::FulfillmentSerializer
|
|
6
6
|
typelize metadata: 'Record<string, unknown> | null',
|
|
7
7
|
order_id: [:string, nullable: true],
|
|
8
8
|
stock_location_id: [:string, nullable: true],
|
|
@@ -26,9 +26,9 @@ module Spree
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
# Override inherited associations to use admin serializers
|
|
29
|
-
one :shipping_method, resource: Spree.api.
|
|
29
|
+
one :shipping_method, key: :delivery_method, resource: Spree.api.admin_delivery_method_serializer, if: proc { expand?('delivery_method') }
|
|
30
30
|
one :stock_location, resource: Spree.api.admin_stock_location_serializer, if: proc { expand?('stock_location') }
|
|
31
|
-
many :shipping_rates, resource: Spree.api.
|
|
31
|
+
many :shipping_rates, key: :delivery_rates, resource: Spree.api.admin_delivery_rate_serializer, if: proc { expand?('delivery_rates') }
|
|
32
32
|
|
|
33
33
|
one :order,
|
|
34
34
|
resource: Spree.api.admin_order_serializer,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
class MediaSerializer < V3::MediaSerializer
|
|
6
|
+
typelize viewable_type: :string, viewable_id: :string
|
|
7
|
+
|
|
8
|
+
attribute :viewable_id do |asset|
|
|
9
|
+
asset.viewable&.prefixed_id
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attributes :viewable_type
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -11,7 +11,7 @@ module Spree
|
|
|
11
11
|
store_owner_notification_delivered: :boolean,
|
|
12
12
|
internal_note: [:string, nullable: true], approver_id: [:string, nullable: true],
|
|
13
13
|
canceler_id: [:string, nullable: true], created_by_id: [:string, nullable: true],
|
|
14
|
-
|
|
14
|
+
customer_id: [:string, nullable: true],
|
|
15
15
|
canceled_at: [:string, nullable: true], approved_at: [:string, nullable: true],
|
|
16
16
|
payment_total: :string, display_payment_total: :string,
|
|
17
17
|
metadata: 'Record<string, unknown> | null'
|
|
@@ -38,14 +38,14 @@ module Spree
|
|
|
38
38
|
order.created_by&.prefixed_id
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
attribute :
|
|
41
|
+
attribute :customer_id do |order|
|
|
42
42
|
order.user&.prefixed_id
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
# Override inherited associations to use admin serializers
|
|
46
46
|
many :order_promotions, key: :promotions, resource: Spree.api.admin_order_promotion_serializer, if: proc { expand?('promotions') }
|
|
47
47
|
many :line_items, key: :items, resource: Spree.api.admin_line_item_serializer, if: proc { expand?('items') }
|
|
48
|
-
many :shipments, resource: Spree.api.
|
|
48
|
+
many :shipments, key: :fulfillments, resource: Spree.api.admin_fulfillment_serializer, if: proc { expand?('fulfillments') }
|
|
49
49
|
many :payments, resource: Spree.api.admin_payment_serializer, if: proc { expand?('payments') }
|
|
50
50
|
|
|
51
51
|
one :bill_address, resource: Spree.api.admin_address_serializer, if: proc { expand?('bill_address') }
|
|
@@ -54,8 +54,9 @@ module Spree
|
|
|
54
54
|
many :payment_methods, resource: Spree.api.admin_payment_method_serializer, if: proc { expand?('payment_methods') }
|
|
55
55
|
|
|
56
56
|
one :user,
|
|
57
|
+
key: :customer,
|
|
57
58
|
resource: Spree.api.admin_customer_serializer,
|
|
58
|
-
if: proc { expand?('
|
|
59
|
+
if: proc { expand?('customer') }
|
|
59
60
|
|
|
60
61
|
one :approver,
|
|
61
62
|
resource: Spree.api.admin_customer_serializer,
|
|
@@ -32,15 +32,14 @@ module Spree
|
|
|
32
32
|
resource: Spree.api.admin_variant_serializer,
|
|
33
33
|
if: proc { expand?('default_variant') }
|
|
34
34
|
|
|
35
|
-
one :
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if: proc { expand?('images') }
|
|
35
|
+
one :primary_media,
|
|
36
|
+
resource: Spree.api.admin_media_serializer,
|
|
37
|
+
if: proc { expand?('primary_media') }
|
|
38
|
+
|
|
39
|
+
many :gallery_media,
|
|
40
|
+
key: :media,
|
|
41
|
+
resource: Spree.api.admin_media_serializer,
|
|
42
|
+
if: proc { expand?('media') }
|
|
44
43
|
|
|
45
44
|
many :option_types,
|
|
46
45
|
resource: Spree.api.admin_option_type_serializer,
|
|
@@ -3,11 +3,11 @@ module Spree
|
|
|
3
3
|
module V3
|
|
4
4
|
module Admin
|
|
5
5
|
class StoreCreditSerializer < V3::StoreCreditSerializer
|
|
6
|
-
typelize
|
|
6
|
+
typelize customer_id: [:string, nullable: true],
|
|
7
7
|
created_by_id: [:string, nullable: true],
|
|
8
8
|
metadata: 'Record<string, unknown> | null'
|
|
9
9
|
|
|
10
|
-
attribute :
|
|
10
|
+
attribute :customer_id do |store_credit|
|
|
11
11
|
store_credit.user&.prefixed_id
|
|
12
12
|
end
|
|
13
13
|
|
|
@@ -20,9 +20,14 @@ module Spree
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# Override inherited associations to use admin serializers
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
one :primary_media,
|
|
24
|
+
resource: Spree.api.admin_media_serializer,
|
|
25
|
+
if: proc { expand?('primary_media') }
|
|
26
|
+
|
|
27
|
+
many :gallery_media,
|
|
28
|
+
key: :media,
|
|
29
|
+
resource: Spree.api.admin_media_serializer,
|
|
30
|
+
if: proc { expand?('media') }
|
|
26
31
|
|
|
27
32
|
many :option_values, resource: Spree.api.admin_option_value_serializer
|
|
28
33
|
|
|
@@ -38,7 +38,7 @@ module Spree
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
# Check if an association should be expanded
|
|
41
|
-
# Supports dot notation: expand?('variants') matches both 'variants' and 'variants.
|
|
41
|
+
# Supports dot notation: expand?('variants') matches both 'variants' and 'variants.media'
|
|
42
42
|
def expand?(name)
|
|
43
43
|
name = name.to_s
|
|
44
44
|
expands.any? { |e| e == name || e.start_with?("#{name}.") }
|
|
@@ -8,7 +8,7 @@ module Spree
|
|
|
8
8
|
special_instructions: [:string, nullable: true], currency: :string, locale: [:string, nullable: true], item_count: :number,
|
|
9
9
|
requirements: 'Array<{step: string, field: string, message: string}>',
|
|
10
10
|
item_total: :string, display_item_total: :string,
|
|
11
|
-
|
|
11
|
+
delivery_total: :string, display_delivery_total: :string,
|
|
12
12
|
adjustment_total: :string, display_adjustment_total: :string,
|
|
13
13
|
promo_total: :string, display_promo_total: :string,
|
|
14
14
|
tax_total: :string, display_tax_total: :string,
|
|
@@ -24,12 +24,20 @@ module Spree
|
|
|
24
24
|
|
|
25
25
|
attributes :number, :token, :email, :special_instructions,
|
|
26
26
|
:currency, :locale, :item_count,
|
|
27
|
-
:item_total, :display_item_total,
|
|
27
|
+
:item_total, :display_item_total,
|
|
28
28
|
:adjustment_total, :display_adjustment_total, :promo_total, :display_promo_total,
|
|
29
29
|
:tax_total, :display_tax_total, :included_tax_total, :display_included_tax_total,
|
|
30
30
|
:additional_tax_total, :display_additional_tax_total, :total, :display_total,
|
|
31
31
|
created_at: :iso8601, updated_at: :iso8601
|
|
32
32
|
|
|
33
|
+
attribute :delivery_total do |order|
|
|
34
|
+
order.ship_total
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
attribute :display_delivery_total do |order|
|
|
38
|
+
order.display_ship_total.to_s
|
|
39
|
+
end
|
|
40
|
+
|
|
33
41
|
attribute :current_step do |order|
|
|
34
42
|
order.current_checkout_step
|
|
35
43
|
end
|
|
@@ -44,7 +52,7 @@ module Spree
|
|
|
44
52
|
|
|
45
53
|
many :cart_promotions, key: :promotions, resource: Spree.api.cart_promotion_serializer
|
|
46
54
|
many :line_items, key: :items, resource: Spree.api.line_item_serializer
|
|
47
|
-
many :shipments, resource: Spree.api.
|
|
55
|
+
many :shipments, key: :fulfillments, resource: Spree.api.fulfillment_serializer
|
|
48
56
|
many :payments, resource: Spree.api.payment_serializer
|
|
49
57
|
one :bill_address, resource: Spree.api.address_serializer
|
|
50
58
|
one :ship_address, resource: Spree.api.address_serializer
|
data/app/serializers/spree/api/v3/{shipping_rate_serializer.rb → delivery_rate_serializer.rb}
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
|
-
class
|
|
5
|
-
typelize name: :string, selected: :boolean,
|
|
4
|
+
class DeliveryRateSerializer < BaseSerializer
|
|
5
|
+
typelize name: :string, selected: :boolean, delivery_method_id: :string,
|
|
6
6
|
cost: :string, display_cost: :string
|
|
7
7
|
|
|
8
|
-
attribute :
|
|
8
|
+
attribute :delivery_method_id do |shipping_rate|
|
|
9
9
|
shipping_rate.shipping_method&.prefixed_id
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ module Spree
|
|
|
15
15
|
shipping_rate.display_cost.to_s
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
one :shipping_method, resource: Spree.api.
|
|
18
|
+
one :shipping_method, key: :delivery_method, resource: Spree.api.delivery_method_serializer
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|