@sanity/sdk-react 2.1.2 → 2.2.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/dist/index.d.ts +30 -22
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/hooks/context/useSanityInstance.ts +2 -2
- package/src/hooks/preview/useDocumentPreview.tsx +1 -1
- package/src/hooks/projection/useDocumentProjection.ts +1 -1
- package/src/hooks/projects/useProjects.test.ts +38 -3
- package/src/hooks/projects/useProjects.ts +37 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/sdk-react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Sanity SDK React toolkit for Content OS",
|
|
6
6
|
"keywords": [
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"browserslist": "extends @sanity/browserslist-config",
|
|
43
43
|
"prettier": "@sanity/prettier-config",
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@sanity/client": "^7.
|
|
45
|
+
"@sanity/client": "^7.10.0",
|
|
46
46
|
"@sanity/message-protocol": "^0.12.0",
|
|
47
47
|
"@sanity/types": "^3.83.0",
|
|
48
48
|
"@types/lodash-es": "^4.17.12",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"react-compiler-runtime": "19.1.0-rc.2",
|
|
52
52
|
"react-error-boundary": "^5.0.0",
|
|
53
53
|
"rxjs": "^7.8.2",
|
|
54
|
-
"@sanity/sdk": "2.
|
|
54
|
+
"@sanity/sdk": "2.2.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@sanity/browserslist-config": "^1.0.5",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"vitest": "^3.1.2",
|
|
77
77
|
"@repo/config-eslint": "0.0.0",
|
|
78
78
|
"@repo/config-test": "0.0.1",
|
|
79
|
-
"@repo/package.config": "0.0.1",
|
|
80
79
|
"@repo/package.bundle": "3.82.0",
|
|
81
|
-
"@repo/tsconfig": "0.0.1"
|
|
80
|
+
"@repo/tsconfig": "0.0.1",
|
|
81
|
+
"@repo/package.config": "0.0.1"
|
|
82
82
|
},
|
|
83
83
|
"peerDependencies": {
|
|
84
84
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -62,7 +62,7 @@ export const useSanityInstance = (config?: SanityConfig): SanityInstance => {
|
|
|
62
62
|
|
|
63
63
|
if (!instance) {
|
|
64
64
|
throw new Error(
|
|
65
|
-
`SanityInstance context not found. ${config ? `Requested config: ${JSON.stringify(config, null, 2)}. ` : ''}Please ensure that your component is wrapped in a
|
|
65
|
+
`SanityInstance context not found. ${config ? `Requested config: ${JSON.stringify(config, null, 2)}. ` : ''}Please ensure that your component is wrapped in a ResourceProvider or a SanityApp component.`,
|
|
66
66
|
)
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -72,7 +72,7 @@ export const useSanityInstance = (config?: SanityConfig): SanityInstance => {
|
|
|
72
72
|
if (!match) {
|
|
73
73
|
throw new Error(
|
|
74
74
|
`Could not find a matching Sanity instance for the requested configuration: ${JSON.stringify(config, null, 2)}.
|
|
75
|
-
Please ensure there is a
|
|
75
|
+
Please ensure there is a ResourceProvider component with a matching configuration in the component hierarchy.`,
|
|
76
76
|
)
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -83,7 +83,7 @@ export function useDocumentPreview({
|
|
|
83
83
|
ref,
|
|
84
84
|
...docHandle
|
|
85
85
|
}: useDocumentPreviewOptions): useDocumentPreviewResults {
|
|
86
|
-
const instance = useSanityInstance()
|
|
86
|
+
const instance = useSanityInstance(docHandle)
|
|
87
87
|
const stateSource = getPreviewState(instance, docHandle)
|
|
88
88
|
|
|
89
89
|
// Create subscribe function for useSyncExternalStore
|
|
@@ -181,7 +181,7 @@ export function useDocumentProjection<TData extends object>({
|
|
|
181
181
|
projection,
|
|
182
182
|
...docHandle
|
|
183
183
|
}: useDocumentProjectionOptions): useDocumentProjectionResults<TData> {
|
|
184
|
-
const instance = useSanityInstance()
|
|
184
|
+
const instance = useSanityInstance(docHandle)
|
|
185
185
|
const stateSource = getProjectionState<TData>(instance, {...docHandle, projection})
|
|
186
186
|
|
|
187
187
|
if (stateSource.getCurrent()?.data === null) {
|
|
@@ -59,12 +59,12 @@ describe('useProjects', () => {
|
|
|
59
59
|
// Mock instance for the test call
|
|
60
60
|
const mockInstance = {} as SanityInstance // Use specific type
|
|
61
61
|
|
|
62
|
-
// Call the shouldSuspend function
|
|
63
|
-
const result = shouldSuspend(mockInstance)
|
|
62
|
+
// Call the shouldSuspend function with both required parameters
|
|
63
|
+
const result = shouldSuspend(mockInstance, undefined) // Pass undefined for options
|
|
64
64
|
|
|
65
65
|
// Assert that getProjectsState was called with the correct arguments
|
|
66
66
|
const mockGetProjectsState = getProjectsState as ReturnType<typeof vi.fn>
|
|
67
|
-
expect(mockGetProjectsState).toHaveBeenCalledWith(mockInstance)
|
|
67
|
+
expect(mockGetProjectsState).toHaveBeenCalledWith(mockInstance, undefined)
|
|
68
68
|
|
|
69
69
|
// Assert that getCurrent was called on the result of getProjectsState
|
|
70
70
|
expect(mockGetProjectsState.mock.results.length).toBeGreaterThan(0)
|
|
@@ -74,4 +74,39 @@ describe('useProjects', () => {
|
|
|
74
74
|
// Assert the result of shouldSuspend based on the mocked getCurrent value
|
|
75
75
|
expect(result).toBe(true) // Since getCurrent is mocked to return undefined
|
|
76
76
|
})
|
|
77
|
+
|
|
78
|
+
it('should call createStateSourceHook with correct getState function signature', async () => {
|
|
79
|
+
await import('./useProjects')
|
|
80
|
+
|
|
81
|
+
const mockCreateStateSourceHook = createStateSourceHook as ReturnType<typeof vi.fn>
|
|
82
|
+
expect(mockCreateStateSourceHook).toHaveBeenCalled()
|
|
83
|
+
|
|
84
|
+
const createStateSourceHookArgs = mockCreateStateSourceHook.mock.calls[0][0]
|
|
85
|
+
const getState = createStateSourceHookArgs.getState
|
|
86
|
+
|
|
87
|
+
// Test that getState can handle the new options parameter
|
|
88
|
+
const mockInstance = {} as SanityInstance
|
|
89
|
+
const mockOptions = {organizationId: 'org123', includeMembers: false}
|
|
90
|
+
|
|
91
|
+
// This should not throw
|
|
92
|
+
expect(() => getState(mockInstance, mockOptions)).not.toThrow()
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('should handle different parameter combinations in shouldSuspend', async () => {
|
|
96
|
+
await import('./useProjects')
|
|
97
|
+
|
|
98
|
+
const mockCreateStateSourceHook = createStateSourceHook as ReturnType<typeof vi.fn>
|
|
99
|
+
const createStateSourceHookArgs = mockCreateStateSourceHook.mock.calls[0][0]
|
|
100
|
+
const shouldSuspend = createStateSourceHookArgs.shouldSuspend
|
|
101
|
+
|
|
102
|
+
const mockInstance = {} as SanityInstance
|
|
103
|
+
|
|
104
|
+
// Test with different options
|
|
105
|
+
expect(() => shouldSuspend(mockInstance, undefined)).not.toThrow()
|
|
106
|
+
expect(() => shouldSuspend(mockInstance, {organizationId: 'org123'})).not.toThrow()
|
|
107
|
+
expect(() => shouldSuspend(mockInstance, {includeMembers: false})).not.toThrow()
|
|
108
|
+
expect(() =>
|
|
109
|
+
shouldSuspend(mockInstance, {organizationId: 'org123', includeMembers: false}),
|
|
110
|
+
).not.toThrow()
|
|
111
|
+
})
|
|
77
112
|
})
|
|
@@ -10,36 +10,47 @@ import {createStateSourceHook} from '../helpers/createStateSourceHook'
|
|
|
10
10
|
*/
|
|
11
11
|
export type ProjectWithoutMembers = Omit<SanityProject, 'members'>
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
* ```tsx
|
|
22
|
-
* const projects = useProjects()
|
|
23
|
-
*
|
|
24
|
-
* return (
|
|
25
|
-
* <select>
|
|
26
|
-
* {projects.map((project) => (
|
|
27
|
-
* <option key={project.id}>{project.displayName}</option>
|
|
28
|
-
* ))}
|
|
29
|
-
* </select>
|
|
30
|
-
* )
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
(): ProjectWithoutMembers[]
|
|
34
|
-
}
|
|
13
|
+
/**
|
|
14
|
+
* @public
|
|
15
|
+
* @category Types
|
|
16
|
+
*/
|
|
17
|
+
type UseProjects = <TIncludeMembers extends boolean = false>(options?: {
|
|
18
|
+
organizationId?: string
|
|
19
|
+
includeMembers?: TIncludeMembers
|
|
20
|
+
}) => TIncludeMembers extends true ? SanityProject[] : ProjectWithoutMembers[]
|
|
35
21
|
|
|
36
22
|
/**
|
|
23
|
+
* Returns metadata for each project you have access to.
|
|
24
|
+
*
|
|
25
|
+
* @category Projects
|
|
26
|
+
* @param options - Configuration options
|
|
27
|
+
* @returns An array of project metadata. If includeMembers is true, returns full SanityProject objects. Otherwise, returns ProjectWithoutMembers objects.
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* const projects = useProjects()
|
|
31
|
+
*
|
|
32
|
+
* return (
|
|
33
|
+
* <select>
|
|
34
|
+
* {projects.map((project) => (
|
|
35
|
+
* <option key={project.id}>{project.displayName}</option>
|
|
36
|
+
* ))}
|
|
37
|
+
* </select>
|
|
38
|
+
* )
|
|
39
|
+
* ```
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* const projectsWithMembers = useProjects({ includeMembers: true })
|
|
43
|
+
* const projectsWithoutMembers = useProjects({ includeMembers: false })
|
|
44
|
+
* ```
|
|
37
45
|
* @public
|
|
38
46
|
* @function
|
|
39
47
|
*/
|
|
40
48
|
export const useProjects: UseProjects = createStateSourceHook({
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
getState: getProjectsState as (
|
|
50
|
+
instance: SanityInstance,
|
|
51
|
+
options?: {organizationId?: string; includeMembers?: boolean},
|
|
52
|
+
) => StateSource<SanityProject[] | ProjectWithoutMembers[]>,
|
|
53
|
+
shouldSuspend: (instance, options) =>
|
|
54
|
+
getProjectsState(instance, options).getCurrent() === undefined,
|
|
44
55
|
suspender: resolveProjects,
|
|
45
|
-
})
|
|
56
|
+
}) as UseProjects
|