@sanity/sdk 2.8.0 → 2.10.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 (111) hide show
  1. package/dist/_chunks-dts/utils.d.ts +2450 -0
  2. package/dist/_chunks-es/_internal.js +129 -0
  3. package/dist/_chunks-es/_internal.js.map +1 -0
  4. package/dist/_chunks-es/createGroqSearchFilter.js +1537 -0
  5. package/dist/_chunks-es/createGroqSearchFilter.js.map +1 -0
  6. package/dist/_chunks-es/telemetryManager.js +87 -0
  7. package/dist/_chunks-es/telemetryManager.js.map +1 -0
  8. package/dist/_chunks-es/version.js +7 -0
  9. package/dist/_chunks-es/version.js.map +1 -0
  10. package/dist/_exports/_internal.d.ts +64 -0
  11. package/dist/_exports/_internal.js +20 -0
  12. package/dist/_exports/_internal.js.map +1 -0
  13. package/dist/index.d.ts +2 -2343
  14. package/dist/index.js +465 -1813
  15. package/dist/index.js.map +1 -1
  16. package/package.json +17 -12
  17. package/src/_exports/_internal.ts +14 -0
  18. package/src/_exports/index.ts +18 -1
  19. package/src/auth/authStore.test.ts +150 -1
  20. package/src/auth/authStore.ts +11 -11
  21. package/src/auth/dashboardAuth.ts +2 -2
  22. package/src/auth/handleAuthCallback.ts +9 -3
  23. package/src/auth/logout.test.ts +1 -1
  24. package/src/auth/logout.ts +1 -1
  25. package/src/auth/refreshStampedToken.test.ts +118 -1
  26. package/src/auth/refreshStampedToken.ts +3 -2
  27. package/src/auth/standaloneAuth.ts +9 -3
  28. package/src/auth/studioAuth.ts +34 -7
  29. package/src/auth/studioModeAuth.ts +2 -1
  30. package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +10 -2
  31. package/src/auth/subscribeToStateAndFetchCurrentUser.ts +5 -1
  32. package/src/auth/subscribeToStorageEventsAndSetToken.ts +2 -2
  33. package/src/auth/utils.ts +33 -0
  34. package/src/client/clientStore.test.ts +44 -30
  35. package/src/client/clientStore.ts +49 -48
  36. package/src/comlink/controller/actions/getOrCreateChannel.ts +2 -2
  37. package/src/comlink/node/actions/getOrCreateNode.ts +2 -2
  38. package/src/comlink/node/getNodeState.ts +2 -1
  39. package/src/config/sanityConfig.ts +78 -12
  40. package/src/document/actions.ts +18 -11
  41. package/src/document/applyDocumentActions.test.ts +7 -6
  42. package/src/document/applyDocumentActions.ts +10 -4
  43. package/src/document/documentStore.test.ts +542 -188
  44. package/src/document/documentStore.ts +142 -76
  45. package/src/document/events.ts +7 -2
  46. package/src/document/permissions.test.ts +18 -16
  47. package/src/document/permissions.ts +35 -11
  48. package/src/document/processActions.test.ts +359 -32
  49. package/src/document/processActions.ts +106 -78
  50. package/src/document/reducers.test.ts +117 -29
  51. package/src/document/reducers.ts +47 -40
  52. package/src/document/sharedListener.ts +16 -6
  53. package/src/document/util.ts +14 -0
  54. package/src/favorites/favorites.test.ts +9 -2
  55. package/src/presence/bifurTransport.test.ts +46 -6
  56. package/src/presence/bifurTransport.ts +19 -2
  57. package/src/presence/presenceStore.test.ts +96 -0
  58. package/src/presence/presenceStore.ts +96 -24
  59. package/src/preview/getPreviewState.test.ts +115 -98
  60. package/src/preview/getPreviewState.ts +38 -60
  61. package/src/preview/previewProjectionUtils.test.ts +179 -0
  62. package/src/preview/previewProjectionUtils.ts +93 -0
  63. package/src/preview/resolvePreview.test.ts +42 -25
  64. package/src/preview/resolvePreview.ts +33 -10
  65. package/src/preview/{previewStore.ts → types.ts} +8 -17
  66. package/src/projection/getProjectionState.test.ts +16 -16
  67. package/src/projection/getProjectionState.ts +6 -5
  68. package/src/projection/projectionQuery.ts +2 -3
  69. package/src/projection/projectionStore.test.ts +2 -2
  70. package/src/projection/resolveProjection.ts +2 -2
  71. package/src/projection/subscribeToStateAndFetchBatches.test.ts +1 -1
  72. package/src/projection/subscribeToStateAndFetchBatches.ts +12 -11
  73. package/src/projection/types.ts +1 -1
  74. package/src/query/queryStore.test.ts +12 -12
  75. package/src/query/queryStore.ts +12 -11
  76. package/src/query/reducers.ts +3 -3
  77. package/src/releases/getPerspectiveState.ts +7 -6
  78. package/src/releases/releasesStore.test.ts +20 -5
  79. package/src/releases/releasesStore.ts +20 -8
  80. package/src/store/createActionBinder.test.ts +31 -31
  81. package/src/store/createActionBinder.ts +43 -38
  82. package/src/store/createSanityInstance.ts +2 -3
  83. package/src/store/createStateSourceAction.test.ts +62 -0
  84. package/src/store/createStateSourceAction.ts +34 -39
  85. package/src/telemetry/__telemetry__/sdk.telemetry.ts +42 -0
  86. package/src/telemetry/devMode.test.ts +52 -0
  87. package/src/telemetry/devMode.ts +40 -0
  88. package/src/telemetry/initTelemetry.test.ts +225 -0
  89. package/src/telemetry/initTelemetry.ts +205 -0
  90. package/src/telemetry/telemetryManager.test.ts +263 -0
  91. package/src/telemetry/telemetryManager.ts +187 -0
  92. package/src/users/reducers.ts +3 -4
  93. package/src/users/usersStore.test.ts +1 -0
  94. package/src/users/usersStore.ts +5 -1
  95. package/src/utils/createFetcherStore.test.ts +6 -4
  96. package/src/utils/createFetcherStore.ts +8 -5
  97. package/src/utils/getStagingApiHost.test.ts +21 -0
  98. package/src/utils/getStagingApiHost.ts +14 -0
  99. package/src/utils/ids.test.ts +1 -29
  100. package/src/utils/ids.ts +0 -10
  101. package/src/utils/isImportError.test.ts +72 -0
  102. package/src/utils/isImportError.ts +34 -0
  103. package/src/utils/object.test.ts +95 -0
  104. package/src/utils/object.ts +142 -0
  105. package/src/utils/setCleanupTimeout.ts +24 -0
  106. package/src/preview/previewQuery.test.ts +0 -236
  107. package/src/preview/previewQuery.ts +0 -153
  108. package/src/preview/previewStore.test.ts +0 -36
  109. package/src/preview/subscribeToStateAndFetchBatches.test.ts +0 -221
  110. package/src/preview/subscribeToStateAndFetchBatches.ts +0 -112
  111. package/src/preview/util.ts +0 -13
@@ -23,6 +23,12 @@ export interface TokenSource {
23
23
  * @public
24
24
  */
25
25
  export interface StudioConfig {
26
+ /**
27
+ * Whether the Studio has already determined the user is authenticated.
28
+ * When `true` and the token source emits `null`, the SDK infers
29
+ * cookie-based auth is in use rather than transitioning to logged-out.
30
+ */
31
+ authenticated?: boolean
26
32
  /** Reactive auth token source from the Studio's auth store. */
27
33
  auth?: {
28
34
  /**
@@ -67,9 +73,14 @@ export interface DatasetHandle<TDataset extends string = string, TProjectId exte
67
73
  dataset?: TDataset
68
74
  /**
69
75
  * @beta
70
- * Explicit source object to use for this operation.
76
+ * Explicit resource object to use for this operation.
77
+ */
78
+ resource?: DocumentResource
79
+ /**
80
+ * @deprecated Use `resource` instead.
81
+ * @beta
71
82
  */
72
- source?: DocumentSource
83
+ source?: DocumentResource
73
84
  }
74
85
 
75
86
  /**
@@ -139,51 +150,106 @@ export interface SanityConfig extends DatasetHandle, PerspectiveHandle {
139
150
 
140
151
  /**
141
152
  * @beta
142
- * A list of named sources to use for this instance.
153
+ * A list of named resources to use for this instance.
143
154
  */
144
- sources?: Record<string, DocumentSource>
155
+ resources?: Record<string, DocumentResource>
156
+ /**
157
+ * @deprecated Use `resources` instead.
158
+ * @beta
159
+ */
160
+ sources?: Record<string, DocumentResource>
145
161
  }
146
162
 
147
163
  /**
148
- * A document source can be used for querying.
164
+ * A document resource can be used for querying.
149
165
  * This will soon be the default way to identify where you are querying from.
150
166
  *
151
167
  * @beta
152
168
  */
153
- export type DocumentSource = DatasetSource | MediaLibrarySource | CanvasSource
169
+ export type DocumentResource = DatasetResource | MediaLibraryResource | CanvasResource
170
+
171
+ /**
172
+ * @beta
173
+ */
174
+ export type DatasetResource = {projectId: string; dataset: string}
175
+
176
+ /**
177
+ * @beta
178
+ */
179
+ export type MediaLibraryResource = {mediaLibraryId: string}
180
+
181
+ /**
182
+ * @beta
183
+ */
184
+ export type CanvasResource = {canvasId: string}
185
+
186
+ /**
187
+ * @beta
188
+ */
189
+ export function isDatasetResource(resource: DocumentResource): resource is DatasetResource {
190
+ return 'projectId' in resource && 'dataset' in resource
191
+ }
192
+
193
+ /**
194
+ * @beta
195
+ */
196
+ export function isMediaLibraryResource(
197
+ resource: DocumentResource,
198
+ ): resource is MediaLibraryResource {
199
+ return 'mediaLibraryId' in resource
200
+ }
201
+
202
+ /**
203
+ * @beta
204
+ */
205
+ export function isCanvasResource(resource: DocumentResource): resource is CanvasResource {
206
+ return 'canvasId' in resource
207
+ }
208
+
209
+ /**
210
+ * @deprecated Use `DocumentResource` instead.
211
+ * @beta
212
+ */
213
+ export type DocumentSource = DocumentResource
154
214
 
155
215
  /**
216
+ * @deprecated Use `DatasetResource` instead.
156
217
  * @beta
157
218
  */
158
- export type DatasetSource = {projectId: string; dataset: string}
219
+ export type DatasetSource = DatasetResource
159
220
 
160
221
  /**
222
+ * @deprecated Use `MediaLibraryResource` instead.
161
223
  * @beta
162
224
  */
163
- export type MediaLibrarySource = {mediaLibraryId: string}
225
+ export type MediaLibrarySource = MediaLibraryResource
164
226
 
165
227
  /**
228
+ * @deprecated Use `CanvasResource` instead.
166
229
  * @beta
167
230
  */
168
- export type CanvasSource = {canvasId: string}
231
+ export type CanvasSource = CanvasResource
169
232
 
170
233
  /**
234
+ * @deprecated Use `isDatasetResource` instead.
171
235
  * @beta
172
236
  */
173
237
  export function isDatasetSource(source: DocumentSource): source is DatasetSource {
174
- return 'projectId' in source && 'dataset' in source
238
+ return isDatasetResource(source)
175
239
  }
176
240
 
177
241
  /**
242
+ * @deprecated Use `isMediaLibraryResource` instead.
178
243
  * @beta
179
244
  */
180
245
  export function isMediaLibrarySource(source: DocumentSource): source is MediaLibrarySource {
181
- return 'mediaLibraryId' in source
246
+ return isMediaLibraryResource(source)
182
247
  }
183
248
 
184
249
  /**
250
+ * @deprecated Use `isCanvasResource` instead.
185
251
  * @beta
186
252
  */
187
253
  export function isCanvasSource(source: DocumentSource): source is CanvasSource {
188
- return 'canvasId' in source
254
+ return isCanvasResource(source)
189
255
  }
@@ -4,7 +4,7 @@ import {type PatchMutation, type PatchOperations} from '@sanity/types'
4
4
  import {type SanityDocument} from 'groq'
5
5
 
6
6
  import {type DocumentHandle, type DocumentTypeHandle} from '../config/sanityConfig'
7
- import {getPublishedId} from '../utils/ids'
7
+ import {getEffectiveDocumentId} from './util'
8
8
 
9
9
  const isSanityMutatePatch = (value: unknown): value is SanityMutatePatchMutation => {
10
10
  if (typeof value !== 'object' || !value) return false
@@ -140,12 +140,15 @@ export function createDocument<
140
140
  >
141
141
  >,
142
142
  ): CreateDocumentAction<TDocumentType, TDataset, TProjectId> {
143
+ // users may pass in an explicit documentId -- make sure we format it correctly for the action
144
+ let effectiveDocumentId
145
+ if (typeof doc.documentId === 'string') {
146
+ effectiveDocumentId = getEffectiveDocumentId({...doc, documentId: doc.documentId})
147
+ }
143
148
  return {
144
149
  type: 'document.create',
145
150
  ...doc,
146
- ...(doc.documentId && {
147
- documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
148
- }),
151
+ ...(effectiveDocumentId && {documentId: effectiveDocumentId}),
149
152
  ...(initialValue && {initialValue}),
150
153
  }
151
154
  }
@@ -163,10 +166,11 @@ export function deleteDocument<
163
166
  >(
164
167
  doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
165
168
  ): DeleteDocumentAction<TDocumentType, TDataset, TProjectId> {
169
+ const effectiveDocumentId = getEffectiveDocumentId(doc)
166
170
  return {
167
171
  type: 'document.delete',
168
172
  ...doc,
169
- documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
173
+ documentId: effectiveDocumentId,
170
174
  }
171
175
  }
172
176
 
@@ -230,14 +234,14 @@ export function editDocument<
230
234
  doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
231
235
  patches?: PatchOperations | PatchOperations[] | SanityMutatePatchMutation,
232
236
  ): EditDocumentAction<TDocumentType, TDataset, TProjectId> {
233
- const documentId = doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId)
237
+ const effectiveDocumentId = getEffectiveDocumentId(doc)
234
238
 
235
239
  if (isSanityMutatePatch(patches)) {
236
240
  const converted = convertSanityMutatePatch(patches) ?? []
237
241
  return {
238
242
  ...doc,
239
243
  type: 'document.edit',
240
- documentId,
244
+ documentId: effectiveDocumentId,
241
245
  patches: converted,
242
246
  }
243
247
  }
@@ -245,7 +249,7 @@ export function editDocument<
245
249
  return {
246
250
  ...doc,
247
251
  type: 'document.edit',
248
- documentId,
252
+ documentId: effectiveDocumentId,
249
253
  ...(patches && {patches: Array.isArray(patches) ? patches : [patches]}),
250
254
  }
251
255
  }
@@ -263,10 +267,11 @@ export function publishDocument<
263
267
  >(
264
268
  doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
265
269
  ): PublishDocumentAction<TDocumentType, TDataset, TProjectId> {
270
+ const effectiveDocumentId = getEffectiveDocumentId(doc)
266
271
  return {
267
272
  type: 'document.publish',
268
273
  ...doc,
269
- documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
274
+ documentId: effectiveDocumentId,
270
275
  }
271
276
  }
272
277
 
@@ -283,10 +288,11 @@ export function unpublishDocument<
283
288
  >(
284
289
  doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
285
290
  ): UnpublishDocumentAction<TDocumentType, TDataset, TProjectId> {
291
+ const effectiveDocumentId = getEffectiveDocumentId(doc)
286
292
  return {
287
293
  type: 'document.unpublish',
288
294
  ...doc,
289
- documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
295
+ documentId: effectiveDocumentId,
290
296
  }
291
297
  }
292
298
 
@@ -303,9 +309,10 @@ export function discardDocument<
303
309
  >(
304
310
  doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
305
311
  ): DiscardDocumentAction<TDocumentType, TDataset, TProjectId> {
312
+ const effectiveDocumentId = getEffectiveDocumentId(doc)
306
313
  return {
307
314
  type: 'document.discard',
308
315
  ...doc,
309
- documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
316
+ documentId: effectiveDocumentId,
310
317
  }
311
318
  }
@@ -1,11 +1,9 @@
1
- // applyDocumentActions.test.ts
2
1
  import {type SanityDocument} from '@sanity/types'
3
2
  import {Subject} from 'rxjs'
4
3
  import {describe, expect, it} from 'vitest'
5
4
 
6
- import {bindActionByDataset} from '../store/createActionBinder'
5
+ import {bindActionByResource} from '../store/createActionBinder'
7
6
  import {createSanityInstance, type SanityInstance} from '../store/createSanityInstance'
8
- import {} from '../store/createStateSourceAction'
9
7
  import {createStoreState, type StoreState} from '../store/createStoreState'
10
8
  import {type DocumentAction} from './actions'
11
9
  import {type DocumentStoreState} from './documentStore'
@@ -14,7 +12,7 @@ import {type AppliedTransaction, type OutgoingTransaction} from './reducers'
14
12
 
15
13
  vi.mock('../store/createActionBinder', async (importOriginal) => ({
16
14
  ...(await importOriginal<typeof import('../store/createActionBinder')>()),
17
- bindActionByDataset: vi.fn(),
15
+ bindActionByResource: vi.fn(),
18
16
  }))
19
17
 
20
18
  type TestState = Pick<
@@ -48,9 +46,9 @@ describe('applyDocumentActions', () => {
48
46
  }
49
47
  state = createStoreState(initialState)
50
48
  instance = createSanityInstance({projectId: 'p', dataset: 'd'})
51
- const key = {name: 'p.d', projectId: 'p', dataset: 'd'}
49
+ const key = {name: 'p.d', resource: {projectId: 'p', dataset: 'd'}}
52
50
 
53
- vi.mocked(bindActionByDataset).mockImplementation(
51
+ vi.mocked(bindActionByResource).mockImplementation(
54
52
  (_storeDef, action) => (instanceParam: SanityInstance, options) =>
55
53
  action({instance: instanceParam, state, key}, options),
56
54
  )
@@ -75,6 +73,7 @@ describe('applyDocumentActions', () => {
75
73
  const applyPromise = applyDocumentActions(instance, {
76
74
  actions: [action],
77
75
  transactionId: 'txn-success',
76
+ resource: {projectId: 'p', dataset: 'd'},
78
77
  })
79
78
 
80
79
  const appliedTx: AppliedTransaction = {
@@ -132,6 +131,7 @@ describe('applyDocumentActions', () => {
132
131
  const applyPromise = applyDocumentActions(instance, {
133
132
  actions: [action],
134
133
  transactionId: 'txn-error',
134
+ resource: {projectId: 'p', dataset: 'd'},
135
135
  })
136
136
 
137
137
  const errorEvent: DocumentEvent = {
@@ -165,6 +165,7 @@ describe('applyDocumentActions', () => {
165
165
  const applyPromise = applyDocumentActions(childInstance, {
166
166
  actions: [action],
167
167
  transactionId: 'txn-child-match',
168
+ resource: {projectId: 'p', dataset: 'd'},
168
169
  })
169
170
 
170
171
  // Simulate an applied transaction on the parent's instance
@@ -1,12 +1,13 @@
1
- import {type SanityClient} from '@sanity/client'
2
1
  import {type SanityDocument} from 'groq'
3
2
  import {distinctUntilChanged, filter, first, firstValueFrom, map, race} from 'rxjs'
4
3
 
5
- import {bindActionByDataset} from '../store/createActionBinder'
4
+ import {type DocumentResource} from '../config/sanityConfig'
5
+ import {bindActionByResource} from '../store/createActionBinder'
6
6
  import {type SanityInstance} from '../store/createSanityInstance'
7
7
  import {type StoreContext} from '../store/defineStore'
8
8
  import {type DocumentAction} from './actions'
9
9
  import {documentStore, type DocumentStoreState} from './documentStore'
10
+ import {type DocumentTransactionSubmissionResult} from './events'
10
11
  import {type DocumentSet} from './processMutations'
11
12
  import {type AppliedTransaction, type QueuedTransaction, queueTransaction} from './reducers'
12
13
 
@@ -19,7 +20,7 @@ export interface ActionsResult<TDocument extends SanityDocument = SanityDocument
19
20
  appeared: string[]
20
21
  updated: string[]
21
22
  disappeared: string[]
22
- submitted: () => ReturnType<SanityClient['action']>
23
+ submitted: () => Promise<DocumentTransactionSubmissionResult>
23
24
  }
24
25
 
25
26
  /** @beta */
@@ -29,6 +30,11 @@ export interface ApplyDocumentActionsOptions {
29
30
  */
30
31
  actions: DocumentAction[]
31
32
 
33
+ /**
34
+ * The resource to which the documents being acted on belong.
35
+ */
36
+ resource?: DocumentResource
37
+
32
38
  /**
33
39
  * Optionally provide an ID to be used as this transaction ID
34
40
  */
@@ -61,7 +67,7 @@ export function applyDocumentActions(
61
67
  return boundApplyDocumentActions(...args)
62
68
  }
63
69
 
64
- const boundApplyDocumentActions = bindActionByDataset(documentStore, _applyDocumentActions)
70
+ const boundApplyDocumentActions = bindActionByResource(documentStore, _applyDocumentActions)
65
71
 
66
72
  /** @internal */
67
73
  async function _applyDocumentActions(