spree_api 5.4.0.beta4 → 5.4.0.beta6

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -4
  3. data/app/controllers/concerns/spree/api/v3/api_key_authentication.rb +1 -1
  4. data/app/controllers/concerns/spree/api/v3/error_handler.rb +12 -2
  5. data/app/controllers/concerns/spree/api/v3/http_caching.rb +10 -2
  6. data/app/controllers/concerns/spree/api/v3/idempotent.rb +82 -0
  7. data/app/controllers/concerns/spree/api/v3/jwt_authentication.rb +4 -1
  8. data/app/controllers/concerns/spree/api/v3/order_concern.rb +1 -6
  9. data/app/controllers/concerns/spree/api/v3/rate_limit_headers.rb +31 -0
  10. data/app/controllers/concerns/spree/api/v3/resource_serializer.rb +30 -2
  11. data/app/controllers/concerns/spree/api/v3/security_headers.rb +4 -0
  12. data/app/controllers/spree/api/v3/admin/base_controller.rb +28 -0
  13. data/app/controllers/spree/api/v3/admin/resource_controller.rb +28 -0
  14. data/app/controllers/spree/api/v3/base_controller.rb +20 -1
  15. data/app/controllers/spree/api/v3/resource_controller.rb +35 -3
  16. data/app/controllers/spree/api/v3/store/auth_controller.rb +4 -24
  17. data/app/controllers/spree/api/v3/store/base_controller.rb +0 -11
  18. data/app/controllers/spree/api/v3/store/cart_controller.rb +6 -2
  19. data/app/controllers/spree/api/v3/store/categories/products_controller.rb +37 -0
  20. data/app/controllers/spree/api/v3/store/{taxons_controller.rb → categories_controller.rb} +8 -6
  21. data/app/controllers/spree/api/v3/store/countries_controller.rb +6 -0
  22. data/app/controllers/spree/api/v3/store/currencies_controller.rb +4 -0
  23. data/app/controllers/spree/api/v3/store/customers_controller.rb +102 -0
  24. data/app/controllers/spree/api/v3/store/locales_controller.rb +4 -0
  25. data/app/controllers/spree/api/v3/store/markets/countries_controller.rb +6 -0
  26. data/app/controllers/spree/api/v3/store/markets_controller.rb +8 -0
  27. data/app/controllers/spree/api/v3/store/orders/payments_controller.rb +38 -0
  28. data/app/controllers/spree/api/v3/store/orders_controller.rb +3 -2
  29. data/app/controllers/spree/api/v3/store/products/filters_controller.rb +9 -8
  30. data/app/controllers/spree/api/v3/store/products_controller.rb +12 -19
  31. data/app/jobs/spree/webhook_delivery_job.rb +4 -1
  32. data/app/serializers/spree/api/v3/admin/address_serializer.rb +24 -0
  33. data/app/serializers/spree/api/v3/admin/adjustment_serializer.rb +36 -0
  34. data/app/serializers/spree/api/v3/admin/admin_user_serializer.rb +15 -0
  35. data/app/serializers/spree/api/v3/admin/asset_serializer.rb +10 -0
  36. data/app/serializers/spree/api/v3/admin/category_serializer.rb +33 -0
  37. data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +22 -0
  38. data/app/serializers/spree/api/v3/admin/customer_serializer.rb +8 -6
  39. data/app/serializers/spree/api/v3/admin/digital_link_serializer.rb +10 -0
  40. data/app/serializers/spree/api/v3/admin/image_serializer.rb +10 -0
  41. data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +36 -1
  42. data/app/serializers/spree/api/v3/admin/option_type_serializer.rb +13 -0
  43. data/app/serializers/spree/api/v3/admin/option_value_serializer.rb +13 -0
  44. data/app/serializers/spree/api/v3/admin/order_promotion_serializer.rb +10 -0
  45. data/app/serializers/spree/api/v3/admin/order_serializer.rb +47 -6
  46. data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +14 -0
  47. data/app/serializers/spree/api/v3/admin/payment_serializer.rb +56 -0
  48. data/app/serializers/spree/api/v3/admin/payment_source_serializer.rb +10 -0
  49. data/app/serializers/spree/api/v3/admin/product_serializer.rb +23 -6
  50. data/app/serializers/spree/api/v3/admin/refund_serializer.rb +21 -0
  51. data/app/serializers/spree/api/v3/admin/reimbursement_serializer.rb +13 -0
  52. data/app/serializers/spree/api/v3/admin/return_authorization_serializer.rb +17 -0
  53. data/app/serializers/spree/api/v3/admin/shipment_serializer.rb +44 -0
  54. data/app/serializers/spree/api/v3/admin/shipping_category_serializer.rb +14 -0
  55. data/app/serializers/spree/api/v3/admin/shipping_method_serializer.rb +11 -0
  56. data/app/serializers/spree/api/v3/admin/shipping_rate_serializer.rb +11 -0
  57. data/app/serializers/spree/api/v3/admin/stock_item_serializer.rb +17 -0
  58. data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +15 -0
  59. data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +27 -0
  60. data/app/serializers/spree/api/v3/admin/tax_category_serializer.rb +15 -0
  61. data/app/serializers/spree/api/v3/admin/variant_serializer.rb +11 -14
  62. data/app/serializers/spree/api/v3/base_serializer.rb +21 -4
  63. data/app/serializers/spree/api/v3/category_serializer.rb +71 -0
  64. data/app/serializers/spree/api/v3/country_serializer.rb +2 -1
  65. data/app/serializers/spree/api/v3/customer_serializer.rb +2 -1
  66. data/app/serializers/spree/api/v3/gift_card_serializer.rb +5 -21
  67. data/app/serializers/spree/api/v3/order_serializer.rb +2 -2
  68. data/app/serializers/spree/api/v3/payment_serializer.rb +1 -1
  69. data/app/serializers/spree/api/v3/product_serializer.rb +11 -11
  70. data/app/serializers/spree/api/v3/shipping_category_serializer.rb +11 -0
  71. data/app/serializers/spree/api/v3/shipping_rate_serializer.rb +2 -6
  72. data/app/serializers/spree/api/v3/tax_category_serializer.rb +11 -0
  73. data/app/serializers/spree/api/v3/variant_serializer.rb +4 -4
  74. data/app/serializers/spree/api/v3/wishlist_serializer.rb +1 -1
  75. data/app/services/spree/api/v3/filters_aggregator.rb +31 -25
  76. data/app/services/spree/webhooks/deliver_webhook.rb +23 -17
  77. data/app/subscribers/spree/webhook_event_subscriber.rb +1 -1
  78. data/config/initializers/alba.rb +1 -1
  79. data/config/initializers/typelizer.rb +26 -16
  80. data/config/locales/en.yml +5 -0
  81. data/config/routes.rb +10 -10
  82. data/lib/spree/api/configuration.rb +3 -1
  83. data/lib/spree/api/dependencies.rb +31 -5
  84. data/lib/spree/api/engine.rb +15 -0
  85. data/lib/spree/api/openapi/schema_helper.rb +27 -7
  86. data/lib/spree/api/testing_support/v3/base.rb +24 -1
  87. metadata +43 -19
  88. data/app/controllers/spree/api/v3/store/customer/account_controller.rb +0 -38
  89. data/app/controllers/spree/api/v3/store/stores_controller.rb +0 -26
  90. data/app/controllers/spree/api/v3/store/taxonomies_controller.rb +0 -19
  91. data/app/controllers/spree/api/v3/store/taxons/products_controller.rb +0 -37
  92. data/app/serializers/spree/api/v3/admin/taxon_serializer.rb +0 -20
  93. data/app/serializers/spree/api/v3/admin/taxonomy_serializer.rb +0 -15
  94. data/app/serializers/spree/api/v3/store_serializer.rb +0 -38
  95. data/app/serializers/spree/api/v3/taxon_serializer.rb +0 -78
  96. data/app/serializers/spree/api/v3/taxonomy_serializer.rb +0 -33
  97. data/app/services/spree/api/v3/orders/update.rb +0 -105
@@ -11,34 +11,75 @@ 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
+ user_id: [:string, nullable: true],
14
15
  canceled_at: [:string, nullable: true], approved_at: [:string, nullable: true],
16
+ payment_total: :string, display_payment_total: :string,
15
17
  metadata: 'Record<string, unknown> | null'
16
18
 
17
19
  # Admin-only attributes
18
20
  attributes :channel, :last_ip_address, :considered_risky,
19
21
  :confirmation_delivered, :store_owner_notification_delivered,
20
- :internal_note, :approver_id,
22
+ :internal_note, :payment_total, :display_payment_total,
21
23
  canceled_at: :iso8601, approved_at: :iso8601
22
24
 
23
25
  attribute :metadata do |order|
24
26
  order.metadata.presence
25
27
  end
26
28
 
29
+ attribute :approver_id do |order|
30
+ order.approver&.prefixed_id
31
+ end
32
+
27
33
  attribute :canceler_id do |order|
28
- order.canceler_id
34
+ order.canceler&.prefixed_id
29
35
  end
30
36
 
31
37
  attribute :created_by_id do |order|
32
- order.created_by_id
38
+ order.created_by&.prefixed_id
39
+ end
40
+
41
+ attribute :user_id do |order|
42
+ order.user&.prefixed_id
33
43
  end
34
44
 
35
- many :line_items, resource: Spree.api.admin_line_item_serializer
45
+ # Override inherited associations to use admin serializers
46
+ many :order_promotions, resource: Spree.api.admin_order_promotion_serializer, if: proc { expand?('order_promotions') }
47
+ many :line_items, resource: Spree.api.admin_line_item_serializer, if: proc { expand?('line_items') }
48
+ many :shipments, resource: Spree.api.admin_shipment_serializer, if: proc { expand?('shipments') }
49
+ many :payments, resource: Spree.api.admin_payment_serializer, if: proc { expand?('payments') }
50
+
51
+ one :bill_address, resource: Spree.api.admin_address_serializer, if: proc { expand?('bill_address') }
52
+ one :ship_address, resource: Spree.api.admin_address_serializer, if: proc { expand?('ship_address') }
53
+
54
+ many :payment_methods, resource: Spree.api.admin_payment_method_serializer, if: proc { expand?('payment_methods') }
36
55
 
37
56
  one :user,
38
57
  resource: Spree.api.admin_customer_serializer,
39
- if: proc { params[:expand]&.include?('user') }
58
+ if: proc { expand?('user') }
59
+
60
+ one :approver,
61
+ resource: Spree.api.admin_customer_serializer,
62
+ if: proc { expand?('approver') }
63
+
64
+ one :canceler,
65
+ resource: Spree.api.admin_customer_serializer,
66
+ if: proc { expand?('canceler') }
67
+
68
+ one :created_by,
69
+ resource: Spree.api.admin_customer_serializer,
70
+ if: proc { expand?('created_by') }
71
+
72
+ many :adjustments,
73
+ resource: Spree.api.admin_adjustment_serializer,
74
+ if: proc { expand?('adjustments') }
75
+
76
+ many :return_authorizations,
77
+ resource: Spree.api.admin_return_authorization_serializer,
78
+ if: proc { expand?('return_authorizations') }
40
79
 
41
- # TODO: Add adjustments associations when Admin API is implemented
80
+ many :reimbursements,
81
+ resource: Spree.api.admin_reimbursement_serializer,
82
+ if: proc { expand?('reimbursements') }
42
83
  end
43
84
  end
44
85
  end
@@ -0,0 +1,14 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class PaymentMethodSerializer < V3::PaymentMethodSerializer
6
+ typelize active: :boolean, auto_capture: [:boolean, nullable: true]
7
+
8
+ attributes :active, :auto_capture,
9
+ created_at: :iso8601, updated_at: :iso8601
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,56 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class PaymentSerializer < V3::PaymentSerializer
6
+ typelize metadata: 'Record<string, unknown> | null',
7
+ captured_amount: :string,
8
+ order_id: [:string, nullable: true],
9
+ avs_response: [:string, nullable: true],
10
+ cvv_response_code: [:string, nullable: true],
11
+ cvv_response_message: [:string, nullable: true]
12
+
13
+ attributes :avs_response, :cvv_response_code, :cvv_response_message
14
+
15
+ attribute :metadata do |payment|
16
+ payment.metadata.presence
17
+ end
18
+
19
+ attribute :captured_amount do |payment|
20
+ payment.captured_amount.to_s
21
+ end
22
+
23
+ attribute :order_id do |payment|
24
+ payment.order&.prefixed_id
25
+ end
26
+
27
+ # Override inherited associations to use admin serializers
28
+ one :payment_method, resource: Spree.api.admin_payment_method_serializer, if: proc { expand?('payment_method') }
29
+
30
+ attribute :source do |payment|
31
+ next nil if payment.source.blank?
32
+
33
+ serializer = case payment.source_type
34
+ when 'Spree::CreditCard'
35
+ Spree.api.admin_credit_card_serializer
36
+ when 'Spree::StoreCredit'
37
+ Spree.api.admin_store_credit_serializer
38
+ else
39
+ Spree.api.admin_payment_source_serializer
40
+ end
41
+
42
+ serializer.new(payment.source).to_h
43
+ end
44
+
45
+ one :order,
46
+ resource: Spree.api.admin_order_serializer,
47
+ if: proc { expand?('order') }
48
+
49
+ many :refunds,
50
+ resource: Spree.api.admin_refund_serializer,
51
+ if: proc { expand?('refunds') }
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,10 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class PaymentSourceSerializer < V3::PaymentSourceSerializer
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -9,14 +9,14 @@ module Spree
9
9
 
10
10
  # Additional type hints for admin-only computed attributes
11
11
  typelize status: :string, make_active_at: [:string, nullable: true], discontinue_on: [:string, nullable: true],
12
- cost_price: [:number, nullable: true], cost_currency: [:string, nullable: true],
12
+ cost_price: [:string, nullable: true], cost_currency: [:string, nullable: true],
13
13
  deleted_at: [:string, nullable: true]
14
14
 
15
15
  # Admin-only attributes
16
16
  attributes :status, :make_active_at, :discontinue_on, deleted_at: :iso8601
17
17
 
18
18
  attribute :cost_price do |product|
19
- product.master&.cost_price&.to_f
19
+ product.master&.cost_price
20
20
  end
21
21
 
22
22
  attribute :cost_currency do |product|
@@ -26,20 +26,37 @@ module Spree
26
26
  # Admin uses admin variant serializer
27
27
  many :variants,
28
28
  resource: Spree.api.admin_variant_serializer,
29
- if: proc { params[:expand]&.include?('variants') }
29
+ if: proc { expand?('variants') }
30
30
 
31
31
  one :default_variant,
32
32
  resource: Spree.api.admin_variant_serializer,
33
- if: proc { params[:expand]&.include?('default_variant') }
33
+ if: proc { expand?('default_variant') }
34
34
 
35
35
  one :master,
36
36
  key: :master_variant,
37
37
  resource: Spree.api.admin_variant_serializer,
38
- if: proc { params[:expand]&.include?('master_variant') }
38
+ if: proc { expand?('master_variant') }
39
+
40
+ many :variant_images,
41
+ key: :images,
42
+ resource: Spree.api.admin_image_serializer,
43
+ if: proc { expand?('images') }
44
+
45
+ many :option_types,
46
+ resource: Spree.api.admin_option_type_serializer,
47
+ if: proc { expand?('option_types') }
48
+
49
+ many :taxons,
50
+ proc { |taxons, params|
51
+ taxons.select { |t| t.taxonomy.store_id == params[:store].id }
52
+ },
53
+ key: :categories,
54
+ resource: Spree.api.admin_category_serializer,
55
+ if: proc { expand?('categories') }
39
56
 
40
57
  many :metafields,
41
58
  resource: Spree.api.admin_metafield_serializer,
42
- if: proc { params[:expand]&.include?('metafields') }
59
+ if: proc { expand?('metafields') }
43
60
  end
44
61
  end
45
62
  end
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class RefundSerializer < V3::RefundSerializer
6
+ typelize payment_id: [:string, nullable: true],
7
+ refund_reason_id: [:string, nullable: true],
8
+ reimbursement_id: [:string, nullable: true]
9
+
10
+ one :payment,
11
+ resource: Spree.api.admin_payment_serializer,
12
+ if: proc { expand?('payment') }
13
+
14
+ one :reimbursement,
15
+ resource: Spree.api.admin_reimbursement_serializer,
16
+ if: proc { expand?('reimbursement') }
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class ReimbursementSerializer < V3::ReimbursementSerializer
6
+ one :order,
7
+ resource: Spree.api.admin_order_serializer,
8
+ if: proc { expand?('order') }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class ReturnAuthorizationSerializer < V3::ReturnAuthorizationSerializer
6
+ one :order,
7
+ resource: Spree.api.admin_order_serializer,
8
+ if: proc { expand?('order') }
9
+
10
+ one :stock_location,
11
+ resource: Spree.api.admin_stock_location_serializer,
12
+ if: proc { expand?('stock_location') }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,44 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class ShipmentSerializer < V3::ShipmentSerializer
6
+ typelize metadata: 'Record<string, unknown> | null',
7
+ order_id: [:string, nullable: true],
8
+ stock_location_id: [:string, nullable: true],
9
+ adjustment_total: :string, additional_tax_total: :string,
10
+ included_tax_total: :string, promo_total: :string,
11
+ pre_tax_amount: :string
12
+
13
+ attributes :adjustment_total, :additional_tax_total,
14
+ :included_tax_total, :promo_total, :pre_tax_amount
15
+
16
+ attribute :metadata do |shipment|
17
+ shipment.metadata.presence
18
+ end
19
+
20
+ attribute :order_id do |shipment|
21
+ shipment.order&.prefixed_id
22
+ end
23
+
24
+ attribute :stock_location_id do |shipment|
25
+ shipment.stock_location&.prefixed_id
26
+ end
27
+
28
+ # Override inherited associations to use admin serializers
29
+ one :shipping_method, resource: Spree.api.admin_shipping_method_serializer, if: proc { expand?('shipping_method') }
30
+ one :stock_location, resource: Spree.api.admin_stock_location_serializer, if: proc { expand?('stock_location') }
31
+ many :shipping_rates, resource: Spree.api.admin_shipping_rate_serializer, if: proc { expand?('shipping_rates') }
32
+
33
+ one :order,
34
+ resource: Spree.api.admin_order_serializer,
35
+ if: proc { expand?('order') }
36
+
37
+ many :adjustments,
38
+ resource: Spree.api.admin_adjustment_serializer,
39
+ if: proc { expand?('adjustments') }
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,14 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class ShippingCategorySerializer < V3::BaseSerializer
6
+ typelize name: :string
7
+
8
+ attributes :name,
9
+ created_at: :iso8601, updated_at: :iso8601
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class ShippingMethodSerializer < V3::ShippingMethodSerializer
6
+ attributes created_at: :iso8601, updated_at: :iso8601
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class ShippingRateSerializer < V3::ShippingRateSerializer
6
+ one :shipping_method, resource: Spree.api.admin_shipping_method_serializer, if: proc { expand?('shipping_method') }
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class StockItemSerializer < V3::StockItemSerializer
6
+ one :stock_location,
7
+ resource: Spree.api.admin_stock_location_serializer,
8
+ if: proc { expand?('stock_location') }
9
+
10
+ one :variant,
11
+ resource: Spree.api.admin_variant_serializer,
12
+ if: proc { expand?('variant') }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class StockLocationSerializer < V3::StockLocationSerializer
6
+ typelize active: :boolean, default: :boolean, backorderable_default: :boolean,
7
+ propagate_all_variants: :boolean
8
+
9
+ attributes :active, :default, :backorderable_default, :propagate_all_variants,
10
+ created_at: :iso8601, updated_at: :iso8601
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class StoreCreditSerializer < V3::StoreCreditSerializer
6
+ typelize user_id: [:string, nullable: true],
7
+ created_by_id: [:string, nullable: true],
8
+ metadata: 'Record<string, unknown> | null'
9
+
10
+ attribute :user_id do |store_credit|
11
+ store_credit.user&.prefixed_id
12
+ end
13
+
14
+ attribute :created_by_id do |store_credit|
15
+ store_credit.created_by&.prefixed_id
16
+ end
17
+
18
+ attribute :metadata do |store_credit|
19
+ store_credit.metadata.presence
20
+ end
21
+
22
+ attributes created_at: :iso8601, updated_at: :iso8601
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Admin
5
+ class TaxCategorySerializer < V3::BaseSerializer
6
+ typelize name: :string, tax_code: [:string, nullable: true],
7
+ is_default: :boolean
8
+
9
+ attributes :name, :tax_code, :is_default,
10
+ created_at: :iso8601, updated_at: :iso8601
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -8,35 +8,32 @@ module Spree
8
8
 
9
9
  # Additional type hints for admin-only attributes
10
10
  typelize position: :number, tax_category_id: [:string, nullable: true],
11
- cost_price: [:number, nullable: true], cost_currency: [:string, nullable: true],
11
+ cost_price: [:string, nullable: true], cost_currency: [:string, nullable: true],
12
12
  total_on_hand: [:number, nullable: true],
13
13
  deleted_at: [:string, nullable: true]
14
14
 
15
15
  # Admin-only attributes
16
- attributes :position, :tax_category_id, deleted_at: :iso8601
17
-
18
- attribute :cost_price do |variant|
19
- variant.cost_price&.to_f
20
- end
21
-
22
- attribute :cost_currency do |variant|
23
- variant.cost_currency
24
- end
16
+ attributes :position, :tax_category_id, :cost_price, :cost_currency, deleted_at: :iso8601
25
17
 
26
18
  attribute :total_on_hand do |variant|
27
19
  variant.total_on_hand
28
20
  end
29
21
 
22
+ # Override inherited associations to use admin serializers
23
+ many :images,
24
+ resource: Spree.api.admin_image_serializer,
25
+ if: proc { expand?('images') }
26
+
27
+ many :option_values, resource: Spree.api.admin_option_value_serializer
28
+
30
29
  # All prices for this variant (for admin management)
31
30
  many :prices,
32
31
  resource: Spree.api.admin_price_serializer,
33
- if: proc { params[:expand]&.include?('prices') }
32
+ if: proc { expand?('prices') }
34
33
 
35
34
  many :metafields,
36
35
  resource: Spree.api.admin_metafield_serializer,
37
- if: proc { params[:expand]&.include?('metafields') }
38
-
39
- # TODO: Add stock_items association when Admin API is implemented
36
+ if: proc { expand?('metafields') }
40
37
  end
41
38
  end
42
39
  end
@@ -38,8 +38,10 @@ 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.images'
41
42
  def expand?(name)
42
- expands.include?(name.to_s)
43
+ name = name.to_s
44
+ expands.any? { |e| e == name || e.start_with?("#{name}.") }
43
45
  end
44
46
 
45
47
  # Get nested expands for a given parent
@@ -48,9 +50,24 @@ module Spree
48
50
  expands.select { |i| i.start_with?(prefix) }.map { |i| i.sub(prefix, '') }
49
51
  end
50
52
 
51
- # Build nested params for child serializers
52
- def nested_params(parent = nil)
53
- params.merge(expand: parent ? nested_expands_for(parent) : [])
53
+ # Build nested params for child serializers with depth limit (max 4 levels)
54
+ def nested_params(parent)
55
+ depth = params.fetch(:_expand_depth, 0)
56
+ nested = depth < 4 ? nested_expands_for(parent) : []
57
+ params.merge(expand: nested, _expand_depth: depth + 1)
58
+ end
59
+
60
+ private
61
+
62
+ # Override Alba's fetch_attribute to automatically inject nested expand params
63
+ # into child serializers via nested_params
64
+ def fetch_attribute(obj, key, attribute)
65
+ if attribute.is_a?(Alba::Association)
66
+ nested = nested_params(attribute.name)
67
+ yield_if_within(attribute.name.to_sym) { |within| attribute.to_h(obj, params: nested, within: within) }
68
+ else
69
+ super
70
+ end
54
71
  end
55
72
 
56
73
  # Returns price for a variant using full Price List resolution
@@ -0,0 +1,71 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ class CategorySerializer < BaseSerializer
5
+ typelize name: :string, permalink: :string, position: :number, depth: :number,
6
+ meta_title: [:string, nullable: true], meta_description: [:string, nullable: true], meta_keywords: [:string, nullable: true],
7
+ parent_id: [:string, nullable: true], children_count: :number,
8
+ description: :string, description_html: :string,
9
+ image_url: [:string, nullable: true], square_image_url: [:string, nullable: true],
10
+ is_root: :boolean, is_child: :boolean, is_leaf: :boolean
11
+
12
+ attributes :name, :permalink, :position, :depth,
13
+ :meta_title, :meta_description, :meta_keywords,
14
+ :children_count,
15
+ created_at: :iso8601, updated_at: :iso8601
16
+
17
+ attribute :parent_id do |category|
18
+ category.parent&.prefixed_id
19
+ end
20
+
21
+ attribute :description do |category|
22
+ category.description&.to_plain_text.to_s
23
+ end
24
+
25
+ attribute :description_html do |category|
26
+ category.description&.body&.to_s.to_s
27
+ end
28
+
29
+ attribute :image_url do |category|
30
+ image_url_for(category.image)
31
+ end
32
+
33
+ attribute :square_image_url do |category|
34
+ image_url_for(category.square_image)
35
+ end
36
+
37
+ attribute :is_root do |category|
38
+ category.root?
39
+ end
40
+
41
+ attribute :is_child do |category|
42
+ category.child?
43
+ end
44
+
45
+ attribute :is_leaf do |category|
46
+ category.leaf?
47
+ end
48
+
49
+ # Conditional associations
50
+ # Note: We pass empty expand to nested categories to prevent infinite recursion
51
+ # (e.g., ancestors trying to load their own ancestors)
52
+ one :parent,
53
+ resource: Spree.api.category_serializer,
54
+ if: proc { expand?('parent') }
55
+
56
+ many :children,
57
+ resource: Spree.api.category_serializer,
58
+ if: proc { expand?('children') }
59
+
60
+ many :ancestors,
61
+ resource: Spree.api.category_serializer,
62
+ if: proc { expand?('ancestors') }
63
+
64
+ many :public_metafields,
65
+ key: :metafields,
66
+ resource: Spree.api.metafield_serializer,
67
+ if: proc { expand?('metafields') }
68
+ end
69
+ end
70
+ end
71
+ end
@@ -6,7 +6,8 @@ module Spree
6
6
  include Typelizer::DSL
7
7
 
8
8
  typelize iso: :string, iso3: :string, name: :string,
9
- states_required: :boolean, zipcode_required: :boolean
9
+ states_required: :boolean, zipcode_required: :boolean,
10
+ market: [:Market, nullable: true]
10
11
 
11
12
  attributes :iso, :iso3, :name, :states_required, :zipcode_required
12
13
 
@@ -5,9 +5,10 @@ module Spree
5
5
  # Customer-facing user data
6
6
  class CustomerSerializer < BaseSerializer
7
7
  typelize email: :string, first_name: [:string, nullable: true], last_name: [:string, nullable: true],
8
+ phone: [:string, nullable: true], accepts_email_marketing: :boolean,
8
9
  default_billing_address: { nullable: true }, default_shipping_address: { nullable: true }
9
10
 
10
- attributes :email, :first_name, :last_name,
11
+ attributes :email, :first_name, :last_name, :phone, :accepts_email_marketing,
11
12
  created_at: :iso8601, updated_at: :iso8601
12
13
 
13
14
  many :addresses, resource: Spree.api.address_serializer
@@ -4,10 +4,10 @@ module Spree
4
4
  class GiftCardSerializer < BaseSerializer
5
5
  typelize code: :string,
6
6
  state: :string,
7
- amount: :number,
8
- amount_used: :number,
9
- amount_authorized: :number,
10
- amount_remaining: :number,
7
+ amount: :string,
8
+ amount_used: :string,
9
+ amount_authorized: :string,
10
+ amount_remaining: :string,
11
11
  display_amount: :string,
12
12
  display_amount_used: :string,
13
13
  display_amount_remaining: :string,
@@ -25,23 +25,7 @@ module Spree
25
25
  gift_card.display_state
26
26
  end
27
27
 
28
- attributes :currency
29
-
30
- attribute :amount do |gift_card|
31
- gift_card.amount.to_f
32
- end
33
-
34
- attribute :amount_used do |gift_card|
35
- gift_card.amount_used.to_f
36
- end
37
-
38
- attribute :amount_authorized do |gift_card|
39
- gift_card.amount_authorized.to_f
40
- end
41
-
42
- attribute :amount_remaining do |gift_card|
43
- gift_card.amount_remaining.to_f
44
- end
28
+ attributes :currency, :amount, :amount_used, :amount_authorized, :amount_remaining
45
29
 
46
30
  attribute :display_amount do |gift_card|
47
31
  gift_card.display_amount.to_s