@sanity/sdk-react 2.4.0 → 2.5.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/sdk-react",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "private": false,
5
5
  "description": "Sanity SDK React toolkit for Content OS",
6
6
  "keywords": [
@@ -18,7 +18,8 @@
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "git+ssh://git@github.com/sanity-io/sdk.git"
21
+ "url": "git+https://github.com/sanity-io/sdk.git",
22
+ "directory": "packages/react"
22
23
  },
23
24
  "license": "MIT",
24
25
  "author": "Sanity <developers@sanity.io>",
@@ -43,7 +44,7 @@
43
44
  "prettier": "@sanity/prettier-config",
44
45
  "dependencies": {
45
46
  "@sanity/client": "^7.12.0",
46
- "@sanity/message-protocol": "^0.12.0",
47
+ "@sanity/message-protocol": "^0.18.0",
47
48
  "@sanity/types": "^3.83.0",
48
49
  "@types/lodash-es": "^4.17.12",
49
50
  "groq": "3.88.1-typegen-experimental.0",
@@ -51,12 +52,12 @@
51
52
  "react-compiler-runtime": "19.1.0-rc.2",
52
53
  "react-error-boundary": "^5.0.0",
53
54
  "rxjs": "^7.8.2",
54
- "@sanity/sdk": "2.4.0"
55
+ "@sanity/sdk": "2.5.0"
55
56
  },
56
57
  "devDependencies": {
57
58
  "@sanity/browserslist-config": "^1.0.5",
58
59
  "@sanity/comlink": "^3.1.1",
59
- "@sanity/pkg-utils": "^7.2.2",
60
+ "@sanity/pkg-utils": "^8.1.29",
60
61
  "@sanity/prettier-config": "^1.0.6",
61
62
  "@testing-library/jest-dom": "^6.9.1",
62
63
  "@testing-library/react": "^16.3.0",
@@ -77,17 +78,17 @@
77
78
  "vite": "^6.3.4",
78
79
  "vitest": "^3.2.4",
79
80
  "@repo/config-eslint": "0.0.0",
80
- "@repo/package.bundle": "3.82.0",
81
81
  "@repo/config-test": "0.0.1",
82
82
  "@repo/package.config": "0.0.1",
83
- "@repo/tsconfig": "0.0.1"
83
+ "@repo/tsconfig": "0.0.1",
84
+ "@repo/package.bundle": "3.82.0"
84
85
  },
85
86
  "peerDependencies": {
86
87
  "react": "^18.0.0 || ^19.0.0",
87
88
  "react-dom": "^18.0.0 || ^19.0.0"
88
89
  },
89
90
  "engines": {
90
- "node": ">=20.0.0"
91
+ "node": ">=20.19"
91
92
  },
92
93
  "publishConfig": {
93
94
  "access": "public"
@@ -13,6 +13,10 @@ export {
13
13
  useAgentTransform,
14
14
  useAgentTranslate,
15
15
  } from '../hooks/agent/agentActions'
16
+ export {
17
+ type AgentResourceContextOptions,
18
+ useAgentResourceContext,
19
+ } from '../hooks/agent/useAgentResourceContext'
16
20
  export {useAuthState} from '../hooks/auth/useAuthState'
17
21
  export {useAuthToken} from '../hooks/auth/useAuthToken'
18
22
  export {useCurrentUser} from '../hooks/auth/useCurrentUser'
@@ -0,0 +1,245 @@
1
+ import {renderHook} from '@testing-library/react'
2
+ import {beforeEach, describe, expect, it, vi} from 'vitest'
3
+
4
+ import {AppProviders} from '../../../test/test-utils'
5
+ import {useWindowConnection} from '../comlink/useWindowConnection'
6
+ import {useAgentResourceContext} from './useAgentResourceContext'
7
+
8
+ vi.mock('../comlink/useWindowConnection', () => ({
9
+ useWindowConnection: vi.fn(),
10
+ }))
11
+
12
+ describe('useAgentResourceContext', () => {
13
+ let mockSendMessage = vi.fn()
14
+
15
+ beforeEach(() => {
16
+ mockSendMessage = vi.fn()
17
+ vi.mocked(useWindowConnection).mockImplementation(() => {
18
+ return {
19
+ sendMessage: mockSendMessage,
20
+ fetch: vi.fn(),
21
+ }
22
+ })
23
+ })
24
+
25
+ it('should send context update on mount', () => {
26
+ renderHook(
27
+ () =>
28
+ useAgentResourceContext({
29
+ projectId: 'test-project',
30
+ dataset: 'production',
31
+ documentId: 'doc-123',
32
+ }),
33
+ {wrapper: AppProviders},
34
+ )
35
+
36
+ expect(mockSendMessage).toHaveBeenCalledWith('dashboard/v1/events/agent/resource/update', {
37
+ projectId: 'test-project',
38
+ dataset: 'production',
39
+ documentId: 'doc-123',
40
+ })
41
+ })
42
+
43
+ it('should send context update without documentId', () => {
44
+ renderHook(
45
+ () =>
46
+ useAgentResourceContext({
47
+ projectId: 'test-project',
48
+ dataset: 'production',
49
+ }),
50
+ {wrapper: AppProviders},
51
+ )
52
+
53
+ expect(mockSendMessage).toHaveBeenCalledWith('dashboard/v1/events/agent/resource/update', {
54
+ projectId: 'test-project',
55
+ dataset: 'production',
56
+ documentId: undefined,
57
+ })
58
+ })
59
+
60
+ it('should send context update when context changes', () => {
61
+ const {rerender} = renderHook(
62
+ ({documentId}: {documentId: string}) =>
63
+ useAgentResourceContext({
64
+ projectId: 'test-project',
65
+ dataset: 'production',
66
+ documentId,
67
+ }),
68
+ {
69
+ wrapper: AppProviders,
70
+ initialProps: {documentId: 'doc-123'},
71
+ },
72
+ )
73
+
74
+ expect(mockSendMessage).toHaveBeenCalledTimes(1)
75
+ expect(mockSendMessage).toHaveBeenCalledWith('dashboard/v1/events/agent/resource/update', {
76
+ projectId: 'test-project',
77
+ dataset: 'production',
78
+ documentId: 'doc-123',
79
+ })
80
+
81
+ // Change documentId
82
+ rerender({documentId: 'doc-456'})
83
+
84
+ expect(mockSendMessage).toHaveBeenCalledTimes(2)
85
+ expect(mockSendMessage).toHaveBeenLastCalledWith('dashboard/v1/events/agent/resource/update', {
86
+ projectId: 'test-project',
87
+ dataset: 'production',
88
+ documentId: 'doc-456',
89
+ })
90
+ })
91
+
92
+ it('should not send duplicate updates for the same context', () => {
93
+ const {rerender} = renderHook(
94
+ ({documentId}: {documentId: string}) =>
95
+ useAgentResourceContext({
96
+ projectId: 'test-project',
97
+ dataset: 'production',
98
+ documentId,
99
+ }),
100
+ {
101
+ wrapper: AppProviders,
102
+ initialProps: {documentId: 'doc-123'},
103
+ },
104
+ )
105
+
106
+ expect(mockSendMessage).toHaveBeenCalledTimes(1)
107
+
108
+ // Re-render with the same documentId
109
+ rerender({documentId: 'doc-123'})
110
+
111
+ // Should still only be called once
112
+ expect(mockSendMessage).toHaveBeenCalledTimes(1)
113
+ })
114
+
115
+ it('should warn when projectId is missing', () => {
116
+ const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
117
+
118
+ renderHook(
119
+ () =>
120
+ useAgentResourceContext({
121
+ projectId: '',
122
+ dataset: 'production',
123
+ documentId: 'doc-123',
124
+ }),
125
+ {wrapper: AppProviders},
126
+ )
127
+
128
+ expect(consoleWarnSpy).toHaveBeenCalledWith(
129
+ '[useAgentResourceContext] projectId and dataset are required',
130
+ {projectId: '', dataset: 'production'},
131
+ )
132
+ expect(mockSendMessage).not.toHaveBeenCalled()
133
+
134
+ consoleWarnSpy.mockRestore()
135
+ })
136
+
137
+ it('should warn when dataset is missing', () => {
138
+ const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
139
+
140
+ renderHook(
141
+ () =>
142
+ useAgentResourceContext({
143
+ projectId: 'test-project',
144
+ dataset: '',
145
+ documentId: 'doc-123',
146
+ }),
147
+ {wrapper: AppProviders},
148
+ )
149
+
150
+ expect(consoleWarnSpy).toHaveBeenCalledWith(
151
+ '[useAgentResourceContext] projectId and dataset are required',
152
+ {projectId: 'test-project', dataset: ''},
153
+ )
154
+ expect(mockSendMessage).not.toHaveBeenCalled()
155
+
156
+ consoleWarnSpy.mockRestore()
157
+ })
158
+
159
+ it('should handle errors when sending messages', () => {
160
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
161
+ mockSendMessage.mockImplementation(() => {
162
+ throw new Error('Failed to send message')
163
+ })
164
+
165
+ // Should not throw, but should log error
166
+ expect(() =>
167
+ renderHook(
168
+ () =>
169
+ useAgentResourceContext({
170
+ projectId: 'test-project',
171
+ dataset: 'production',
172
+ documentId: 'doc-123',
173
+ }),
174
+ {wrapper: AppProviders},
175
+ ),
176
+ ).not.toThrow()
177
+
178
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
179
+ '[useAgentResourceContext] Failed to update context:',
180
+ expect.any(Error),
181
+ )
182
+
183
+ consoleErrorSpy.mockRestore()
184
+ })
185
+
186
+ it('should update context when switching between documents', () => {
187
+ const {rerender} = renderHook(
188
+ ({documentId}: {documentId: string}) =>
189
+ useAgentResourceContext({
190
+ projectId: 'test-project',
191
+ dataset: 'production',
192
+ documentId,
193
+ }),
194
+ {
195
+ wrapper: AppProviders,
196
+ initialProps: {documentId: 'doc-123'},
197
+ },
198
+ )
199
+
200
+ expect(mockSendMessage).toHaveBeenCalledTimes(1)
201
+
202
+ // Switch to document 456
203
+ rerender({documentId: 'doc-456'})
204
+ expect(mockSendMessage).toHaveBeenCalledTimes(2)
205
+
206
+ // Switch to document 789
207
+ rerender({documentId: 'doc-789'})
208
+ expect(mockSendMessage).toHaveBeenCalledTimes(3)
209
+
210
+ // Switch back to document 123
211
+ rerender({documentId: 'doc-123'})
212
+ expect(mockSendMessage).toHaveBeenCalledTimes(4)
213
+ })
214
+
215
+ it('should update context when document is cleared', () => {
216
+ const {rerender} = renderHook(
217
+ ({documentId}: {documentId: string | undefined}) =>
218
+ useAgentResourceContext({
219
+ projectId: 'test-project',
220
+ dataset: 'production',
221
+ documentId,
222
+ }),
223
+ {
224
+ wrapper: AppProviders,
225
+ initialProps: {documentId: 'doc-123' as string | undefined},
226
+ },
227
+ )
228
+
229
+ expect(mockSendMessage).toHaveBeenCalledWith('dashboard/v1/events/agent/resource/update', {
230
+ projectId: 'test-project',
231
+ dataset: 'production',
232
+ documentId: 'doc-123',
233
+ })
234
+
235
+ // Clear documentId
236
+ rerender({documentId: undefined})
237
+
238
+ expect(mockSendMessage).toHaveBeenCalledTimes(2)
239
+ expect(mockSendMessage).toHaveBeenLastCalledWith('dashboard/v1/events/agent/resource/update', {
240
+ projectId: 'test-project',
241
+ dataset: 'production',
242
+ documentId: undefined,
243
+ })
244
+ })
245
+ })
@@ -0,0 +1,106 @@
1
+ import {type Events, SDK_CHANNEL_NAME, SDK_NODE_NAME} from '@sanity/message-protocol'
2
+ import {type FrameMessage} from '@sanity/sdk'
3
+ import {useCallback, useEffect, useRef} from 'react'
4
+
5
+ import {useWindowConnection} from '../comlink/useWindowConnection'
6
+
7
+ /**
8
+ * @public
9
+ */
10
+ export interface AgentResourceContextOptions {
11
+ /**
12
+ * The project ID of the current context
13
+ */
14
+ projectId: string
15
+ /**
16
+ * The dataset of the current context
17
+ */
18
+ dataset: string
19
+ /**
20
+ * Optional document ID if the user is viewing/editing a specific document
21
+ */
22
+ documentId?: string
23
+ }
24
+
25
+ /**
26
+ * @public
27
+ * Hook for emitting agent resource context updates to the Dashboard.
28
+ * This allows the Agent to understand what resource the user is currently
29
+ * interacting with (e.g., which document they're editing).
30
+ *
31
+ * The hook will automatically emit the context when it changes, and also
32
+ * emit the initial context when the hook is first mounted.
33
+ *
34
+ * @category Agent
35
+ * @param options - The resource context options containing projectId, dataset, and optional documentId
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * import {useAgentResourceContext} from '@sanity/sdk-react'
40
+ *
41
+ * function MyComponent() {
42
+ * const documentId = 'my-document-id'
43
+ *
44
+ * // Automatically updates the Agent's context whenever the document changes
45
+ * useAgentResourceContext({
46
+ * projectId: 'my-project',
47
+ * dataset: 'production',
48
+ * documentId,
49
+ * })
50
+ *
51
+ * return <div>Editing document: {documentId}</div>
52
+ * }
53
+ * ```
54
+ */
55
+ export function useAgentResourceContext(options: AgentResourceContextOptions): void {
56
+ const {projectId, dataset, documentId} = options
57
+ const {sendMessage} = useWindowConnection<Events.AgentResourceUpdateMessage, FrameMessage>({
58
+ name: SDK_NODE_NAME,
59
+ connectTo: SDK_CHANNEL_NAME,
60
+ })
61
+
62
+ // Track the last sent context to avoid duplicate updates
63
+ const lastContextRef = useRef<string | null>(null)
64
+
65
+ const updateContext = useCallback(() => {
66
+ // Validate required fields
67
+ if (!projectId || !dataset) {
68
+ // eslint-disable-next-line no-console
69
+ console.warn('[useAgentResourceContext] projectId and dataset are required', {
70
+ projectId,
71
+ dataset,
72
+ })
73
+ return
74
+ }
75
+
76
+ // Create a stable key for the current context
77
+ const contextKey = `${projectId}:${dataset}:${documentId || ''}`
78
+
79
+ // Skip if context hasn't changed
80
+ if (lastContextRef.current === contextKey) {
81
+ return
82
+ }
83
+
84
+ try {
85
+ const message: Events.AgentResourceUpdateMessage = {
86
+ type: 'dashboard/v1/events/agent/resource/update',
87
+ data: {
88
+ projectId,
89
+ dataset,
90
+ documentId,
91
+ },
92
+ }
93
+
94
+ sendMessage(message.type, message.data)
95
+ lastContextRef.current = contextKey
96
+ } catch (error) {
97
+ // eslint-disable-next-line no-console
98
+ console.error('[useAgentResourceContext] Failed to update context:', error)
99
+ }
100
+ }, [projectId, dataset, documentId, sendMessage])
101
+
102
+ // Update context whenever it changes
103
+ useEffect(() => {
104
+ updateContext()
105
+ }, [updateContext])
106
+ }
@@ -38,10 +38,7 @@ describe('useDispatchIntent', () => {
38
38
  })
39
39
 
40
40
  it('should throw error when neither action nor intentId is provided', () => {
41
- const {result} = renderHook(() =>
42
- // @ts-expect-error - Testing runtime error when neither is provided
43
- useDispatchIntent({documentHandle: mockDocumentHandle}),
44
- )
41
+ const {result} = renderHook(() => useDispatchIntent({documentHandle: mockDocumentHandle}))
45
42
 
46
43
  expect(() => result.current.dispatchIntent()).toThrow(
47
44
  'useDispatchIntent: Either `action` or `intentId` must be provided.',
@@ -1,20 +1,135 @@
1
- import {applyDocumentActions} from '@sanity/sdk'
1
+ import {applyDocumentActions, type SanityInstance} from '@sanity/sdk'
2
2
  import {describe, it} from 'vitest'
3
3
 
4
- import {createCallbackHook} from '../helpers/createCallbackHook'
4
+ import {useSanityInstance} from '../context/useSanityInstance'
5
+ import {useApplyDocumentActions} from './useApplyDocumentActions'
5
6
 
6
- vi.mock('../helpers/createCallbackHook', () => ({
7
- createCallbackHook: vi.fn((cb) => () => cb),
8
- }))
9
7
  vi.mock('@sanity/sdk', async (importOriginal) => {
10
8
  const original = await importOriginal<typeof import('@sanity/sdk')>()
11
9
  return {...original, applyDocumentActions: vi.fn()}
12
10
  })
13
11
 
12
+ vi.mock('../context/useSanityInstance')
13
+
14
+ // These are quite fragile mocks, but they are useful enough for now.
15
+ const instances: Record<string, SanityInstance | undefined> = {
16
+ 'p123.d': {__id: 'p123.d'} as unknown as SanityInstance,
17
+ 'p.d123': {__id: 'p.d123'} as unknown as SanityInstance,
18
+ 'p123.d123': {__id: 'p123.d123'} as unknown as SanityInstance,
19
+ }
20
+
21
+ const instance = {
22
+ match({projectId = 'p', dataset = 'd'}): SanityInstance | undefined {
23
+ return instances[`${projectId}.${dataset}`]
24
+ },
25
+ } as unknown as SanityInstance
26
+
14
27
  describe('useApplyDocumentActions', () => {
15
- it('calls `createCallbackHook` with `applyActions`', async () => {
16
- expect(createCallbackHook).not.toHaveBeenCalled()
17
- await import('./useApplyDocumentActions')
18
- expect(createCallbackHook).toHaveBeenCalledWith(applyDocumentActions)
28
+ beforeEach(() => {
29
+ vi.resetAllMocks()
30
+ vi.mocked(useSanityInstance).mockReturnValueOnce(instance)
31
+ })
32
+
33
+ it('uses the SanityInstance', async () => {
34
+ const apply = useApplyDocumentActions()
35
+ apply({
36
+ type: 'document.edit',
37
+ documentType: 'post',
38
+ documentId: 'abc',
39
+ })
40
+
41
+ expect(applyDocumentActions).toHaveBeenCalledExactlyOnceWith(instance, {
42
+ actions: [
43
+ {
44
+ type: 'document.edit',
45
+ documentType: 'post',
46
+ documentId: 'abc',
47
+ },
48
+ ],
49
+ })
50
+ })
51
+
52
+ it('uses SanityInstance.match when projectId is overrideen', async () => {
53
+ const apply = useApplyDocumentActions()
54
+ apply({
55
+ type: 'document.edit',
56
+ documentType: 'post',
57
+ documentId: 'abc',
58
+
59
+ projectId: 'p123',
60
+ })
61
+
62
+ expect(applyDocumentActions).toHaveBeenCalledExactlyOnceWith(instances['p123.d'], {
63
+ actions: [
64
+ {
65
+ type: 'document.edit',
66
+ documentType: 'post',
67
+ documentId: 'abc',
68
+
69
+ projectId: 'p123',
70
+ },
71
+ ],
72
+ })
73
+ })
74
+
75
+ it('uses SanityInstance when dataset is overrideen', async () => {
76
+ const apply = useApplyDocumentActions()
77
+ apply({
78
+ type: 'document.edit',
79
+ documentType: 'post',
80
+ documentId: 'abc',
81
+
82
+ dataset: 'd123',
83
+ })
84
+
85
+ expect(applyDocumentActions).toHaveBeenCalledExactlyOnceWith(instance, {
86
+ actions: [
87
+ {
88
+ type: 'document.edit',
89
+ documentType: 'post',
90
+ documentId: 'abc',
91
+
92
+ dataset: 'd123',
93
+ },
94
+ ],
95
+ })
96
+ })
97
+
98
+ it('uses SanityInstance.amcth when projectId and dataset is overrideen', async () => {
99
+ const apply = useApplyDocumentActions()
100
+ apply({
101
+ type: 'document.edit',
102
+ documentType: 'post',
103
+ documentId: 'abc',
104
+
105
+ projectId: 'p123',
106
+ dataset: 'd123',
107
+ })
108
+
109
+ expect(applyDocumentActions).toHaveBeenCalledExactlyOnceWith(instances['p123.d123'], {
110
+ actions: [
111
+ {
112
+ type: 'document.edit',
113
+ documentType: 'post',
114
+ documentId: 'abc',
115
+
116
+ projectId: 'p123',
117
+ dataset: 'd123',
118
+ },
119
+ ],
120
+ })
121
+ })
122
+
123
+ it("throws if SanityInstance.match doesn't find anything", async () => {
124
+ const apply = useApplyDocumentActions()
125
+ expect(() => {
126
+ apply({
127
+ type: 'document.edit',
128
+ documentType: 'post',
129
+ documentId: 'abc',
130
+
131
+ projectId: 'other',
132
+ })
133
+ }).toThrow()
19
134
  })
20
135
  })
@@ -6,7 +6,7 @@ import {
6
6
  } from '@sanity/sdk'
7
7
  import {type SanityDocument} from 'groq'
8
8
 
9
- import {createCallbackHook} from '../helpers/createCallbackHook'
9
+ import {useSanityInstance} from '../context/useSanityInstance'
10
10
  // this import is used in an `{@link useEditDocument}`
11
11
  // eslint-disable-next-line unused-imports/no-unused-imports, import/consistent-type-specifier-style
12
12
  import type {useEditDocument} from './useEditDocument'
@@ -150,6 +150,46 @@ interface UseApplyDocumentActions {
150
150
  * }
151
151
  * ```
152
152
  */
153
- export const useApplyDocumentActions = createCallbackHook(
154
- applyDocumentActions,
155
- ) as UseApplyDocumentActions
153
+ export const useApplyDocumentActions: UseApplyDocumentActions = () => {
154
+ const instance = useSanityInstance()
155
+
156
+ return (actionOrActions, options) => {
157
+ const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions]
158
+
159
+ let projectId
160
+ let dataset
161
+ for (const action of actions) {
162
+ if (action.projectId) {
163
+ if (!projectId) projectId = action.projectId
164
+ if (action.projectId !== projectId) {
165
+ throw new Error(
166
+ `Mismatched project IDs found in actions. All actions must belong to the same project. Found "${action.projectId}" but expected "${projectId}".`,
167
+ )
168
+ }
169
+
170
+ if (action.dataset) {
171
+ if (!dataset) dataset = action.dataset
172
+ if (action.dataset !== dataset) {
173
+ throw new Error(
174
+ `Mismatched datasets found in actions. All actions must belong to the same dataset. Found "${action.dataset}" but expected "${dataset}".`,
175
+ )
176
+ }
177
+ }
178
+ }
179
+ }
180
+
181
+ if (projectId || dataset) {
182
+ const actualInstance = instance.match({projectId, dataset})
183
+ if (!actualInstance) {
184
+ throw new Error(
185
+ `Could not find a matching Sanity instance for the requested action: ${JSON.stringify({projectId, dataset}, null, 2)}.
186
+ Please ensure there is a ResourceProvider component with a matching configuration in the component hierarchy.`,
187
+ )
188
+ }
189
+
190
+ return applyDocumentActions(actualInstance, {actions, ...options})
191
+ }
192
+
193
+ return applyDocumentActions(instance, {actions, ...options})
194
+ }
195
+ }
@@ -97,7 +97,7 @@ describe('usePermissions', () => {
97
97
  })
98
98
 
99
99
  // ResourceProvider handles the instance configuration
100
- expect(getPermissionsState).toHaveBeenCalledWith(expect.any(Object), mockAction)
100
+ expect(getPermissionsState).toHaveBeenCalledWith(expect.any(Object), {actions: [mockAction]})
101
101
  expect(result.current).toEqual(mockPermissionAllowed)
102
102
  })
103
103
 
@@ -140,7 +140,7 @@ describe('usePermissions', () => {
140
140
  ),
141
141
  })
142
142
 
143
- expect(getPermissionsState).toHaveBeenCalledWith(expect.any(Object), actions)
143
+ expect(getPermissionsState).toHaveBeenCalledWith(expect.any(Object), {actions})
144
144
  })
145
145
 
146
146
  it('should throw an error if actions have mismatched project IDs', () => {
@@ -226,7 +226,7 @@ describe('usePermissions', () => {
226
226
 
227
227
  // Now it should render properly
228
228
  await waitFor(() => {
229
- expect(getPermissionsState).toHaveBeenCalledWith(expect.any(Object), mockAction)
229
+ expect(getPermissionsState).toHaveBeenCalledWith(expect.any(Object), {actions: [mockAction]})
230
230
  })
231
231
  })
232
232