@sanity/sdk 3.0.0-rc.1 → 3.0.0-rc.2
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 +12 -0
- package/dist/_exports/_internal.d.ts +71 -3
- package/dist/_exports/_internal.d.ts.map +1 -1
- package/dist/_exports/_internal.js +332 -24
- package/dist/_exports/_internal.js.map +1 -1
- package/dist/_exports/agent.d.ts +65 -0
- package/dist/_exports/agent.d.ts.map +1 -0
- package/dist/_exports/agent.js +71 -0
- package/dist/_exports/agent.js.map +1 -0
- package/dist/_exports/comlink.d.ts +118 -0
- package/dist/_exports/comlink.d.ts.map +1 -0
- package/dist/_exports/comlink.js +69 -0
- package/dist/_exports/comlink.js.map +1 -0
- package/dist/authStore-CtE9bLHW.js +754 -0
- package/dist/authStore-CtE9bLHW.js.map +1 -0
- package/dist/authStore-DKFX8fn7.d.ts +3179 -0
- package/dist/authStore-DKFX8fn7.d.ts.map +1 -0
- package/dist/clientStore-BtE2-q2i.js +90 -0
- package/dist/clientStore-BtE2-q2i.js.map +1 -0
- package/dist/createSanityInstance-DUI1bGIg.d.ts +278 -0
- package/dist/createSanityInstance-DUI1bGIg.d.ts.map +1 -0
- package/dist/createStateSourceAction-BOKtqFNm.js +300 -0
- package/dist/createStateSourceAction-BOKtqFNm.js.map +1 -0
- package/dist/getEnv-D5RGkQLu.js +8 -0
- package/dist/getEnv-D5RGkQLu.js.map +1 -0
- package/dist/getNodeState-CR3__B2D.js +67 -0
- package/dist/getNodeState-CR3__B2D.js.map +1 -0
- package/dist/index.d.ts +3 -2335
- package/dist/index.js +4048 -3874
- package/dist/index.js.map +1 -1
- package/dist/logger-DAtJb5RQ.js +173 -0
- package/dist/logger-DAtJb5RQ.js.map +1 -0
- package/dist/object-CxXlSVg7.js +83 -0
- package/dist/object-CxXlSVg7.js.map +1 -0
- package/dist/queryStore-DPf9sN3V.js +1346 -0
- package/dist/queryStore-DPf9sN3V.js.map +1 -0
- package/dist/rolldown-runtime-vyAXikos.js +9 -0
- package/dist/setCleanupTimeout-BiM6q1KF.js +31 -0
- package/dist/setCleanupTimeout-BiM6q1KF.js.map +1 -0
- package/dist/telemetryManager-Dq_qCkeI.js +127 -0
- package/dist/telemetryManager-Dq_qCkeI.js.map +1 -0
- package/dist/version-BChjsi4u.js +9 -0
- package/dist/version-BChjsi4u.js.map +1 -0
- package/package.json +13 -19
- package/src/_exports/_internal.ts +1 -0
- package/src/_exports/agent.ts +19 -0
- package/src/_exports/comlink.ts +16 -0
- package/src/_exports/index.ts +38 -86
- package/src/applications/applications.test-d.ts +5 -0
- package/src/applications/applications.ts +5 -2
- package/src/auth/authMode.test.ts +0 -25
- package/src/auth/authMode.ts +3 -6
- package/src/auth/authStore.test.ts +1 -1
- package/src/auth/authStore.ts +0 -1
- package/src/comments/addonDatasetStore.test.ts +215 -0
- package/src/comments/addonDatasetStore.ts +249 -0
- package/src/comments/buildCommentThreads.test.ts +83 -0
- package/src/comments/buildCommentThreads.ts +54 -0
- package/src/comments/commentActions.test.ts +540 -0
- package/src/comments/commentActions.ts +555 -0
- package/src/comments/commentFieldPath.test.ts +40 -0
- package/src/comments/commentFieldPath.ts +44 -0
- package/src/comments/commentsConstants.ts +80 -0
- package/src/comments/commentsStore.test.ts +419 -0
- package/src/comments/commentsStore.ts +483 -0
- package/src/comments/normalizeComment.test.ts +116 -0
- package/src/comments/normalizeComment.ts +45 -0
- package/src/comments/observeComments.test.ts +193 -0
- package/src/comments/observeComments.ts +113 -0
- package/src/comments/reducers.test.ts +277 -0
- package/src/comments/reducers.ts +316 -0
- package/src/comments/types.ts +249 -0
- package/src/comments/weakenReferences.test.ts +47 -0
- package/src/comments/weakenReferences.ts +29 -0
- package/src/config/sanityConfig.ts +3 -75
- package/src/document/applyDocumentActions.test.ts +8 -12
- package/src/document/documentConstants.ts +8 -0
- package/src/document/documentStore.test.ts +104 -19
- package/src/document/documentStore.ts +36 -5
- package/src/document/patchOperations.test.ts +27 -0
- package/src/document/patchOperations.ts +10 -1
- package/src/document/permissions.test.ts +3 -1
- package/src/document/reducers.test.ts +133 -0
- package/src/document/reducers.ts +18 -3
- package/src/document/util.test.ts +46 -0
- package/src/document/util.ts +37 -1
- package/src/installations/installations.test-d.ts +5 -0
- package/src/installations/installations.ts +4 -0
- package/src/presence/bifurTransport.test.ts +155 -3
- package/src/presence/bifurTransport.ts +79 -12
- package/src/presence/paths.test.ts +70 -0
- package/src/presence/paths.ts +41 -0
- package/src/presence/presenceStore.test.ts +822 -2
- package/src/presence/presenceStore.ts +518 -102
- package/src/presence/types.ts +175 -3
- package/src/preview/types.ts +0 -25
- package/src/projection/projectionStore.test.ts +0 -8
- package/src/projection/types.ts +0 -8
- package/src/query/queryStore.ts +7 -6
- package/src/store/createActionBinder.test.ts +51 -29
- package/src/store/createActionBinder.ts +16 -62
- package/src/store/createSanityInstance.test.ts +0 -68
- package/src/store/createSanityInstance.ts +0 -63
- package/src/store/createStateSourceAction.ts +1 -1
- package/src/users/reducers.test.ts +0 -3
- package/dist/_chunks-dts/createGroqSearchFilter.d.ts +0 -1147
- package/dist/_chunks-dts/createGroqSearchFilter.d.ts.map +0 -1
- package/dist/_chunks-es/_internal.js +0 -134
- package/dist/_chunks-es/_internal.js.map +0 -1
- package/dist/_chunks-es/createGroqSearchFilter.js +0 -1864
- package/dist/_chunks-es/createGroqSearchFilter.js.map +0 -1
- package/dist/_chunks-es/telemetryManager.js +0 -93
- package/dist/_chunks-es/telemetryManager.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/src/applications/userApplications.test.ts +0 -126
- package/src/applications/userApplications.ts +0 -261
- package/src/preview/getPreviewState.test.ts +0 -137
- package/src/preview/getPreviewState.ts +0 -69
- package/src/preview/resolvePreview.test.ts +0 -64
- package/src/preview/resolvePreview.ts +0 -43
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/sdk",
|
|
3
|
-
"version": "3.0.0-rc.
|
|
3
|
+
"version": "3.0.0-rc.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Sanity SDK",
|
|
6
6
|
"keywords": [
|
|
@@ -33,34 +33,28 @@
|
|
|
33
33
|
"module": "./dist/index.js",
|
|
34
34
|
"types": "./dist/index.d.ts",
|
|
35
35
|
"exports": {
|
|
36
|
-
".":
|
|
37
|
-
"source": "./src/_exports/index.ts",
|
|
38
|
-
"import": "./dist/index.js",
|
|
39
|
-
"default": "./dist/index.js"
|
|
40
|
-
},
|
|
36
|
+
".": "./dist/index.js",
|
|
41
37
|
"./package.json": "./package.json",
|
|
42
|
-
"./_internal":
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"default": "./dist/_exports/_internal.js"
|
|
46
|
-
}
|
|
38
|
+
"./_internal": "./dist/_exports/_internal.js",
|
|
39
|
+
"./agent": "./dist/_exports/agent.js",
|
|
40
|
+
"./comlink": "./dist/_exports/comlink.js"
|
|
47
41
|
},
|
|
48
42
|
"publishConfig": {
|
|
49
43
|
"access": "public"
|
|
50
44
|
},
|
|
51
45
|
"dependencies": {
|
|
52
46
|
"@sanity/bifur-client": "^1.0.0",
|
|
53
|
-
"@sanity/client": "^7.
|
|
54
|
-
"@sanity/comlink": "^4.0.
|
|
47
|
+
"@sanity/client": "^7.26.2",
|
|
48
|
+
"@sanity/comlink": "^4.0.3",
|
|
55
49
|
"@sanity/diff-match-patch": "^3.2.0",
|
|
56
50
|
"@sanity/diff-patch": "^6.0.0",
|
|
57
51
|
"@sanity/id-utils": "^1.0.0",
|
|
58
52
|
"@sanity/image-url": "^2.1.1",
|
|
59
53
|
"@sanity/json-match": "^1.0.5",
|
|
60
|
-
"@sanity/message-protocol": "^0.
|
|
54
|
+
"@sanity/message-protocol": "^0.24.0",
|
|
61
55
|
"@sanity/mutate": "^0.18.1",
|
|
62
56
|
"@sanity/telemetry": "^1.1.0",
|
|
63
|
-
"@sanity/types": "^6.
|
|
57
|
+
"@sanity/types": "^6.9.1",
|
|
64
58
|
"groq": "3.88.1-typegen-experimental.0",
|
|
65
59
|
"groq-js": "^2.0.0",
|
|
66
60
|
"reselect": "^5.1.1",
|
|
@@ -69,20 +63,20 @@
|
|
|
69
63
|
},
|
|
70
64
|
"devDependencies": {
|
|
71
65
|
"@sanity/browserslist-config": "^1.0.5",
|
|
72
|
-
"@sanity/pkg-utils": "^
|
|
66
|
+
"@sanity/pkg-utils": "^12.1.0",
|
|
73
67
|
"@types/node": "^24.13.3",
|
|
74
68
|
"@vitest/coverage-v8": "^4.1.10",
|
|
75
69
|
"eslint": "^10.6.0",
|
|
76
70
|
"oxfmt": "^0.58.0",
|
|
77
|
-
"
|
|
71
|
+
"rolldown": "^1.2.3",
|
|
78
72
|
"typescript": "^6.0.3",
|
|
79
73
|
"vite": "^8.1.5",
|
|
80
74
|
"vitest": "^4.1.10",
|
|
81
75
|
"@repo/config-eslint": "0.0.0",
|
|
76
|
+
"@repo/package.bundle": "3.82.0",
|
|
82
77
|
"@repo/config-test": "0.0.1",
|
|
83
78
|
"@repo/package.config": "0.0.1",
|
|
84
|
-
"@repo/tsconfig": "0.0.1"
|
|
85
|
-
"@repo/package.bundle": "3.82.0"
|
|
79
|
+
"@repo/tsconfig": "0.0.1"
|
|
86
80
|
},
|
|
87
81
|
"browserslist": "extends @sanity/browserslist-config",
|
|
88
82
|
"scripts": {
|
|
@@ -6,6 +6,7 @@ export {
|
|
|
6
6
|
getClientErrorApiType,
|
|
7
7
|
isProjectUserNotFoundClientError,
|
|
8
8
|
} from '../auth/utils'
|
|
9
|
+
export {getCommentsOptionsKey, parseCommentsOptionsKey} from '../comments/commentsStore' // only used for memoizing in React, not needed for actual functionality
|
|
9
10
|
export {PREVIEW_PROJECTION} from '../preview/previewConstants'
|
|
10
11
|
export {transformProjectionToPreview} from '../preview/previewProjectionUtils'
|
|
11
12
|
export {getQueryKey, parseQueryKey} from '../query/queryStore' // only used for memoizing in React, not needed for actual functionality
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
AgentGenerateOptions,
|
|
3
|
+
AgentGenerateResult,
|
|
4
|
+
AgentPatchOptions,
|
|
5
|
+
AgentPatchResult,
|
|
6
|
+
AgentPromptOptions,
|
|
7
|
+
AgentPromptResult,
|
|
8
|
+
AgentTransformOptions,
|
|
9
|
+
AgentTransformResult,
|
|
10
|
+
AgentTranslateOptions,
|
|
11
|
+
AgentTranslateResult,
|
|
12
|
+
} from '../agent/agentActions'
|
|
13
|
+
export {
|
|
14
|
+
agentGenerate,
|
|
15
|
+
agentPatch,
|
|
16
|
+
agentPrompt,
|
|
17
|
+
agentTransform,
|
|
18
|
+
agentTranslate,
|
|
19
|
+
} from '../agent/agentActions'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export {
|
|
2
|
+
type ComlinkControllerState,
|
|
3
|
+
destroyController,
|
|
4
|
+
getOrCreateChannel,
|
|
5
|
+
getOrCreateController,
|
|
6
|
+
releaseChannel,
|
|
7
|
+
} from '../comlink/controller/comlinkControllerStore'
|
|
8
|
+
export type {ComlinkNodeState} from '../comlink/node/comlinkNodeStore'
|
|
9
|
+
export {getOrCreateNode, releaseNode} from '../comlink/node/comlinkNodeStore'
|
|
10
|
+
export {getNodeState, type NodeState} from '../comlink/node/getNodeState'
|
|
11
|
+
export {
|
|
12
|
+
type FrameMessage,
|
|
13
|
+
type NewTokenResponseMessage,
|
|
14
|
+
type RequestNewTokenMessage,
|
|
15
|
+
type WindowMessage,
|
|
16
|
+
} from '../comlink/types'
|
package/src/_exports/index.ts
CHANGED
|
@@ -7,25 +7,6 @@ export type SanityProject = _SanityProject
|
|
|
7
7
|
|
|
8
8
|
export {checkPermissions} from '../access/checkPermissions'
|
|
9
9
|
export {type AccessResourceType} from '../access/checkPermissions'
|
|
10
|
-
export type {
|
|
11
|
-
AgentGenerateOptions,
|
|
12
|
-
AgentGenerateResult,
|
|
13
|
-
AgentPatchOptions,
|
|
14
|
-
AgentPatchResult,
|
|
15
|
-
AgentPromptOptions,
|
|
16
|
-
AgentPromptResult,
|
|
17
|
-
AgentTransformOptions,
|
|
18
|
-
AgentTransformResult,
|
|
19
|
-
AgentTranslateOptions,
|
|
20
|
-
AgentTranslateResult,
|
|
21
|
-
} from '../agent/agentActions'
|
|
22
|
-
export {
|
|
23
|
-
agentGenerate,
|
|
24
|
-
agentPatch,
|
|
25
|
-
agentPrompt,
|
|
26
|
-
agentTransform,
|
|
27
|
-
agentTranslate,
|
|
28
|
-
} from '../agent/agentActions'
|
|
29
10
|
export {
|
|
30
11
|
application,
|
|
31
12
|
applications,
|
|
@@ -48,23 +29,6 @@ export {
|
|
|
48
29
|
type DeletedResult,
|
|
49
30
|
type UpdateApplicationInput,
|
|
50
31
|
} from '../applications/applications'
|
|
51
|
-
export {
|
|
52
|
-
createUserApplication,
|
|
53
|
-
deleteUserApplication,
|
|
54
|
-
updateUserApplication,
|
|
55
|
-
userApplication,
|
|
56
|
-
userApplications,
|
|
57
|
-
} from '../applications/userApplications'
|
|
58
|
-
export {
|
|
59
|
-
type CreateUserApplicationInput,
|
|
60
|
-
type DeleteUserApplicationInput,
|
|
61
|
-
type UpdateUserApplicationInput,
|
|
62
|
-
type UserApplication,
|
|
63
|
-
type UserApplicationDeployment,
|
|
64
|
-
type UserApplicationsOptions,
|
|
65
|
-
type UserApplicationWriteFields,
|
|
66
|
-
} from '../applications/userApplications'
|
|
67
|
-
export {isStudioConfig} from '../auth/authMode'
|
|
68
32
|
export {AuthStateType} from '../auth/authStateType'
|
|
69
33
|
export {
|
|
70
34
|
type AuthState,
|
|
@@ -84,31 +48,38 @@ export {
|
|
|
84
48
|
export {observeOrganizationVerificationState} from '../auth/getOrganizationVerificationState'
|
|
85
49
|
export {handleAuthCallback} from '../auth/handleAuthCallback'
|
|
86
50
|
export {logout} from '../auth/logout'
|
|
87
|
-
export {
|
|
88
|
-
type ApiErrorBody,
|
|
89
|
-
getClientErrorApiBody,
|
|
90
|
-
getClientErrorApiDescription,
|
|
91
|
-
getClientErrorApiType,
|
|
92
|
-
isProjectUserNotFoundClientError,
|
|
93
|
-
} from '../auth/utils'
|
|
94
51
|
export type {ClientStoreState as ClientState} from '../client/clientStore'
|
|
95
52
|
export {type ClientOptions, getClient, getClientState} from '../client/clientStore'
|
|
96
53
|
export {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
54
|
+
createComment,
|
|
55
|
+
type CreateCommentOptions,
|
|
56
|
+
removeComment,
|
|
57
|
+
type RemoveCommentOptions,
|
|
58
|
+
replyToComment,
|
|
59
|
+
type ReplyToCommentOptions,
|
|
60
|
+
setCommentStatus,
|
|
61
|
+
type SetCommentStatusOptions,
|
|
62
|
+
updateComment,
|
|
63
|
+
type UpdateCommentOptions,
|
|
64
|
+
} from '../comments/commentActions'
|
|
65
|
+
export {
|
|
66
|
+
type CommentsOptions,
|
|
67
|
+
getCommentsState,
|
|
68
|
+
getCommentThreadsState,
|
|
69
|
+
resolveComments,
|
|
70
|
+
type ResolveCommentsOptions,
|
|
71
|
+
resolveCommentThreads,
|
|
72
|
+
} from '../comments/commentsStore'
|
|
106
73
|
export {
|
|
107
|
-
type
|
|
108
|
-
type
|
|
109
|
-
type
|
|
110
|
-
type
|
|
111
|
-
|
|
74
|
+
type Comment,
|
|
75
|
+
type CommentLocalState,
|
|
76
|
+
type CommentMessage,
|
|
77
|
+
type CommentReaction,
|
|
78
|
+
type CommentStatus,
|
|
79
|
+
type CommentTextSelection,
|
|
80
|
+
type CommentTextSelectionItem,
|
|
81
|
+
type CommentThread,
|
|
82
|
+
} from '../comments/types'
|
|
112
83
|
export {type AuthConfig, type AuthProvider} from '../config/authConfig'
|
|
113
84
|
export {
|
|
114
85
|
createDatasetHandle,
|
|
@@ -127,22 +98,15 @@ export {
|
|
|
127
98
|
} from '../config/loggingConfig'
|
|
128
99
|
export {
|
|
129
100
|
type CanvasResource,
|
|
130
|
-
type CanvasSource,
|
|
131
101
|
type DatasetHandle,
|
|
132
102
|
type DatasetResource,
|
|
133
|
-
type DatasetSource,
|
|
134
103
|
type DocumentHandle,
|
|
135
104
|
type DocumentResource,
|
|
136
|
-
type DocumentSource,
|
|
137
105
|
type DocumentTypeHandle,
|
|
138
106
|
isCanvasResource,
|
|
139
|
-
isCanvasSource,
|
|
140
107
|
isDatasetResource,
|
|
141
|
-
isDatasetSource,
|
|
142
108
|
isMediaLibraryResource,
|
|
143
|
-
isMediaLibrarySource,
|
|
144
109
|
type MediaLibraryResource,
|
|
145
|
-
type MediaLibrarySource,
|
|
146
110
|
type PerspectiveHandle,
|
|
147
111
|
type ProjectHandle,
|
|
148
112
|
type ReleaseHandle,
|
|
@@ -239,26 +203,22 @@ export {
|
|
|
239
203
|
} from '../organization/organization'
|
|
240
204
|
export {organizations} from '../organizations/organizations'
|
|
241
205
|
export {type Organizations, type OrganizationsOptions} from '../organizations/organizations'
|
|
242
|
-
export {getPresence} from '../presence/presenceStore'
|
|
206
|
+
export {getDocumentPresence, getPresence, reportPresence} from '../presence/presenceStore'
|
|
243
207
|
export type {
|
|
244
208
|
DisconnectEvent,
|
|
209
|
+
DocumentPresence,
|
|
210
|
+
DocumentPresenceOptions,
|
|
245
211
|
PresenceLocation,
|
|
212
|
+
PresencePerspectiveOptions,
|
|
213
|
+
PresenceSelection,
|
|
214
|
+
PresenceSelectionPoint,
|
|
215
|
+
ReportPresenceOptions,
|
|
246
216
|
RollCallEvent,
|
|
247
217
|
StateEvent,
|
|
248
218
|
TransportEvent,
|
|
249
219
|
UserPresence,
|
|
250
220
|
} from '../presence/types'
|
|
251
|
-
export {
|
|
252
|
-
export {PREVIEW_PROJECTION} from '../preview/previewConstants'
|
|
253
|
-
export {transformProjectionToPreview} from '../preview/previewProjectionUtils'
|
|
254
|
-
export {resolvePreview, type ResolvePreviewOptions} from '../preview/resolvePreview'
|
|
255
|
-
export type {
|
|
256
|
-
PreviewMedia,
|
|
257
|
-
PreviewQueryResult,
|
|
258
|
-
PreviewStoreState,
|
|
259
|
-
PreviewValue,
|
|
260
|
-
ValuePending,
|
|
261
|
-
} from '../preview/types'
|
|
221
|
+
export type {PreviewMedia, PreviewQueryResult, PreviewValue} from '../preview/types'
|
|
262
222
|
export {type OrgVerificationResult} from '../project/organizationVerification'
|
|
263
223
|
export {project} from '../project/project'
|
|
264
224
|
export {
|
|
@@ -271,22 +231,15 @@ export {
|
|
|
271
231
|
} from '../project/project'
|
|
272
232
|
export {getProjectionState} from '../projection/getProjectionState'
|
|
273
233
|
export {resolveProjection} from '../projection/resolveProjection'
|
|
274
|
-
export {type ProjectionValuePending
|
|
234
|
+
export {type ProjectionValuePending} from '../projection/types'
|
|
275
235
|
export {projects} from '../projects/projects'
|
|
276
236
|
export {type ProjectsOptions} from '../projects/projects'
|
|
277
|
-
export {
|
|
278
|
-
getQueryKey,
|
|
279
|
-
getQueryState,
|
|
280
|
-
parseQueryKey,
|
|
281
|
-
type QueryOptions,
|
|
282
|
-
resolveQuery,
|
|
283
|
-
} from '../query/queryStore'
|
|
237
|
+
export {getQueryState, type QueryOptions, resolveQuery} from '../query/queryStore'
|
|
284
238
|
export {getPerspectiveState} from '../releases/getPerspectiveState'
|
|
285
239
|
export type {ReleaseState} from '../releases/releasesStore'
|
|
286
240
|
export {getActiveReleasesState, getAllReleasesState} from '../releases/releasesStore'
|
|
287
241
|
export {createSanityInstance, type SanityInstance} from '../store/createSanityInstance'
|
|
288
242
|
export {type Selector, type StateSource} from '../store/createStateSourceAction'
|
|
289
|
-
export {getUsersKey, parseUsersKey} from '../users/reducers'
|
|
290
243
|
export {
|
|
291
244
|
type GetUserOptions,
|
|
292
245
|
type GetUsersOptions,
|
|
@@ -307,7 +260,6 @@ export {
|
|
|
307
260
|
resolveUsers,
|
|
308
261
|
} from '../users/usersStore'
|
|
309
262
|
export {type FetcherStore, type FetcherStoreState} from '../utils/createFetcherStore'
|
|
310
|
-
export {createGroqSearchFilter} from '../utils/createGroqSearchFilter'
|
|
311
263
|
export {getCorsErrorProjectId} from '../utils/getCorsErrorProjectId'
|
|
312
264
|
export {isImportError} from '../utils/isImportError'
|
|
313
265
|
export {CORE_SDK_VERSION} from '../version'
|
|
@@ -30,6 +30,11 @@ test('Application — no includes: only the base shape, no config or activeDeplo
|
|
|
30
30
|
expectTypeOf<Extract<keyof Application, ChildKeys>>().toEqualTypeOf<never>()
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
+
test('ApplicationBase — carries name and reference as strings', () => {
|
|
34
|
+
expectTypeOf<ApplicationBase['name']>().toEqualTypeOf<string>()
|
|
35
|
+
expectTypeOf<ApplicationBase['reference']>().toEqualTypeOf<string>()
|
|
36
|
+
})
|
|
37
|
+
|
|
33
38
|
test('Application — config.studio adds a required config.studio', () => {
|
|
34
39
|
expectTypeOf<
|
|
35
40
|
Application<'config.studio'>['config']['studio']
|
|
@@ -120,6 +120,10 @@ export interface ApplicationBase {
|
|
|
120
120
|
id: string
|
|
121
121
|
type: 'studio' | 'coreApp'
|
|
122
122
|
title: string
|
|
123
|
+
/** Stable, immutable identity, distinct from the mutable `slug` address. */
|
|
124
|
+
name: string
|
|
125
|
+
/** Qualified, globally-unique handle: `sanity/<name>` for singletons, `<organizationId>/<name>` otherwise. */
|
|
126
|
+
reference: string
|
|
123
127
|
icon: string | null
|
|
124
128
|
isSingleton: boolean
|
|
125
129
|
visibility: 'default' | 'unlisted' | 'disabled'
|
|
@@ -280,8 +284,7 @@ export interface DeletedResult {
|
|
|
280
284
|
}
|
|
281
285
|
|
|
282
286
|
/**
|
|
283
|
-
* Dashboard visibility for an application.
|
|
284
|
-
* application's `dashboardStatus`.
|
|
287
|
+
* Dashboard visibility for an application.
|
|
285
288
|
*
|
|
286
289
|
* @see https://www.sanity.io/docs/http-reference/applications-api
|
|
287
290
|
* @internal
|
|
@@ -9,11 +9,6 @@ describe('resolveAuthMode', () => {
|
|
|
9
9
|
expect(resolveAuthMode(config, 'https://example.com')).toBe('studio')
|
|
10
10
|
})
|
|
11
11
|
|
|
12
|
-
it('returns "studio" when deprecated studioMode.enabled is true', () => {
|
|
13
|
-
const config: SanityConfig = {studioMode: {enabled: true}}
|
|
14
|
-
expect(resolveAuthMode(config, 'https://example.com')).toBe('studio')
|
|
15
|
-
})
|
|
16
|
-
|
|
17
12
|
it('returns "dashboard" when _context URL param has a non-empty JSON object', () => {
|
|
18
13
|
const context = encodeURIComponent(JSON.stringify({orgId: '123'}))
|
|
19
14
|
const href = `https://example.com?_context=${context}`
|
|
@@ -23,14 +18,6 @@ describe('resolveAuthMode', () => {
|
|
|
23
18
|
it('returns "standalone" by default', () => {
|
|
24
19
|
expect(resolveAuthMode({}, 'https://example.com')).toBe('standalone')
|
|
25
20
|
})
|
|
26
|
-
|
|
27
|
-
it('prefers studio config over studioMode', () => {
|
|
28
|
-
const config: SanityConfig = {
|
|
29
|
-
studio: {},
|
|
30
|
-
studioMode: {enabled: true},
|
|
31
|
-
}
|
|
32
|
-
expect(resolveAuthMode(config, 'https://example.com')).toBe('studio')
|
|
33
|
-
})
|
|
34
21
|
})
|
|
35
22
|
|
|
36
23
|
describe('isStudioConfig', () => {
|
|
@@ -38,19 +25,7 @@ describe('isStudioConfig', () => {
|
|
|
38
25
|
expect(isStudioConfig({studio: {}})).toBe(true)
|
|
39
26
|
})
|
|
40
27
|
|
|
41
|
-
it('returns true when deprecated studioMode.enabled is true', () => {
|
|
42
|
-
expect(isStudioConfig({studioMode: {enabled: true}})).toBe(true)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('returns false when studioMode.enabled is false', () => {
|
|
46
|
-
expect(isStudioConfig({studioMode: {enabled: false}})).toBe(false)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
28
|
it('returns false for empty config', () => {
|
|
50
29
|
expect(isStudioConfig({})).toBe(false)
|
|
51
30
|
})
|
|
52
|
-
|
|
53
|
-
it('returns true when both studio and studioMode are present', () => {
|
|
54
|
-
expect(isStudioConfig({studio: {}, studioMode: {enabled: true}})).toBe(true)
|
|
55
|
-
})
|
|
56
31
|
})
|
package/src/auth/authMode.ts
CHANGED
|
@@ -20,9 +20,8 @@ type AuthMode = 'studio' | 'dashboard' | 'standalone'
|
|
|
20
20
|
*
|
|
21
21
|
* Priority:
|
|
22
22
|
* 1. `studio` config provided → `'studio'`
|
|
23
|
-
* 2. `
|
|
24
|
-
* 3.
|
|
25
|
-
* 4. Otherwise → `'standalone'`
|
|
23
|
+
* 2. Dashboard context detected (`_context` URL param with content) → `'dashboard'`
|
|
24
|
+
* 3. Otherwise → `'standalone'`
|
|
26
25
|
*
|
|
27
26
|
* @internal
|
|
28
27
|
*/
|
|
@@ -34,13 +33,11 @@ export function resolveAuthMode(config: SanityConfig, locationHref: string): Aut
|
|
|
34
33
|
|
|
35
34
|
/**
|
|
36
35
|
* Returns `true` when the config indicates the SDK is running inside a Studio.
|
|
37
|
-
* Checks the new `studio` field first, then falls back to the deprecated
|
|
38
|
-
* `studioMode.enabled` for backwards compatibility.
|
|
39
36
|
*
|
|
40
37
|
* @internal
|
|
41
38
|
*/
|
|
42
39
|
export function isStudioConfig(config: SanityConfig): boolean {
|
|
43
|
-
return !!config.studio
|
|
40
|
+
return !!config.studio
|
|
44
41
|
}
|
|
45
42
|
|
|
46
43
|
/**
|
package/src/auth/authStore.ts
CHANGED
|
@@ -110,7 +110,6 @@ export const authStore = defineStore<AuthStoreState>({
|
|
|
110
110
|
hasCustomProviders: !!(
|
|
111
111
|
instance.config.auth?.providers && instance.config.auth.providers.length > 0
|
|
112
112
|
),
|
|
113
|
-
studioMode: instance.config.studioMode?.enabled ?? false,
|
|
114
113
|
})
|
|
115
114
|
|
|
116
115
|
const {
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import {type SanityClient} from '@sanity/client'
|
|
2
|
+
import {BehaviorSubject, firstValueFrom, NEVER, of, throwError} from 'rxjs'
|
|
3
|
+
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'
|
|
4
|
+
|
|
5
|
+
import {getClient, getClientState} from '../client/clientStore'
|
|
6
|
+
import {createSanityInstance, type SanityInstance} from '../store/createSanityInstance'
|
|
7
|
+
import {type StateSource} from '../store/createStateSourceAction'
|
|
8
|
+
import {
|
|
9
|
+
getAddonDatasetState,
|
|
10
|
+
observeAddonDatasetClient,
|
|
11
|
+
provisionAddonDataset,
|
|
12
|
+
} from './addonDatasetStore'
|
|
13
|
+
|
|
14
|
+
vi.mock('../client/clientStore', () => ({
|
|
15
|
+
getClient: vi.fn(),
|
|
16
|
+
getClientState: vi.fn(),
|
|
17
|
+
}))
|
|
18
|
+
|
|
19
|
+
let instance: SanityInstance
|
|
20
|
+
let observableRequest: ReturnType<typeof vi.fn>
|
|
21
|
+
let request: ReturnType<typeof vi.fn>
|
|
22
|
+
|
|
23
|
+
function mockClient() {
|
|
24
|
+
observableRequest = vi.fn()
|
|
25
|
+
request = vi.fn()
|
|
26
|
+
const client = {observable: {request: observableRequest}, request} as unknown as SanityClient
|
|
27
|
+
|
|
28
|
+
vi.mocked(getClient).mockReturnValue(client)
|
|
29
|
+
vi.mocked(getClientState).mockReturnValue({
|
|
30
|
+
observable: of(client),
|
|
31
|
+
getCurrent: () => client,
|
|
32
|
+
subscribe: () => () => {},
|
|
33
|
+
} as unknown as StateSource<SanityClient>)
|
|
34
|
+
|
|
35
|
+
return client
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Waits for discovery, which runs asynchronously when the store initializes. */
|
|
39
|
+
function resolvedAddonDataset() {
|
|
40
|
+
return firstValueFrom(getAddonDatasetState(instance, {}).observable.pipe())
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
beforeEach(() => {
|
|
44
|
+
vi.resetAllMocks()
|
|
45
|
+
instance = createSanityInstance({projectId: 'p', dataset: 'd'})
|
|
46
|
+
mockClient()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
instance.dispose()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
describe('getAddonDatasetState', () => {
|
|
54
|
+
it('reports the dataset name once discovery answers', async () => {
|
|
55
|
+
observableRequest.mockReturnValue(of([{name: 'd-comments'}]))
|
|
56
|
+
|
|
57
|
+
await vi.waitFor(() =>
|
|
58
|
+
expect(getAddonDatasetState(instance, {}).getCurrent()).toBe('d-comments'),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
expect(observableRequest).toHaveBeenCalledWith({
|
|
62
|
+
uri: '/projects/p/datasets?datasetProfile=comments&addonFor=d',
|
|
63
|
+
tag: 'comments.addon-dataset.list',
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('reports null when the project has no comments dataset', async () => {
|
|
68
|
+
observableRequest.mockReturnValue(of([]))
|
|
69
|
+
|
|
70
|
+
await vi.waitFor(() => expect(getAddonDatasetState(instance, {}).getCurrent()).toBe(null))
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('reports null rather than erroring when discovery is forbidden', async () => {
|
|
74
|
+
// A member without access to the addon dataset gets a 403. There is nothing
|
|
75
|
+
// for them to read, which is the same outcome as the dataset not existing.
|
|
76
|
+
observableRequest.mockReturnValue(throwError(() => ({statusCode: 403})))
|
|
77
|
+
|
|
78
|
+
await vi.waitFor(() => expect(getAddonDatasetState(instance, {}).getCurrent()).toBe(null))
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('recovers when a new authenticated client arrives after a transient failure', async () => {
|
|
82
|
+
const firstClient = {
|
|
83
|
+
observable: {request: vi.fn(() => throwError(() => ({statusCode: 500})))},
|
|
84
|
+
} as unknown as SanityClient
|
|
85
|
+
const secondClient = {
|
|
86
|
+
observable: {request: vi.fn(() => of([{name: 'd-comments'}]))},
|
|
87
|
+
} as unknown as SanityClient
|
|
88
|
+
const clients = new BehaviorSubject(firstClient)
|
|
89
|
+
|
|
90
|
+
vi.mocked(getClientState).mockReturnValue({
|
|
91
|
+
observable: clients,
|
|
92
|
+
getCurrent: () => clients.getValue(),
|
|
93
|
+
subscribe: () => () => {},
|
|
94
|
+
} as unknown as StateSource<SanityClient>)
|
|
95
|
+
|
|
96
|
+
const state = getAddonDatasetState(instance, {})
|
|
97
|
+
expect(state.getCurrent()).toBe(undefined)
|
|
98
|
+
|
|
99
|
+
clients.next(secondClient)
|
|
100
|
+
|
|
101
|
+
await vi.waitFor(() => expect(state.getCurrent()).toBe('d-comments'))
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('stays undefined while discovery is in flight', () => {
|
|
105
|
+
observableRequest.mockReturnValue(NEVER)
|
|
106
|
+
expect(getAddonDatasetState(instance, {}).getCurrent()).toBe(undefined)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('throws for a resource that is not a dataset', () => {
|
|
110
|
+
expect(() => getAddonDatasetState(instance, {resource: {mediaLibraryId: 'ml-1'}})).toThrow(
|
|
111
|
+
/only supported for dataset resources/,
|
|
112
|
+
)
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
describe('provisionAddonDataset', () => {
|
|
117
|
+
it('returns the existing dataset without writing anything', async () => {
|
|
118
|
+
observableRequest.mockReturnValue(of([{name: 'd-comments'}]))
|
|
119
|
+
await resolvedAddonDataset()
|
|
120
|
+
|
|
121
|
+
await expect(provisionAddonDataset(instance, {})).resolves.toBe('d-comments')
|
|
122
|
+
expect(request).not.toHaveBeenCalled()
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('re-checks before creating, and adopts a dataset another user just made', async () => {
|
|
126
|
+
// Discovery said missing when this client started, but someone else has
|
|
127
|
+
// provisioned it since. Creating it again would fail.
|
|
128
|
+
observableRequest.mockReturnValueOnce(of([])).mockReturnValueOnce(of([{name: 'd-comments'}]))
|
|
129
|
+
await resolvedAddonDataset()
|
|
130
|
+
|
|
131
|
+
await expect(provisionAddonDataset(instance, {})).resolves.toBe('d-comments')
|
|
132
|
+
expect(request).not.toHaveBeenCalled()
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('creates the dataset when the re-check confirms it is missing', async () => {
|
|
136
|
+
observableRequest.mockReturnValue(of([]))
|
|
137
|
+
request.mockResolvedValue({datasetName: 'd-comments'})
|
|
138
|
+
await resolvedAddonDataset()
|
|
139
|
+
|
|
140
|
+
await expect(provisionAddonDataset(instance, {})).resolves.toBe('d-comments')
|
|
141
|
+
expect(request).toHaveBeenCalledWith({
|
|
142
|
+
uri: '/comments/d/setup',
|
|
143
|
+
method: 'POST',
|
|
144
|
+
tag: 'comments.addon-dataset.setup',
|
|
145
|
+
})
|
|
146
|
+
expect(getAddonDatasetState(instance, {}).getCurrent()).toBe('d-comments')
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('issues one POST for concurrent callers', async () => {
|
|
150
|
+
observableRequest.mockReturnValue(of([]))
|
|
151
|
+
request.mockResolvedValue({datasetName: 'd-comments'})
|
|
152
|
+
await resolvedAddonDataset()
|
|
153
|
+
|
|
154
|
+
const results = await Promise.all([
|
|
155
|
+
provisionAddonDataset(instance, {}),
|
|
156
|
+
provisionAddonDataset(instance, {}),
|
|
157
|
+
provisionAddonDataset(instance, {}),
|
|
158
|
+
])
|
|
159
|
+
|
|
160
|
+
expect(results).toEqual(['d-comments', 'd-comments', 'd-comments'])
|
|
161
|
+
expect(request).toHaveBeenCalledTimes(1)
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it('throws when setup returns no dataset name', async () => {
|
|
165
|
+
observableRequest.mockReturnValue(of([]))
|
|
166
|
+
request.mockResolvedValue({})
|
|
167
|
+
await resolvedAddonDataset()
|
|
168
|
+
|
|
169
|
+
await expect(provisionAddonDataset(instance, {})).rejects.toThrow(/no dataset name/)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('allows a retry after a failure', async () => {
|
|
173
|
+
observableRequest.mockReturnValue(of([]))
|
|
174
|
+
request.mockRejectedValueOnce(new Error('boom')).mockResolvedValue({datasetName: 'd-comments'})
|
|
175
|
+
await resolvedAddonDataset()
|
|
176
|
+
|
|
177
|
+
await expect(provisionAddonDataset(instance, {})).rejects.toThrow('boom')
|
|
178
|
+
await expect(provisionAddonDataset(instance, {})).resolves.toBe('d-comments')
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
describe('observeAddonDatasetClient', () => {
|
|
183
|
+
it('does not report a missing dataset while discovery is still in flight', () => {
|
|
184
|
+
observableRequest.mockReturnValue(NEVER)
|
|
185
|
+
const values: Array<SanityClient | null> = []
|
|
186
|
+
|
|
187
|
+
const subscription = observeAddonDatasetClient(instance, {}).subscribe((value) =>
|
|
188
|
+
values.push(value),
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
expect(values).toEqual([])
|
|
192
|
+
subscription.unsubscribe()
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
it('emits null while the project has no comments dataset', async () => {
|
|
196
|
+
observableRequest.mockReturnValue(of([]))
|
|
197
|
+
|
|
198
|
+
await expect(firstValueFrom(observeAddonDatasetClient(instance, {}))).resolves.toBe(null)
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
it('emits a client once the dataset is known', async () => {
|
|
202
|
+
const client = mockClient()
|
|
203
|
+
observableRequest.mockReturnValue(of([{name: 'd-comments'}]))
|
|
204
|
+
|
|
205
|
+
await vi.waitFor(async () =>
|
|
206
|
+
expect(await firstValueFrom(observeAddonDatasetClient(instance, {}))).toBe(client),
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
expect(getClientState).toHaveBeenCalledWith(instance, {
|
|
210
|
+
apiVersion: 'v2025-05-06',
|
|
211
|
+
projectId: 'p',
|
|
212
|
+
dataset: 'd-comments',
|
|
213
|
+
})
|
|
214
|
+
})
|
|
215
|
+
})
|