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
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'spree/api/preference_families'
4
+
3
5
  module Spree
4
6
  module Api
5
7
  module OpenAPI
@@ -33,6 +35,29 @@ module Spree
33
35
  end
34
36
 
35
37
  # Common schemas that are not from serializers
38
+ # The nested calculator of a promotion action and a delivery method,
39
+ # keyed by the preference family its `preferences` belong to.
40
+ CALCULATOR_SCHEMAS = {
41
+ 'PromotionCalculator' => [:PromotionActionCalculator, {
42
+ type: :object,
43
+ description: "The action's nested calculator (when the action carries one — null for actions like `free_shipping`)",
44
+ properties: {
45
+ type: { type: :string, example: 'flat_rate', description: 'Wire shorthand for the calculator subclass' },
46
+ preferences: { '$ref' => '#/components/schemas/PromotionCalculatorPreferences' }
47
+ },
48
+ required: %w[type preferences]
49
+ }],
50
+ 'DeliveryCalculator' => [:DeliveryMethodCalculator, {
51
+ type: :object,
52
+ description: 'How the delivery method prices a shipment',
53
+ properties: {
54
+ type: { type: :string, example: 'flat_rate', description: 'Wire shorthand for the calculator subclass' },
55
+ preferences: { '$ref' => '#/components/schemas/DeliveryCalculatorPreferences' }
56
+ },
57
+ required: %w[type preferences]
58
+ }]
59
+ }.freeze
60
+
36
61
  def common_schemas
37
62
  {
38
63
  PaginationMeta: {
@@ -92,7 +117,7 @@ module Spree
92
117
  properties: {
93
118
  allow: { type: :boolean, description: 'true for `can`, false for `cannot`' },
94
119
  actions: { type: :array, items: { type: :string }, description: 'Action names, e.g. ["read", "update"] or ["manage"]' },
95
- subjects: { type: :array, items: { type: :string }, description: 'Subject class names, e.g. ["Spree::Product"] or ["all"]' },
120
+ subjects: { type: :array, items: { type: :string }, description: 'Subject short names, e.g. ["product"] or ["all"]' },
96
121
  has_conditions: { type: :boolean, description: 'True if the server-side rule has per-record conditions. The SPA shows the action optimistically and handles 403 from the API.' }
97
122
  },
98
123
  required: %w[allow actions subjects has_conditions]
@@ -162,26 +187,13 @@ module Spree
162
187
  },
163
188
  required: %w[id name code]
164
189
  },
165
- PreferenceField: {
190
+ PreferenceSchema: {
166
191
  type: :object,
167
- description: 'A single configurable preference on a payment method, promotion rule/action, or calculator. The frontend uses `type` + `default` to render a sensible input.',
168
- properties: {
169
- key: { type: :string, example: 'amount_min' },
170
- type: { type: :string, example: 'decimal', description: 'string | text | password | integer | decimal | boolean | array | hash' },
171
- default: { description: 'Default value (any JSON type), null when there is no default', nullable: true }
172
- },
173
- required: %w[key type]
174
- },
175
- PromotionActionCalculator: {
176
- type: :object,
177
- description: "The action's nested calculator (when the action carries one — null for actions like `free_shipping`)",
178
- properties: {
179
- type: { type: :string, example: 'flat_rate', description: 'Wire shorthand for the calculator subclass' },
180
- label: { type: :string, example: 'Flat Rate' },
181
- preferences: { type: :object, additionalProperties: true },
182
- preference_schema: { type: :array, items: { '$ref' => '#/components/schemas/PreferenceField' } }
183
- },
184
- required: %w[type label preferences preference_schema]
192
+ description: 'The JSON Schema (draft 2020-12) of a type\'s `preferences`: one property per setting, ' \
193
+ 'with `format` (`money`, `currency`, `iso-country`, `prefixed-id`, …), `enum`, `default`, ' \
194
+ '`x-spree-secret` for a secret and `x-spree-prefix` for an id list. Unknown keys are refused.',
195
+ additionalProperties: true,
196
+ example: { type: 'object', properties: { amount: { type: 'string', format: 'money', default: '0.0' } }, additionalProperties: false }
185
197
  },
186
198
  PromotionActionLineItem: {
187
199
  type: :object,
@@ -243,7 +255,7 @@ module Spree
243
255
  Rails.logger.warn "Failed to load Typelizer admin schemas: #{e.message}"
244
256
  end
245
257
 
246
- schemas
258
+ add_preference_schemas(schemas, Spree::Api::PreferenceFamilies::REGISTRIES.keys)
247
259
  end
248
260
 
249
261
  # Get all seller schemas (Typelizer + common).
@@ -280,7 +292,7 @@ module Spree
280
292
  Rails.logger.warn "Failed to load Typelizer seller schemas: #{e.message}"
281
293
  end
282
294
 
283
- schemas
295
+ add_preference_schemas(schemas, Spree::Api::PreferenceFamilies::SELLER)
284
296
  end
285
297
 
286
298
  # Hand-written shapes the seller branch answers with that no serializer
@@ -353,45 +365,6 @@ module Spree
353
365
  },
354
366
  required: %w[status progress requirements]
355
367
  },
356
- SellerCountry: {
357
- type: :object,
358
- description: "A country as the panel's address forms need it",
359
- properties: {
360
- iso: { type: :string, example: 'US' },
361
- iso3: { type: :string, example: 'USA' },
362
- name: { type: :string, example: 'United States' },
363
- states_required: { type: :boolean, example: true },
364
- zipcode_required: { type: :boolean, example: true },
365
- states: {
366
- type: :array,
367
- items: {
368
- type: :object,
369
- properties: {
370
- abbr: { type: :string, example: 'CA' },
371
- name: { type: :string, example: 'California' }
372
- },
373
- required: %w[abbr name]
374
- }
375
- }
376
- },
377
- required: %w[iso iso3 name]
378
- },
379
- DirectUploadResponse: {
380
- type: :object,
381
- description: 'A presigned upload target. PUT the file to `direct_upload.url` with the given headers, then send `signed_id` as the submission\'s `file`.',
382
- properties: {
383
- signed_id: { type: :string, description: 'Send this as a submission\'s `file`', example: 'eyJfcmFpbHMiOnsibWVzc2FnZSI6...' },
384
- direct_upload: {
385
- type: :object,
386
- properties: {
387
- url: { type: :string, example: 'https://storage.example.com/uploads/abc123' },
388
- headers: { type: :object, additionalProperties: { type: :string } }
389
- },
390
- required: %w[url headers]
391
- }
392
- },
393
- required: %w[signed_id direct_upload]
394
- },
395
368
  AuthProvidersResponse: {
396
369
  type: :object,
397
370
  description: 'Sign-in methods this marketplace offers sellers, for the login page',
@@ -415,17 +388,45 @@ module Spree
415
388
  s[:'x-typelizer'] = true
416
389
  strip_null_from_enums(s)
417
390
  end
391
+ patch_typescript_only_types(schemas, writer_name)
418
392
  patch_cart_schema(schemas)
419
393
  patch_fulfillment_schema(schemas)
420
394
  patch_admin_user_schema(schemas)
421
395
  patch_promotion_rule_schema(schemas)
422
396
  patch_promotion_action_schema(schemas)
423
- patch_price_rule_schema(schemas)
424
397
  patch_import_schema(schemas)
425
398
  schemas
426
399
  end
427
400
  end
428
401
 
402
+ # Typelizer publishes a type only TypeScript can express (`Array<{ … }>`,
403
+ # `any`) as a plain object. Give each such property the shape the API
404
+ # sends — an array, or any value — so responses validate against it;
405
+ # the patches below then point some arrays at a named item component.
406
+ def patch_typescript_only_types(schemas, writer_name)
407
+ Typelizer.interfaces(writer_name: writer_name).each do |interface|
408
+ properties = (schemas[interface.name] || schemas[interface.name.to_sym])&.dig(:properties)
409
+ next unless properties
410
+
411
+ interface.properties.each do |property|
412
+ key = [property.name.to_s, property.name.to_sym].find { |name| properties.key?(name) }
413
+ schema = key && !property.type.is_a?(Array) && typescript_only_type_schema(property.type.to_s)
414
+ next unless schema
415
+
416
+ schema[:nullable] = true if property.nullable || property.type.to_s.end_with?('| null')
417
+ properties[key] = schema.merge(properties[key].slice(:description))
418
+ end
419
+ end
420
+ end
421
+
422
+ def typescript_only_type_schema(type)
423
+ case type.delete_suffix(' | null')
424
+ when /\AArray<(string|number|boolean)>\z/ then { type: :array, items: { type: Regexp.last_match(1).to_sym } }
425
+ when /\AArray</ then { type: :array, items: { type: :object } }
426
+ when 'any', 'unknown' then {}
427
+ end
428
+ end
429
+
429
430
  # Same Array<{...}> issue as cart/fulfillment — patch Import#schema_fields
430
431
  # to reference the ImportSchemaField component schema.
431
432
  def patch_import_schema(schemas)
@@ -504,22 +505,12 @@ module Spree
504
505
  return unless rule
505
506
 
506
507
  patch_id_arrays(rule, %w[product_ids category_ids customer_ids option_value_ids])
507
- patch_preference_schema(rule)
508
- end
509
-
510
- def patch_price_rule_schema(schemas)
511
- rule = schemas['PriceRule'] || schemas[:PriceRule]
512
- return unless rule
513
-
514
- patch_preference_schema(rule)
515
508
  end
516
509
 
517
510
  def patch_promotion_action_schema(schemas)
518
511
  action = schemas['PromotionAction'] || schemas[:PromotionAction]
519
512
  return unless action
520
513
 
521
- patch_preference_schema(action)
522
-
523
514
  props = action[:properties]
524
515
  return unless props
525
516
 
@@ -557,17 +548,72 @@ module Spree
557
548
  end
558
549
  end
559
550
 
560
- def patch_preference_schema(schema)
561
- props = schema[:properties]
562
- return unless props
551
+ # One component per subtype Spree ships (`PromotionRuleItemTotalPreferences`)
552
+ # and one per family (`PromotionRulePreferences`) that the family's
553
+ # resource points its `preferences` at. A type an extension registers
554
+ # matches the final plain object; its shape is the `schema` in the
555
+ # family's `/types` response.
556
+ #
557
+ # @param schemas [Hash] components, changed in place
558
+ # @param families [Array<String>]
559
+ # @return [Hash] the components
560
+ def add_preference_schemas(schemas, families)
561
+ Spree::Api::PreferenceFamilies.schemas(families).each do |family, members|
562
+ refs = members.to_h do |type, schema|
563
+ name = Spree::Api::PreferenceFamilies.member_name(family, type)
564
+ schemas[name] = openapi_schema(schema)
565
+ [type, "#/components/schemas/#{name}"]
566
+ end
563
567
 
564
- key = props.key?('preference_schema') ? 'preference_schema' : :preference_schema
565
- return unless props[key]
568
+ schemas["#{family}Preferences"] = {
569
+ description: "Settings of a #{family.titleize.downcase}, shaped by its `type` (see `x-spree-preferences-by-type`). " \
570
+ 'A type an extension registers is a plain object, described by the `schema` its `/types` entry carries.',
571
+ anyOf: refs.values.map { |ref| { '$ref' => ref } } + [{ type: :object, additionalProperties: true }],
572
+ 'x-spree-preferences-by-type' => refs
573
+ }
566
574
 
567
- props[key] = {
568
- type: :array,
569
- items: { '$ref' => '#/components/schemas/PreferenceField' }
570
- }
575
+ resource = schemas[family] || schemas[family.to_sym]
576
+ props = resource&.dig(:properties)
577
+ key = props&.key?('preferences') ? 'preferences' : :preferences
578
+ props[key] = { '$ref' => "#/components/schemas/#{family}Preferences" } if props&.key?(key)
579
+ end
580
+
581
+ # A calculator names its family's union, so it is published only
582
+ # alongside that union.
583
+ CALCULATOR_SCHEMAS.slice(*families).each_value { |name, schema| schemas[name] = schema }
584
+ patch_delivery_method_calculator(schemas)
585
+ schemas
586
+ end
587
+
588
+ # The generated JSON Schema is draft 2020-12; OpenAPI 3.0 spells a
589
+ # nullable type as `nullable: true` and has no `propertyNames`.
590
+ def openapi_schema(schema)
591
+ case schema
592
+ when Hash
593
+ converted = schema.each_with_object({}) do |(key, value), result|
594
+ next if key == 'propertyNames'
595
+
596
+ result[key] = %w[enum default required].include?(key) ? value : openapi_schema(value)
597
+ end
598
+ if schema['type'].is_a?(Array)
599
+ converted['type'] = (schema['type'] - ['null']).first
600
+ converted['nullable'] = true if schema['type'].include?('null')
601
+ end
602
+ converted['enum'] = converted['enum'].compact if converted['enum']
603
+ converted['x-spree-property-names'] = openapi_schema(schema['propertyNames']) if schema['propertyNames']
604
+ converted
605
+ when Array then schema.map { |item| openapi_schema(item) }
606
+ else schema
607
+ end
608
+ end
609
+
610
+ def patch_delivery_method_calculator(schemas)
611
+ method = schemas['DeliveryMethod'] || schemas[:DeliveryMethod]
612
+ props = method&.dig(:properties)
613
+ return unless props
614
+
615
+ key = props.key?('calculator') ? 'calculator' : :calculator
616
+ props[key] = { allOf: [{ '$ref' => '#/components/schemas/DeliveryMethodCalculator' }], nullable: true } if props[key]
571
617
  end
572
618
 
573
619
  # Typelizer cannot represent Array<{...}> inline object types in OpenAPI,
@@ -0,0 +1,46 @@
1
+ module Spree
2
+ module Api
3
+ # The configurable families whose subtypes each declare their own
4
+ # `preferences`: the subtypes Spree ships, keyed by their wire `type`, with
5
+ # the JSON Schema of each one's preferences. The OpenAPI components and the
6
+ # SDK's preference types are both generated from it, so the two cannot
7
+ # describe different shapes.
8
+ module PreferenceFamilies
9
+ # Family name => its registry. The name is the resource the family's
10
+ # rows are serialized as, or, for calculators, the calculator's role.
11
+ REGISTRIES = {
12
+ 'CommissionRule' => -> { Spree.commission_rules },
13
+ 'DeliveryCalculator' => -> { Spree::DeliveryMethod.calculators },
14
+ 'DeliveryMethodRule' => -> { Spree.delivery_method_rules },
15
+ 'Integration' => -> { Spree::Integration.registered_classes },
16
+ 'OrderRoutingRule' => -> { Spree.order_routing.rules },
17
+ 'PaymentMethod' => -> { Spree::PaymentMethod.providers },
18
+ 'PriceRule' => -> { Array(Spree.pricing&.rules) },
19
+ 'PromotionCalculator' => lambda {
20
+ Spree.calculators.promotion_actions_create_adjustments + Spree.calculators.promotion_actions_create_item_adjustments
21
+ },
22
+ 'PromotionRule' => -> { Spree.promotions.rules },
23
+ 'SellerRequirement' => -> { Spree.seller_requirements }
24
+ }.freeze
25
+
26
+ # The families a seller reads and writes.
27
+ SELLER = %w[DeliveryCalculator DeliveryMethodRule].freeze
28
+
29
+ # @param names [Array<String>] family names, every family by default
30
+ # @return [Hash{String => Hash{String => Hash}}] family => { type => JSON Schema of its preferences }
31
+ def self.schemas(names = REGISTRIES.keys)
32
+ names.to_h do |name|
33
+ classes = REGISTRIES.fetch(name).call.map { |entry| entry.is_a?(Class) ? entry : entry.to_s.constantize }
34
+ [name, classes.uniq.sort_by(&:api_type).to_h { |klass| [klass.api_type, klass.preference_json_schema] }]
35
+ end
36
+ end
37
+
38
+ # @param family [String] e.g. `PromotionRule`
39
+ # @param type [String] e.g. `item_total`
40
+ # @return [String] e.g. `PromotionRuleItemTotalPreferences`
41
+ def self.member_name(family, type)
42
+ "#{family}#{type.camelize}Preferences"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,138 @@
1
+ require 'spree/api/preference_families'
2
+
3
+ module Spree
4
+ module Api
5
+ # Renders each configurable family's preference schemas
6
+ # ({Spree::Api::PreferenceFamilies}) into the TypeScript types the Admin
7
+ # and Seller SDKs export: one interface per subtype Spree ships, a map from
8
+ # `type` to it, and the family's resource with `preferences` typed by its
9
+ # `type`.
10
+ #
11
+ # The map is an interface, so an extension types its own subtypes by
12
+ # declaration merging. A union with a catch-all member for unknown types
13
+ # would stop TypeScript from narrowing on `type` at all.
14
+ #
15
+ # Run by `rake typelizer:generate`; `preference_types_spec.rb` fails when
16
+ # the committed files no longer match the declarations.
17
+ class PreferenceTypes
18
+ HEADER = "// This file is auto-generated from Spree's preference declarations by `rake typelizer:generate`. Do not edit directly.\n".freeze
19
+
20
+ FILES = {
21
+ 'packages/admin-sdk/src/types/preferences.ts' => PreferenceFamilies::REGISTRIES.keys,
22
+ 'packages/seller-sdk/src/types/preferences.ts' => PreferenceFamilies::SELLER
23
+ }.freeze
24
+
25
+ # Families serialized as rows of their own; calculators are nested in
26
+ # their owner, whose serializer types `calculator` with `Typed<Family>`.
27
+ RESOURCES = (PreferenceFamilies::REGISTRIES.keys - %w[DeliveryCalculator PromotionCalculator]).freeze
28
+
29
+ # @return [Hash{String => String}] file contents keyed by path under the monorepo root
30
+ def render
31
+ FILES.transform_values { |families| source(PreferenceFamilies.schemas(families)) }
32
+ end
33
+
34
+ # Typelizer imports a type a serializer names (`TypedDeliveryCalculator`)
35
+ # from its generated index, so that index re-exports these types too.
36
+ INDEX_EXPORT = "export type * from '../preferences'\n".freeze
37
+
38
+ # @param root [Pathname] the monorepo root
39
+ # @return [void]
40
+ def write!(root)
41
+ render.each do |path, content|
42
+ File.write(root.join(path), content)
43
+
44
+ index = root.join(path).dirname.join('generated/index.ts')
45
+ File.write(index, index.read + INDEX_EXPORT) if index.exist? && !index.read.include?(INDEX_EXPORT)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ NARROWED = <<~TS.freeze
52
+ /** `Resource` with its `preferences` typed by its `type`, one member per entry of `Map`. */
53
+ type Narrowed<Resource, Map> = {
54
+ [Type in keyof Map]: Omit<Resource, 'type' | 'preferences'> & {
55
+ type: Type
56
+ preferences: Map[Type]
57
+ }
58
+ }[keyof Map]
59
+ TS
60
+
61
+ def source(families)
62
+ resources = families.keys & RESOURCES
63
+ imports = resources.map { |family| "import type #{family} from './generated/#{family}'\n" }.join
64
+ parts = families.flat_map { |family, members| family_parts(family, members, resources.include?(family)) }
65
+ parts.unshift(NARROWED) if resources.any?
66
+ parts.unshift(imports) if imports.present?
67
+
68
+ HEADER + parts.join("\n")
69
+ end
70
+
71
+ def family_parts(family, members, resource)
72
+ label = family.titleize.downcase
73
+ parts = members.map do |type, schema|
74
+ name = PreferenceFamilies.member_name(family, type)
75
+ properties = schema['properties']
76
+ next "/** Settings of the `#{type}` #{label}: none. */\nexport type #{name} = Record<string, never>\n" if properties.empty?
77
+
78
+ fields = properties.map { |key, property| "#{field_comment(property)} #{key}: #{ts_type(property)}\n" }.join
79
+ # A type, not an interface, so it stays assignable to
80
+ # `Record<string, unknown>`, which generic preference forms take.
81
+ "/** Settings of the `#{type}` #{label}. */\nexport type #{name} = {\n#{fields}}\n"
82
+ end
83
+
84
+ map = "#{family}PreferencesMap"
85
+ entries = members.keys.map { |type| " #{type}: #{PreferenceFamilies.member_name(family, type)}\n" }.join
86
+ ignore = members.empty? ? "// biome-ignore lint/suspicious/noEmptyInterface: extensions add their types by declaration merging\n" : ''
87
+ parts << "/**\n * The settings of each #{label} type Spree ships, by `type`. An interface,\n" \
88
+ " * so an extension types its own by declaration merging.\n */\n" \
89
+ "#{ignore}export interface #{map} {#{"\n#{entries}" if entries.present?}}\n"
90
+ article = label.match?(/\A[aeiou]/) ? 'An' : 'A'
91
+ parts << if resource
92
+ "/** #{article} #{label} whose `preferences` are typed by its `type`. */\nexport type Typed#{family} = Narrowed<#{family}, #{map}>\n"
93
+ else
94
+ # A calculator is nested in its owner, which types its
95
+ # `calculator` field with this union.
96
+ "/** #{article} #{label}, its `preferences` typed by its `type`. */\n" \
97
+ "export type Typed#{family} = {\n [Type in keyof #{map}]: {\n type: Type\n preferences: #{map}[Type]\n }\n}[keyof #{map}]\n"
98
+ end
99
+ parts
100
+ end
101
+
102
+ def field_comment(property)
103
+ note = if property['x-spree-secret'] then 'Masked when read (`••••1234`); send it back unchanged to keep it, `null` to clear it.'
104
+ elsif property.dig('items', 'x-spree-prefix') then "Prefixed `#{property.dig('items', 'x-spree-prefix')}_` ids."
105
+ elsif property['format'] == 'money' then 'An amount, as an exact decimal string.'
106
+ elsif property['format'] then "Format: `#{property['format']}`."
107
+ end
108
+ note ? " /** #{note} */\n" : ''
109
+ end
110
+
111
+ def ts_type(schema)
112
+ types = Array(schema['type'])
113
+ base = base_type(schema, (types - ['null']).first)
114
+ types.include?('null') ? "#{base} | null" : base
115
+ end
116
+
117
+ def base_type(schema, type)
118
+ return schema['enum'].compact.map { |value| value.is_a?(String) ? "'#{value}'" : value.to_s }.join(' | ') if schema['enum']
119
+
120
+ case type
121
+ when 'string' then 'string'
122
+ when 'integer', 'number' then 'number'
123
+ when 'boolean' then 'boolean'
124
+ when 'array' then schema['items'] ? "Array<#{ts_type(schema['items'])}>" : 'Array<unknown>'
125
+ when 'object'
126
+ if schema['properties']
127
+ "{ #{schema['properties'].map { |key, property| "#{key}: #{ts_type(property)}" }.join('; ')} }"
128
+ elsif schema['additionalProperties'].is_a?(Hash)
129
+ "Record<string, #{ts_type(schema['additionalProperties'])}>"
130
+ else
131
+ 'Record<string, unknown>'
132
+ end
133
+ else 'unknown'
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,39 @@
1
+ module Spree
2
+ module Api
3
+ # Generates every SDK's TypeScript types from the serializers, the email
4
+ # template types included. Runs inside spree_emails' test app, the one
5
+ # place where the API's and the email serializers are all loaded: running
6
+ # it with any serializer missing would delete that serializer's types.
7
+ module TypelizerGeneration
8
+ # @param serializer_dirs [Array<String, Pathname>] directories to load before generating
9
+ def self.call(serializer_dirs)
10
+ serializer_dirs.each { |dir| Rails.autoloaders.main.eager_load_dir(dir.to_s) }
11
+
12
+ require 'typelizer/generator'
13
+ Typelizer::Generator.call(force: true)
14
+
15
+ # `interface` rather than `type`, so SDK consumers can extend generated
16
+ # types through declaration merging.
17
+ api_root = Spree::Api::Engine.root
18
+ [api_root.join('../../packages/sdk/src/types/generated'), api_root.join('../../packages/admin-sdk/src/types/generated'),
19
+ api_root.join('../../packages/admin-sdk/src/types/generated/emails')].each do |dir|
20
+ Dir[File.join(dir, '*.ts')].each do |file|
21
+ next if File.basename(file) == 'index.ts'
22
+
23
+ content = File.read(file)
24
+ updated = content.gsub(/^type (\w+) = \{/, 'interface \1 {')
25
+ File.write(file, updated) if updated != content
26
+ end
27
+ end
28
+
29
+ # The typed webhook events in @spree/sdk, from the event catalog.
30
+ require Spree::Api::Engine.root.join('lib/spree/api/webhook_event_types').to_s
31
+ Spree::Api::WebhookEventTypes.new.write!(api_root.join('../..'))
32
+
33
+ # Each configurable family's preferences, typed by `type`, in the Admin and Seller SDKs.
34
+ require Spree::Api::Engine.root.join('lib/spree/api/preference_types').to_s
35
+ Spree::Api::PreferenceTypes.new.write!(api_root.join('../..'))
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,140 @@
1
+ module Spree
2
+ module Api
3
+ # Renders the event catalog ({Spree::Events.catalog}) into the typed event
4
+ # map `@spree/sdk/webhooks` exports and the matching Zod schema map, so a
5
+ # webhook consumer's `event.name` check narrows `event.data` to the record
6
+ # the event carries.
7
+ #
8
+ # Run by `rake typelizer:generate`; `webhook_event_types_spec.rb` fails when
9
+ # the committed files no longer match the catalog.
10
+ class WebhookEventTypes
11
+ # The payload of an event whose record has no Store serializer.
12
+ RECORD_REFERENCE = 'WebhookRecordReference'.freeze
13
+ BACK_OFFICE_SERIALIZER = /\ASpree::Api::V3::\w+::/
14
+ HEADER = "// This file is auto-generated from Spree's event catalog by `rake typelizer:generate`. Do not edit directly.\n".freeze
15
+
16
+ FILES = {
17
+ types: 'packages/sdk/src/webhooks/generated/events.ts',
18
+ schemas: 'packages/sdk/src/webhooks/generated/schemas.ts'
19
+ }.freeze
20
+
21
+ # @param catalog [Spree::Events::Catalog]
22
+ def initialize(catalog = Spree::Events.catalog)
23
+ @catalog = catalog
24
+ end
25
+
26
+ # @return [Hash{Symbol => String}] file contents keyed like {FILES}
27
+ def render
28
+ { types: types_source, schemas: schemas_source }
29
+ end
30
+
31
+ # Writes both files under the monorepo root.
32
+ #
33
+ # @param root [Pathname]
34
+ # @return [void]
35
+ def write!(root)
36
+ render.each do |key, source|
37
+ path = root.join(FILES.fetch(key))
38
+ FileUtils.mkdir_p(path.dirname)
39
+ File.write(path, source)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ attr_reader :catalog
46
+
47
+ def entries
48
+ @entries ||= catalog.webhook_events
49
+ end
50
+
51
+ def payload_type_names
52
+ @payload_type_names ||= type_names.values.uniq.sort - [RECORD_REFERENCE]
53
+ end
54
+
55
+ def type_name(entry)
56
+ type_names.fetch(entry.name)
57
+ end
58
+
59
+ def type_names
60
+ @type_names ||= entries.to_h { |entry| [entry.name, resolve_type_name(entry)] }
61
+ end
62
+
63
+ # Named the way the Store SDK's type writer names it. A back-office shape
64
+ # stays behind the Admin API even when a Store-level class inherits it
65
+ # (docs/plans/6.0-typed-webhook-events.md).
66
+ def resolve_type_name(entry)
67
+ serializer = entry.payload_serializer
68
+ return RECORD_REFERENCE unless serializer
69
+
70
+ back_office = serializer.ancestors.grep(Class).any? { |ancestor| ancestor.name.to_s.match?(BACK_OFFICE_SERIALIZER) }
71
+ if back_office || store_writer.reject_class.call(serializer: serializer)
72
+ raise ArgumentError, "#{entry.name} is built by #{serializer.name}, which is not a Store API serializer"
73
+ end
74
+
75
+ store_writer.serializer_name_mapper.call(serializer)
76
+ end
77
+
78
+ def store_writer
79
+ Typelizer.configuration.writers.fetch(:store)
80
+ end
81
+
82
+ def types_source
83
+ <<~TS
84
+ #{HEADER}import type {
85
+ #{payload_type_names.map { |name| " #{name}," }.join("\n")}
86
+ } from '../../types/generated'
87
+
88
+ /** The payload of an event whose record has no Store API representation. */
89
+ export interface #{RECORD_REFERENCE} {
90
+ id: string
91
+ created_at: string | null
92
+ updated_at: string | null
93
+ }
94
+
95
+ /**
96
+ * Every webhook event Spree publishes, mapped to the record its `data`
97
+ * carries. An interface, so an extension adds its own events by
98
+ * declaration merging.
99
+ */
100
+ export interface WebhookEventMap {
101
+ #{entries.map { |entry| map_line(entry) }.join("\n")}
102
+ }
103
+ TS
104
+ end
105
+
106
+ def map_line(entry)
107
+ notes = []
108
+ notes << "@deprecated Use `#{entry.deprecated_alias_of}` instead." if entry.deprecated?
109
+ notes << 'Carries a live credential: delivered only to endpoints that name this event.' if entry.credential?
110
+ comment = notes.map { |note| " /** #{note} */\n" }.join
111
+ "#{comment} '#{entry.name}': #{type_name(entry)}"
112
+ end
113
+
114
+ def schemas_source
115
+ schema_names = payload_type_names.map { |name| "#{name}Schema" }
116
+
117
+ <<~TS
118
+ #{HEADER}import { z } from 'zod'
119
+ import {
120
+ #{schema_names.map { |name| " #{name}," }.join("\n")}
121
+ } from '../../zod/generated'
122
+
123
+ export const #{RECORD_REFERENCE}Schema = z.object({
124
+ id: z.string(),
125
+ created_at: z.string().nullable(),
126
+ updated_at: z.string().nullable(),
127
+ })
128
+
129
+ type WebhookEventName =
130
+ #{entries.map { |entry| " | '#{entry.name}'" }.join("\n")}
131
+
132
+ /** The Zod schema for each webhook event's `data`, for `constructWebhookEvent`'s `schemas` option. */
133
+ export const webhookEventSchemas: Readonly<Record<WebhookEventName, z.ZodType>> = {
134
+ #{entries.map { |entry| " '#{entry.name}': #{type_name(entry)}Schema," }.join("\n")}
135
+ }
136
+ TS
137
+ end
138
+ end
139
+ end
140
+ end
data/lib/spree/api.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  require 'spree/core'
2
2
  require 'pagy'
3
- require 'alba'
4
- require 'oj'
5
3
  require 'typelizer'
6
4
  require 'typelizer/proc_resource_resolution'
7
5
  require 'typelizer/open_enums'