spree_api 6.0.0.rc2 → 6.0.0.rc4

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/spree/api/v3/admin/email_template_lookup.rb +6 -1
  3. data/app/controllers/concerns/spree/api/v3/admin/reporting_authorization.rb +17 -8
  4. data/app/controllers/concerns/spree/api/v3/admin/store_context.rb +7 -0
  5. data/app/controllers/concerns/spree/api/v3/admin_authentication.rb +61 -0
  6. data/app/controllers/concerns/spree/api/v3/error_handler.rb +49 -0
  7. data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +76 -7
  8. data/app/controllers/concerns/spree/api/v3/scoped_authorization.rb +60 -3
  9. data/app/controllers/concerns/spree/api/v3/store/search_provider_support.rb +8 -3
  10. data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +11 -5
  11. data/app/controllers/spree/api/v3/admin/concerns/external_references.rb +3 -0
  12. data/app/controllers/spree/api/v3/admin/exports_controller.rb +15 -3
  13. data/app/controllers/spree/api/v3/admin/imports_controller.rb +12 -3
  14. data/app/controllers/spree/api/v3/admin/markets_controller.rb +3 -1
  15. data/app/controllers/spree/api/v3/admin/me_controller.rb +21 -1
  16. data/app/controllers/spree/api/v3/admin/oauth/application_tokens_controller.rb +56 -0
  17. data/app/controllers/spree/api/v3/admin/oauth/applications_controller.rb +55 -0
  18. data/app/controllers/spree/api/v3/admin/oauth/authorizations_controller.rb +294 -0
  19. data/app/controllers/spree/api/v3/admin/order_groups_controller.rb +1 -1
  20. data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +8 -0
  21. data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +1 -0
  22. data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +7 -0
  23. data/app/controllers/spree/api/v3/admin/orders_controller.rb +9 -2
  24. data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +1 -0
  25. data/app/controllers/spree/api/v3/admin/reporting_controller.rb +20 -14
  26. data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +1 -1
  27. data/app/controllers/spree/api/v3/admin/tags_controller.rb +8 -5
  28. data/app/controllers/spree/api/v3/admin/tax_exemption_reasons_controller.rb +58 -0
  29. data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +0 -1
  30. data/app/controllers/spree/api/v3/admin/translations/batches_controller.rb +17 -11
  31. data/app/controllers/spree/api/v3/oauth/authorizations_controller.rb +61 -0
  32. data/app/controllers/spree/api/v3/oauth/metadata_controller.rb +57 -0
  33. data/app/controllers/spree/api/v3/oauth/server_metadata_controller.rb +57 -0
  34. data/app/controllers/spree/api/v3/resource_controller.rb +1 -0
  35. data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +13 -1
  36. data/app/controllers/spree/api/v3/store/carts_controller.rb +4 -7
  37. data/app/request_schemas/spree/api/v3/admin/email_template_preview_request_schema.rb +4 -0
  38. data/app/request_schemas/spree/api/v3/store/address_request_schema.rb +2 -0
  39. data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +2 -0
  40. data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +2 -0
  41. data/app/serializers/spree/api/v3/admin/oauth_access_token_serializer.rb +62 -0
  42. data/app/serializers/spree/api/v3/admin/oauth_application_serializer.rb +56 -0
  43. data/app/serializers/spree/api/v3/admin/oauth_consent_request_serializer.rb +25 -0
  44. data/app/serializers/spree/api/v3/admin/oauth_protected_resource_serializer.rb +27 -0
  45. data/app/serializers/spree/api/v3/admin/oauth_redirect_serializer.rb +17 -0
  46. data/app/serializers/spree/api/v3/admin/payment_capture_event_serializer.rb +16 -0
  47. data/app/serializers/spree/api/v3/admin/payment_serializer.rb +12 -1
  48. data/app/serializers/spree/api/v3/admin/price_history_serializer.rb +1 -0
  49. data/app/serializers/spree/api/v3/admin/price_serializer.rb +2 -0
  50. data/app/serializers/spree/api/v3/admin/return_serializer.rb +2 -0
  51. data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +7 -3
  52. data/app/serializers/spree/api/v3/admin/tax_exemption_reason_serializer.rb +20 -0
  53. data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +1 -2
  54. data/app/serializers/spree/api/v3/admin/webhook_delivery_serializer.rb +4 -1
  55. data/app/serializers/spree/api/v3/base_serializer.rb +14 -0
  56. data/app/serializers/spree/api/v3/cart_serializer.rb +5 -1
  57. data/app/serializers/spree/api/v3/price_history_serializer.rb +6 -1
  58. data/app/serializers/spree/api/v3/price_serializer.rb +11 -1
  59. data/app/serializers/spree/api/v3/seller/price_history_serializer.rb +1 -0
  60. data/app/serializers/spree/api/v3/seller/price_serializer.rb +2 -0
  61. data/config/routes.rb +61 -1
  62. data/lib/spree/api/agent_membership_map.rb +73 -0
  63. data/lib/spree/api/agent_resource_map.rb +350 -0
  64. data/lib/spree/api/agent_workflow_endpoints.rb +113 -0
  65. data/lib/spree/api/agent_write_schemas.rb +119 -0
  66. data/lib/spree/api/dependencies.rb +4 -3
  67. data/lib/spree/api/engine.rb +40 -0
  68. data/lib/spree/api/extension_fields.rb +167 -0
  69. data/lib/spree/api/oauth.rb +243 -0
  70. data/lib/spree/api.rb +8 -0
  71. data/lib/typelizer/open_enums.rb +17 -3
  72. metadata +26 -6
@@ -0,0 +1,243 @@
1
+ module Spree
2
+ module Api
3
+ # OAuth 2.1 authorization server for the Spree API.
4
+ #
5
+ # Spree is the authorization server here, not a client of one: a
6
+ # self-hosted store has no external identity provider to delegate to, and
7
+ # requiring one would exclude the installations this exists for. This is
8
+ # the opposite direction from SSO login, which makes Spree an OIDC client
9
+ # so staff can sign in through a provider; the two share a spec family and
10
+ # almost no code.
11
+ #
12
+ # The first consumer is the Admin MCP server, whose consumer clients
13
+ # (hosted connectors) accept no other credential. A marketplace app or a
14
+ # merchant-approved integration is the same flow with a different client,
15
+ # which is why this lives in `spree_api` rather than in any one gem that
16
+ # happens to need it.
17
+ module Oauth
18
+ # Protected resources, each registered by the surface that owns it as a
19
+ # path relative to this application's own origin.
20
+ #
21
+ # Spree::Api::Oauth.register_resource(:admin, '/api/v3/admin')
22
+ #
23
+ # A path rather than a full URL because the identifier must equal the
24
+ # URL the client was actually pointed at: the origin comes from the
25
+ # request where there is one, and from the application's configured
26
+ # URL options otherwise. A store's own `url` column is deliberately not
27
+ # consulted — it describes the storefront, which is frequently neither
28
+ # the host nor the scheme the Admin API answers on.
29
+ # Whether a redirect URI points at the machine the client runs on.
30
+ #
31
+ # Decided by parsing the host as an address, the same way Doorkeeper
32
+ # does when it ignores the port of a loopback redirect — so `localhost`
33
+ # is deliberately not loopback here either, and a registration must use
34
+ # the IP literal for an ephemeral port to match.
35
+ #
36
+ # @param uri [URI, String]
37
+ # @return [Boolean]
38
+ def self.loopback_uri?(uri)
39
+ host = uri.respond_to?(:host) ? uri.host : URI.parse(uri.to_s).host
40
+ return false if host.blank?
41
+
42
+ IPAddr.new(host).loopback?
43
+ rescue StandardError
44
+ false
45
+ end
46
+
47
+ mattr_accessor :resources, default: {}
48
+
49
+ class << self
50
+ # @param key [Symbol]
51
+ # @param path [String] absolute path this resource answers on
52
+ def register_resource(key, path)
53
+ resources[key.to_sym] = path
54
+ end
55
+
56
+ # @param origin [String, nil] scheme and host the client used
57
+ # @return [Array<String>] every resource identifier this installation
58
+ # serves
59
+ def resource_identifiers(origin = nil)
60
+ base = origin.presence || application_origin
61
+ resources.values.map { |path| "#{base}#{path}" }
62
+ end
63
+
64
+ # @param key [Symbol]
65
+ # @param path [String] absolute path this resource answers on
66
+ def register_resource(key, path)
67
+ resources[key.to_sym] = path
68
+ end
69
+
70
+ # @param origin [String, nil] scheme and host the client used
71
+ # @return [Array<String>] every resource identifier this installation
72
+ # serves
73
+ def resource_identifiers(origin = nil)
74
+ base = origin.presence || application_origin
75
+ resources.values.map { |path| "#{base}#{path}" }
76
+ end
77
+
78
+ # @param key [Symbol]
79
+ # @param origin [String, nil] scheme and host the client used
80
+ # @return [String, nil]
81
+ def resource_identifier(key, origin = nil)
82
+ path = resources[key.to_sym]
83
+ return if path.nil?
84
+
85
+ "#{origin.presence || application_origin}#{path}"
86
+ end
87
+
88
+ # Where this application answers, from the URL options a deployment
89
+ # already has to set for mailer links to work.
90
+ #
91
+ # @return [String]
92
+ def application_origin
93
+ options = Rails.application.routes.default_url_options
94
+ host = options[:host]
95
+ return '' if host.blank?
96
+
97
+ origin = "#{options[:protocol].presence || 'https'}://#{host}"
98
+ options[:port].present? ? "#{origin}:#{options[:port]}" : origin
99
+ end
100
+
101
+ # The grantable scope list, re-read after host and extension
102
+ # initializers have run.
103
+ #
104
+ # `optional_scopes` builds its value eagerly, and an extension
105
+ # registers its scopes from a config initializer — which runs after
106
+ # {.configure!}, because a host's own `doorkeeper.rb` has to be able
107
+ # to win. Without this second pass the vocabulary would be whatever
108
+ # core shipped, and an extension's keys could never be granted.
109
+ def refresh_scopes!
110
+ ::Doorkeeper.config.instance_variable_set(
111
+ :@optional_scopes,
112
+ ::Doorkeeper::OAuth::Scopes.from_array(staff_scope_keys)
113
+ )
114
+ end
115
+
116
+ # Scopes that govern credentials rather than commerce, and so are
117
+ # never offered to a delegated client.
118
+ #
119
+ # Granting an agent `write_oauth_applications` would let it connect another
120
+ # agent; `write_api_keys` would let it mint a key that outlives the
121
+ # grant it was given. Neither is an escalation a merchant could
122
+ # reasonably be asked to judge on a consent screen, and the tools
123
+ # withhold the models anyway — so the scopes should not be offered in
124
+ # the first place, rather than offered and quietly inert.
125
+ CREDENTIAL_SCOPES = %w[oauth_applications api_keys integrations webhooks staff].freeze
126
+
127
+ # @return [Array<String>]
128
+ def staff_scope_keys
129
+ Spree.permissions.grantable_keys(Spree::PermissionConfiguration::STAFF_AUDIENCE).
130
+ reject { |key| CREDENTIAL_SCOPES.any? { |scope| key.to_s.end_with?("_#{scope}") } }
131
+ end
132
+
133
+ # Whether every requested audience names a resource this application
134
+ # actually serves.
135
+ #
136
+ # Compared by path rather than by full URL: the origin a client used
137
+ # is whatever it was pointed at, and a deployment behind a proxy or
138
+ # reachable at several hostnames would otherwise refuse its own
139
+ # tokens.
140
+ #
141
+ # @param requested [Array<String>] the `resource` values asked for
142
+ # @return [Boolean]
143
+ def indicators_valid?(requested, _client = nil)
144
+ return false if requested.blank?
145
+
146
+ paths = resources.values
147
+ requested.all? do |indicator|
148
+ path = URI.parse(indicator.to_s).path
149
+ paths.include?(path)
150
+ rescue URI::InvalidURIError
151
+ false
152
+ end
153
+ end
154
+
155
+ def configure!
156
+ ::Doorkeeper.configure do
157
+ orm :active_record
158
+
159
+ application_class 'Spree::OauthApplication'
160
+ access_grant_class 'Spree::OauthAccessGrant'
161
+ access_token_class 'Spree::OauthAccessToken'
162
+
163
+ # Consent is Spree's own, at
164
+ # `Spree::Api::V3::Admin::Oauth::AuthorizationsController`, and
165
+ # Doorkeeper's authorization controllers are not mounted — so
166
+ # this is only reached if a host app mounts them. Failing loudly
167
+ # beats a NoMethodError inside a before_action, which
168
+ # `handle_auth_errors :raise` would turn into a 500 on an
169
+ # authorization endpoint.
170
+ resource_owner_authenticator do
171
+ raise "Doorkeeper's own consent screens are not mounted in Spree. " \
172
+ 'Consent is served by the Admin API at /api/v3/admin/oauth/authorize.'
173
+ end
174
+
175
+ # An admin user today, a customer when a storefront client needs
176
+ # one — recorded polymorphically so either can own a grant.
177
+ use_polymorphic_resource_owner
178
+
179
+ # Authorization code only. A password grant asks a client to
180
+ # handle someone's password, and client credentials identify no
181
+ # person, so neither belongs on a surface whose authority is a
182
+ # user's own permissions.
183
+ grant_flows %w[authorization_code]
184
+
185
+ # Mandatory, not merely supported: these are public clients, and
186
+ # without PKCE an intercepted code is enough to obtain a token.
187
+ force_pkce
188
+ # S256 only — `plain` is in the gem's defaults and protects
189
+ # nothing against an intercepted code.
190
+ pkce_code_challenge_methods %w[S256]
191
+
192
+ # A redirect URI is where authorization codes are delivered, so a
193
+ # plain-http one hands them to anyone on the path — except a
194
+ # loopback one, which never leaves the machine. A terminal client
195
+ # listens on an ephemeral local port and has no certificate for
196
+ # it, so RFC 8252 §7.3 makes that the recommended shape, and
197
+ # refusing it would lock out Claude Code and Codex entirely.
198
+ #
199
+ # Passed as a callable so the exemption is per URI rather than
200
+ # per environment: everything else still has to be https.
201
+ force_ssl_in_redirect_uri do |uri|
202
+ next false if Rails.env.development?
203
+
204
+ !Spree::Api::Oauth.loopback_uri?(uri)
205
+ end
206
+
207
+ # RFC 8707. Registering the validator is what binds an audience
208
+ # into the token; left nil, the `resource` parameter is ignored
209
+ # and a token minted for another service would be accepted.
210
+ resource_indicator_validator(lambda do |requested, _client|
211
+ Spree::Api::Oauth.indicators_valid?(requested)
212
+ end)
213
+
214
+ # Spree's own permission catalog is the scope vocabulary, so a
215
+ # grant carries the same keys an API key would and the tool
216
+ # registry needs no translation. Seeded here and re-read in
217
+ # `refresh_scopes!` once extensions have registered theirs.
218
+ optional_scopes(*Spree::Api::Oauth.staff_scope_keys)
219
+
220
+ use_refresh_token
221
+ # One live token per authorization, so re-consenting does not
222
+ # leave the previous one usable.
223
+ revoke_previous_authorization_code_token
224
+ # No `fallback: :plain`: every token this server writes is
225
+ # hashed, so a plaintext lookup could never match and keeping
226
+ # the path alive only invites a future migration to rely on it.
227
+ hash_token_secrets
228
+ access_token_expires_in 2.hours
229
+ # Refresh rotation with replay detection comes from the
230
+ # `previous_refresh_token` column the migration adds — Doorkeeper
231
+ # enables it by the column's presence, not by a setting.
232
+
233
+ api_only
234
+ handle_auth_errors :raise
235
+ # Never from a query parameter: the spec forbids it, and a URL
236
+ # reaches logs and proxies.
237
+ access_token_methods :from_bearer_authorization
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end
data/lib/spree/api.rb CHANGED
@@ -3,6 +3,7 @@ require 'pagy'
3
3
  require 'typelizer'
4
4
  require 'typelizer/proc_resource_resolution'
5
5
  require 'typelizer/open_enums'
6
+ require 'spree/api/extension_fields'
6
7
 
7
8
  module Spree
8
9
  module Api
@@ -40,6 +41,13 @@ module Spree
40
41
  api_dependency?(base_name) || super
41
42
  end
42
43
 
44
+ # Fields extensions add to core serializers' responses.
45
+ #
46
+ # @return [Spree::Api::ExtensionFields]
47
+ def extension_fields
48
+ @extension_fields ||= Spree::Api::ExtensionFields.new
49
+ end
50
+
43
51
  # Direct access to raw dependencies object for backwards compatibility
44
52
  def dependencies
45
53
  Spree::Api::Dependencies
@@ -11,16 +11,30 @@ module Typelizer
11
11
  # ISO lists are the exception: a named type several serializers and the
12
12
  # request types share, but closed, since nothing outside the standard can
13
13
  # add a country or a currency, and markets only accept the locales
14
- # `Spree::Locales::ALL` lists.
14
+ # `Spree::Locales::ALL` lists. The SDKs define them once, as values and
15
+ # types, in `@spree/sdk-core` (generated from the API reference by
16
+ # `pnpm generate:iso-codes`), so each SDK's `Enums.ts` re-exports that
17
+ # definition instead of carrying a copy of the list.
15
18
  module OpenEnums
16
19
  CLOSED_TYPE_NAMES = %w[CountryCode CurrencyCode LocaleCode].freeze
17
20
 
18
21
  module Property
19
22
  def enum_definition(...)
20
23
  definition = super
21
- return definition if CLOSED_TYPE_NAMES.include?(enum_type_name)
24
+ return definition unless definition
25
+ return "type { #{enum_type_name} } from '@spree/sdk-core'" if CLOSED_TYPE_NAMES.include?(enum_type_name)
22
26
 
23
- definition && "#{definition} | (string & {})"
27
+ "#{definition} | (string & {})"
28
+ end
29
+
30
+ # Typelizer skips rewriting a file whose digest is unchanged, and the
31
+ # digest covers a property's values but not the definition above. Folding
32
+ # the re-export in makes a checkout that still carries the old inline
33
+ # list regenerate.
34
+ def fingerprint
35
+ return super unless CLOSED_TYPE_NAMES.include?(enum_type_name)
36
+
37
+ [super, enum_definition].inspect
24
38
  end
25
39
  end
26
40
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.rc2
4
+ version: 6.0.0.rc4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vendo Connect Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-13 00:00:00.000000000 Z
11
+ date: 2026-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rswag-specs
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 6.0.0.rc2
47
+ version: 6.0.0.rc4
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 6.0.0.rc2
54
+ version: 6.0.0.rc4
55
55
  description: Spree Commerce Store / Admin API and HTTP webhooks
56
56
  email:
57
57
  - hello@spreecommerce.org
@@ -191,6 +191,9 @@ files:
191
191
  - app/controllers/spree/api/v3/admin/me_controller.rb
192
192
  - app/controllers/spree/api/v3/admin/media_controller.rb
193
193
  - app/controllers/spree/api/v3/admin/media_library_controller.rb
194
+ - app/controllers/spree/api/v3/admin/oauth/application_tokens_controller.rb
195
+ - app/controllers/spree/api/v3/admin/oauth/applications_controller.rb
196
+ - app/controllers/spree/api/v3/admin/oauth/authorizations_controller.rb
194
197
  - app/controllers/spree/api/v3/admin/option_types_controller.rb
195
198
  - app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb
196
199
  - app/controllers/spree/api/v3/admin/order_groups_controller.rb
@@ -261,6 +264,7 @@ files:
261
264
  - app/controllers/spree/api/v3/admin/suppliers_controller.rb
262
265
  - app/controllers/spree/api/v3/admin/tags_controller.rb
263
266
  - app/controllers/spree/api/v3/admin/tax_categories_controller.rb
267
+ - app/controllers/spree/api/v3/admin/tax_exemption_reasons_controller.rb
264
268
  - app/controllers/spree/api/v3/admin/tax_providers_controller.rb
265
269
  - app/controllers/spree/api/v3/admin/tax_rates_controller.rb
266
270
  - app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb
@@ -274,6 +278,9 @@ files:
274
278
  - app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb
275
279
  - app/controllers/spree/api/v3/admin/webhook_events_controller.rb
276
280
  - app/controllers/spree/api/v3/base_controller.rb
281
+ - app/controllers/spree/api/v3/oauth/authorizations_controller.rb
282
+ - app/controllers/spree/api/v3/oauth/metadata_controller.rb
283
+ - app/controllers/spree/api/v3/oauth/server_metadata_controller.rb
277
284
  - app/controllers/spree/api/v3/resource_controller.rb
278
285
  - app/controllers/spree/api/v3/seller/auth_controller.rb
279
286
  - app/controllers/spree/api/v3/seller/balances_controller.rb
@@ -490,6 +497,11 @@ files:
490
497
  - app/serializers/spree/api/v3/admin/media_serializer.rb
491
498
  - app/serializers/spree/api/v3/admin/membership_product_serializer.rb
492
499
  - app/serializers/spree/api/v3/admin/newsletter_subscriber_serializer.rb
500
+ - app/serializers/spree/api/v3/admin/oauth_access_token_serializer.rb
501
+ - app/serializers/spree/api/v3/admin/oauth_application_serializer.rb
502
+ - app/serializers/spree/api/v3/admin/oauth_consent_request_serializer.rb
503
+ - app/serializers/spree/api/v3/admin/oauth_protected_resource_serializer.rb
504
+ - app/serializers/spree/api/v3/admin/oauth_redirect_serializer.rb
493
505
  - app/serializers/spree/api/v3/admin/option_type_serializer.rb
494
506
  - app/serializers/spree/api/v3/admin/option_value_serializer.rb
495
507
  - app/serializers/spree/api/v3/admin/order_cancellation_reason_serializer.rb
@@ -497,6 +509,7 @@ files:
497
509
  - app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb
498
510
  - app/serializers/spree/api/v3/admin/order_serializer.rb
499
511
  - app/serializers/spree/api/v3/admin/package_type_serializer.rb
512
+ - app/serializers/spree/api/v3/admin/payment_capture_event_serializer.rb
500
513
  - app/serializers/spree/api/v3/admin/payment_method_serializer.rb
501
514
  - app/serializers/spree/api/v3/admin/payment_serializer.rb
502
515
  - app/serializers/spree/api/v3/admin/payment_source_serializer.rb
@@ -553,6 +566,7 @@ files:
553
566
  - app/serializers/spree/api/v3/admin/supplier_serializer.rb
554
567
  - app/serializers/spree/api/v3/admin/tax_category_serializer.rb
555
568
  - app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb
569
+ - app/serializers/spree/api/v3/admin/tax_exemption_reason_serializer.rb
556
570
  - app/serializers/spree/api/v3/admin/tax_identifier_serializer.rb
557
571
  - app/serializers/spree/api/v3/admin/tax_line_serializer.rb
558
572
  - app/serializers/spree/api/v3/admin/tax_rate_serializer.rb
@@ -767,10 +781,16 @@ files:
767
781
  - config/locales/zh-TW.yml
768
782
  - config/routes.rb
769
783
  - lib/spree/api.rb
784
+ - lib/spree/api/agent_membership_map.rb
785
+ - lib/spree/api/agent_resource_map.rb
786
+ - lib/spree/api/agent_workflow_endpoints.rb
787
+ - lib/spree/api/agent_write_schemas.rb
770
788
  - lib/spree/api/configuration.rb
771
789
  - lib/spree/api/dependencies.rb
772
790
  - lib/spree/api/engine.rb
791
+ - lib/spree/api/extension_fields.rb
773
792
  - lib/spree/api/middleware/request_size_limit.rb
793
+ - lib/spree/api/oauth.rb
774
794
  - lib/spree/api/openapi/filter_documentation.rb
775
795
  - lib/spree/api/openapi/path_sorter.rb
776
796
  - lib/spree/api/openapi/schema_helper.rb
@@ -792,9 +812,9 @@ licenses:
792
812
  - BSD-3-Clause
793
813
  metadata:
794
814
  bug_tracker_uri: https://github.com/spree/spree/issues
795
- changelog_uri: https://github.com/spree/spree/releases/tag/v6.0.0.rc2
815
+ changelog_uri: https://github.com/spree/spree/releases/tag/v6.0.0.rc4
796
816
  documentation_uri: https://docs.spreecommerce.org/
797
- source_code_uri: https://github.com/spree/spree/tree/v6.0.0.rc2
817
+ source_code_uri: https://github.com/spree/spree/tree/v6.0.0.rc4
798
818
  post_install_message:
799
819
  rdoc_options: []
800
820
  require_paths: