@sanity/sdk 0.0.0-alpha.21 → 0.0.0-alpha.23
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 +428 -325
- package/dist/index.js +1618 -1553
- package/dist/index.js.map +1 -1
- package/package.json +6 -7
- package/src/_exports/index.ts +31 -30
- package/src/auth/authStore.test.ts +149 -104
- package/src/auth/authStore.ts +51 -100
- package/src/auth/handleAuthCallback.test.ts +67 -34
- package/src/auth/handleAuthCallback.ts +8 -7
- package/src/auth/logout.test.ts +61 -29
- package/src/auth/logout.ts +26 -28
- package/src/auth/refreshStampedToken.test.ts +9 -9
- package/src/auth/refreshStampedToken.ts +62 -56
- package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +5 -5
- package/src/auth/subscribeToStateAndFetchCurrentUser.ts +45 -47
- package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +4 -5
- package/src/auth/subscribeToStorageEventsAndSetToken.ts +22 -24
- package/src/client/clientStore.test.ts +131 -67
- package/src/client/clientStore.ts +117 -116
- package/src/comlink/controller/actions/destroyController.test.ts +38 -13
- package/src/comlink/controller/actions/destroyController.ts +11 -15
- package/src/comlink/controller/actions/getOrCreateChannel.test.ts +56 -27
- package/src/comlink/controller/actions/getOrCreateChannel.ts +37 -35
- package/src/comlink/controller/actions/getOrCreateController.test.ts +27 -16
- package/src/comlink/controller/actions/getOrCreateController.ts +23 -22
- package/src/comlink/controller/actions/releaseChannel.test.ts +37 -13
- package/src/comlink/controller/actions/releaseChannel.ts +22 -21
- package/src/comlink/controller/comlinkControllerStore.test.ts +65 -36
- package/src/comlink/controller/comlinkControllerStore.ts +44 -5
- package/src/comlink/node/actions/getOrCreateNode.test.ts +31 -15
- package/src/comlink/node/actions/getOrCreateNode.ts +30 -29
- package/src/comlink/node/actions/releaseNode.test.ts +75 -55
- package/src/comlink/node/actions/releaseNode.ts +19 -21
- package/src/comlink/node/comlinkNodeStore.test.ts +6 -11
- package/src/comlink/node/comlinkNodeStore.ts +22 -5
- package/src/config/authConfig.ts +79 -0
- package/src/config/sanityConfig.ts +48 -0
- package/src/datasets/datasets.test.ts +2 -2
- package/src/datasets/datasets.ts +18 -5
- package/src/document/actions.test.ts +22 -10
- package/src/document/actions.ts +44 -56
- package/src/document/applyDocumentActions.test.ts +96 -36
- package/src/document/applyDocumentActions.ts +140 -99
- package/src/document/documentStore.test.ts +103 -155
- package/src/document/documentStore.ts +247 -237
- package/src/document/listen.ts +56 -55
- package/src/document/patchOperations.ts +0 -43
- package/src/document/permissions.test.ts +25 -12
- package/src/document/permissions.ts +11 -4
- package/src/document/processActions.test.ts +41 -8
- package/src/document/reducers.test.ts +87 -16
- package/src/document/reducers.ts +2 -2
- package/src/document/sharedListener.test.ts +34 -16
- package/src/document/sharedListener.ts +33 -11
- package/src/preview/getPreviewState.test.ts +40 -39
- package/src/preview/getPreviewState.ts +68 -56
- package/src/preview/previewConstants.ts +43 -0
- package/src/preview/previewQuery.test.ts +1 -1
- package/src/preview/previewQuery.ts +4 -5
- package/src/preview/previewStore.test.ts +13 -58
- package/src/preview/previewStore.ts +7 -21
- package/src/preview/resolvePreview.test.ts +33 -104
- package/src/preview/resolvePreview.ts +11 -21
- package/src/preview/subscribeToStateAndFetchBatches.test.ts +96 -97
- package/src/preview/subscribeToStateAndFetchBatches.ts +85 -81
- package/src/preview/util.ts +1 -0
- package/src/project/project.test.ts +3 -3
- package/src/project/project.ts +28 -5
- package/src/projection/getProjectionState.test.ts +69 -49
- package/src/projection/getProjectionState.ts +42 -50
- package/src/projection/projectionQuery.ts +1 -1
- package/src/projection/projectionStore.test.ts +13 -51
- package/src/projection/projectionStore.ts +6 -18
- package/src/projection/resolveProjection.test.ts +32 -127
- package/src/projection/resolveProjection.ts +15 -28
- package/src/projection/subscribeToStateAndFetchBatches.test.ts +105 -90
- package/src/projection/subscribeToStateAndFetchBatches.ts +94 -81
- package/src/projection/util.ts +2 -0
- package/src/projects/projects.test.ts +13 -4
- package/src/projects/projects.ts +6 -1
- package/src/query/queryStore.test.ts +10 -47
- package/src/query/queryStore.ts +151 -133
- package/src/query/queryStoreConstants.ts +2 -0
- package/src/store/createActionBinder.test.ts +153 -0
- package/src/store/createActionBinder.ts +176 -0
- package/src/store/createSanityInstance.test.ts +84 -0
- package/src/store/createSanityInstance.ts +124 -0
- package/src/store/createStateSourceAction.test.ts +196 -0
- package/src/store/createStateSourceAction.ts +260 -0
- package/src/store/createStoreInstance.test.ts +81 -0
- package/src/store/createStoreInstance.ts +80 -0
- package/src/store/createStoreState.test.ts +85 -0
- package/src/store/createStoreState.ts +92 -0
- package/src/store/defineStore.test.ts +18 -0
- package/src/store/defineStore.ts +81 -0
- package/src/users/reducers.test.ts +318 -0
- package/src/users/reducers.ts +88 -0
- package/src/users/types.ts +46 -4
- package/src/users/usersConstants.ts +4 -0
- package/src/users/usersStore.test.ts +350 -223
- package/src/users/usersStore.ts +285 -149
- package/src/utils/createFetcherStore.test.ts +6 -7
- package/src/utils/createFetcherStore.ts +150 -153
- package/src/{common/util.test.ts → utils/hashString.test.ts} +1 -1
- package/src/auth/fetchLoginUrls.test.ts +0 -163
- package/src/auth/fetchLoginUrls.ts +0 -74
- package/src/common/createLiveEventSubscriber.test.ts +0 -121
- package/src/common/createLiveEventSubscriber.ts +0 -55
- package/src/common/types.ts +0 -4
- package/src/instance/identity.test.ts +0 -46
- package/src/instance/identity.ts +0 -29
- package/src/instance/sanityInstance.test.ts +0 -77
- package/src/instance/sanityInstance.ts +0 -57
- package/src/instance/types.ts +0 -37
- package/src/preview/getPreviewProjection.ts +0 -45
- package/src/resources/README.md +0 -370
- package/src/resources/createAction.test.ts +0 -101
- package/src/resources/createAction.ts +0 -44
- package/src/resources/createResource.test.ts +0 -112
- package/src/resources/createResource.ts +0 -102
- package/src/resources/createStateSourceAction.test.ts +0 -114
- package/src/resources/createStateSourceAction.ts +0 -83
- package/src/resources/createStore.test.ts +0 -67
- package/src/resources/createStore.ts +0 -46
- package/src/store/createStore.test.ts +0 -108
- package/src/store/createStore.ts +0 -106
- /package/src/{common/util.ts → utils/hashString.ts} +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {type SanityDocumentLike} from '@sanity/types'
|
|
2
|
+
|
|
3
|
+
import {type AuthConfig} from './authConfig'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export interface ProjectHandle {
|
|
9
|
+
projectId?: string | undefined
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export interface DatasetHandle extends ProjectHandle {
|
|
16
|
+
dataset?: string | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @public */
|
|
20
|
+
export interface DocumentTypeHandle<TDocument extends SanityDocumentLike = SanityDocumentLike>
|
|
21
|
+
extends DatasetHandle {
|
|
22
|
+
documentId?: string
|
|
23
|
+
documentType: TDocument['_type']
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @public
|
|
28
|
+
* A minimal set of metadata for a given document, comprising the document's ID and type.
|
|
29
|
+
* Used by most document-related hooks (such as {@link usePreview}, {@link useDocument}, and {@link useEditDocument})
|
|
30
|
+
* to reference a particular document without fetching the entire document upfront.
|
|
31
|
+
* @category Types
|
|
32
|
+
*/
|
|
33
|
+
export interface DocumentHandle<TDocument extends SanityDocumentLike = SanityDocumentLike>
|
|
34
|
+
extends DocumentTypeHandle<TDocument> {
|
|
35
|
+
documentId: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Represents the complete configuration for a Sanity SDK instance
|
|
40
|
+
* @public
|
|
41
|
+
*/
|
|
42
|
+
export interface SanityConfig extends DatasetHandle {
|
|
43
|
+
/**
|
|
44
|
+
* Authentication configuration for the instance
|
|
45
|
+
* @remarks Merged with parent configurations when using createChild
|
|
46
|
+
*/
|
|
47
|
+
auth?: AuthConfig
|
|
48
|
+
}
|
|
@@ -3,8 +3,8 @@ import {of} from 'rxjs'
|
|
|
3
3
|
import {describe, it} from 'vitest'
|
|
4
4
|
|
|
5
5
|
import {getClientState} from '../client/clientStore'
|
|
6
|
-
import {createSanityInstance} from '../
|
|
7
|
-
import {type StateSource} from '../
|
|
6
|
+
import {createSanityInstance} from '../store/createSanityInstance'
|
|
7
|
+
import {type StateSource} from '../store/createStateSourceAction'
|
|
8
8
|
import {resolveDatasets} from './datasets'
|
|
9
9
|
|
|
10
10
|
vi.mock('../client/clientStore')
|
package/src/datasets/datasets.ts
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
import {switchMap} from 'rxjs'
|
|
2
2
|
|
|
3
3
|
import {getClientState} from '../client/clientStore'
|
|
4
|
+
import {type ProjectHandle} from '../config/sanityConfig'
|
|
4
5
|
import {createFetcherStore} from '../utils/createFetcherStore'
|
|
5
6
|
|
|
7
|
+
const API_VERSION = 'v2025-02-19'
|
|
8
|
+
|
|
6
9
|
/** @public */
|
|
7
10
|
export const datasets = createFetcherStore({
|
|
8
11
|
name: 'Datasets',
|
|
9
|
-
getKey: () =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
getKey: (instance, options?: ProjectHandle) => {
|
|
13
|
+
const projectId = options?.projectId ?? instance.config.projectId
|
|
14
|
+
if (!projectId) {
|
|
15
|
+
throw new Error('A projectId is required to use the project API.')
|
|
16
|
+
}
|
|
17
|
+
return projectId
|
|
18
|
+
},
|
|
19
|
+
fetcher: (instance) => (options?: ProjectHandle) => {
|
|
20
|
+
return getClientState(instance, {
|
|
21
|
+
apiVersion: API_VERSION,
|
|
22
|
+
// non-null assertion is fine because we check above
|
|
23
|
+
projectId: (options?.projectId ?? instance.config.projectId)!,
|
|
24
|
+
useProjectHostname: true,
|
|
25
|
+
}).observable.pipe(switchMap((client) => client.observable.datasets.list()))
|
|
26
|
+
},
|
|
14
27
|
})
|
|
15
28
|
|
|
16
29
|
/** @public */
|
|
@@ -2,6 +2,7 @@ import {at, patch, set, setIfMissing} from '@sanity/mutate'
|
|
|
2
2
|
import {type PatchOperations} from '@sanity/types'
|
|
3
3
|
import {describe, expect, it} from 'vitest'
|
|
4
4
|
|
|
5
|
+
import {type DocumentHandle} from '../config/sanityConfig'
|
|
5
6
|
import {
|
|
6
7
|
createDocument,
|
|
7
8
|
deleteDocument,
|
|
@@ -10,14 +11,13 @@ import {
|
|
|
10
11
|
publishDocument,
|
|
11
12
|
unpublishDocument,
|
|
12
13
|
} from '../document/actions'
|
|
13
|
-
import {type DocumentHandle} from './patchOperations'
|
|
14
14
|
|
|
15
15
|
const dummyPatch: PatchOperations = {
|
|
16
16
|
diffMatchPatch: {'dummy.path': 'dummy patch'},
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
const dummyDocHandle: DocumentHandle = {
|
|
20
|
-
const dummyDocString = {
|
|
19
|
+
const dummyDocHandle: DocumentHandle = {documentId: 'drafts.abc123', documentType: 'testType'}
|
|
20
|
+
const dummyDocString = {documentId: 'drafts.abc123', documentType: 'testType'}
|
|
21
21
|
|
|
22
22
|
describe('document actions', () => {
|
|
23
23
|
describe('createDocument', () => {
|
|
@@ -26,20 +26,20 @@ describe('document actions', () => {
|
|
|
26
26
|
expect(action).toEqual({
|
|
27
27
|
type: 'document.create',
|
|
28
28
|
// getId returns the input if it does not end with a dot.
|
|
29
|
-
documentId:
|
|
30
|
-
documentType: dummyDocHandle.
|
|
29
|
+
documentId: 'abc123',
|
|
30
|
+
documentType: dummyDocHandle.documentType,
|
|
31
31
|
})
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
it('creates a document action from a document type handle', () => {
|
|
35
35
|
// A document type handle is similar to a document handle,
|
|
36
36
|
// but _id is optional.
|
|
37
|
-
const typeHandle = {
|
|
37
|
+
const typeHandle = {documentId: 'abc456', documentType: 'anotherType'}
|
|
38
38
|
const action = createDocument(typeHandle)
|
|
39
39
|
expect(action).toEqual({
|
|
40
40
|
type: 'document.create',
|
|
41
|
-
documentId:
|
|
42
|
-
documentType: typeHandle.
|
|
41
|
+
documentId: 'abc456',
|
|
42
|
+
documentType: typeHandle.documentType,
|
|
43
43
|
})
|
|
44
44
|
})
|
|
45
45
|
})
|
|
@@ -51,6 +51,7 @@ describe('document actions', () => {
|
|
|
51
51
|
expect(action).toEqual({
|
|
52
52
|
type: 'document.delete',
|
|
53
53
|
documentId: 'abc123',
|
|
54
|
+
documentType: dummyDocString.documentType,
|
|
54
55
|
})
|
|
55
56
|
})
|
|
56
57
|
|
|
@@ -59,6 +60,7 @@ describe('document actions', () => {
|
|
|
59
60
|
expect(action).toEqual({
|
|
60
61
|
type: 'document.delete',
|
|
61
62
|
documentId: 'abc123',
|
|
63
|
+
documentType: dummyDocHandle.documentType,
|
|
62
64
|
})
|
|
63
65
|
})
|
|
64
66
|
})
|
|
@@ -69,6 +71,7 @@ describe('document actions', () => {
|
|
|
69
71
|
expect(action).toEqual({
|
|
70
72
|
type: 'document.edit',
|
|
71
73
|
documentId: 'abc123',
|
|
74
|
+
documentType: dummyDocString.documentType,
|
|
72
75
|
patches: [dummyPatch],
|
|
73
76
|
})
|
|
74
77
|
})
|
|
@@ -78,14 +81,16 @@ describe('document actions', () => {
|
|
|
78
81
|
expect(action).toEqual({
|
|
79
82
|
type: 'document.edit',
|
|
80
83
|
documentId: 'abc123',
|
|
84
|
+
documentType: dummyDocHandle.documentType,
|
|
81
85
|
patches: [dummyPatch],
|
|
82
86
|
})
|
|
83
87
|
})
|
|
84
88
|
|
|
85
89
|
it('allows @sanity/mutate-style patches', () => {
|
|
86
90
|
const action = editDocument(
|
|
91
|
+
dummyDocHandle,
|
|
87
92
|
patch(
|
|
88
|
-
|
|
93
|
+
dummyDocHandle.documentId,
|
|
89
94
|
[
|
|
90
95
|
at('published', set(true)),
|
|
91
96
|
at('address', setIfMissing({_type: 'address'})),
|
|
@@ -96,7 +101,8 @@ describe('document actions', () => {
|
|
|
96
101
|
)
|
|
97
102
|
|
|
98
103
|
expect(action).toEqual({
|
|
99
|
-
documentId: '
|
|
104
|
+
documentId: 'abc123',
|
|
105
|
+
documentType: 'testType',
|
|
100
106
|
patches: [
|
|
101
107
|
{ifRevisionID: 'txn0', set: {published: true}},
|
|
102
108
|
{ifRevisionID: 'txn0', setIfMissing: {address: {_type: 'address'}}},
|
|
@@ -113,6 +119,7 @@ describe('document actions', () => {
|
|
|
113
119
|
expect(action).toEqual({
|
|
114
120
|
type: 'document.publish',
|
|
115
121
|
documentId: 'abc123',
|
|
122
|
+
documentType: dummyDocString.documentType,
|
|
116
123
|
})
|
|
117
124
|
})
|
|
118
125
|
|
|
@@ -121,6 +128,7 @@ describe('document actions', () => {
|
|
|
121
128
|
expect(action).toEqual({
|
|
122
129
|
type: 'document.publish',
|
|
123
130
|
documentId: 'abc123',
|
|
131
|
+
documentType: dummyDocHandle.documentType,
|
|
124
132
|
})
|
|
125
133
|
})
|
|
126
134
|
})
|
|
@@ -131,6 +139,7 @@ describe('document actions', () => {
|
|
|
131
139
|
expect(action).toEqual({
|
|
132
140
|
type: 'document.unpublish',
|
|
133
141
|
documentId: 'abc123',
|
|
142
|
+
documentType: dummyDocString.documentType,
|
|
134
143
|
})
|
|
135
144
|
})
|
|
136
145
|
|
|
@@ -139,6 +148,7 @@ describe('document actions', () => {
|
|
|
139
148
|
expect(action).toEqual({
|
|
140
149
|
type: 'document.unpublish',
|
|
141
150
|
documentId: 'abc123',
|
|
151
|
+
documentType: dummyDocHandle.documentType,
|
|
142
152
|
})
|
|
143
153
|
})
|
|
144
154
|
})
|
|
@@ -149,6 +159,7 @@ describe('document actions', () => {
|
|
|
149
159
|
expect(action).toEqual({
|
|
150
160
|
type: 'document.discard',
|
|
151
161
|
documentId: 'abc123',
|
|
162
|
+
documentType: dummyDocString.documentType,
|
|
152
163
|
})
|
|
153
164
|
})
|
|
154
165
|
|
|
@@ -157,6 +168,7 @@ describe('document actions', () => {
|
|
|
157
168
|
expect(action).toEqual({
|
|
158
169
|
type: 'document.discard',
|
|
159
170
|
documentId: 'abc123',
|
|
171
|
+
documentType: dummyDocHandle.documentType,
|
|
160
172
|
})
|
|
161
173
|
})
|
|
162
174
|
})
|
package/src/document/actions.ts
CHANGED
|
@@ -2,12 +2,8 @@ import {SanityEncoder} from '@sanity/mutate'
|
|
|
2
2
|
import {type PatchMutation as SanityMutatePatchMutation} from '@sanity/mutate/_unstable_store'
|
|
3
3
|
import {type PatchMutation, type PatchOperations, type SanityDocumentLike} from '@sanity/types'
|
|
4
4
|
|
|
5
|
+
import {type DocumentHandle, type DocumentTypeHandle} from '../config/sanityConfig'
|
|
5
6
|
import {getPublishedId} from '../utils/ids'
|
|
6
|
-
import {
|
|
7
|
-
type DocumentHandle,
|
|
8
|
-
type DocumentResourceId,
|
|
9
|
-
type DocumentTypeHandle,
|
|
10
|
-
} from './patchOperations'
|
|
11
7
|
|
|
12
8
|
const isSanityMutatePatch = (value: unknown): value is SanityMutatePatchMutation => {
|
|
13
9
|
if (typeof value !== 'object' || !value) return false
|
|
@@ -18,51 +14,40 @@ const isSanityMutatePatch = (value: unknown): value is SanityMutatePatchMutation
|
|
|
18
14
|
}
|
|
19
15
|
|
|
20
16
|
/** @beta */
|
|
21
|
-
export interface CreateDocumentAction<TDocument extends SanityDocumentLike = SanityDocumentLike>
|
|
17
|
+
export interface CreateDocumentAction<TDocument extends SanityDocumentLike = SanityDocumentLike>
|
|
18
|
+
extends DocumentTypeHandle<TDocument> {
|
|
22
19
|
type: 'document.create'
|
|
23
|
-
documentId?: string
|
|
24
|
-
resourceId?: DocumentResourceId
|
|
25
|
-
documentType: TDocument['_type']
|
|
26
20
|
}
|
|
27
21
|
|
|
28
|
-
// the unused `_TDocument` is primarily for typescript meta-programming to
|
|
29
|
-
// capture and preserve the document type as best as possible
|
|
30
22
|
/** @beta */
|
|
31
|
-
export interface DeleteDocumentAction<
|
|
23
|
+
export interface DeleteDocumentAction<TDocument extends SanityDocumentLike = SanityDocumentLike>
|
|
24
|
+
extends DocumentHandle<TDocument> {
|
|
32
25
|
type: 'document.delete'
|
|
33
|
-
documentId: string
|
|
34
|
-
resourceId?: DocumentResourceId
|
|
35
26
|
}
|
|
36
27
|
|
|
37
28
|
/** @beta */
|
|
38
|
-
export interface EditDocumentAction<
|
|
29
|
+
export interface EditDocumentAction<TDocument extends SanityDocumentLike = SanityDocumentLike>
|
|
30
|
+
extends DocumentHandle<TDocument> {
|
|
39
31
|
type: 'document.edit'
|
|
40
|
-
documentId: string
|
|
41
|
-
resourceId?: DocumentResourceId
|
|
42
32
|
patches?: PatchOperations[]
|
|
43
33
|
}
|
|
44
34
|
|
|
45
35
|
/** @beta */
|
|
46
|
-
export interface PublishDocumentAction<
|
|
36
|
+
export interface PublishDocumentAction<TDocument extends SanityDocumentLike = SanityDocumentLike>
|
|
37
|
+
extends DocumentHandle<TDocument> {
|
|
47
38
|
type: 'document.publish'
|
|
48
|
-
documentId: string
|
|
49
|
-
resourceId?: DocumentResourceId
|
|
50
39
|
}
|
|
51
40
|
|
|
52
41
|
/** @beta */
|
|
53
|
-
export interface UnpublishDocumentAction<
|
|
54
|
-
|
|
55
|
-
> {
|
|
42
|
+
export interface UnpublishDocumentAction<TDocument extends SanityDocumentLike = SanityDocumentLike>
|
|
43
|
+
extends DocumentHandle<TDocument> {
|
|
56
44
|
type: 'document.unpublish'
|
|
57
|
-
documentId: string
|
|
58
|
-
resourceId?: DocumentResourceId
|
|
59
45
|
}
|
|
60
46
|
|
|
61
47
|
/** @beta */
|
|
62
|
-
export interface DiscardDocumentAction<
|
|
48
|
+
export interface DiscardDocumentAction<TDocument extends SanityDocumentLike = SanityDocumentLike>
|
|
49
|
+
extends DocumentHandle<TDocument> {
|
|
63
50
|
type: 'document.discard'
|
|
64
|
-
documentId: string
|
|
65
|
-
resourceId?: DocumentResourceId
|
|
66
51
|
}
|
|
67
52
|
|
|
68
53
|
/** @beta */
|
|
@@ -76,13 +61,12 @@ export type DocumentAction<TDocument extends SanityDocumentLike = SanityDocument
|
|
|
76
61
|
|
|
77
62
|
/** @beta */
|
|
78
63
|
export function createDocument<TDocument extends SanityDocumentLike>(
|
|
79
|
-
doc: DocumentTypeHandle<TDocument
|
|
64
|
+
doc: DocumentTypeHandle<TDocument>,
|
|
80
65
|
): CreateDocumentAction<TDocument> {
|
|
81
66
|
return {
|
|
82
67
|
type: 'document.create',
|
|
83
|
-
...
|
|
84
|
-
|
|
85
|
-
...(doc.resourceId && {resourceId: doc.resourceId}),
|
|
68
|
+
...doc,
|
|
69
|
+
...(doc.documentId && {documentId: getPublishedId(doc.documentId)}),
|
|
86
70
|
}
|
|
87
71
|
}
|
|
88
72
|
|
|
@@ -92,29 +76,25 @@ export function deleteDocument<TDocument extends SanityDocumentLike>(
|
|
|
92
76
|
): DeleteDocumentAction<TDocument> {
|
|
93
77
|
return {
|
|
94
78
|
type: 'document.delete',
|
|
95
|
-
|
|
96
|
-
|
|
79
|
+
...doc,
|
|
80
|
+
documentId: getPublishedId(doc.documentId),
|
|
97
81
|
}
|
|
98
82
|
}
|
|
99
83
|
|
|
100
84
|
function convertSanityMutatePatch(
|
|
101
85
|
sanityPatchMutation: SanityMutatePatchMutation,
|
|
102
|
-
): EditDocumentAction {
|
|
86
|
+
): EditDocumentAction['patches'] {
|
|
103
87
|
const encoded = SanityEncoder.encode(sanityPatchMutation) as PatchMutation[]
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const copy: PatchOperations = {...i.patch}
|
|
110
|
-
if ('id' in copy) delete copy.id
|
|
111
|
-
return copy
|
|
112
|
-
}),
|
|
113
|
-
}
|
|
88
|
+
return encoded.map((i) => {
|
|
89
|
+
const copy: PatchOperations = {...i.patch}
|
|
90
|
+
if ('id' in copy) delete copy.id
|
|
91
|
+
return copy
|
|
92
|
+
})
|
|
114
93
|
}
|
|
115
94
|
|
|
116
95
|
/** @beta */
|
|
117
96
|
export function editDocument<TDocument extends SanityDocumentLike>(
|
|
97
|
+
doc: DocumentHandle<TDocument>,
|
|
118
98
|
sanityMutatePatch: SanityMutatePatchMutation,
|
|
119
99
|
): EditDocumentAction<TDocument>
|
|
120
100
|
/** @beta */
|
|
@@ -124,16 +104,24 @@ export function editDocument<TDocument extends SanityDocumentLike>(
|
|
|
124
104
|
): EditDocumentAction<TDocument>
|
|
125
105
|
/** @beta */
|
|
126
106
|
export function editDocument<TDocument extends SanityDocumentLike>(
|
|
127
|
-
doc:
|
|
128
|
-
patches?: PatchOperations | PatchOperations[],
|
|
107
|
+
doc: DocumentHandle<TDocument>,
|
|
108
|
+
patches?: PatchOperations | PatchOperations[] | SanityMutatePatchMutation,
|
|
129
109
|
): EditDocumentAction<TDocument> {
|
|
130
|
-
if (isSanityMutatePatch(
|
|
110
|
+
if (isSanityMutatePatch(patches)) {
|
|
111
|
+
const converted = convertSanityMutatePatch(patches) ?? []
|
|
112
|
+
return {
|
|
113
|
+
...doc,
|
|
114
|
+
type: 'document.edit',
|
|
115
|
+
documentId: getPublishedId(doc.documentId),
|
|
116
|
+
patches: converted,
|
|
117
|
+
}
|
|
118
|
+
}
|
|
131
119
|
|
|
132
120
|
return {
|
|
121
|
+
...doc,
|
|
133
122
|
type: 'document.edit',
|
|
134
|
-
documentId: getPublishedId(doc.
|
|
123
|
+
documentId: getPublishedId(doc.documentId),
|
|
135
124
|
...(patches && {patches: Array.isArray(patches) ? patches : [patches]}),
|
|
136
|
-
...(doc.resourceId && {resourceId: doc.resourceId}),
|
|
137
125
|
}
|
|
138
126
|
}
|
|
139
127
|
|
|
@@ -143,8 +131,8 @@ export function publishDocument<TDocument extends SanityDocumentLike>(
|
|
|
143
131
|
): PublishDocumentAction<TDocument> {
|
|
144
132
|
return {
|
|
145
133
|
type: 'document.publish',
|
|
146
|
-
|
|
147
|
-
|
|
134
|
+
...doc,
|
|
135
|
+
documentId: getPublishedId(doc.documentId),
|
|
148
136
|
}
|
|
149
137
|
}
|
|
150
138
|
|
|
@@ -154,8 +142,8 @@ export function unpublishDocument<TDocument extends SanityDocumentLike>(
|
|
|
154
142
|
): UnpublishDocumentAction<TDocument> {
|
|
155
143
|
return {
|
|
156
144
|
type: 'document.unpublish',
|
|
157
|
-
|
|
158
|
-
|
|
145
|
+
...doc,
|
|
146
|
+
documentId: getPublishedId(doc.documentId),
|
|
159
147
|
}
|
|
160
148
|
}
|
|
161
149
|
|
|
@@ -165,7 +153,7 @@ export function discardDocument<TDocument extends SanityDocumentLike>(
|
|
|
165
153
|
): DiscardDocumentAction<TDocument> {
|
|
166
154
|
return {
|
|
167
155
|
type: 'document.discard',
|
|
168
|
-
|
|
169
|
-
|
|
156
|
+
...doc,
|
|
157
|
+
documentId: getPublishedId(doc.documentId),
|
|
170
158
|
}
|
|
171
159
|
}
|
|
@@ -3,15 +3,20 @@ import {type SanityDocument} from '@sanity/types'
|
|
|
3
3
|
import {Subject} from 'rxjs'
|
|
4
4
|
import {describe, expect, it} from 'vitest'
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import {type
|
|
8
|
-
import {
|
|
6
|
+
import {bindActionByDataset} from '../store/createActionBinder'
|
|
7
|
+
import {createSanityInstance, type SanityInstance} from '../store/createSanityInstance'
|
|
8
|
+
import {} from '../store/createStateSourceAction'
|
|
9
|
+
import {createStoreState, type StoreState} from '../store/createStoreState'
|
|
9
10
|
import {type DocumentAction} from './actions'
|
|
10
|
-
import {applyDocumentActions} from './applyDocumentActions'
|
|
11
11
|
import {type DocumentStoreState} from './documentStore'
|
|
12
12
|
import {type DocumentEvent} from './events'
|
|
13
13
|
import {type AppliedTransaction, type OutgoingTransaction} from './reducers'
|
|
14
14
|
|
|
15
|
+
vi.mock('../store/createActionBinder', async (importOriginal) => ({
|
|
16
|
+
...(await importOriginal<typeof import('../store/createActionBinder')>()),
|
|
17
|
+
bindActionByDataset: vi.fn(),
|
|
18
|
+
}))
|
|
19
|
+
|
|
15
20
|
type TestState = Pick<
|
|
16
21
|
DocumentStoreState,
|
|
17
22
|
'documentStates' | 'queued' | 'applied' | 'outgoing' | 'error' | 'events'
|
|
@@ -26,8 +31,13 @@ const exampleDoc: SanityDocument = {
|
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
describe('applyDocumentActions', () => {
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
let state: StoreState<TestState>
|
|
35
|
+
let instance: SanityInstance
|
|
36
|
+
let eventsSubject: Subject<DocumentEvent>
|
|
37
|
+
let applyDocumentActions: typeof import('./applyDocumentActions').applyDocumentActions
|
|
38
|
+
|
|
39
|
+
beforeEach(async () => {
|
|
40
|
+
eventsSubject = new Subject<DocumentEvent>()
|
|
31
41
|
const initialState: TestState = {
|
|
32
42
|
documentStates: {},
|
|
33
43
|
queued: [],
|
|
@@ -36,24 +46,35 @@ describe('applyDocumentActions', () => {
|
|
|
36
46
|
error: undefined,
|
|
37
47
|
events: eventsSubject,
|
|
38
48
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
state = createStoreState(initialState)
|
|
50
|
+
instance = createSanityInstance({projectId: 'p', dataset: 'd'})
|
|
51
|
+
|
|
52
|
+
vi.mocked(bindActionByDataset).mockImplementation(
|
|
53
|
+
(_storeDef, action) =>
|
|
54
|
+
(instanceParam: SanityInstance, ...params: unknown[]) =>
|
|
55
|
+
action({instance: instanceParam, state}, ...params),
|
|
56
|
+
)
|
|
57
|
+
// Import dynamically to ensure mocks are set up before the module under test is loaded
|
|
58
|
+
const module = await import('./applyDocumentActions')
|
|
59
|
+
applyDocumentActions = module.applyDocumentActions
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
afterEach(() => {
|
|
63
|
+
instance.dispose()
|
|
64
|
+
})
|
|
42
65
|
|
|
66
|
+
it('resolves with a successful applied transaction and accepted event', async () => {
|
|
43
67
|
const action: DocumentAction = {
|
|
44
68
|
type: 'document.edit',
|
|
45
69
|
documentId: 'doc1',
|
|
70
|
+
documentType: 'example',
|
|
46
71
|
patches: [{set: {foo: 'bar'}}],
|
|
47
72
|
}
|
|
48
73
|
|
|
49
74
|
// Call applyDocumentActions with a fixed transactionId for reproducibility.
|
|
50
|
-
const applyPromise = applyDocumentActions(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
{
|
|
54
|
-
transactionId: 'txn-success',
|
|
55
|
-
},
|
|
56
|
-
)
|
|
75
|
+
const applyPromise = applyDocumentActions(instance, action, {
|
|
76
|
+
transactionId: 'txn-success',
|
|
77
|
+
})
|
|
57
78
|
|
|
58
79
|
const appliedTx: AppliedTransaction = {
|
|
59
80
|
transactionId: 'txn-success',
|
|
@@ -99,33 +120,17 @@ describe('applyDocumentActions', () => {
|
|
|
99
120
|
})
|
|
100
121
|
|
|
101
122
|
it('throws an error if a transaction error event is emitted', async () => {
|
|
102
|
-
const eventsSubject = new Subject<DocumentEvent>()
|
|
103
|
-
const initialState: TestState = {
|
|
104
|
-
documentStates: {},
|
|
105
|
-
queued: [],
|
|
106
|
-
applied: [],
|
|
107
|
-
outgoing: undefined,
|
|
108
|
-
error: undefined,
|
|
109
|
-
events: eventsSubject,
|
|
110
|
-
}
|
|
111
|
-
const state = createResourceState(initialState)
|
|
112
|
-
const instance = createSanityInstance({projectId: 'p', dataset: 'd'})
|
|
113
|
-
const context: ActionContext<TestState> = {instance, state}
|
|
114
|
-
|
|
115
123
|
const action: DocumentAction = {
|
|
116
124
|
type: 'document.edit',
|
|
117
125
|
documentId: 'doc1',
|
|
126
|
+
documentType: 'example',
|
|
118
127
|
patches: [{set: {foo: 'error'}}],
|
|
119
128
|
}
|
|
120
129
|
|
|
121
130
|
// Call applyDocumentActions with a fixed transactionId.
|
|
122
|
-
const applyPromise = applyDocumentActions(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
{
|
|
126
|
-
transactionId: 'txn-error',
|
|
127
|
-
},
|
|
128
|
-
)
|
|
131
|
+
const applyPromise = applyDocumentActions(instance, action, {
|
|
132
|
+
transactionId: 'txn-error',
|
|
133
|
+
})
|
|
129
134
|
|
|
130
135
|
const errorEvent: DocumentEvent = {
|
|
131
136
|
type: 'error',
|
|
@@ -138,4 +143,59 @@ describe('applyDocumentActions', () => {
|
|
|
138
143
|
|
|
139
144
|
await expect(applyPromise).rejects.toThrow('Simulated error')
|
|
140
145
|
})
|
|
146
|
+
|
|
147
|
+
it('matches parent instance via child when action projectId and dataset do not match child config', async () => {
|
|
148
|
+
// Create a parent instance
|
|
149
|
+
const parentInstance = createSanityInstance({projectId: 'p', dataset: 'd'})
|
|
150
|
+
// Create a child instance with different config
|
|
151
|
+
const childInstance = parentInstance.createChild({projectId: 'child-p', dataset: 'child-d'})
|
|
152
|
+
// Use the child instance in context
|
|
153
|
+
// Create an action that refers to the parent's configuration
|
|
154
|
+
const action: DocumentAction = {
|
|
155
|
+
type: 'document.edit',
|
|
156
|
+
documentId: 'doc1',
|
|
157
|
+
documentType: 'example',
|
|
158
|
+
patches: [{set: {foo: 'childTest'}}],
|
|
159
|
+
projectId: 'p',
|
|
160
|
+
dataset: 'd',
|
|
161
|
+
}
|
|
162
|
+
// Call applyDocumentActions with the context using childInstance, but with action requiring parent's config
|
|
163
|
+
const applyPromise = applyDocumentActions(childInstance, action, {
|
|
164
|
+
transactionId: 'txn-child-match',
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
// Simulate an applied transaction on the parent's instance
|
|
168
|
+
const appliedTx: AppliedTransaction = {
|
|
169
|
+
transactionId: 'txn-child-match',
|
|
170
|
+
actions: [action],
|
|
171
|
+
disableBatching: false,
|
|
172
|
+
outgoingActions: [],
|
|
173
|
+
outgoingMutations: [],
|
|
174
|
+
base: {doc1: {...exampleDoc, _id: 'doc1', foo: 'old', _rev: 'rev-old'}},
|
|
175
|
+
working: {doc1: {...exampleDoc, _id: 'doc1', foo: 'childTest', _rev: 'rev-new'}},
|
|
176
|
+
previous: {doc1: {...exampleDoc, _id: 'doc1', foo: 'old', _rev: 'rev-old'}},
|
|
177
|
+
previousRevs: {doc1: 'rev-old'},
|
|
178
|
+
timestamp: new Date().toISOString(),
|
|
179
|
+
}
|
|
180
|
+
state.set('simulateApplied', {applied: [appliedTx]})
|
|
181
|
+
|
|
182
|
+
const result = await applyPromise
|
|
183
|
+
expect(result.transactionId).toEqual('txn-child-match')
|
|
184
|
+
expect(result.documents).toEqual(appliedTx.working)
|
|
185
|
+
expect(result.previous).toEqual(appliedTx.previous)
|
|
186
|
+
expect(result.previousRevs).toEqual(appliedTx.previousRevs)
|
|
187
|
+
|
|
188
|
+
const acceptedResult = {transactionId: 'accepted-child'}
|
|
189
|
+
const acceptedEvent: DocumentEvent = {
|
|
190
|
+
type: 'accepted',
|
|
191
|
+
outgoing: {batchedTransactionIds: ['txn-child-match']} as OutgoingTransaction,
|
|
192
|
+
result: acceptedResult,
|
|
193
|
+
}
|
|
194
|
+
eventsSubject.next(acceptedEvent)
|
|
195
|
+
const submittedResult = await result.submitted()
|
|
196
|
+
expect(submittedResult).toEqual(acceptedResult)
|
|
197
|
+
|
|
198
|
+
childInstance.dispose()
|
|
199
|
+
parentInstance.dispose()
|
|
200
|
+
})
|
|
141
201
|
})
|