@sanity/sdk-react 2.8.0 → 3.0.0-rc.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.
Files changed (87) hide show
  1. package/README.md +125 -63
  2. package/dist/index.d.ts +381 -571
  3. package/dist/index.js +435 -366
  4. package/dist/index.js.map +1 -1
  5. package/package.json +7 -9
  6. package/src/_exports/index.ts +4 -0
  7. package/src/_exports/sdk-react.ts +16 -0
  8. package/src/components/SDKProvider.test.tsx +23 -58
  9. package/src/components/SDKProvider.tsx +38 -30
  10. package/src/components/SanityApp.test.tsx +12 -68
  11. package/src/components/SanityApp.tsx +88 -65
  12. package/src/components/auth/AuthBoundary.test.tsx +8 -26
  13. package/src/components/auth/LoginError.tsx +5 -5
  14. package/src/config/handles.ts +53 -0
  15. package/src/context/ComlinkTokenRefresh.test.tsx +27 -10
  16. package/src/context/DefaultResourceContext.ts +10 -0
  17. package/src/context/PerspectiveContext.ts +12 -0
  18. package/src/context/ResourceProvider.test.tsx +99 -19
  19. package/src/context/ResourceProvider.tsx +103 -37
  20. package/src/context/ResourcesContext.tsx +7 -0
  21. package/src/context/SDKStudioContext.test.tsx +33 -28
  22. package/src/context/SDKStudioContext.ts +6 -0
  23. package/src/context/renderSanityApp.test.tsx +49 -151
  24. package/src/context/renderSanityApp.tsx +8 -12
  25. package/src/hooks/agent/agentActions.test.tsx +1 -1
  26. package/src/hooks/agent/agentActions.ts +56 -19
  27. package/src/hooks/auth/useDashboardOrganizationId.test.tsx +8 -2
  28. package/src/hooks/auth/useVerifyOrgProjects.test.tsx +32 -8
  29. package/src/hooks/client/useClient.test.tsx +4 -1
  30. package/src/hooks/client/useClient.ts +0 -1
  31. package/src/hooks/context/useDefaultResource.test.tsx +25 -0
  32. package/src/hooks/context/useDefaultResource.ts +30 -0
  33. package/src/hooks/context/useSanityInstance.test.tsx +2 -140
  34. package/src/hooks/context/useSanityInstance.ts +9 -53
  35. package/src/hooks/dashboard/useDispatchIntent.test.ts +24 -15
  36. package/src/hooks/dashboard/useDispatchIntent.ts +7 -7
  37. package/src/hooks/dashboard/useManageFavorite.test.tsx +34 -94
  38. package/src/hooks/dashboard/useManageFavorite.ts +16 -10
  39. package/src/hooks/dashboard/useNavigateToStudioDocument.test.ts +7 -5
  40. package/src/hooks/dashboard/useNavigateToStudioDocument.ts +6 -2
  41. package/src/hooks/dashboard/useRecordDocumentHistoryEvent.test.ts +2 -0
  42. package/src/hooks/dashboard/useRecordDocumentHistoryEvent.ts +2 -1
  43. package/src/hooks/dashboard/utils/useResourceIdFromDocumentHandle.test.ts +17 -38
  44. package/src/hooks/dashboard/utils/useResourceIdFromDocumentHandle.ts +12 -19
  45. package/src/hooks/datasets/useDatasets.test.ts +8 -22
  46. package/src/hooks/datasets/useDatasets.ts +8 -16
  47. package/src/hooks/document/useApplyDocumentActions.test.ts +98 -52
  48. package/src/hooks/document/useApplyDocumentActions.ts +35 -37
  49. package/src/hooks/document/useDocument.test.tsx +8 -37
  50. package/src/hooks/document/useDocument.ts +78 -129
  51. package/src/hooks/document/useDocumentEvent.test.tsx +7 -19
  52. package/src/hooks/document/useDocumentEvent.ts +21 -19
  53. package/src/hooks/document/useDocumentPermissions.test.tsx +75 -84
  54. package/src/hooks/document/useDocumentPermissions.ts +41 -28
  55. package/src/hooks/document/useDocumentSyncStatus.test.ts +13 -3
  56. package/src/hooks/document/useDocumentSyncStatus.ts +19 -14
  57. package/src/hooks/document/useEditDocument.test.tsx +28 -70
  58. package/src/hooks/document/useEditDocument.ts +29 -149
  59. package/src/hooks/documents/useDocuments.test.tsx +44 -64
  60. package/src/hooks/documents/useDocuments.ts +19 -25
  61. package/src/hooks/helpers/createCallbackHook.test.tsx +19 -13
  62. package/src/hooks/helpers/createStateSourceHook.test.tsx +10 -10
  63. package/src/hooks/helpers/createStateSourceHook.tsx +2 -4
  64. package/src/hooks/helpers/useNormalizedResourceOptions.test.ts +65 -0
  65. package/src/hooks/helpers/useNormalizedResourceOptions.ts +127 -0
  66. package/src/hooks/paginatedDocuments/usePaginatedDocuments.test.tsx +27 -34
  67. package/src/hooks/paginatedDocuments/usePaginatedDocuments.ts +19 -20
  68. package/src/hooks/presence/usePresence.test.tsx +71 -9
  69. package/src/hooks/presence/usePresence.ts +28 -3
  70. package/src/hooks/preview/useDocumentPreview.test.tsx +85 -193
  71. package/src/hooks/preview/useDocumentPreview.tsx +42 -62
  72. package/src/hooks/projection/useDocumentProjection.test.tsx +9 -37
  73. package/src/hooks/projection/useDocumentProjection.ts +9 -82
  74. package/src/hooks/projects/useProject.test.ts +1 -2
  75. package/src/hooks/projects/useProject.ts +7 -8
  76. package/src/hooks/query/useQuery.test.tsx +5 -6
  77. package/src/hooks/query/useQuery.ts +12 -91
  78. package/src/hooks/releases/useActiveReleases.test.tsx +2 -2
  79. package/src/hooks/releases/useActiveReleases.ts +25 -13
  80. package/src/hooks/releases/usePerspective.test.tsx +9 -17
  81. package/src/hooks/releases/usePerspective.ts +29 -18
  82. package/src/hooks/users/useUser.test.tsx +9 -3
  83. package/src/hooks/users/useUser.ts +1 -1
  84. package/src/hooks/users/useUsers.test.tsx +5 -2
  85. package/src/hooks/users/useUsers.ts +1 -1
  86. package/src/context/SourcesContext.tsx +0 -7
  87. package/src/hooks/helpers/useNormalizedSourceOptions.ts +0 -85
@@ -1,12 +1,5 @@
1
1
  import {type DatasetsResponse} from '@sanity/client'
2
- import {
3
- getDatasetsState,
4
- type ProjectHandle,
5
- resolveDatasets,
6
- type SanityInstance,
7
- type StateSource,
8
- } from '@sanity/sdk'
9
- import {identity} from 'rxjs'
2
+ import {getDatasetsState, resolveDatasets, type SanityInstance, type StateSource} from '@sanity/sdk'
10
3
 
11
4
  import {createStateSourceHook} from '../helpers/createStateSourceHook'
12
5
 
@@ -16,11 +9,12 @@ type UseDatasets = {
16
9
  * Returns metadata for each dataset the current user has access to.
17
10
  *
18
11
  * @category Datasets
19
- * @returns The metadata for your the datasets
12
+ * @param options - An object containing the `projectId` to list datasets for.
13
+ * @returns The metadata for the datasets
20
14
  *
21
15
  * @example
22
16
  * ```tsx
23
- * const datasets = useDatasets()
17
+ * const datasets = useDatasets({projectId: 'my-project-id'})
24
18
  *
25
19
  * return (
26
20
  * <select>
@@ -32,7 +26,7 @@ type UseDatasets = {
32
26
  * ```
33
27
  *
34
28
  */
35
- (): DatasetsResponse
29
+ (options: {projectId: string}): DatasetsResponse
36
30
  }
37
31
 
38
32
  /**
@@ -42,11 +36,9 @@ type UseDatasets = {
42
36
  export const useDatasets: UseDatasets = createStateSourceHook({
43
37
  getState: getDatasetsState as (
44
38
  instance: SanityInstance,
45
- projectHandle?: ProjectHandle,
39
+ options: {projectId: string},
46
40
  ) => StateSource<DatasetsResponse>,
47
- shouldSuspend: (instance, projectHandle?: ProjectHandle) =>
48
- // remove `undefined` since we're suspending when that is the case
49
- getDatasetsState(instance, projectHandle).getCurrent() === undefined,
41
+ shouldSuspend: (instance, options: {projectId: string}) =>
42
+ getDatasetsState(instance, options).getCurrent() === undefined,
50
43
  suspender: resolveDatasets,
51
- getConfig: identity as (projectHandle?: ProjectHandle) => ProjectHandle,
52
44
  })
@@ -1,6 +1,8 @@
1
1
  import {applyDocumentActions, type SanityInstance} from '@sanity/sdk'
2
+ import React from 'react'
2
3
  import {describe, it} from 'vitest'
3
4
 
5
+ import {renderHook} from '../../../test/test-utils'
4
6
  import {useSanityInstance} from '../context/useSanityInstance'
5
7
  import {useApplyDocumentActions} from './useApplyDocumentActions'
6
8
 
@@ -11,18 +13,7 @@ vi.mock('@sanity/sdk', async (importOriginal) => {
11
13
 
12
14
  vi.mock('../context/useSanityInstance')
13
15
 
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
16
+ const instance = {instanceId: 'test'} as unknown as SanityInstance
26
17
 
27
18
  describe('useApplyDocumentActions', () => {
28
19
  beforeEach(() => {
@@ -30,12 +21,13 @@ describe('useApplyDocumentActions', () => {
30
21
  vi.mocked(useSanityInstance).mockReturnValueOnce(instance)
31
22
  })
32
23
 
33
- it('uses the SanityInstance', async () => {
34
- const apply = useApplyDocumentActions()
35
- apply({
24
+ it('uses the SanityInstance and injects resource from context', async () => {
25
+ const {result} = renderHook(() => useApplyDocumentActions())
26
+ result.current({
36
27
  type: 'document.edit',
37
28
  documentType: 'post',
38
29
  documentId: 'abc',
30
+ resource: {projectId: 'p123', dataset: 'd123'},
39
31
  })
40
32
 
41
33
  expect(applyDocumentActions).toHaveBeenCalledExactlyOnceWith(instance, {
@@ -44,42 +36,42 @@ describe('useApplyDocumentActions', () => {
44
36
  type: 'document.edit',
45
37
  documentType: 'post',
46
38
  documentId: 'abc',
39
+ resource: {projectId: 'p123', dataset: 'd123'},
47
40
  },
48
41
  ],
42
+ resource: {projectId: 'p123', dataset: 'd123'},
49
43
  })
50
44
  })
51
45
 
52
- it('uses SanityInstance.match when projectId is overrideen', async () => {
53
- const apply = useApplyDocumentActions()
54
- apply({
46
+ it('passes resource from action to applyDocumentActions', async () => {
47
+ const {result} = renderHook(() => useApplyDocumentActions())
48
+ result.current({
55
49
  type: 'document.edit',
56
50
  documentType: 'post',
57
51
  documentId: 'abc',
58
-
59
- projectId: 'p123',
52
+ resource: {projectId: 'p123', dataset: 'd123'},
60
53
  })
61
54
 
62
- expect(applyDocumentActions).toHaveBeenCalledExactlyOnceWith(instances['p123.d'], {
55
+ expect(applyDocumentActions).toHaveBeenCalledExactlyOnceWith(instance, {
63
56
  actions: [
64
57
  {
65
58
  type: 'document.edit',
66
59
  documentType: 'post',
67
60
  documentId: 'abc',
68
-
69
- projectId: 'p123',
61
+ resource: {projectId: 'p123', dataset: 'd123'},
70
62
  },
71
63
  ],
64
+ resource: {projectId: 'p123', dataset: 'd123'},
72
65
  })
73
66
  })
74
67
 
75
- it('uses SanityInstance when dataset is overrideen', async () => {
76
- const apply = useApplyDocumentActions()
77
- apply({
68
+ it('uses context resource when action has no resource', async () => {
69
+ const {result} = renderHook(() => useApplyDocumentActions())
70
+ result.current({
78
71
  type: 'document.edit',
79
72
  documentType: 'post',
80
73
  documentId: 'abc',
81
-
82
- dataset: 'd123',
74
+ resource: {projectId: 'test', dataset: 'test'},
83
75
  })
84
76
 
85
77
  expect(applyDocumentActions).toHaveBeenCalledExactlyOnceWith(instance, {
@@ -88,48 +80,102 @@ describe('useApplyDocumentActions', () => {
88
80
  type: 'document.edit',
89
81
  documentType: 'post',
90
82
  documentId: 'abc',
91
-
92
- dataset: 'd123',
83
+ resource: {projectId: 'test', dataset: 'test'},
93
84
  },
94
85
  ],
86
+ resource: {projectId: 'test', dataset: 'test'},
95
87
  })
96
88
  })
97
89
 
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
- })
90
+ it('throws when actions have mismatched resources', async () => {
91
+ const {result} = renderHook(() => useApplyDocumentActions())
92
+ expect(() => {
93
+ result.current([
94
+ {
95
+ type: 'document.edit',
96
+ documentType: 'post',
97
+ documentId: 'abc',
98
+ resource: {projectId: 'p', dataset: 'd1'},
99
+ },
100
+ {
101
+ type: 'document.edit',
102
+ documentType: 'post',
103
+ documentId: 'def',
104
+ resource: {projectId: 'p', dataset: 'd2'},
105
+ },
106
+ ])
107
+ }).toThrow(/Mismatched resources found in actions/)
108
+ })
108
109
 
109
- expect(applyDocumentActions).toHaveBeenCalledExactlyOnceWith(instances['p123.d123'], {
110
- actions: [
110
+ it('throws when actions have mismatched project IDs', async () => {
111
+ const {result} = renderHook(() => useApplyDocumentActions())
112
+ expect(() => {
113
+ result.current([
111
114
  {
112
115
  type: 'document.edit',
113
116
  documentType: 'post',
114
117
  documentId: 'abc',
118
+ resource: {projectId: 'p123', dataset: 'd1'},
119
+ },
120
+ {
121
+ type: 'document.edit',
122
+ documentType: 'post',
123
+ documentId: 'def',
124
+ resource: {projectId: 'p456', dataset: 'd1'},
125
+ },
126
+ ])
127
+ }).toThrow(/Mismatched resources found in actions/)
128
+ })
115
129
 
116
- projectId: 'p123',
117
- dataset: 'd123',
130
+ it('throws when actions have mismatched datasets', async () => {
131
+ const {result} = renderHook(() => useApplyDocumentActions())
132
+ expect(() => {
133
+ result.current([
134
+ {
135
+ type: 'document.edit',
136
+ documentType: 'post',
137
+ documentId: 'abc',
138
+ resource: {projectId: 'p', dataset: 'd1'},
118
139
  },
119
- ],
120
- })
140
+ {
141
+ type: 'document.edit',
142
+ documentType: 'post',
143
+ documentId: 'def',
144
+ resource: {projectId: 'p', dataset: 'd2'},
145
+ },
146
+ ])
147
+ }).toThrow(/Mismatched resources found in actions/)
121
148
  })
122
149
 
123
- it("throws if SanityInstance.match doesn't find anything", async () => {
124
- const apply = useApplyDocumentActions()
150
+ it('throws when no resource is found from actions or context', async () => {
151
+ // Use a minimal wrapper without resource context so contextResource is undefined
152
+ const {result} = renderHook(() => useApplyDocumentActions(), {
153
+ wrapper: (props) => React.createElement(React.Fragment, null, props.children),
154
+ })
155
+
125
156
  expect(() => {
126
- apply({
157
+ result.current({
127
158
  type: 'document.edit',
128
159
  documentType: 'post',
129
160
  documentId: 'abc',
161
+ // no resource
162
+ } as never)
163
+ }).toThrow(/resource is required/)
164
+ })
165
+
166
+ it('throws when options resource mismatches action resource', async () => {
167
+ const {result} = renderHook(() => useApplyDocumentActions())
130
168
 
131
- projectId: 'other',
132
- })
133
- }).toThrow()
169
+ expect(() => {
170
+ result.current(
171
+ {
172
+ type: 'document.edit',
173
+ documentType: 'post',
174
+ documentId: 'abc',
175
+ resource: {projectId: 'p1', dataset: 'd1'},
176
+ },
177
+ {resource: {projectId: 'p2', dataset: 'd2'}},
178
+ )
179
+ }).toThrow(/Mismatched resources found in actions/)
134
180
  })
135
181
  })
@@ -1,12 +1,11 @@
1
- import {
2
- type ActionsResult,
3
- applyDocumentActions,
4
- type ApplyDocumentActionsOptions,
5
- type DocumentAction,
6
- } from '@sanity/sdk'
7
- import {type SanityDocument} from 'groq'
1
+ import {type ActionsResult, applyDocumentActions, type DocumentAction} from '@sanity/sdk'
2
+ import {useContext} from 'react'
8
3
 
4
+ import {type ResourceHandle} from '../../config/handles'
5
+ import {ResourceContext} from '../../context/DefaultResourceContext'
6
+ import {ResourcesContext} from '../../context/ResourcesContext'
9
7
  import {useSanityInstance} from '../context/useSanityInstance'
8
+ import {normalizeResourceOptions} from '../helpers/useNormalizedResourceOptions'
10
9
  // this import is used in an `{@link useEditDocument}`
11
10
  // eslint-disable-next-line unused-imports/no-unused-imports, import/consistent-type-specifier-style
12
11
  import type {useEditDocument} from './useEditDocument'
@@ -23,8 +22,8 @@ interface UseApplyDocumentActions {
23
22
  action:
24
23
  | DocumentAction<TDocumentType, TDataset, TProjectId>
25
24
  | DocumentAction<TDocumentType, TDataset, TProjectId>[],
26
- options?: ApplyDocumentActionsOptions,
27
- ) => Promise<ActionsResult<SanityDocument<TDocumentType, `${TProjectId}.${TDataset}`>>>
25
+ options?: ResourceHandle,
26
+ ) => Promise<ActionsResult>
28
27
  }
29
28
 
30
29
  /**
@@ -152,44 +151,43 @@ interface UseApplyDocumentActions {
152
151
  */
153
152
  export const useApplyDocumentActions: UseApplyDocumentActions = () => {
154
153
  const instance = useSanityInstance()
154
+ const resources = useContext(ResourcesContext)
155
+ const contextResource = useContext(ResourceContext)
155
156
 
156
157
  return (actionOrActions, options) => {
157
158
  const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions]
159
+ const optionsResource = options
160
+ ? normalizeResourceOptions(options, resources, contextResource).resource
161
+ : undefined
158
162
 
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
- }
163
+ const normalizedActions = actions.map((action) =>
164
+ normalizeResourceOptions(action, resources, contextResource),
165
+ )
166
+ let resource
169
167
 
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) {
168
+ for (const action of normalizedActions) {
169
+ if (!resource) resource = action.resource
170
+ if (action.resource !== resource) {
184
171
  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.`,
172
+ `Mismatched resources found in actions. All actions must belong to the same resource. Found "${JSON.stringify(action.resource)}" but expected "${JSON.stringify(resource)}".`,
187
173
  )
188
174
  }
175
+ }
176
+
177
+ if (optionsResource && resource && optionsResource !== resource) {
178
+ throw new Error(
179
+ `Mismatched resources found in actions. Found top-level resource "${JSON.stringify(optionsResource)}" but expected resource from action handles "${JSON.stringify(resource)}".`,
180
+ )
181
+ }
189
182
 
190
- return applyDocumentActions(actualInstance, {actions, ...options})
183
+ const effectiveResource = resource ?? optionsResource
184
+ if (!effectiveResource) {
185
+ throw new Error('No resource found. Provide a resource via the action handle or context.')
191
186
  }
192
187
 
193
- return applyDocumentActions(instance, {actions, ...options})
188
+ return applyDocumentActions(instance, {
189
+ actions,
190
+ resource: effectiveResource,
191
+ })
194
192
  }
195
193
  }
@@ -2,7 +2,6 @@
2
2
  import {getDocumentState, resolveDocument, type StateSource} from '@sanity/sdk'
3
3
  import {type SanityDocument} from '@sanity/types'
4
4
  import {renderHook} from '@testing-library/react'
5
- import {type SchemaOrigin} from 'groq'
6
5
  import {beforeEach, describe, expect, it, vi} from 'vitest'
7
6
 
8
7
  import {ResourceProvider} from '../../context/ResourceProvider'
@@ -13,40 +12,6 @@ vi.mock('@sanity/sdk', async (importOriginal) => {
13
12
  return {...original, getDocumentState: vi.fn(), resolveDocument: vi.fn()}
14
13
  })
15
14
 
16
- // Define a single generic TestDocument type
17
- type UseDocumentTestType = SchemaOrigin<
18
- SanityDocument & {
19
- _type: 'use-document-test-type'
20
- foo?: string
21
- extra?: boolean
22
- title?: string
23
- nested?: {
24
- value?: number
25
- }
26
- },
27
- 'p.use-document-test-dataset'
28
- >
29
-
30
- type UseDocumentTestTypeAlt = SchemaOrigin<
31
- SanityDocument & {
32
- _type: 'use-document-test-type'
33
- bar: string[]
34
- nested?: {
35
- value?: number
36
- }
37
- },
38
- 'p.use-document-test-alt-dataset'
39
- >
40
-
41
- // Scope the TestDocument type to the project/datasets used in tests
42
-
43
- declare module 'groq' {
44
- interface SanitySchemas {
45
- 'p.use-document-test-dataset': UseDocumentTestType
46
- 'p.use-document-test-alt-dataset': UseDocumentTestTypeAlt
47
- }
48
- }
49
-
50
15
  const book: SanityDocument = {
51
16
  _id: 'doc1',
52
17
  foo: 'bar',
@@ -71,7 +36,10 @@ describe('useDocument hook', () => {
71
36
 
72
37
  const {result} = renderHook(() => useDocument({documentId: 'doc1', documentType: 'book'}), {
73
38
  wrapper: ({children}) => (
74
- <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
39
+ <ResourceProvider
40
+ resource={{projectId: 'test-project', dataset: 'test-dataset'}}
41
+ fallback={null}
42
+ >
75
43
  {children}
76
44
  </ResourceProvider>
77
45
  ),
@@ -106,7 +74,10 @@ describe('useDocument hook', () => {
106
74
  },
107
75
  {
108
76
  wrapper: ({children}) => (
109
- <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
77
+ <ResourceProvider
78
+ resource={{projectId: 'test-project', dataset: 'test-dataset'}}
79
+ fallback={null}
80
+ >
110
81
  {children}
111
82
  </ResourceProvider>
112
83
  ),