spree_api 6.0.0.beta4 → 6.0.0.rc2

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 (531) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -48
  3. data/app/controllers/concerns/spree/api/v3/admin/email_template_lookup.rb +139 -0
  4. data/app/controllers/concerns/spree/api/v3/admin/product_membership.rb +10 -0
  5. data/app/controllers/concerns/spree/api/v3/admin/stock_receipt_actions.rb +26 -4
  6. data/app/controllers/concerns/spree/api/v3/admin/store_context.rb +1 -1
  7. data/app/controllers/concerns/spree/api/v3/admin/subclassed_resource.rb +15 -29
  8. data/app/controllers/concerns/spree/api/v3/admin/validation_details.rb +1 -1
  9. data/app/controllers/concerns/spree/api/v3/cart_resolvable.rb +10 -2
  10. data/app/controllers/concerns/spree/api/v3/channel_resolution.rb +3 -3
  11. data/app/controllers/concerns/spree/api/v3/company_address_writes.rb +3 -1
  12. data/app/controllers/concerns/spree/api/v3/current_password_confirmation.rb +1 -1
  13. data/app/controllers/concerns/spree/api/v3/error_handler.rb +55 -4
  14. data/app/controllers/concerns/spree/api/v3/file_uploads.rb +35 -0
  15. data/app/controllers/concerns/spree/api/v3/http_caching.rb +44 -11
  16. data/app/controllers/concerns/spree/api/v3/idempotent.rb +20 -5
  17. data/app/controllers/concerns/spree/api/v3/items_payload.rb +1 -1
  18. data/app/controllers/concerns/spree/api/v3/money_params.rb +52 -0
  19. data/app/controllers/concerns/spree/api/v3/order_lock.rb +2 -2
  20. data/app/controllers/concerns/spree/api/v3/orders/claim_actions.rb +1 -5
  21. data/app/controllers/concerns/spree/api/v3/orders/delivery_actions.rb +7 -11
  22. data/app/controllers/concerns/spree/api/v3/orders/exchange_actions.rb +1 -4
  23. data/app/controllers/concerns/spree/api/v3/orders/fulfillment_actions.rb +3 -15
  24. data/app/controllers/concerns/spree/api/v3/orders/post_sale_actions.rb +2 -10
  25. data/app/controllers/concerns/spree/api/v3/orders/return_actions.rb +1 -4
  26. data/app/controllers/concerns/spree/api/v3/orders/shipping_label_actions.rb +8 -28
  27. data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +5 -0
  28. data/app/controllers/concerns/spree/api/v3/permission_serialization.rb +9 -1
  29. data/app/controllers/concerns/spree/api/v3/purchase_serialization.rb +26 -0
  30. data/app/controllers/concerns/spree/api/v3/request_params.rb +65 -0
  31. data/app/controllers/concerns/spree/api/v3/seller/seller_context.rb +1 -1
  32. data/app/controllers/concerns/spree/api/v3/store/storefront_products.rb +5 -4
  33. data/app/controllers/concerns/spree/api/v3/storefront_gating.rb +11 -5
  34. data/app/controllers/concerns/spree/api/v3/strict_money_params.rb +94 -0
  35. data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +8 -4
  36. data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +8 -1
  37. data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +16 -8
  38. data/app/controllers/spree/api/v3/admin/base_controller.rb +1 -0
  39. data/app/controllers/spree/api/v3/admin/catalogs/order_minimums_controller.rb +2 -6
  40. data/app/controllers/spree/api/v3/admin/catalogs/quantity_rules_controller.rb +7 -9
  41. data/app/controllers/spree/api/v3/admin/catalogs_controller.rb +61 -34
  42. data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +4 -1
  43. data/app/controllers/spree/api/v3/admin/categories_controller.rb +40 -20
  44. data/app/controllers/spree/api/v3/admin/channels_controller.rb +39 -10
  45. data/app/controllers/spree/api/v3/admin/claim_reasons_controller.rb +5 -1
  46. data/app/controllers/spree/api/v3/admin/collections/products_controller.rb +5 -3
  47. data/app/controllers/spree/api/v3/admin/collections_controller.rb +44 -15
  48. data/app/controllers/spree/api/v3/admin/commission_rates_controller.rb +62 -14
  49. data/app/controllers/spree/api/v3/admin/companies/addresses_controller.rb +11 -4
  50. data/app/controllers/spree/api/v3/admin/companies/invitations_controller.rb +1 -5
  51. data/app/controllers/spree/api/v3/admin/companies/memberships_controller.rb +9 -5
  52. data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +20 -27
  53. data/app/controllers/spree/api/v3/admin/companies/tax_identifiers_controller.rb +6 -5
  54. data/app/controllers/spree/api/v3/admin/companies_controller.rb +17 -7
  55. data/app/controllers/spree/api/v3/admin/countries_controller.rb +6 -2
  56. data/app/controllers/spree/api/v3/admin/coupon_codes_controller.rb +0 -4
  57. data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +22 -4
  58. data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +12 -9
  59. data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +9 -5
  60. data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +12 -11
  61. data/app/controllers/spree/api/v3/admin/customers/credit_cards_controller.rb +0 -4
  62. data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +11 -13
  63. data/app/controllers/spree/api/v3/admin/customers/tax_identifiers_controller.rb +6 -1
  64. data/app/controllers/spree/api/v3/admin/customers_controller.rb +37 -9
  65. data/app/controllers/spree/api/v3/admin/data_requests_controller.rb +8 -0
  66. data/app/controllers/spree/api/v3/admin/delivery_method_rules_controller.rb +1 -1
  67. data/app/controllers/spree/api/v3/admin/delivery_methods/rules_controller.rb +16 -8
  68. data/app/controllers/spree/api/v3/admin/delivery_methods_controller.rb +95 -62
  69. data/app/controllers/spree/api/v3/admin/delivery_profiles/origin_groups_controller.rb +8 -1
  70. data/app/controllers/spree/api/v3/admin/delivery_profiles_controller.rb +14 -7
  71. data/app/controllers/spree/api/v3/admin/delivery_zones_controller.rb +21 -5
  72. data/app/controllers/spree/api/v3/admin/email_templates/drafts_controller.rb +53 -0
  73. data/app/controllers/spree/api/v3/admin/email_templates/previews_controller.rb +34 -0
  74. data/app/controllers/spree/api/v3/admin/email_templates/publications_controller.rb +37 -0
  75. data/app/controllers/spree/api/v3/admin/email_templates/restorations_controller.rb +42 -0
  76. data/app/controllers/spree/api/v3/admin/email_templates/revisions_controller.rb +35 -0
  77. data/app/controllers/spree/api/v3/admin/email_templates/sample_records_controller.rb +33 -0
  78. data/app/controllers/spree/api/v3/admin/email_templates/test_emails_controller.rb +44 -0
  79. data/app/controllers/spree/api/v3/admin/email_templates_controller.rb +46 -0
  80. data/app/controllers/spree/api/v3/admin/exports_controller.rb +23 -6
  81. data/app/controllers/spree/api/v3/admin/files_controller.rb +29 -0
  82. data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +20 -1
  83. data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +19 -1
  84. data/app/controllers/spree/api/v3/admin/imports_controller.rb +37 -11
  85. data/app/controllers/spree/api/v3/admin/integrations_controller.rb +13 -1
  86. data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +9 -2
  87. data/app/controllers/spree/api/v3/admin/invitations_controller.rb +8 -8
  88. data/app/controllers/spree/api/v3/admin/locales_controller.rb +1 -1
  89. data/app/controllers/spree/api/v3/admin/markets_controller.rb +30 -9
  90. data/app/controllers/spree/api/v3/admin/me_controller.rb +13 -4
  91. data/app/controllers/spree/api/v3/admin/media_controller.rb +22 -9
  92. data/app/controllers/spree/api/v3/admin/media_library_controller.rb +9 -5
  93. data/app/controllers/spree/api/v3/admin/option_types_controller.rb +24 -7
  94. data/app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb +5 -1
  95. data/app/controllers/spree/api/v3/admin/order_routing_rules_controller.rb +13 -5
  96. data/app/controllers/spree/api/v3/admin/orders/claims_controller.rb +39 -1
  97. data/app/controllers/spree/api/v3/admin/orders/deliveries_controller.rb +20 -6
  98. data/app/controllers/spree/api/v3/admin/orders/discount_codes_controller.rb +6 -2
  99. data/app/controllers/spree/api/v3/admin/orders/discounts_controller.rb +30 -6
  100. data/app/controllers/spree/api/v3/admin/orders/exchanges_controller.rb +36 -1
  101. data/app/controllers/spree/api/v3/admin/orders/fees_controller.rb +22 -1
  102. data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +83 -22
  103. data/app/controllers/spree/api/v3/admin/orders/gift_cards_controller.rb +9 -5
  104. data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +11 -1
  105. data/app/controllers/spree/api/v3/admin/orders/labels_controller.rb +37 -12
  106. data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +18 -19
  107. data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +7 -5
  108. data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +37 -1
  109. data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +6 -3
  110. data/app/controllers/spree/api/v3/admin/orders_controller.rb +76 -62
  111. data/app/controllers/spree/api/v3/admin/package_types_controller.rb +30 -5
  112. data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +26 -7
  113. data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +38 -22
  114. data/app/controllers/spree/api/v3/admin/policies_controller.rb +8 -4
  115. data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +32 -67
  116. data/app/controllers/spree/api/v3/admin/prices_controller.rb +51 -8
  117. data/app/controllers/spree/api/v3/admin/product_types_controller.rb +25 -8
  118. data/app/controllers/spree/api/v3/admin/products/digital_assets_controller.rb +29 -16
  119. data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +9 -18
  120. data/app/controllers/spree/api/v3/admin/products_controller.rb +122 -71
  121. data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +11 -6
  122. data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +10 -5
  123. data/app/controllers/spree/api/v3/admin/promotions_controller.rb +50 -14
  124. data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +55 -8
  125. data/app/controllers/spree/api/v3/admin/refund_reasons_controller.rb +5 -1
  126. data/app/controllers/spree/api/v3/admin/reporting/saved_reports_controller.rb +9 -1
  127. data/app/controllers/spree/api/v3/admin/reporting_controller.rb +34 -0
  128. data/app/controllers/spree/api/v3/admin/resource_controller.rb +2 -1
  129. data/app/controllers/spree/api/v3/admin/return_reasons_controller.rb +5 -1
  130. data/app/controllers/spree/api/v3/admin/roles_controller.rb +13 -1
  131. data/app/controllers/spree/api/v3/admin/seller_payouts_controller.rb +7 -9
  132. data/app/controllers/spree/api/v3/admin/seller_requirement_submissions_controller.rb +17 -10
  133. data/app/controllers/spree/api/v3/admin/seller_requirements_controller.rb +32 -6
  134. data/app/controllers/spree/api/v3/admin/seller_transfers_controller.rb +0 -4
  135. data/app/controllers/spree/api/v3/admin/sellers/invitations_controller.rb +1 -1
  136. data/app/controllers/spree/api/v3/admin/sellers/payouts_controller.rb +1 -1
  137. data/app/controllers/spree/api/v3/admin/sellers_controller.rb +77 -32
  138. data/app/controllers/spree/api/v3/admin/setup_controller.rb +54 -23
  139. data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +38 -9
  140. data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +41 -9
  141. data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +49 -8
  142. data/app/controllers/spree/api/v3/admin/store_controller.rb +122 -48
  143. data/app/controllers/spree/api/v3/admin/store_credits_controller.rb +1 -7
  144. data/app/controllers/spree/api/v3/admin/suppliers_controller.rb +16 -6
  145. data/app/controllers/spree/api/v3/admin/tags_controller.rb +8 -5
  146. data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +7 -4
  147. data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +21 -3
  148. data/app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb +4 -0
  149. data/app/controllers/spree/api/v3/admin/translations/batches_controller.rb +17 -9
  150. data/app/controllers/spree/api/v3/admin/translations_controller.rb +4 -0
  151. data/app/controllers/spree/api/v3/admin/translations_coverage_controller.rb +5 -0
  152. data/app/controllers/spree/api/v3/admin/updates_controller.rb +39 -0
  153. data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +40 -13
  154. data/app/controllers/spree/api/v3/admin/webhook_events_controller.rb +25 -0
  155. data/app/controllers/spree/api/v3/base_controller.rb +12 -0
  156. data/app/controllers/spree/api/v3/resource_controller.rb +99 -3
  157. data/app/controllers/spree/api/v3/seller/auth_controller.rb +10 -2
  158. data/app/controllers/spree/api/v3/seller/base_controller.rb +1 -0
  159. data/app/controllers/spree/api/v3/seller/countries_controller.rb +3 -3
  160. data/app/controllers/spree/api/v3/seller/delivery_methods_controller.rb +49 -60
  161. data/app/controllers/spree/api/v3/seller/exports_controller.rb +21 -4
  162. data/app/controllers/spree/api/v3/seller/files_controller.rb +27 -0
  163. data/app/controllers/spree/api/v3/seller/imports_controller.rb +25 -9
  164. data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +12 -4
  165. data/app/controllers/spree/api/v3/seller/invitations_controller.rb +1 -1
  166. data/app/controllers/spree/api/v3/seller/me_controller.rb +15 -4
  167. data/app/controllers/spree/api/v3/seller/onboarding_controller.rb +11 -0
  168. data/app/controllers/spree/api/v3/seller/orders/claims_controller.rb +35 -0
  169. data/app/controllers/spree/api/v3/seller/orders/deliveries_controller.rb +12 -0
  170. data/app/controllers/spree/api/v3/seller/orders/exchanges_controller.rb +33 -0
  171. data/app/controllers/spree/api/v3/seller/orders/fulfillments_controller.rb +28 -2
  172. data/app/controllers/spree/api/v3/seller/orders/labels_controller.rb +23 -2
  173. data/app/controllers/spree/api/v3/seller/orders/notes_controller.rb +8 -1
  174. data/app/controllers/spree/api/v3/seller/orders/returns_controller.rb +32 -0
  175. data/app/controllers/spree/api/v3/seller/orders_controller.rb +35 -14
  176. data/app/controllers/spree/api/v3/seller/package_types_controller.rb +21 -9
  177. data/app/controllers/spree/api/v3/seller/password_resets_controller.rb +20 -11
  178. data/app/controllers/spree/api/v3/seller/policies_controller.rb +12 -4
  179. data/app/controllers/spree/api/v3/seller/products_controller.rb +115 -28
  180. data/app/controllers/spree/api/v3/seller/profile_controller.rb +33 -10
  181. data/app/controllers/spree/api/v3/seller/requirement_submissions_controller.rb +13 -6
  182. data/app/controllers/spree/api/v3/seller/resource_controller.rb +12 -0
  183. data/app/controllers/spree/api/v3/seller/stock_locations_controller.rb +44 -13
  184. data/app/controllers/spree/api/v3/seller/tax_identifiers_controller.rb +10 -1
  185. data/app/controllers/spree/api/v3/seller/team_controller.rb +5 -1
  186. data/app/controllers/spree/api/v3/store/auth_controller.rb +10 -0
  187. data/app/controllers/spree/api/v3/store/carts/discount_codes_controller.rb +9 -2
  188. data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +11 -11
  189. data/app/controllers/spree/api/v3/store/carts/gift_cards_controller.rb +13 -4
  190. data/app/controllers/spree/api/v3/store/carts/items_controller.rb +23 -7
  191. data/app/controllers/spree/api/v3/store/carts/payment_sessions_controller.rb +21 -7
  192. data/app/controllers/spree/api/v3/store/carts/payments_controller.rb +16 -3
  193. data/app/controllers/spree/api/v3/store/carts/po_documents_controller.rb +26 -28
  194. data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +9 -1
  195. data/app/controllers/spree/api/v3/store/carts/tax_identifiers_controller.rb +5 -1
  196. data/app/controllers/spree/api/v3/store/carts_controller.rb +64 -52
  197. data/app/controllers/spree/api/v3/store/companies/addresses_controller.rb +12 -8
  198. data/app/controllers/spree/api/v3/store/companies/invitations_controller.rb +1 -5
  199. data/app/controllers/spree/api/v3/store/companies/members_controller.rb +4 -0
  200. data/app/controllers/spree/api/v3/store/companies_controller.rb +5 -1
  201. data/app/controllers/spree/api/v3/store/company_invitations_controller.rb +10 -2
  202. data/app/controllers/spree/api/v3/store/customer/addresses_controller.rb +8 -11
  203. data/app/controllers/spree/api/v3/store/customer/credit_cards_controller.rb +0 -4
  204. data/app/controllers/spree/api/v3/store/customer/data_requests_controller.rb +5 -5
  205. data/app/controllers/spree/api/v3/store/customer/digital_links_controller.rb +0 -4
  206. data/app/controllers/spree/api/v3/store/customer/gift_cards_controller.rb +0 -4
  207. data/app/controllers/spree/api/v3/store/customer/orders_controller.rb +0 -4
  208. data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +25 -6
  209. data/app/controllers/spree/api/v3/store/customer/payment_setup_sessions_controller.rb +10 -9
  210. data/app/controllers/spree/api/v3/store/customer/store_credits_controller.rb +0 -5
  211. data/app/controllers/spree/api/v3/store/customer/tax_identifiers_controller.rb +5 -1
  212. data/app/controllers/spree/api/v3/store/customers_controller.rb +28 -2
  213. data/app/controllers/spree/api/v3/store/data_request_downloads_controller.rb +1 -1
  214. data/app/controllers/spree/api/v3/store/delivery_methods_controller.rb +1 -1
  215. data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +27 -14
  216. data/app/controllers/spree/api/v3/store/orders/claims_controller.rb +12 -7
  217. data/app/controllers/spree/api/v3/store/orders/returns_controller.rb +11 -6
  218. data/app/controllers/spree/api/v3/store/orders_controller.rb +47 -10
  219. data/app/controllers/spree/api/v3/store/products_controller.rb +8 -0
  220. data/app/controllers/spree/api/v3/store/wishlist_items_controller.rb +10 -8
  221. data/app/controllers/spree/api/v3/store/wishlists_controller.rb +12 -4
  222. data/app/request_schemas/spree/api/v3/address_request_schema.rb +27 -0
  223. data/app/request_schemas/spree/api/v3/admin/address_request_schema.rb +13 -0
  224. data/app/request_schemas/spree/api/v3/admin/bulk_tags_request_schema.rb +17 -0
  225. data/app/request_schemas/spree/api/v3/admin/catalog_order_minimum_request_schema.rb +17 -0
  226. data/app/request_schemas/spree/api/v3/admin/email_template_language_request_schema.rb +17 -0
  227. data/app/request_schemas/spree/api/v3/admin/email_template_preview_request_schema.rb +32 -0
  228. data/app/request_schemas/spree/api/v3/admin/price_adjustment_tier_request_schema.rb +21 -0
  229. data/app/request_schemas/spree/api/v3/admin/price_list_price_request_schema.rb +21 -0
  230. data/app/request_schemas/spree/api/v3/admin/price_list_rule_request_schema.rb +19 -0
  231. data/app/request_schemas/spree/api/v3/admin/product_membership_reposition_request_schema.rb +17 -0
  232. data/app/request_schemas/spree/api/v3/admin/promotion_action_calculator_request_schema.rb +18 -0
  233. data/app/request_schemas/spree/api/v3/admin/promotion_action_line_item_request_schema.rb +15 -0
  234. data/app/request_schemas/spree/api/v3/admin/promotion_action_request_schema.rb +19 -0
  235. data/app/request_schemas/spree/api/v3/admin/promotion_rule_request_schema.rb +22 -0
  236. data/app/request_schemas/spree/api/v3/admin/reason_request_schema.rb +14 -0
  237. data/app/request_schemas/spree/api/v3/admin/tax_identifier_request_schema.rb +15 -0
  238. data/app/request_schemas/spree/api/v3/custom_field_value_request_schema.rb +15 -0
  239. data/app/request_schemas/spree/api/v3/file_upload_request_schema.rb +20 -0
  240. data/app/request_schemas/spree/api/v3/media_request_schema.rb +27 -0
  241. data/app/request_schemas/spree/api/v3/price_request_schema.rb +17 -0
  242. data/app/request_schemas/spree/api/v3/stock_level_request_schema.rb +18 -0
  243. data/app/request_schemas/spree/api/v3/store/address_request_schema.rb +29 -0
  244. data/app/request_schemas/spree/api/v3/tax_identifier_request_schema.rb +18 -0
  245. data/app/request_schemas/spree/api/v3/variant_option_request_schema.rb +13 -0
  246. data/app/request_schemas/spree/api/v3/variant_request_schema.rb +52 -0
  247. data/app/serializers/concerns/spree/api/v3/purchase_summary.rb +48 -0
  248. data/app/serializers/spree/api/v3/address_serializer.rb +4 -2
  249. data/app/serializers/spree/api/v3/admin/address_serializer.rb +8 -7
  250. data/app/serializers/spree/api/v3/admin/api_key_serializer.rb +2 -6
  251. data/app/serializers/spree/api/v3/admin/applied_promotion_serializer.rb +3 -1
  252. data/app/serializers/spree/api/v3/admin/cart_serializer.rb +3 -1
  253. data/app/serializers/spree/api/v3/admin/catalog_assignment_serializer.rb +1 -3
  254. data/app/serializers/spree/api/v3/admin/catalog_order_minimum_serializer.rb +3 -8
  255. data/app/serializers/spree/api/v3/admin/catalog_price_serializer.rb +3 -4
  256. data/app/serializers/spree/api/v3/admin/catalog_price_tier_serializer.rb +4 -3
  257. data/app/serializers/spree/api/v3/admin/catalog_product_term_serializer.rb +1 -3
  258. data/app/serializers/spree/api/v3/admin/catalog_quantity_rule_serializer.rb +1 -3
  259. data/app/serializers/spree/api/v3/admin/channel_serializer.rb +7 -10
  260. data/app/serializers/spree/api/v3/admin/claim_line_item_serializer.rb +7 -0
  261. data/app/serializers/spree/api/v3/admin/claim_reason_serializer.rb +1 -3
  262. data/app/serializers/spree/api/v3/admin/claim_serializer.rb +5 -0
  263. data/app/serializers/spree/api/v3/admin/commission_line_serializer.rb +7 -18
  264. data/app/serializers/spree/api/v3/admin/commission_rate_serializer.rb +7 -11
  265. data/app/serializers/spree/api/v3/admin/commission_rule_serializer.rb +1 -5
  266. data/app/serializers/spree/api/v3/admin/country_serializer.rb +4 -0
  267. data/app/serializers/spree/api/v3/admin/coupon_code_serializer.rb +1 -7
  268. data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +1 -7
  269. data/app/serializers/spree/api/v3/admin/custom_field_definition_serializer.rb +6 -2
  270. data/app/serializers/spree/api/v3/admin/customer_serializer.rb +5 -17
  271. data/app/serializers/spree/api/v3/admin/data_request_serializer.rb +2 -6
  272. data/app/serializers/spree/api/v3/admin/delivery_method_rule_serializer.rb +0 -2
  273. data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +20 -30
  274. data/app/serializers/spree/api/v3/admin/delivery_method_service_serializer.rb +9 -1
  275. data/app/serializers/spree/api/v3/admin/delivery_origin_group_serializer.rb +1 -3
  276. data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +8 -0
  277. data/app/serializers/spree/api/v3/admin/delivery_serializer.rb +1 -3
  278. data/app/serializers/spree/api/v3/admin/delivery_zone_serializer.rb +1 -7
  279. data/app/serializers/spree/api/v3/admin/digital_asset_serializer.rb +4 -2
  280. data/app/serializers/spree/api/v3/admin/discount_serializer.rb +3 -1
  281. data/app/serializers/spree/api/v3/admin/email_template_draft_serializer.rb +19 -0
  282. data/app/serializers/spree/api/v3/admin/email_template_preview_serializer.rb +38 -0
  283. data/app/serializers/spree/api/v3/admin/email_template_revision_serializer.rb +18 -0
  284. data/app/serializers/spree/api/v3/admin/email_template_sample_record_serializer.rb +13 -0
  285. data/app/serializers/spree/api/v3/admin/email_template_serializer.rb +61 -0
  286. data/app/serializers/spree/api/v3/admin/exchange_line_item_serializer.rb +5 -0
  287. data/app/serializers/spree/api/v3/admin/exchange_serializer.rb +6 -3
  288. data/app/serializers/spree/api/v3/admin/export_serializer.rb +1 -7
  289. data/app/serializers/spree/api/v3/admin/fee_serializer.rb +3 -1
  290. data/app/serializers/spree/api/v3/admin/file_upload_serializer.rb +11 -0
  291. data/app/serializers/spree/api/v3/admin/file_upload_target_serializer.rb +10 -0
  292. data/app/serializers/spree/api/v3/admin/fulfillment_item_serializer.rb +1 -7
  293. data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +13 -17
  294. data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +4 -10
  295. data/app/serializers/spree/api/v3/admin/import_serializer.rb +2 -2
  296. data/app/serializers/spree/api/v3/admin/integration_serializer.rb +1 -3
  297. data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +14 -18
  298. data/app/serializers/spree/api/v3/admin/locale_serializer.rb +13 -0
  299. data/app/serializers/spree/api/v3/admin/market_serializer.rb +7 -2
  300. data/app/serializers/spree/api/v3/admin/media_serializer.rb +4 -5
  301. data/app/serializers/spree/api/v3/admin/order_cancellation_reason_serializer.rb +1 -3
  302. data/app/serializers/spree/api/v3/admin/order_group_serializer.rb +5 -9
  303. data/app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb +2 -6
  304. data/app/serializers/spree/api/v3/admin/order_serializer.rb +38 -48
  305. data/app/serializers/spree/api/v3/admin/package_type_serializer.rb +1 -3
  306. data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +7 -4
  307. data/app/serializers/spree/api/v3/admin/payment_serializer.rb +6 -8
  308. data/app/serializers/spree/api/v3/admin/payment_split_serializer.rb +8 -9
  309. data/app/serializers/spree/api/v3/admin/permission_serializer.rb +4 -4
  310. data/app/serializers/spree/api/v3/admin/price_adjustment_tier_serializer.rb +3 -6
  311. data/app/serializers/spree/api/v3/admin/price_history_serializer.rb +5 -2
  312. data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +1 -5
  313. data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +2 -6
  314. data/app/serializers/spree/api/v3/admin/price_serializer.rb +2 -0
  315. data/app/serializers/spree/api/v3/admin/product_serializer.rb +4 -10
  316. data/app/serializers/spree/api/v3/admin/product_submission_serializer.rb +2 -10
  317. data/app/serializers/spree/api/v3/admin/product_type_serializer.rb +1 -3
  318. data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +5 -9
  319. data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +1 -5
  320. data/app/serializers/spree/api/v3/admin/purchase_order_item_serializer.rb +6 -25
  321. data/app/serializers/spree/api/v3/admin/purchase_order_serializer.rb +4 -17
  322. data/app/serializers/spree/api/v3/admin/refund_reason_serializer.rb +1 -3
  323. data/app/serializers/spree/api/v3/admin/refund_serializer.rb +7 -0
  324. data/app/serializers/spree/api/v3/admin/reporting_result_serializer.rb +9 -2
  325. data/app/serializers/spree/api/v3/admin/return_line_item_serializer.rb +9 -0
  326. data/app/serializers/spree/api/v3/admin/return_reason_serializer.rb +1 -3
  327. data/app/serializers/spree/api/v3/admin/return_serializer.rb +8 -12
  328. data/app/serializers/spree/api/v3/admin/saved_report_serializer.rb +1 -3
  329. data/app/serializers/spree/api/v3/admin/seller_balance_serializer.rb +15 -10
  330. data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +7 -7
  331. data/app/serializers/spree/api/v3/admin/seller_requirement_status_serializer.rb +2 -6
  332. data/app/serializers/spree/api/v3/admin/seller_requirement_submission_serializer.rb +1 -7
  333. data/app/serializers/spree/api/v3/admin/seller_serializer.rb +8 -16
  334. data/app/serializers/spree/api/v3/admin/seller_transfer_serializer.rb +11 -10
  335. data/app/serializers/spree/api/v3/admin/shipping_label_serializer.rb +8 -21
  336. data/app/serializers/spree/api/v3/admin/stock_level_serializer.rb +1 -3
  337. data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +4 -3
  338. data/app/serializers/spree/api/v3/admin/stock_movement_serializer.rb +3 -9
  339. data/app/serializers/spree/api/v3/admin/stock_receipt_item_serializer.rb +1 -7
  340. data/app/serializers/spree/api/v3/admin/stock_receipt_serializer.rb +1 -3
  341. data/app/serializers/spree/api/v3/admin/stock_reservation_serializer.rb +1 -3
  342. data/app/serializers/spree/api/v3/admin/stock_transfer_item_serializer.rb +1 -3
  343. data/app/serializers/spree/api/v3/admin/store_credit_event_serializer.rb +6 -3
  344. data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +11 -20
  345. data/app/serializers/spree/api/v3/admin/store_serializer.rb +21 -84
  346. data/app/serializers/spree/api/v3/admin/supplier_serializer.rb +2 -4
  347. data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +6 -10
  348. data/app/serializers/spree/api/v3/admin/tax_identifier_serializer.rb +1 -3
  349. data/app/serializers/spree/api/v3/admin/tax_line_serializer.rb +9 -3
  350. data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +3 -19
  351. data/app/serializers/spree/api/v3/admin/update_status_serializer.rb +28 -0
  352. data/app/serializers/spree/api/v3/admin/variant_serializer.rb +13 -10
  353. data/app/serializers/spree/api/v3/admin/webhook_delivery_serializer.rb +1 -3
  354. data/app/serializers/spree/api/v3/admin/webhook_event_serializer.rb +23 -0
  355. data/app/serializers/spree/api/v3/applied_promotion_serializer.rb +2 -4
  356. data/app/serializers/spree/api/v3/base_serializer.rb +132 -7
  357. data/app/serializers/spree/api/v3/cart_serializer.rb +20 -66
  358. data/app/serializers/spree/api/v3/category_serializer.rb +5 -15
  359. data/app/serializers/spree/api/v3/claim_line_item_serializer.rb +6 -29
  360. data/app/serializers/spree/api/v3/claim_serializer.rb +2 -16
  361. data/app/serializers/spree/api/v3/collection_serializer.rb +1 -3
  362. data/app/serializers/spree/api/v3/company_serializer.rb +1 -3
  363. data/app/serializers/spree/api/v3/country_serializer.rb +2 -1
  364. data/app/serializers/spree/api/v3/currency_serializer.rb +9 -1
  365. data/app/serializers/spree/api/v3/custom_field_serializer.rb +1 -2
  366. data/app/serializers/spree/api/v3/customer_serializer.rb +3 -2
  367. data/app/serializers/spree/api/v3/delivery_rate_serializer.rb +8 -32
  368. data/app/serializers/spree/api/v3/delivery_zone_member_serializer.rb +1 -1
  369. data/app/serializers/spree/api/v3/digital_asset_serializer.rb +1 -3
  370. data/app/serializers/spree/api/v3/digital_link_serializer.rb +3 -9
  371. data/app/serializers/spree/api/v3/discount_serializer.rb +4 -12
  372. data/app/serializers/spree/api/v3/exchange_line_item_serializer.rb +6 -30
  373. data/app/serializers/spree/api/v3/exchange_serializer.rb +2 -16
  374. data/app/serializers/spree/api/v3/export_serializer.rb +1 -3
  375. data/app/serializers/spree/api/v3/fee_serializer.rb +2 -10
  376. data/app/serializers/spree/api/v3/file_upload_serializer.rb +28 -0
  377. data/app/serializers/spree/api/v3/file_upload_target_serializer.rb +17 -0
  378. data/app/serializers/spree/api/v3/fulfillment_serializer.rb +4 -11
  379. data/app/serializers/spree/api/v3/gift_card_batch_serializer.rb +3 -7
  380. data/app/serializers/spree/api/v3/gift_card_serializer.rb +7 -17
  381. data/app/serializers/spree/api/v3/import_row_serializer.rb +2 -6
  382. data/app/serializers/spree/api/v3/import_serializer.rb +3 -26
  383. data/app/serializers/spree/api/v3/invitation_serializer.rb +2 -19
  384. data/app/serializers/spree/api/v3/line_item_serializer.rb +19 -23
  385. data/app/serializers/spree/api/v3/locale_serializer.rb +3 -1
  386. data/app/serializers/spree/api/v3/market_serializer.rb +5 -5
  387. data/app/serializers/spree/api/v3/media_event_serializer.rb +1 -3
  388. data/app/serializers/spree/api/v3/media_serializer.rb +8 -5
  389. data/app/serializers/spree/api/v3/newsletter_subscriber_request_event_serializer.rb +35 -0
  390. data/app/serializers/spree/api/v3/newsletter_subscriber_serializer.rb +2 -6
  391. data/app/serializers/spree/api/v3/option_value_serializer.rb +1 -3
  392. data/app/serializers/spree/api/v3/order_group_serializer.rb +12 -25
  393. data/app/serializers/spree/api/v3/order_serializer.rb +14 -58
  394. data/app/serializers/spree/api/v3/password_reset_requested_event_serializer.rb +29 -0
  395. data/app/serializers/spree/api/v3/payment_method_serializer.rb +2 -6
  396. data/app/serializers/spree/api/v3/payment_serializer.rb +5 -10
  397. data/app/serializers/spree/api/v3/payment_session_serializer.rb +5 -13
  398. data/app/serializers/spree/api/v3/payment_setup_session_serializer.rb +3 -11
  399. data/app/serializers/spree/api/v3/policy_serializer.rb +1 -3
  400. data/app/serializers/spree/api/v3/price_history_serializer.rb +6 -8
  401. data/app/serializers/spree/api/v3/price_serializer.rb +7 -12
  402. data/app/serializers/spree/api/v3/product_filter_price_range_serializer.rb +10 -4
  403. data/app/serializers/spree/api/v3/product_publication_serializer.rb +1 -7
  404. data/app/serializers/spree/api/v3/product_serializer.rb +10 -24
  405. data/app/serializers/spree/api/v3/product_submission_serializer.rb +26 -0
  406. data/app/serializers/spree/api/v3/purchase_order_event_serializer.rb +23 -4
  407. data/app/serializers/spree/api/v3/refund_serializer.rb +11 -16
  408. data/app/serializers/spree/api/v3/return_line_item_serializer.rb +6 -21
  409. data/app/serializers/spree/api/v3/return_serializer.rb +4 -16
  410. data/app/serializers/spree/api/v3/saved_report_event_serializer.rb +23 -0
  411. data/app/serializers/spree/api/v3/seller/address_serializer.rb +12 -0
  412. data/app/serializers/spree/api/v3/seller/balance_serializer.rb +15 -10
  413. data/app/serializers/spree/api/v3/seller/claim_line_item_serializer.rb +7 -0
  414. data/app/serializers/spree/api/v3/seller/claim_serializer.rb +5 -0
  415. data/app/serializers/spree/api/v3/seller/country_serializer.rb +19 -0
  416. data/app/serializers/spree/api/v3/seller/delivery_method_rule_serializer.rb +1 -3
  417. data/app/serializers/spree/api/v3/seller/delivery_method_serializer.rb +5 -15
  418. data/app/serializers/spree/api/v3/seller/delivery_rate_serializer.rb +8 -13
  419. data/app/serializers/spree/api/v3/seller/delivery_serializer.rb +1 -3
  420. data/app/serializers/spree/api/v3/seller/delivery_zone_serializer.rb +1 -3
  421. data/app/serializers/spree/api/v3/seller/exchange_line_item_serializer.rb +5 -0
  422. data/app/serializers/spree/api/v3/seller/exchange_serializer.rb +6 -3
  423. data/app/serializers/spree/api/v3/seller/file_upload_serializer.rb +11 -0
  424. data/app/serializers/spree/api/v3/seller/file_upload_target_serializer.rb +10 -0
  425. data/app/serializers/spree/api/v3/seller/fulfillment_item_serializer.rb +1 -7
  426. data/app/serializers/spree/api/v3/seller/fulfillment_serializer.rb +2 -6
  427. data/app/serializers/spree/api/v3/seller/import_serializer.rb +2 -2
  428. data/app/serializers/spree/api/v3/seller/invitation_serializer.rb +1 -3
  429. data/app/serializers/spree/api/v3/seller/media_serializer.rb +2 -5
  430. data/app/serializers/spree/api/v3/seller/order_line_item_serializer.rb +8 -13
  431. data/app/serializers/spree/api/v3/seller/order_serializer.rb +19 -40
  432. data/app/serializers/spree/api/v3/seller/payment_split_serializer.rb +8 -9
  433. data/app/serializers/spree/api/v3/seller/payout_serializer.rb +6 -6
  434. data/app/serializers/spree/api/v3/seller/price_history_serializer.rb +11 -0
  435. data/app/serializers/spree/api/v3/seller/price_serializer.rb +11 -0
  436. data/app/serializers/spree/api/v3/seller/product_serializer.rb +3 -7
  437. data/app/serializers/spree/api/v3/seller/product_submission_serializer.rb +1 -21
  438. data/app/serializers/spree/api/v3/seller/profile_serializer.rb +9 -13
  439. data/app/serializers/spree/api/v3/seller/requirement_status_serializer.rb +3 -9
  440. data/app/serializers/spree/api/v3/seller/return_line_item_serializer.rb +8 -0
  441. data/app/serializers/spree/api/v3/seller/return_serializer.rb +8 -17
  442. data/app/serializers/spree/api/v3/seller/state_serializer.rb +10 -0
  443. data/app/serializers/spree/api/v3/seller/stock_location_serializer.rb +3 -0
  444. data/app/serializers/spree/api/v3/seller/transfer_serializer.rb +10 -9
  445. data/app/serializers/spree/api/v3/seller/variant_serializer.rb +8 -4
  446. data/app/serializers/spree/api/v3/seller_serializer.rb +1 -3
  447. data/app/serializers/spree/api/v3/shipping_label_event_serializer.rb +22 -4
  448. data/app/serializers/spree/api/v3/stock_level_serializer.rb +1 -7
  449. data/app/serializers/spree/api/v3/stock_location_serializer.rb +8 -1
  450. data/app/serializers/spree/api/v3/stock_movement_serializer.rb +1 -3
  451. data/app/serializers/spree/api/v3/stock_receipt_event_serializer.rb +20 -4
  452. data/app/serializers/spree/api/v3/stock_transfer_serializer.rb +1 -7
  453. data/app/serializers/spree/api/v3/store_credit_event_serializer.rb +2 -13
  454. data/app/serializers/spree/api/v3/store_credit_serializer.rb +3 -27
  455. data/app/serializers/spree/api/v3/supplier_event_serializer.rb +6 -4
  456. data/app/serializers/spree/api/v3/tax_line_serializer.rb +11 -23
  457. data/app/serializers/spree/api/v3/variant_serializer.rb +10 -24
  458. data/app/serializers/spree/api/v3/wishlist_item_serializer.rb +1 -11
  459. data/app/serializers/spree/api/v3/wishlist_serializer.rb +2 -6
  460. data/app/services/spree/api/v3/filter_predicates.rb +29 -0
  461. data/app/services/spree/api/v3/filter_table.rb +337 -0
  462. data/app/services/spree/api/v3/filters_aggregator.rb +2 -2
  463. data/app/services/spree/api/v3/request_schema.rb +430 -0
  464. data/app/services/spree/webhooks/deliver_webhook.rb +7 -3
  465. data/app/subscribers/spree/webhook_event_subscriber.rb +3 -10
  466. data/config/initializers/pagy.rb +1 -1
  467. data/config/initializers/typelizer.rb +7 -9
  468. data/config/locales/ar.yml +15 -0
  469. data/config/locales/be.yml +15 -0
  470. data/config/locales/bg.yml +15 -0
  471. data/config/locales/ca.yml +15 -0
  472. data/config/locales/cs.yml +15 -0
  473. data/config/locales/da.yml +15 -0
  474. data/config/locales/de-CH.yml +11 -0
  475. data/config/locales/de.yml +15 -0
  476. data/config/locales/el.yml +15 -0
  477. data/config/locales/en.yml +5 -40
  478. data/config/locales/es-CL.yml +10 -0
  479. data/config/locales/es-EC.yml +11 -0
  480. data/config/locales/es-MX.yml +12 -0
  481. data/config/locales/es.yml +15 -0
  482. data/config/locales/et.yml +15 -0
  483. data/config/locales/fa.yml +15 -0
  484. data/config/locales/fi.yml +15 -0
  485. data/config/locales/fr.yml +15 -0
  486. data/config/locales/hu.yml +15 -0
  487. data/config/locales/id.yml +15 -0
  488. data/config/locales/it.yml +15 -0
  489. data/config/locales/ja.yml +15 -0
  490. data/config/locales/km.yml +15 -0
  491. data/config/locales/ko.yml +15 -0
  492. data/config/locales/ku.yml +15 -0
  493. data/config/locales/lt.yml +15 -0
  494. data/config/locales/lv.yml +15 -0
  495. data/config/locales/nb.yml +15 -0
  496. data/config/locales/ne.yml +15 -0
  497. data/config/locales/nl.yml +15 -0
  498. data/config/locales/pl.yml +15 -0
  499. data/config/locales/pt-BR.yml +13 -0
  500. data/config/locales/pt.yml +15 -0
  501. data/config/locales/ro.yml +15 -0
  502. data/config/locales/ru.yml +15 -0
  503. data/config/locales/sk.yml +15 -0
  504. data/config/locales/sl-SI.yml +15 -0
  505. data/config/locales/sv.yml +15 -0
  506. data/config/locales/th.yml +15 -0
  507. data/config/locales/tr.yml +15 -0
  508. data/config/locales/uk.yml +15 -0
  509. data/config/locales/vi.yml +15 -0
  510. data/config/locales/zh-CN.yml +15 -0
  511. data/config/locales/zh-TW.yml +15 -0
  512. data/config/routes.rb +54 -102
  513. data/lib/spree/api/configuration.rb +5 -0
  514. data/lib/spree/api/dependencies.rb +54 -274
  515. data/lib/spree/api/middleware/request_size_limit.rb +24 -3
  516. data/lib/spree/api/openapi/filter_documentation.rb +136 -0
  517. data/lib/spree/api/openapi/schema_helper.rb +127 -81
  518. data/lib/spree/api/preference_families.rb +46 -0
  519. data/lib/spree/api/preference_types.rb +138 -0
  520. data/lib/spree/api/typelizer_generation.rb +39 -0
  521. data/lib/spree/api/webhook_event_types.rb +140 -0
  522. data/lib/spree/api.rb +0 -2
  523. data/lib/tasks/filters.rake +12 -0
  524. data/lib/typelizer/open_enums.rb +10 -0
  525. metadata +125 -40
  526. data/app/controllers/concerns/spree/api/v3/address_params.rb +0 -17
  527. data/app/controllers/concerns/spree/api/v3/direct_uploads.rb +0 -35
  528. data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +0 -54
  529. data/app/controllers/spree/api/v3/seller/direct_uploads_controller.rb +0 -21
  530. data/config/i18n-tasks.yml +0 -40
  531. data/config/initializers/alba.rb +0 -5
@@ -11,6 +11,33 @@ module Spree
11
11
  module HttpCaching
12
12
  extend ActiveSupport::Concern
13
13
 
14
+ # Every request header that changes a publicly cacheable response.
15
+ # A shared cache (CDN, reverse proxy) keys stored responses on these,
16
+ # so a header missing here lets one visitor's response be served to
17
+ # another:
18
+ # - +Accept+ — response format
19
+ # - +X-Spree-Api-Key+ — the publishable key selects the store (and
20
+ # may bind a channel)
21
+ # - +Authorization+ — a customer JWT turns the response private
22
+ # (customer-group prices, gated catalog); without it a guest
23
+ # response could be served to a signed-in customer
24
+ # - +X-Spree-Country+ — selects the market (currency, prices, tax
25
+ # display, availability)
26
+ # - +X-Spree-Currency+ / +X-Spree-Locale+ — currency and language
27
+ # - +X-Spree-Channel+ — price hiding + channel-scoped visibility
28
+ #
29
+ # Query-param equivalents (+?country=+, +?currency=+, +?locale=+)
30
+ # are part of the URL and so already part of every cache key.
31
+ VARY_HEADERS = %w[
32
+ Accept
33
+ X-Spree-Api-Key
34
+ Authorization
35
+ X-Spree-Country
36
+ X-Spree-Currency
37
+ X-Spree-Locale
38
+ X-Spree-Channel
39
+ ].freeze
40
+
14
41
  included do
15
42
  after_action :set_vary_headers
16
43
  end
@@ -22,13 +49,11 @@ module Spree
22
49
  current_user.nil?
23
50
  end
24
51
 
25
- # Set Vary headers to ensure proper CDN caching by currency/locale/channel.
26
- # X-Spree-Channel is included because the resolved channel changes the
27
- # serialized body (price hiding + channel-scoped visibility), so a shared
28
- # cache must not serve one channel's guest response to another channel.
52
+ # Set Vary so a shared cache stores one guest response per
53
+ # store/market/currency/locale/channel combination (see VARY_HEADERS).
29
54
  def set_vary_headers
30
55
  if guest_user?
31
- response.headers['Vary'] = 'Accept, x-spree-currency, x-spree-locale, x-spree-channel'
56
+ response.headers['Vary'] = VARY_HEADERS.join(', ')
32
57
  else
33
58
  response.headers['Cache-Control'] = 'private, no-store'
34
59
  end
@@ -70,12 +95,12 @@ module Spree
70
95
 
71
96
  expires_in expires_in, public: true
72
97
 
73
- # Use Rails' stale? which handles ETag and Last-Modified. The channel
74
- # is folded into the ETag so a shared cache never serves one channel's
75
- # guest response to another; Last-Modified mirrors the resource's own
76
- # timestamp as before.
98
+ # Use Rails' stale? which handles ETag and Last-Modified. The request
99
+ # context (currency, locale, market, channel) is folded into the ETag
100
+ # so a revalidation never 304s across contexts; Last-Modified mirrors
101
+ # the resource's own timestamp as before.
77
102
  stale?(
78
- etag: [resource, cache_channel_fragment],
103
+ etag: [resource, current_currency, current_locale, cache_market_fragment, cache_channel_fragment],
79
104
  last_modified: resource.try(:updated_at),
80
105
  public: true
81
106
  )
@@ -84,7 +109,7 @@ module Spree
84
109
  private
85
110
 
86
111
  # Build a cache key for a collection
87
- # Includes: latest updated_at, total count, query params, pagination, expand, currency, locale, channel
112
+ # Includes: latest updated_at, total count, query params, pagination, expand, currency, locale, market, channel
88
113
  def collection_cache_key(collection)
89
114
  # For ActiveRecord collections use updated_at, for plain arrays use store's updated_at as proxy
90
115
  latest_updated_at = if collection.first&.respond_to?(:updated_at)
@@ -103,12 +128,20 @@ module Spree
103
128
  params[:limit],
104
129
  current_currency,
105
130
  current_locale,
131
+ cache_market_fragment,
106
132
  cache_channel_fragment
107
133
  ]
108
134
 
109
135
  parts.compact.join('/')
110
136
  end
111
137
 
138
+ # Identifies the resolved market (from X-Spree-Country / ?country=).
139
+ # The market drives tax display and availability as well as currency,
140
+ # so it is part of the guest cache identity.
141
+ def cache_market_fragment
142
+ Spree::Current.market&.id
143
+ end
144
+
112
145
  # Identifies the resolved channel for cache-key purposes. The channel
113
146
  # changes the serialized body (price hiding + channel-scoped visibility),
114
147
  # so it must be part of the guest cache identity. Uses the same
@@ -29,6 +29,8 @@ module Spree
29
29
  return
30
30
  end
31
31
 
32
+ return yield if caller_identity.nil?
33
+
32
34
  cache_key = idempotency_cache_key(key)
33
35
  cached = Rails.cache.read(cache_key)
34
36
 
@@ -36,7 +38,7 @@ module Spree
36
38
  if cached[:fingerprint] != request_fingerprint
37
39
  render_error(
38
40
  code: ErrorHandler::ERROR_CODES[:idempotency_key_reused],
39
- message: Spree.t(:idempotency_key_reused),
41
+ message: I18n.t('spree.idempotency_key_reused'),
40
42
  status: :unprocessable_content
41
43
  )
42
44
  return
@@ -66,17 +68,30 @@ module Spree
66
68
  MUTATING_METHODS.include?(request.method)
67
69
  end
68
70
 
71
+ def caller_identity
72
+ return @caller_identity if defined?(@caller_identity)
73
+
74
+ credentials = []
75
+
76
+ credentials << ['secret_key', Spree::ApiKey.compute_token_digest(extract_api_key)] if secret_key_request?
77
+
78
+ bearer_token = extract_token
79
+ credentials << ['bearer', Digest::SHA256.hexdigest(bearer_token)] if bearer_token.present?
80
+
81
+ credentials << ['order_token', Digest::SHA256.hexdigest(order_token)] if order_token.present?
82
+
83
+ @caller_identity = credentials.presence
84
+ end
85
+
69
86
  def idempotency_cache_key(key)
70
- credential = request.headers['X-Spree-Api-Key'].presence ||
71
- spree_current_user&.id ||
72
- request.remote_ip
73
87
  # The resolved store partitions the namespace: a staff JWT spans
74
88
  # stores, and replaying one store's cached response for a request
75
89
  # aimed at another would cross store boundaries. The resolved
76
90
  # store — not the raw header — so a header naming the default store
77
91
  # and no header at all land in the same partition, as they resolve
78
92
  # to the same store.
79
- "spree:idempotency:#{Digest::SHA256.hexdigest("#{credential}\0#{current_store&.id}\0#{key}")}"
93
+ digest = Digest::SHA256.hexdigest([*caller_identity.flatten, current_store&.id, key].join("\0"))
94
+ "spree:idempotency:#{digest}"
80
95
  end
81
96
 
82
97
  def request_fingerprint
@@ -45,7 +45,7 @@ module Spree
45
45
  # `return_line_items`).
46
46
  def render_invalid_items
47
47
  errors = ActiveModel::Errors.new(@resource || model_class.new)
48
- errors.add(:base, :invalid_items, message: Spree.t('errors.messages.items_not_a_list'))
48
+ errors.add(:base, :invalid_items, message: I18n.t('spree.errors.messages.items_not_a_list'))
49
49
  render_validation_error(errors)
50
50
  end
51
51
  end
@@ -0,0 +1,52 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ # Money read from a request. The contract is a canonical decimal string
5
+ # ("19.99"); a JSON number, a localized string or more decimals than the
6
+ # currency has is answered with `invalid_money_format`, naming the field.
7
+ module MoneyParams
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ rescue_from Spree::Money::InvalidFormat, with: :render_invalid_money_format
12
+ end
13
+
14
+ protected
15
+
16
+ # @param name [Symbol] the request parameter
17
+ # @param currency [String] the currency the amount is in
18
+ # @param unit_price [Boolean] allows up to four decimals
19
+ # @return [BigDecimal, nil] nil when the parameter is absent
20
+ # @raise [Spree::Money::InvalidFormat]
21
+ def money_param(name, currency, unit_price: false)
22
+ Spree::Money::Rounding.parse_canonical(params[name], currency, unit_price: unit_price)
23
+ rescue Spree::Money::InvalidFormat => error
24
+ raise Spree::Money::InvalidFormat.new(error.message, field: name)
25
+ end
26
+
27
+ # A rate or other plain decimal: any number of decimals, but still a
28
+ # canonical decimal string.
29
+ #
30
+ # @param name [Symbol] the request parameter
31
+ # @return [BigDecimal, nil] nil when the parameter is absent
32
+ # @raise [Spree::Money::InvalidFormat]
33
+ def decimal_param(name)
34
+ Spree::Money::Rounding.parse_canonical_decimal(params[name])
35
+ rescue Spree::Money::InvalidFormat => error
36
+ raise Spree::Money::InvalidFormat.new(error.message, field: name)
37
+ end
38
+
39
+ private
40
+
41
+ def render_invalid_money_format(error)
42
+ render_error(
43
+ code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:invalid_money_format],
44
+ message: [error.field, error.message].compact.join(' '),
45
+ status: :unprocessable_content,
46
+ details: error.field ? { error.field => [error.message] } : nil
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -29,7 +29,7 @@ module Spree
29
29
  if order.is_a?(Spree::Cart) && order.completion_claimed?
30
30
  next render_error(
31
31
  code: 'completion_in_progress',
32
- message: Spree.t(:cart_completion_in_progress),
32
+ message: I18n.t('spree.cart_completion_in_progress'),
33
33
  status: :conflict
34
34
  )
35
35
  end
@@ -51,7 +51,7 @@ module Spree
51
51
  Rails.error.report(exception, context: { order_id: (@order || @parent || @cart)&.id }, source: 'spree.api.v3')
52
52
  render_error(
53
53
  code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:cart_already_updated],
54
- message: Spree.t(:cart_already_updated),
54
+ message: I18n.t('spree.cart_already_updated'),
55
55
  status: :conflict
56
56
  )
57
57
  end
@@ -59,11 +59,7 @@ module Spree
59
59
  private
60
60
 
61
61
  def create_params
62
- @create_params ||= params.permit(
63
- :memo, :reason_id,
64
- items: [:line_item_id, :quantity, :description, :send_replacement,
65
- :replacement_variant_id, :refund_amount]
66
- )
62
+ @create_params ||= params.permit(*declared_permitted_attributes)
67
63
  end
68
64
 
69
65
  # Every claimed line is resolved through the order itself, so a line
@@ -25,14 +25,10 @@ module Spree
25
25
  # reject rather than a keyword it was never given.
26
26
  result = Spree.delivery_create_service.call(
27
27
  owner: @parent,
28
- **resource_permitted_attributes.index_with { |key| delivery_params[key] }
28
+ **delivery_keys.index_with { |key| delivery_params[key] }
29
29
  )
30
30
 
31
- if result.success?
32
- render json: serialize_resource(result.value), status: :created
33
- else
34
- render_result_error(result)
35
- end
31
+ render_result(result, status: :created)
36
32
  end
37
33
  end
38
34
 
@@ -81,14 +77,14 @@ module Spree
81
77
  [:shipping_label]
82
78
  end
83
79
 
84
- def resource_permitted_attributes
85
- [:tracking_number, :carrier, :service, :tracking_url]
86
- end
87
-
88
80
  private
89
81
 
90
82
  def delivery_params
91
- @delivery_params ||= params.permit(*resource_permitted_attributes)
83
+ @delivery_params ||= params.permit(*declared_permitted_attributes)
84
+ end
85
+
86
+ def delivery_keys
87
+ declared_permitted_attributes.grep(Symbol)
92
88
  end
93
89
 
94
90
  # Deliveries can hang off something other than a fulfillment, which
@@ -61,10 +61,7 @@ module Spree
61
61
  private
62
62
 
63
63
  def create_params
64
- @create_params ||= params.permit(
65
- :memo, :reason_id, :stock_location_id,
66
- items: [:fulfillment_item_id, :new_variant_id, :quantity]
67
- )
64
+ @create_params ||= params.permit(*declared_permitted_attributes)
68
65
  end
69
66
 
70
67
  # The units going back are resolved through the order; what comes
@@ -45,11 +45,7 @@ module Spree
45
45
  **fulfill_workflow_options
46
46
  )
47
47
 
48
- if result.success?
49
- render json: serialize_resource(result.value)
50
- else
51
- render_result_error(result)
52
- end
48
+ render_result(result)
53
49
  end
54
50
  end
55
51
 
@@ -60,11 +56,7 @@ module Spree
60
56
  with_order_lock do
61
57
  result = Spree.fulfillment_cancel_workflow.call(fulfillment: @resource)
62
58
 
63
- if result.success?
64
- render json: serialize_resource(result.value)
65
- else
66
- render_result_error(result)
67
- end
59
+ render_result(result)
68
60
  end
69
61
  end
70
62
 
@@ -102,11 +94,7 @@ module Spree
102
94
  private
103
95
 
104
96
  def fulfill_params
105
- @fulfill_params ||= params.permit(*fulfill_permitted_keys)
106
- end
107
-
108
- def fulfill_permitted_keys
109
- [:tracking, :tracking_carrier, :notify_customer, { items: [:item_id, :quantity] }]
97
+ @fulfill_params ||= params.permit(*declared_permitted_attributes)
110
98
  end
111
99
 
112
100
  # Extra keywords the branch's own fulfil accepts — forcing past a
@@ -28,11 +28,7 @@ module Spree
28
28
  def run_workflow(workflow, **arguments)
29
29
  result = workflow.call(workflow_record_key => @resource, **arguments)
30
30
 
31
- if result.success?
32
- render json: serialize_resource(result.value)
33
- else
34
- render_result_error(result)
35
- end
31
+ render_result(result)
36
32
  end
37
33
 
38
34
  # @return [Symbol] the keyword this entity's workflows take it under
@@ -63,11 +59,7 @@ module Spree
63
59
  **arguments
64
60
  )
65
61
 
66
- if result.success?
67
- render json: serialize_resource(result.value), status: :created
68
- else
69
- render_result_error(result)
70
- end
62
+ render_result(result, status: :created)
71
63
  end
72
64
  end
73
65
  end
@@ -61,10 +61,7 @@ module Spree
61
61
  private
62
62
 
63
63
  def create_params
64
- @create_params ||= params.permit(
65
- :memo, :reason_id, :stock_location_id,
66
- items: [:fulfillment_item_id, :quantity]
67
- )
64
+ @create_params ||= params.permit(*declared_permitted_attributes)
68
65
  end
69
66
 
70
67
  # The units coming back, resolved through the order itself, so a
@@ -18,9 +18,6 @@ module Spree
18
18
  included do
19
19
  include ActiveStorage::SetCurrent
20
20
  include Spree::Api::V3::StreamsShippingLabel
21
-
22
- rescue_from ActiveSupport::MessageVerifier::InvalidSignature,
23
- with: :render_invalid_signature
24
21
  end
25
22
 
26
23
  # GET .../labels/:id/download
@@ -31,7 +28,7 @@ module Spree
31
28
  stream_shipping_label(@resource) do
32
29
  render_error(
33
30
  code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:validation_error],
34
- message: Spree.t('shipping_labels.errors.no_file_url'),
31
+ message: I18n.t('spree.shipping_labels.errors.no_file_url'),
35
32
  status: :unprocessable_content
36
33
  )
37
34
  end
@@ -45,7 +42,7 @@ module Spree
45
42
  unless @resource.uploaded?
46
43
  return render_error(
47
44
  code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:validation_error],
48
- message: Spree.t('shipping_labels.errors.purchased_not_deletable'),
45
+ message: I18n.t('spree.shipping_labels.errors.purchased_not_deletable'),
49
46
  status: :unprocessable_content
50
47
  )
51
48
  end
@@ -83,44 +80,27 @@ module Spree
83
80
 
84
81
  private
85
82
 
86
- def label_permitted_keys
87
- [:file, :tracking_number, :carrier, :service,
88
- :cost, :currency, :file_format, :tracking_url]
89
- end
90
-
91
83
  def label_params
92
- @label_params ||= params.permit(*label_permitted_keys)
84
+ @label_params ||= params.permit(*declared_permitted_attributes)
93
85
  end
94
86
 
95
87
  # Records a label bought outside Spree.
96
88
  #
97
89
  # Every key is passed whether or not the request carried it, so the
98
90
  # workflow sees a missing tracking number as a blank one to reject
99
- # rather than a keyword it was never given.
91
+ # rather than a keyword it was never given. The workflow takes any
92
+ # attachable as `file`; the API names the reference `file_signed_id`.
100
93
  def record_uploaded_label
101
94
  with_order_lock do
102
95
  result = Spree.shipping_label_record_workflow.call(
103
96
  owner: @parent,
104
- **label_permitted_keys.index_with { |key| label_params[key] }
97
+ file: label_params[:file_signed_id],
98
+ **(declared_permitted_attributes.grep(Symbol) - [:file_signed_id]).index_with { |key| label_params[key] }
105
99
  )
106
100
 
107
- if result.success?
108
- render json: serialize_resource(result.value), status: :created
109
- else
110
- render_result_error(result)
111
- end
101
+ render_result(result, status: :created)
112
102
  end
113
103
  end
114
-
115
- # A tampered or expired direct-upload signature is a bad parameter,
116
- # not a server fault.
117
- def render_invalid_signature
118
- render_error(
119
- code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:parameter_invalid],
120
- message: Spree.t('shipping_labels.errors.file_required'),
121
- status: :unprocessable_content
122
- )
123
- end
124
104
  end
125
105
  end
126
106
  end
@@ -30,6 +30,11 @@ module Spree
30
30
  def resolve_prefixed_ids(hash)
31
31
  hash.each_with_object({}.with_indifferent_access) do |(key, value), result|
32
32
  result[key] = case
33
+ # Preferences declare which of their values are ids
34
+ # and decode only those, after checking them against
35
+ # their schema.
36
+ when key.to_s == 'preferences'
37
+ value
33
38
  when key.to_s.end_with?('_id') && prefixed_id?(value)
34
39
  decode_prefixed_id(value)
35
40
  when key.to_s.end_with?('_ids') && value.is_a?(Array)
@@ -6,6 +6,7 @@ module Spree
6
6
  # branches answer different audiences, but the frontend permission model
7
7
  # is one implementation, so its input has to be too.
8
8
  #
9
+ # - Subjects are short names (`product`), not Ruby class names.
9
10
  # - Rule order is preserved so the frontend matcher can apply
10
11
  # CanCanCan's "last matching rule wins" semantics.
11
12
  # - Per-record conditions are NOT serialized (they often reference
@@ -23,12 +24,19 @@ module Spree
23
24
  {
24
25
  allow: rule.base_behavior,
25
26
  actions: Array(rule.actions).map(&:to_s),
26
- subjects: Array(rule.subjects).map { |subject| subject.is_a?(Class) ? subject.name : subject.to_s },
27
+ subjects: Array(rule.subjects).map { |subject| serialize_subject(subject) },
27
28
  has_conditions: rule_has_conditions?(rule)
28
29
  }
29
30
  end
30
31
  end
31
32
 
33
+ # A model subject travels as its short name (`product`, `customer`),
34
+ # never the Ruby class; `all` and symbol subjects (`dashboard`) pass
35
+ # through as they are.
36
+ def serialize_subject(subject)
37
+ subject.is_a?(Class) ? Spree::Base.polymorphic_api_type(subject.name) : subject.to_s
38
+ end
39
+
32
40
  def serialize_permission_keys(ability)
33
41
  ability.respond_to?(:permission_keys) ? ability.permission_keys : []
34
42
  end
@@ -0,0 +1,26 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ # Which serializer describes what a checkout produced.
5
+ #
6
+ # A checkout answers with one record: the order it placed, or — when the
7
+ # basket reached several sellers — the group holding one order per
8
+ # seller. Which of the two it is follows the record, never the endpoint,
9
+ # so every surface that resolves a checkout hands back the whole purchase
10
+ # rather than one seller's share of it.
11
+ module PurchaseSerialization
12
+ extend ActiveSupport::Concern
13
+
14
+ protected
15
+
16
+ # @param record [Spree::Order, Spree::OrderGroup, Spree::Cart]
17
+ # @return [Class] the serializer that describes it
18
+ def purchase_serializer_for(record)
19
+ return Spree.api.order_group_serializer if record.is_a?(Spree::OrderGroup)
20
+
21
+ Spree.api.order_serializer
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,65 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ # Declares what a controller's write actions accept (see
5
+ # Spree::Api::V3::RequestSchema). The resource controller permits from the
6
+ # declaration, and the integration specs document it with
7
+ # `request_body_for`, which is where the SDK request types come from.
8
+ #
9
+ # request_params :product do ... end # create and update
10
+ # request_params 'ProductBulkStatusParams', action: :bulk_status_update do ... end
11
+ module RequestParams
12
+ extend ActiveSupport::Concern
13
+
14
+ RESOURCE_ACTIONS = %w[create update].freeze
15
+
16
+ included do
17
+ class_attribute :request_params_schemas, instance_writer: false, default: {}
18
+ end
19
+
20
+ class_methods do
21
+ # @param name [String, Symbol, nil] the resource the published types
22
+ # are named after (defaults to the singular controller name), or a
23
+ # name ending in `Params` for a single action's body
24
+ # @param action [Symbol, nil] an action other than create and update
25
+ def request_params(name = nil, action: nil, &block)
26
+ if action && !name.to_s.end_with?('Params')
27
+ raise ArgumentError, "name the body of #{action} with a name ending in Params"
28
+ end
29
+
30
+ schema = Spree::Api::V3::RequestSchema.new(name || controller_name.singularize, &block)
31
+ self.request_params_schemas = request_params_schemas.merge((action || :resource).to_sym => schema)
32
+ end
33
+
34
+ # @param action [Symbol, String]
35
+ # @return [Spree::Api::V3::RequestSchema, nil] what the action accepts
36
+ def request_params_schema(action = :create)
37
+ action = action.to_s
38
+ request_params_schemas[action.to_sym] || (request_params_schemas[:resource] if RESOURCE_ACTIONS.include?(action))
39
+ end
40
+ end
41
+
42
+ protected
43
+
44
+ # The current action's declaration. An action without its own (a
45
+ # custom one writing through +permitted_params+) accepts what update
46
+ # does.
47
+ #
48
+ # @return [Spree::Api::V3::RequestSchema, nil]
49
+ def request_params_schema
50
+ self.class.request_params_schema(action_name) || request_params_schemas[:resource]
51
+ end
52
+
53
+ # The declared `params.permit` list for the current action.
54
+ #
55
+ # @return [Array<Symbol, Hash>]
56
+ def declared_permitted_attributes
57
+ action = action_name.to_s
58
+ # A member action with no body of its own changes an existing
59
+ # record, so it takes what update takes — never a create-only field.
60
+ request_params_schema.permit_list(RESOURCE_ACTIONS.include?(action) ? action : :update)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -96,7 +96,7 @@ module Spree
96
96
 
97
97
  render_error(
98
98
  code: ErrorHandler::ERROR_CODES[:access_denied],
99
- message: Spree.t(:seller_access_denied),
99
+ message: I18n.t('spree.seller_access_denied'),
100
100
  status: :forbidden
101
101
  )
102
102
  false
@@ -5,9 +5,10 @@ module Spree
5
5
  # The products a storefront buyer may see: available now (or on
6
6
  # pre-order) in the current currency, narrowed to the catalogs their
7
7
  # company, customer group or channel resolve to. The product listing
8
- # reads through it, and so does anything else that accepts a product
9
- # or variant from the buyer, so an id cannot reach what the listing
10
- # would never show.
8
+ # and wishlist items read through it, so an id cannot reach what the
9
+ # listing would never show. Carts narrow through
10
+ # {Spree::Cart#orderable_variants} instead, which asks the same
11
+ # catalogs about the cart's own buyer and company.
11
12
  module StorefrontProducts
12
13
  extend ActiveSupport::Concern
13
14
 
@@ -26,7 +27,7 @@ module Spree
26
27
 
27
28
  # @return [ActiveRecord::Relation<Spree::Variant>]
28
29
  def storefront_variants
29
- Spree::Variant.where(product_id: storefront_products.reorder(nil).select(Spree::Product.arel_table[:id]))
30
+ Spree::Variant.for_products(storefront_products)
30
31
  end
31
32
  end
32
33
  end
@@ -41,12 +41,18 @@ module Spree
41
41
  end
42
42
 
43
43
  # Renders a 401 with the shared +authentication_required+ error code.
44
- # @param message_key [String] i18n key for the error message
45
- # @param default_message [String] fallback when the key is missing
46
- def render_authentication_required(message_key, default_message)
44
+ # @param message [String] translated error message
45
+ # @param legacy_default [String, nil] deprecated: the two-argument form
46
+ # (key under +spree.+, fallback text) is removed in Spree 6.1
47
+ def render_authentication_required(message, legacy_default = nil)
48
+ unless legacy_default.nil?
49
+ Spree::Deprecation.warn('render_authentication_required(key, default) is deprecated and will be removed in Spree 6.1. Pass the translated message instead.')
50
+ message = I18n.t("spree.#{message}", default: legacy_default)
51
+ end
52
+
47
53
  render_error(
48
54
  code: ErrorHandler::ERROR_CODES[:authentication_required],
49
- message: Spree.t(message_key, default: default_message),
55
+ message: message,
50
56
  status: :unauthorized
51
57
  )
52
58
  end
@@ -57,7 +63,7 @@ module Spree
57
63
  return if try_spree_current_user.present?
58
64
  return unless current_channel&.storefront_login_required?
59
65
 
60
- render_authentication_required('api.errors.storefront_login_required', 'Authentication required to access this store')
66
+ render_authentication_required(I18n.t('spree.api.errors.storefront_login_required'))
61
67
  end
62
68
  end
63
69
  end