@sanity/sdk-react 3.0.0-rc.0 → 3.0.0-rc.1
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/README.md +103 -155
- package/dist/index.d.ts +1564 -682
- package/dist/index.js +1118 -612
- package/dist/index.js.map +1 -1
- package/package.json +51 -54
- package/src/_exports/index.ts +2 -4
- package/src/_exports/sdk-react.ts +26 -17
- package/src/components/SDKProvider.test.tsx +173 -32
- package/src/components/SDKProvider.tsx +87 -28
- package/src/components/SanityApp.test.tsx +68 -12
- package/src/components/SanityApp.tsx +94 -87
- package/src/components/auth/AuthBoundary.recovery.test.tsx +86 -0
- package/src/components/auth/AuthBoundary.test.tsx +26 -8
- package/src/components/auth/AuthBoundary.tsx +28 -6
- package/src/components/auth/DashboardAccessRequest.tsx +37 -0
- package/src/components/auth/LoginError.test.tsx +191 -5
- package/src/components/auth/LoginError.tsx +103 -59
- package/src/components/errors/ChunkLoadError.test.tsx +59 -0
- package/src/components/errors/ChunkLoadError.tsx +56 -0
- package/src/components/errors/CorsErrorComponent.tsx +2 -2
- package/src/components/errors/chunkReloadStorage.ts +57 -0
- package/src/config/handles.ts +29 -27
- package/src/constants.ts +5 -0
- package/src/context/ComlinkTokenRefresh.test.tsx +10 -27
- package/src/context/DefaultResourceContext.ts +3 -3
- package/src/context/OrganizationResourcesProvider.test.tsx +189 -0
- package/src/context/OrganizationResourcesProvider.tsx +111 -0
- package/src/context/PerspectiveContext.ts +3 -3
- package/src/context/ProjectContext.ts +15 -0
- package/src/context/ResourceProvider.test.tsx +72 -90
- package/src/context/ResourceProvider.tsx +59 -93
- package/src/context/SDKStudioContext.test.tsx +28 -33
- package/src/context/SanityInstanceProvider.test.tsx +100 -0
- package/src/context/SanityInstanceProvider.tsx +71 -0
- package/src/context/WorkbenchTokenRefresh.test.tsx +106 -0
- package/src/context/WorkbenchTokenRefresh.tsx +61 -0
- package/src/context/renderSanityApp.test.tsx +151 -49
- package/src/context/renderSanityApp.tsx +12 -8
- package/src/context/workbenchToken.ts +63 -0
- package/src/hooks/access/useCheckPermissions.test-d.ts +15 -0
- package/src/hooks/access/useCheckPermissions.test.tsx +53 -0
- package/src/hooks/access/useCheckPermissions.ts +24 -0
- package/src/hooks/agent/agentActions.test.tsx +1 -1
- package/src/hooks/agent/agentActions.ts +51 -71
- package/src/hooks/applications/useApplication.test-d.ts +30 -0
- package/src/hooks/applications/useApplication.ts +22 -0
- package/src/hooks/applications/useApplications.test-d.ts +31 -0
- package/src/hooks/applications/useApplications.ts +25 -0
- package/src/hooks/applications/useCreateUserApplication.test-d.ts +14 -0
- package/src/hooks/applications/useCreateUserApplication.ts +11 -0
- package/src/hooks/applications/useDeleteApplication.test-d.ts +12 -0
- package/src/hooks/applications/useDeleteApplication.ts +11 -0
- package/src/hooks/applications/useDeleteUserApplication.test-d.ts +14 -0
- package/src/hooks/applications/useDeleteUserApplication.ts +11 -0
- package/src/hooks/applications/useUpdateApplication.test-d.ts +12 -0
- package/src/hooks/applications/useUpdateApplication.ts +11 -0
- package/src/hooks/applications/useUpdateUserApplication.test-d.ts +14 -0
- package/src/hooks/applications/useUpdateUserApplication.ts +11 -0
- package/src/hooks/applications/useUserApplication.test-d.ts +11 -0
- package/src/hooks/applications/useUserApplication.ts +14 -0
- package/src/hooks/applications/useUserApplications.test-d.ts +11 -0
- package/src/hooks/applications/useUserApplications.ts +14 -0
- package/src/hooks/auth/useDashboardOrganizationId.test.tsx +2 -8
- package/src/hooks/auth/useVerifyOrgProjects.test.tsx +8 -32
- package/src/hooks/auth/useVerifyOrgProjects.tsx +13 -6
- package/src/hooks/client/useClient.test.tsx +1 -4
- package/src/hooks/client/useClient.ts +1 -0
- package/src/hooks/context/useResource.test.tsx +32 -0
- package/src/hooks/context/useResource.ts +24 -0
- package/src/hooks/context/useSanityInstance.test.tsx +72 -3
- package/src/hooks/context/useSanityInstance.ts +30 -8
- package/src/hooks/dashboard/useManageFavorite.test.tsx +110 -46
- package/src/hooks/dashboard/useManageFavorite.ts +10 -16
- package/src/hooks/dashboard/useNavigateToStudioDocument.test.ts +5 -7
- package/src/hooks/dashboard/useNavigateToStudioDocument.ts +2 -6
- package/src/hooks/dashboard/useRecordDocumentHistoryEvent.test.ts +0 -2
- package/src/hooks/dashboard/useRecordDocumentHistoryEvent.ts +1 -2
- package/src/hooks/dashboard/useWindowTitle.test.ts +244 -0
- package/src/hooks/dashboard/useWindowTitle.ts +114 -0
- package/src/hooks/datasets/useDatasets.test.tsx +116 -0
- package/src/hooks/datasets/useDatasets.ts +33 -13
- package/src/hooks/document/useApplyDocumentActions.test.tsx +48 -0
- package/src/hooks/document/useApplyDocumentActions.ts +66 -48
- package/src/hooks/document/useCreateDocument.test.tsx +83 -0
- package/src/hooks/document/useCreateDocument.ts +117 -0
- package/src/hooks/document/useDocument.test.tsx +37 -8
- package/src/hooks/document/useDocument.ts +131 -66
- package/src/hooks/document/useDocumentEvent.test.tsx +16 -4
- package/src/hooks/document/useDocumentEvent.ts +16 -10
- package/src/hooks/document/useDocumentPermissions.test.tsx +8 -7
- package/src/hooks/document/useDocumentPermissions.ts +71 -39
- package/src/hooks/document/useDocumentSyncStatus.test.ts +1 -0
- package/src/hooks/document/useDocumentSyncStatus.ts +13 -9
- package/src/hooks/document/useEditDocument.test.tsx +21 -14
- package/src/hooks/document/useEditDocument.ts +163 -17
- package/src/hooks/documents/useDocuments.test.tsx +64 -44
- package/src/hooks/documents/useDocuments.ts +36 -20
- package/src/hooks/helpers/createCallbackHook.test.tsx +13 -19
- package/src/hooks/helpers/createFetcherHook.test.tsx +180 -0
- package/src/hooks/helpers/createFetcherHook.ts +69 -0
- package/src/hooks/helpers/createMutationHook.test.tsx +125 -0
- package/src/hooks/helpers/createMutationHook.tsx +93 -0
- package/src/hooks/helpers/createStateSourceHook.test.tsx +10 -10
- package/src/hooks/helpers/createStateSourceHook.tsx +2 -1
- package/src/hooks/{document/useApplyDocumentActions.test.ts → helpers/useApplyActions.test.tsx} +92 -53
- package/src/hooks/helpers/useApplyActions.ts +68 -0
- package/src/hooks/helpers/useNormalizedResourceOptions.test.tsx +253 -0
- package/src/hooks/helpers/useNormalizedResourceOptions.ts +92 -50
- package/src/hooks/helpers/useResolvedProjectId.test.tsx +59 -0
- package/src/hooks/helpers/useResolvedProjectId.ts +35 -0
- package/src/hooks/helpers/useTrackHookUsage.ts +37 -0
- package/src/hooks/installations/useInstallation.test-d.ts +19 -0
- package/src/hooks/installations/useInstallation.ts +22 -0
- package/src/hooks/installations/useInstallations.test-d.ts +26 -0
- package/src/hooks/installations/useInstallations.ts +25 -0
- package/src/hooks/organizations/useOrganization.test-d.ts +60 -0
- package/src/hooks/organizations/useOrganization.test.ts +63 -0
- package/src/hooks/organizations/useOrganization.ts +34 -0
- package/src/hooks/organizations/useOrganizations.test-d.ts +68 -0
- package/src/hooks/organizations/useOrganizations.test.ts +63 -0
- package/src/hooks/organizations/useOrganizations.ts +39 -0
- package/src/hooks/paginatedDocuments/usePaginatedDocuments.test.tsx +34 -27
- package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +40 -22
- package/src/hooks/presence/usePresence.test.tsx +0 -15
- package/src/hooks/presence/usePresence.ts +9 -20
- package/src/hooks/preview/useDocumentPreview.test.tsx +0 -1
- package/src/hooks/preview/useDocumentPreview.tsx +10 -8
- package/src/hooks/projection/useDocumentProjection.test.tsx +78 -9
- package/src/hooks/projection/useDocumentProjection.ts +81 -2
- package/src/hooks/projects/useProject.test-d.ts +56 -0
- package/src/hooks/projects/useProject.test.tsx +120 -0
- package/src/hooks/projects/useProject.ts +42 -43
- package/src/hooks/projects/useProjects.test-d.ts +60 -0
- package/src/hooks/projects/useProjects.test.ts +45 -98
- package/src/hooks/projects/useProjects.ts +19 -26
- package/src/hooks/query/useQuery.test.tsx +6 -5
- package/src/hooks/query/useQuery.ts +91 -9
- package/src/hooks/releases/useActiveReleases.test.tsx +13 -7
- package/src/hooks/releases/useActiveReleases.ts +28 -24
- package/src/hooks/releases/useAllReleases.test.tsx +93 -0
- package/src/hooks/releases/useAllReleases.ts +62 -0
- package/src/hooks/releases/useApplyReleaseActions.test.tsx +66 -0
- package/src/hooks/releases/useApplyReleaseActions.ts +82 -0
- package/src/hooks/releases/usePerspective.test.tsx +18 -10
- package/src/hooks/releases/usePerspective.ts +13 -17
- package/src/hooks/users/useUser.test.tsx +3 -9
- package/src/hooks/users/useUser.ts +2 -0
- package/src/hooks/users/useUsers.test.tsx +103 -7
- package/src/hooks/users/useUsers.ts +37 -3
- package/src/utils/resolveOrgResources.test.ts +111 -0
- package/src/utils/resolveOrgResources.ts +69 -0
- package/src/hooks/context/useDefaultResource.test.tsx +0 -25
- package/src/hooks/context/useDefaultResource.ts +0 -30
- package/src/hooks/dashboard/useDispatchIntent.test.ts +0 -254
- package/src/hooks/dashboard/useDispatchIntent.ts +0 -157
- package/src/hooks/dashboard/utils/useResourceIdFromDocumentHandle.test.ts +0 -107
- package/src/hooks/dashboard/utils/useResourceIdFromDocumentHandle.ts +0 -39
- package/src/hooks/datasets/useDatasets.test.ts +0 -66
- package/src/hooks/helpers/useNormalizedResourceOptions.test.ts +0 -65
- package/src/hooks/projects/useProject.test.ts +0 -79
|
@@ -22,10 +22,7 @@ describe('useDashboardOrganizationId', () => {
|
|
|
22
22
|
|
|
23
23
|
const {result} = renderHook(() => useDashboardOrganizationId(), {
|
|
24
24
|
wrapper: ({children}) => (
|
|
25
|
-
<ResourceProvider
|
|
26
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
27
|
-
fallback={null}
|
|
28
|
-
>
|
|
25
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
29
26
|
{children}
|
|
30
27
|
</ResourceProvider>
|
|
31
28
|
),
|
|
@@ -44,10 +41,7 @@ describe('useDashboardOrganizationId', () => {
|
|
|
44
41
|
|
|
45
42
|
const {result} = renderHook(() => useDashboardOrganizationId(), {
|
|
46
43
|
wrapper: ({children}) => (
|
|
47
|
-
<ResourceProvider
|
|
48
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
49
|
-
fallback={null}
|
|
50
|
-
>
|
|
44
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
51
45
|
{children}
|
|
52
46
|
</ResourceProvider>
|
|
53
47
|
),
|
|
@@ -26,10 +26,7 @@ describe('useVerifyOrgProjects', () => {
|
|
|
26
26
|
it('should return null and not observe state if disabled', () => {
|
|
27
27
|
const {result} = renderHook(() => useVerifyOrgProjects(true, testProjectIds), {
|
|
28
28
|
wrapper: ({children}) => (
|
|
29
|
-
<ResourceProvider
|
|
30
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
31
|
-
fallback={null}
|
|
32
|
-
>
|
|
29
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
33
30
|
{children}
|
|
34
31
|
</ResourceProvider>
|
|
35
32
|
),
|
|
@@ -42,10 +39,7 @@ describe('useVerifyOrgProjects', () => {
|
|
|
42
39
|
it('should return null and not observe state if projectIds is missing or empty', () => {
|
|
43
40
|
const {result: resultUndefined} = renderHook(() => useVerifyOrgProjects(false, undefined), {
|
|
44
41
|
wrapper: ({children}) => (
|
|
45
|
-
<ResourceProvider
|
|
46
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
47
|
-
fallback={null}
|
|
48
|
-
>
|
|
42
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
49
43
|
{children}
|
|
50
44
|
</ResourceProvider>
|
|
51
45
|
),
|
|
@@ -55,10 +49,7 @@ describe('useVerifyOrgProjects', () => {
|
|
|
55
49
|
|
|
56
50
|
const {result: resultEmpty} = renderHook(() => useVerifyOrgProjects(false, []), {
|
|
57
51
|
wrapper: ({children}) => (
|
|
58
|
-
<ResourceProvider
|
|
59
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
60
|
-
fallback={null}
|
|
61
|
-
>
|
|
52
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
62
53
|
{children}
|
|
63
54
|
</ResourceProvider>
|
|
64
55
|
),
|
|
@@ -73,10 +64,7 @@ describe('useVerifyOrgProjects', () => {
|
|
|
73
64
|
|
|
74
65
|
const {result} = renderHook(() => useVerifyOrgProjects(false, testProjectIds), {
|
|
75
66
|
wrapper: ({children}) => (
|
|
76
|
-
<ResourceProvider
|
|
77
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
78
|
-
fallback={null}
|
|
79
|
-
>
|
|
67
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
80
68
|
{children}
|
|
81
69
|
</ResourceProvider>
|
|
82
70
|
),
|
|
@@ -92,10 +80,7 @@ describe('useVerifyOrgProjects', () => {
|
|
|
92
80
|
|
|
93
81
|
const {result} = renderHook(() => useVerifyOrgProjects(false, testProjectIds), {
|
|
94
82
|
wrapper: ({children}) => (
|
|
95
|
-
<ResourceProvider
|
|
96
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
97
|
-
fallback={null}
|
|
98
|
-
>
|
|
83
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
99
84
|
{children}
|
|
100
85
|
</ResourceProvider>
|
|
101
86
|
),
|
|
@@ -117,10 +102,7 @@ describe('useVerifyOrgProjects', () => {
|
|
|
117
102
|
|
|
118
103
|
const {result} = renderHook(() => useVerifyOrgProjects(false, testProjectIds), {
|
|
119
104
|
wrapper: ({children}) => (
|
|
120
|
-
<ResourceProvider
|
|
121
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
122
|
-
fallback={null}
|
|
123
|
-
>
|
|
105
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
124
106
|
{children}
|
|
125
107
|
</ResourceProvider>
|
|
126
108
|
),
|
|
@@ -142,10 +124,7 @@ describe('useVerifyOrgProjects', () => {
|
|
|
142
124
|
|
|
143
125
|
const {unmount} = renderHook(() => useVerifyOrgProjects(false, testProjectIds), {
|
|
144
126
|
wrapper: ({children}) => (
|
|
145
|
-
<ResourceProvider
|
|
146
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
147
|
-
fallback={null}
|
|
148
|
-
>
|
|
127
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
149
128
|
{children}
|
|
150
129
|
</ResourceProvider>
|
|
151
130
|
),
|
|
@@ -173,10 +152,7 @@ describe('useVerifyOrgProjects', () => {
|
|
|
173
152
|
{
|
|
174
153
|
initialProps: {disabled: false, pIds: testProjectIds},
|
|
175
154
|
wrapper: ({children}) => (
|
|
176
|
-
<ResourceProvider
|
|
177
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
178
|
-
fallback={null}
|
|
179
|
-
>
|
|
155
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
180
156
|
{children}
|
|
181
157
|
</ResourceProvider>
|
|
182
158
|
),
|
|
@@ -27,13 +27,20 @@ export function useVerifyOrgProjects(disabled = false, projectIds?: string[]): s
|
|
|
27
27
|
const instance = useSanityInstance()
|
|
28
28
|
const [error, setError] = useState<string | null>(null)
|
|
29
29
|
|
|
30
|
+
const isInactive = disabled || !projectIds || projectIds.length === 0
|
|
31
|
+
|
|
32
|
+
// Reset stale errors when verification turns off so the next activation
|
|
33
|
+
// doesn't briefly leak the previous result.
|
|
34
|
+
const [prevInactive, setPrevInactive] = useState(isInactive)
|
|
35
|
+
if (prevInactive !== isInactive) {
|
|
36
|
+
setPrevInactive(isInactive)
|
|
37
|
+
if (isInactive) setError(null)
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
useEffect(() => {
|
|
31
|
-
if (
|
|
32
|
-
if (error !== null) setError(null)
|
|
33
|
-
return
|
|
34
|
-
}
|
|
41
|
+
if (isInactive) return
|
|
35
42
|
|
|
36
|
-
const verificationObservable$ = observeOrganizationVerificationState(instance, projectIds)
|
|
43
|
+
const verificationObservable$ = observeOrganizationVerificationState(instance, projectIds!)
|
|
37
44
|
|
|
38
45
|
const subscription = verificationObservable$.subscribe((result: OrgVerificationResult) => {
|
|
39
46
|
setError(result.error)
|
|
@@ -42,7 +49,7 @@ export function useVerifyOrgProjects(disabled = false, projectIds?: string[]): s
|
|
|
42
49
|
return () => {
|
|
43
50
|
subscription.unsubscribe()
|
|
44
51
|
}
|
|
45
|
-
}, [instance,
|
|
52
|
+
}, [instance, isInactive, projectIds])
|
|
46
53
|
|
|
47
54
|
return error
|
|
48
55
|
}
|
|
@@ -6,10 +6,7 @@ import {useClient} from './useClient'
|
|
|
6
6
|
|
|
7
7
|
describe('useClient', () => {
|
|
8
8
|
const wrapper = ({children}: {children: React.ReactNode}) => (
|
|
9
|
-
<ResourceProvider
|
|
10
|
-
resource={{projectId: 'test-project', dataset: 'test-dataset'}}
|
|
11
|
-
fallback={null}
|
|
12
|
-
>
|
|
9
|
+
<ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
|
|
13
10
|
{children}
|
|
14
11
|
</ResourceProvider>
|
|
15
12
|
)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {renderHook as reactRenderHook} from '@testing-library/react'
|
|
2
|
+
import {type ReactNode} from 'react'
|
|
3
|
+
import {describe, expect, it} from 'vitest'
|
|
4
|
+
|
|
5
|
+
import {renderHook} from '../../../test/test-utils'
|
|
6
|
+
import {ResourceProvider} from '../../context/ResourceProvider'
|
|
7
|
+
import {useResource} from './useResource'
|
|
8
|
+
|
|
9
|
+
describe('useResource', () => {
|
|
10
|
+
it('returns the resource from the instance config when no explicit resource is set', () => {
|
|
11
|
+
// test-utils wraps with ResourceProvider projectId="test" dataset="test"
|
|
12
|
+
const {result} = renderHook(() => useResource())
|
|
13
|
+
expect(result.current).toEqual({projectId: 'test', dataset: 'test'})
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('returns the explicit resource when ResourceProvider has a resource prop', () => {
|
|
17
|
+
const resource = {projectId: 'explicit-project', dataset: 'explicit-dataset'}
|
|
18
|
+
const {result} = reactRenderHook(() => useResource(), {
|
|
19
|
+
wrapper: ({children}: {children: ReactNode}) => (
|
|
20
|
+
<ResourceProvider resource={resource} fallback={null}>
|
|
21
|
+
{children}
|
|
22
|
+
</ResourceProvider>
|
|
23
|
+
),
|
|
24
|
+
})
|
|
25
|
+
expect(result.current).toEqual(resource)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('returns undefined when no resource or instance config is available', () => {
|
|
29
|
+
const {result} = reactRenderHook(() => useResource())
|
|
30
|
+
expect(result.current).toBeUndefined()
|
|
31
|
+
})
|
|
32
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {type DocumentResource} from '@sanity/sdk'
|
|
2
|
+
|
|
3
|
+
import {useEffectiveContextResource} from '../helpers/useNormalizedResourceOptions'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns the currently active `DocumentResource` for the nearest resource context.
|
|
7
|
+
*
|
|
8
|
+
* Resolves in priority order:
|
|
9
|
+
* 1. A `resource` prop on the nearest `<ResourceProvider>`
|
|
10
|
+
* 2. The `projectId`/`dataset` from the current `SanityInstance` config
|
|
11
|
+
* 3. `undefined` when neither is available
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
* @category Platform
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* const resource = useResource()
|
|
19
|
+
* console.log(resource?.projectId, resource?.dataset)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function useResource(): DocumentResource | undefined {
|
|
23
|
+
return useEffectiveContextResource()
|
|
24
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {createSanityInstance, type SanityInstance} from '@sanity/sdk'
|
|
1
|
+
import {createSanityInstance, type SanityConfig, type SanityInstance} from '@sanity/sdk'
|
|
2
2
|
import {renderHook} from '@testing-library/react'
|
|
3
3
|
import {type ReactNode} from 'react'
|
|
4
|
-
import {describe, expect, it} from 'vitest'
|
|
4
|
+
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'
|
|
5
5
|
|
|
6
6
|
import {SanityInstanceContext} from '../../context/SanityInstanceContext'
|
|
7
7
|
import {useSanityInstance} from './useSanityInstance'
|
|
@@ -16,20 +16,89 @@ describe('useSanityInstance', () => {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
it('should return the Sanity instance from context', () => {
|
|
19
|
-
|
|
19
|
+
// Create a Sanity instance
|
|
20
|
+
const instance = createSanityInstance({projectId: 'test-project', dataset: 'test-dataset'})
|
|
20
21
|
|
|
22
|
+
// Render the hook with the wrapper that provides the context
|
|
21
23
|
const {result} = renderHook(() => useSanityInstance(), {
|
|
22
24
|
wrapper: createWrapper(instance),
|
|
23
25
|
})
|
|
24
26
|
|
|
27
|
+
// Check that the correct instance is returned
|
|
25
28
|
expect(result.current).toBe(instance)
|
|
26
29
|
})
|
|
27
30
|
|
|
28
31
|
it('should throw an error if no instance is found in context', () => {
|
|
32
|
+
// Expect the hook to throw when no instance is in context
|
|
29
33
|
expect(() => {
|
|
30
34
|
renderHook(() => useSanityInstance(), {
|
|
31
35
|
wrapper: createWrapper(null),
|
|
32
36
|
})
|
|
33
37
|
}).toThrow('SanityInstance context not found')
|
|
34
38
|
})
|
|
39
|
+
|
|
40
|
+
it('should return the current instance when no config is provided', () => {
|
|
41
|
+
// Create a Sanity instance
|
|
42
|
+
const instance = createSanityInstance({projectId: 'gp', dataset: 'gp-ds'})
|
|
43
|
+
|
|
44
|
+
// Render the hook with the wrapper that provides the context
|
|
45
|
+
const {result} = renderHook(() => useSanityInstance(), {
|
|
46
|
+
wrapper: createWrapper(instance),
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
// Should return the instance
|
|
50
|
+
expect(result.current).toBe(instance)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
describe('deprecated config parameter', () => {
|
|
54
|
+
let warnSpy: ReturnType<typeof vi.spyOn>
|
|
55
|
+
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
afterEach(() => {
|
|
61
|
+
warnSpy.mockRestore()
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should return the current context instance regardless of config', () => {
|
|
65
|
+
const instance = createSanityInstance({projectId: 'test-project', dataset: 'test-dataset'})
|
|
66
|
+
const requestedConfig: SanityConfig = {projectId: 'test-project', dataset: 'test-dataset'}
|
|
67
|
+
|
|
68
|
+
const {result} = renderHook(() => useSanityInstance(requestedConfig), {
|
|
69
|
+
wrapper: createWrapper(instance),
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
expect(result.current).toBe(instance)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
it('should throw if no instance in context even when config is provided', () => {
|
|
76
|
+
expect(() => {
|
|
77
|
+
renderHook(() => useSanityInstance({projectId: 'test'}), {
|
|
78
|
+
wrapper: createWrapper(null),
|
|
79
|
+
})
|
|
80
|
+
}).toThrow('SanityInstance context not found')
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('warns once when a config argument is passed', () => {
|
|
84
|
+
const instance = createSanityInstance({projectId: 'test-project', dataset: 'test-dataset'})
|
|
85
|
+
const {rerender} = renderHook(() => useSanityInstance({projectId: 'test-project'}), {
|
|
86
|
+
wrapper: createWrapper(instance),
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
expect(warnSpy).toHaveBeenCalledTimes(1)
|
|
90
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('[useSanityInstance]'))
|
|
91
|
+
|
|
92
|
+
rerender()
|
|
93
|
+
rerender()
|
|
94
|
+
expect(warnSpy).toHaveBeenCalledTimes(1)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('does not warn when no config is passed', () => {
|
|
98
|
+
const instance = createSanityInstance({projectId: 'test-project', dataset: 'test-dataset'})
|
|
99
|
+
renderHook(() => useSanityInstance(), {wrapper: createWrapper(instance)})
|
|
100
|
+
|
|
101
|
+
expect(warnSpy).not.toHaveBeenCalled()
|
|
102
|
+
})
|
|
103
|
+
})
|
|
35
104
|
})
|
|
@@ -1,34 +1,56 @@
|
|
|
1
|
-
import {type SanityInstance} from '@sanity/sdk'
|
|
1
|
+
import {type SanityConfig, type SanityInstance} from '@sanity/sdk'
|
|
2
2
|
import {useContext} from 'react'
|
|
3
3
|
|
|
4
4
|
import {SanityInstanceContext} from '../../context/SanityInstanceContext'
|
|
5
5
|
|
|
6
|
+
const warnedCallers = new Set<string>()
|
|
7
|
+
|
|
6
8
|
/**
|
|
7
|
-
* Retrieves the current Sanity instance from
|
|
9
|
+
* Retrieves the current Sanity instance from context
|
|
8
10
|
*
|
|
9
11
|
* @public
|
|
10
12
|
*
|
|
11
13
|
* @category Platform
|
|
12
|
-
* @
|
|
14
|
+
* @param config - Deprecated. Formerly used to match against the instance hierarchy.
|
|
15
|
+
* @returns The current Sanity instance
|
|
13
16
|
*
|
|
14
17
|
* @remarks
|
|
15
|
-
* This hook accesses the nearest Sanity instance from React context
|
|
16
|
-
*
|
|
18
|
+
* This hook accesses the nearest Sanity instance from the React context.
|
|
19
|
+
* The hook must be used within a component wrapped by a `ResourceProvider` or `SanityApp`.
|
|
17
20
|
*
|
|
18
21
|
* @example Get the current instance
|
|
19
22
|
* ```tsx
|
|
20
23
|
* const instance = useSanityInstance()
|
|
21
|
-
* console.log(instance.config)
|
|
24
|
+
* console.log(instance.config.projectId)
|
|
22
25
|
* ```
|
|
23
26
|
*
|
|
24
27
|
* @throws Error if no SanityInstance is found in context
|
|
25
28
|
*/
|
|
26
|
-
export const useSanityInstance = (
|
|
29
|
+
export const useSanityInstance = (
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Passing a config to match against the instance hierarchy is deprecated.
|
|
32
|
+
* Use `useSanityInstance()` without arguments instead.
|
|
33
|
+
*/
|
|
34
|
+
config?: SanityConfig,
|
|
35
|
+
): SanityInstance => {
|
|
36
|
+
if (config !== undefined) {
|
|
37
|
+
const caller = new Error().stack?.split('\n')[2]?.trim() ?? 'unknown'
|
|
38
|
+
if (!warnedCallers.has(caller)) {
|
|
39
|
+
warnedCallers.add(caller)
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.warn(
|
|
42
|
+
'[useSanityInstance] Passing a config argument is deprecated and has no effect. ' +
|
|
43
|
+
'SDK apps use a single instance for all resources, so the config argument is no longer needed. ' +
|
|
44
|
+
'Call useSanityInstance() without arguments instead, or useResource() to get your currently active resource.',
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
27
49
|
const instance = useContext(SanityInstanceContext)
|
|
28
50
|
|
|
29
51
|
if (!instance) {
|
|
30
52
|
throw new Error(
|
|
31
|
-
|
|
53
|
+
`SanityInstance context not found. Please ensure that your component is wrapped in a ResourceProvider or a SanityApp component.`,
|
|
32
54
|
)
|
|
33
55
|
}
|
|
34
56
|
|