@spree/docs 0.1.299 → 0.1.301
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.
- package/dist/api-reference/store.yaml +1 -1
- package/dist/developer/cli/quickstart.md +6 -5
- package/dist/developer/create-spree-app/quickstart.md +1 -1
- package/dist/developer/dashboard/customization/navigation.md +3 -3
- package/dist/developer/dashboard/customization/permissions.md +8 -8
- package/dist/developer/dashboard/customization/routes.md +1 -1
- package/dist/developer/dashboard/customization/slots.md +1 -1
- package/dist/developer/dashboard/recipes/page-action-button.md +2 -2
- package/dist/developer/dashboard/recipes/sidebar-widget.md +1 -1
- package/dist/developer/dashboard/slots-catalog.md +1 -1
- package/dist/developer/upgrades/5.6-to-6.0.md +1 -1
- package/dist/developer/upgrades/quickstart.md +7 -7
- package/package.json +1 -1
|
@@ -11738,7 +11738,7 @@ components:
|
|
|
11738
11738
|
type: array
|
|
11739
11739
|
items:
|
|
11740
11740
|
type: string
|
|
11741
|
-
description: Subject
|
|
11741
|
+
description: Subject short names, e.g. ["product"] or ["all"]
|
|
11742
11742
|
has_conditions:
|
|
11743
11743
|
type: boolean
|
|
11744
11744
|
description: True if the server-side rule has per-record conditions. The
|
|
@@ -94,11 +94,12 @@ spree build --yes # Skip confirmation prompts (for CI)
|
|
|
94
94
|
|
|
95
95
|
Upgrade your project to the latest Spree release in one go. It works for both kinds of project:
|
|
96
96
|
|
|
97
|
-
1. **Update the server**
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
1. **Update the server** — on a project that runs the prebuilt image, it pulls the latest Spree image. On an [ejected](#spree-eject) project, it updates the Spree gems with `bundle update`.
|
|
98
|
+
2. **Update the `@spree/*` packages** — `@spree/cli` in the project root, and the dashboard packages and Admin SDK in `apps/dashboard` and `apps/seller-dashboard`. Each package moves to the newest release its declared range in `package.json` allows, the same way `bundle update` respects your `Gemfile`. To move to a new major version, change the range in `package.json` first.
|
|
99
|
+
3. **Migrate the database** — on a prebuilt-image project, it recreates the containers and the migrations run as they start. On an ejected project, it applies pending migrations.
|
|
100
|
+
4. **Run data backfills** — the version-specific steps from the upgrade manifest that convert existing records. An ejected project's app is then restarted so it loads the new gems.
|
|
101
|
+
|
|
102
|
+
The packages are updated before the database steps, so a failed migration or backfill no longer stops them from moving to the newest release their ranges allow. Fix the cause and run `spree upgrade` again.
|
|
102
103
|
|
|
103
104
|
```bash
|
|
104
105
|
spree upgrade # Run every step, asking before each one
|
|
@@ -151,7 +151,7 @@ To update to the latest Spree version:
|
|
|
151
151
|
spree upgrade
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
This updates the server (the Docker image, or the Spree gems on an ejected project)
|
|
154
|
+
This updates the server (the Docker image, or the Spree gems on an ejected project) and the `@spree/*` packages of the project and its dashboard apps, then runs database migrations and data backfills. See [`spree upgrade`](../cli/quickstart.md#spree-upgrade) for details.
|
|
155
155
|
|
|
156
156
|
To pin a specific version, edit `SPREE_VERSION_TAG` in `.env`:
|
|
157
157
|
|
|
@@ -22,7 +22,7 @@ nav.add({
|
|
|
22
22
|
path: '/analytics', // prefixed with /$storeId at render time
|
|
23
23
|
icon: BarChartIcon,
|
|
24
24
|
position: 650,
|
|
25
|
-
subject: '
|
|
25
|
+
subject: 'order', // optional permission subject — hides item without read permission
|
|
26
26
|
})
|
|
27
27
|
```
|
|
28
28
|
|
|
@@ -70,7 +70,7 @@ nav.addChild('products', {
|
|
|
70
70
|
key: 'products.brands',
|
|
71
71
|
label: 'Brands',
|
|
72
72
|
path: '/products/brands',
|
|
73
|
-
subject: '
|
|
73
|
+
subject: 'brand',
|
|
74
74
|
})
|
|
75
75
|
```
|
|
76
76
|
|
|
@@ -177,7 +177,7 @@ settingsNav.add({
|
|
|
177
177
|
path: '/integrations/stripe-tax', // prefixed with /$storeId/settings
|
|
178
178
|
group: 'integrations',
|
|
179
179
|
position: 100,
|
|
180
|
-
subject: '
|
|
180
|
+
subject: 'tax_rate',
|
|
181
181
|
})
|
|
182
182
|
```
|
|
183
183
|
|
|
@@ -33,10 +33,10 @@ interface Permissions {
|
|
|
33
33
|
It mirrors the backend ability at the **class level**:
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
|
-
permissions.can('read', '
|
|
36
|
+
permissions.can('read', 'order')
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
Subjects are
|
|
39
|
+
Subjects are short names: the model's class name without its namespace, underscored (`'order'`, `'product'`, or `'report'` for your own `MyApp::Report`). Use the `Subject` constants from `@spree/dashboard-core` for Spree's own models. There is no client-side record-level check — when a rule is conditional on record attributes, `isConditional` returns `true` and the API is the arbiter: render the control and handle a possible 403.
|
|
40
40
|
|
|
41
41
|
## `subject` shortcut
|
|
42
42
|
|
|
@@ -47,7 +47,7 @@ nav.add({
|
|
|
47
47
|
key: 'reports',
|
|
48
48
|
label: 'Reports',
|
|
49
49
|
path: '/reports',
|
|
50
|
-
subject: '
|
|
50
|
+
subject: 'order', // hides nav item without read:order
|
|
51
51
|
})
|
|
52
52
|
```
|
|
53
53
|
|
|
@@ -58,7 +58,7 @@ routes: [{
|
|
|
58
58
|
key: 'reports',
|
|
59
59
|
path: '/reports',
|
|
60
60
|
component: ReportsPage,
|
|
61
|
-
subject: '
|
|
61
|
+
subject: 'order',
|
|
62
62
|
}],
|
|
63
63
|
```
|
|
64
64
|
|
|
@@ -76,7 +76,7 @@ nav.add({
|
|
|
76
76
|
label: 'Reports',
|
|
77
77
|
path: '/reports',
|
|
78
78
|
if: ({ permissions, store }) =>
|
|
79
|
-
permissions.can('read', '
|
|
79
|
+
permissions.can('read', 'order') &&
|
|
80
80
|
!!(store as Store | null)?.setup_tasks?.every((task) => task.done),
|
|
81
81
|
})
|
|
82
82
|
```
|
|
@@ -94,18 +94,18 @@ import { usePermissions } from '@spree/dashboard'
|
|
|
94
94
|
|
|
95
95
|
function ReportsPage() {
|
|
96
96
|
const { permissions } = usePermissions()
|
|
97
|
-
if (!permissions.can('read', '
|
|
97
|
+
if (!permissions.can('read', 'order')) {
|
|
98
98
|
return <Forbidden />
|
|
99
99
|
}
|
|
100
100
|
return <ReportsList />
|
|
101
101
|
}
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
The same `permissions` object backs the nav registry's `if` predicate, so you can move logic between the two without changing behaviour. For declarative gating, `<Can I="update" a="
|
|
104
|
+
The same `permissions` object backs the nav registry's `if` predicate, so you can move logic between the two without changing behaviour. For declarative gating, `<Can I="update" a="order">…</Can>` (also from `@spree/dashboard-core`) renders children only when the check passes.
|
|
105
105
|
|
|
106
106
|
## Custom permissions
|
|
107
107
|
|
|
108
|
-
If your customization introduces a new model on the backend, register it as a permission catalog scope there (`Spree.permissions.register_scope` in your engine's initializer). Its keys then appear in the role editor and the API-key scope picker, and any role granted them makes `permissions.can('read', '
|
|
108
|
+
If your customization introduces a new model on the backend, register it as a permission catalog scope there (`Spree.permissions.register_scope` in your engine's initializer). Its keys then appear in the role editor and the API-key scope picker, and any role granted them makes `permissions.can('read', 'report')` resolve in the dashboard exactly like a first-party check — the abilities ship with the current-user response (`GET /api/v3/admin/me`) at sign-in, alongside `permission_keys`, the flat key list the role editor grants from.
|
|
109
109
|
|
|
110
110
|
## Reference
|
|
111
111
|
|
|
@@ -68,7 +68,7 @@ import { usePermissions } from '@spree/dashboard'
|
|
|
68
68
|
|
|
69
69
|
function AdminOnlyMenuItem() {
|
|
70
70
|
const { permissions } = usePermissions()
|
|
71
|
-
if (!permissions.can('manage', '
|
|
71
|
+
if (!permissions.can('manage', 'customer')) return null
|
|
72
72
|
return <DropdownMenuItem>…</DropdownMenuItem>
|
|
73
73
|
}
|
|
74
74
|
```
|
|
@@ -33,7 +33,7 @@ export function SendInvoiceButton({ resource }: Props) {
|
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
// Only show to users who can act, and only on completed orders.
|
|
36
|
-
if (!permissions.can('update', '
|
|
36
|
+
if (!permissions.can('update', 'order')) return null
|
|
37
37
|
if (resource.status !== 'placed') return null
|
|
38
38
|
|
|
39
39
|
return (
|
|
@@ -95,7 +95,7 @@ export function SyncToErpItem({ resource }: Props) {
|
|
|
95
95
|
successMessage: 'Synced',
|
|
96
96
|
})
|
|
97
97
|
|
|
98
|
-
if (!permissions.can('manage', '
|
|
98
|
+
if (!permissions.can('manage', 'order')) return null
|
|
99
99
|
|
|
100
100
|
return (
|
|
101
101
|
<DropdownMenuItem
|
|
@@ -42,7 +42,7 @@ interface Props {
|
|
|
42
42
|
export function LoyaltyStatusCard({ customer }: Props) {
|
|
43
43
|
const { storeId } = useStore()
|
|
44
44
|
const { permissions } = usePermissions()
|
|
45
|
-
const canRead = permissions.can('read', '
|
|
45
|
+
const canRead = permissions.can('read', 'loyalty_record')
|
|
46
46
|
const { data, isLoading } = useQuery({
|
|
47
47
|
queryKey: ['loyalty', storeId, customer.id],
|
|
48
48
|
queryFn: () =>
|
|
@@ -44,7 +44,7 @@ import { usePermissions, useStore } from '@spree/dashboard'
|
|
|
44
44
|
function MyWidget({ product }: { product: Product }) {
|
|
45
45
|
const { permissions } = usePermissions()
|
|
46
46
|
const { store } = useStore()
|
|
47
|
-
if (!permissions.can('read', '
|
|
47
|
+
if (!permissions.can('read', 'loyalty_record')) return null
|
|
48
48
|
// ...
|
|
49
49
|
}
|
|
50
50
|
```
|
|
@@ -506,7 +506,7 @@ If your storefront or webhook receiver reads any of these fields, compare agains
|
|
|
506
506
|
| `payment_source_type` | Store API payment setup sessions, `payment_setup_session.*` webhooks | `Spree::CreditCard` | `credit_card` |
|
|
507
507
|
| `type` | Custom fields on products, variants, categories and collections | `Spree::CustomFields::ShortText` | removed — read `field_type` (`short_text`) |
|
|
508
508
|
|
|
509
|
-
The Admin API follows the same rule everywhere: providers and strategies (`fulfillment_provider: 'manual'`, `preferred_order_routing_strategy: 'rules'`), custom field definition `resource_type` (`product`, `category`), tag `taggable_type`, the owner and originator types on records, and filters such as `q[type_eq]=orders`. An integration written against the Admin API preview sends and expects these short names; the [Admin SDK](../sdk/admin/resources.md) types list them.
|
|
509
|
+
The Admin API follows the same rule everywhere: providers and strategies (`fulfillment_provider: 'manual'`, `preferred_order_routing_strategy: 'rules'`), custom field definition `resource_type` (`product`, `category`), tag `taggable_type`, the owner and originator types on records, the permission subjects `/me` returns (`product`, `category`), and filters such as `q[type_eq]=orders`. An integration written against the Admin API preview sends and expects these short names; the [Admin SDK](../sdk/admin/resources.md) types list them.
|
|
510
510
|
|
|
511
511
|
## Every event is declared
|
|
512
512
|
|
|
@@ -11,7 +11,7 @@ We strongly advise upgrading Spree incrementally, rather than in one big go.
|
|
|
11
11
|
|
|
12
12
|
## How to upgrade
|
|
13
13
|
|
|
14
|
-
An upgrade updates the server, migrates the database, runs the version's data backfills
|
|
14
|
+
An upgrade updates the server and the `@spree/*` packages of your dashboard apps, migrates the database, and runs the version's data backfills. Always read the guide for the version you're moving to first — it lists the behavior changes to review.
|
|
15
15
|
|
|
16
16
|
**Spree CLI:**
|
|
17
17
|
|
|
@@ -19,23 +19,23 @@ An upgrade updates the server, migrates the database, runs the version's data ba
|
|
|
19
19
|
spree upgrade
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
One command for every project: it pulls the new image, or updates the Spree gems on an [ejected](../cli/quickstart.md#spree-eject) project, then runs migrations
|
|
22
|
+
One command for every project: it pulls the new image, or updates the Spree gems on an [ejected](../cli/quickstart.md#spree-eject) project, then updates the packages and runs migrations and data backfills. See [`spree upgrade`](../cli/quickstart.md#spree-upgrade) for its options.
|
|
23
23
|
|
|
24
24
|
**Without CLI:**
|
|
25
25
|
|
|
26
26
|
Run from the project root:
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
cd server
|
|
30
|
-
bundle update $(bundle list --name-only | grep ^spree)
|
|
31
|
-
bin/rails spree:install:migrations db:migrate
|
|
32
|
-
bin/rails spree:upgrade
|
|
33
|
-
cd ..
|
|
29
|
+
(cd server && bundle update $(bundle list --name-only | grep ^spree))
|
|
34
30
|
|
|
35
31
|
# The project root and each dashboard app have their own package.json
|
|
36
32
|
pnpm update "@spree/*"
|
|
37
33
|
(cd apps/dashboard && pnpm update "@spree/*")
|
|
38
34
|
(cd apps/seller-dashboard && pnpm update "@spree/*")
|
|
35
|
+
|
|
36
|
+
cd server
|
|
37
|
+
bin/rails spree:install:migrations db:migrate
|
|
38
|
+
bin/rails spree:upgrade
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
On npm or Yarn, run `npm update` or `yarn upgrade` instead, naming each `@spree/*` package from that `package.json` (they do not accept the `"@spree/*"` pattern).
|